@morphika/webframe 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +46 -0
  3. package/admin/assets.ts +4 -0
  4. package/admin/database.ts +4 -0
  5. package/admin/index.ts +6 -0
  6. package/admin/login.ts +4 -0
  7. package/admin/navigation.ts +4 -0
  8. package/admin/pages-editor.ts +4 -0
  9. package/admin/pages.ts +4 -0
  10. package/admin/projects-editor.ts +4 -0
  11. package/admin/projects.ts +4 -0
  12. package/admin/settings.ts +4 -0
  13. package/admin/setup.ts +4 -0
  14. package/admin/storage.ts +4 -0
  15. package/admin/styles.ts +4 -0
  16. package/app/(site)/[slug]/loading.tsx +20 -0
  17. package/app/(site)/[slug]/page.tsx +83 -0
  18. package/app/(site)/error.tsx +32 -0
  19. package/app/(site)/layout.tsx +53 -0
  20. package/app/(site)/loading.tsx +20 -0
  21. package/app/(site)/not-found.tsx +41 -0
  22. package/app/(site)/page.tsx +43 -0
  23. package/app/(site)/preview/page.tsx +99 -0
  24. package/app/(site)/work/[slug]/loading.tsx +23 -0
  25. package/app/(site)/work/[slug]/page.tsx +84 -0
  26. package/app/admin/assets/page.tsx +573 -0
  27. package/app/admin/database/page.tsx +302 -0
  28. package/app/admin/error.tsx +53 -0
  29. package/app/admin/layout.tsx +273 -0
  30. package/app/admin/login/page.tsx +88 -0
  31. package/app/admin/navigation/page.tsx +157 -0
  32. package/app/admin/page.tsx +17 -0
  33. package/app/admin/pages/[slug]/page.tsx +849 -0
  34. package/app/admin/pages/page.tsx +588 -0
  35. package/app/admin/projects/[slug]/page.tsx +3 -0
  36. package/app/admin/projects/page.tsx +669 -0
  37. package/app/admin/settings/page.tsx +132 -0
  38. package/app/admin/setup/page.tsx +64 -0
  39. package/app/admin/storage/page.tsx +518 -0
  40. package/app/admin/styles/page.tsx +243 -0
  41. package/app/api/admin/assets/file/route.ts +81 -0
  42. package/app/api/admin/assets/health/route.ts +170 -0
  43. package/app/api/admin/assets/register/route.ts +163 -0
  44. package/app/api/admin/assets/registry/route.ts +98 -0
  45. package/app/api/admin/assets/relink/confirm/route.ts +242 -0
  46. package/app/api/admin/assets/relink/route.ts +202 -0
  47. package/app/api/admin/assets/scan/route.ts +271 -0
  48. package/app/api/admin/auth/route.ts +160 -0
  49. package/app/api/admin/custom-sections/[slug]/route.ts +159 -0
  50. package/app/api/admin/custom-sections/route.ts +127 -0
  51. package/app/api/admin/database/route.ts +53 -0
  52. package/app/api/admin/pages/[slug]/duplicate/route.ts +91 -0
  53. package/app/api/admin/pages/[slug]/route.ts +617 -0
  54. package/app/api/admin/pages/[slug]/set-home/route.ts +76 -0
  55. package/app/api/admin/pages/route.ts +129 -0
  56. package/app/api/admin/preview/route.ts +53 -0
  57. package/app/api/admin/r2/connect/route.ts +181 -0
  58. package/app/api/admin/r2/delete/route.ts +198 -0
  59. package/app/api/admin/r2/disconnect/route.ts +42 -0
  60. package/app/api/admin/r2/rename/route.ts +265 -0
  61. package/app/api/admin/r2/status/route.ts +106 -0
  62. package/app/api/admin/r2/upload-url/route.ts +148 -0
  63. package/app/api/admin/revalidate/route.ts +55 -0
  64. package/app/api/admin/settings/route.ts +279 -0
  65. package/app/api/admin/setup/complete/route.ts +51 -0
  66. package/app/api/admin/setup/route.ts +118 -0
  67. package/app/api/admin/storage/switch/route.ts +117 -0
  68. package/app/api/admin/styles/fonts/route.ts +97 -0
  69. package/app/api/admin/styles/route.ts +304 -0
  70. package/app/api/assets/[...path]/route.ts +98 -0
  71. package/app/api/custom-sections/[id]/route.ts +43 -0
  72. package/app/api/draft-mode/disable/route.ts +10 -0
  73. package/app/api/draft-mode/enable/route.ts +26 -0
  74. package/app/api/projects/route.ts +42 -0
  75. package/app/api/styles/route.ts +88 -0
  76. package/app/favicon.ico +0 -0
  77. package/app/globals.css +7 -0
  78. package/app/layout.tsx +53 -0
  79. package/app/robots.ts +17 -0
  80. package/app/sitemap.ts +48 -0
  81. package/app/studio/[[...index]]/page.tsx +8 -0
  82. package/components/admin/MetadataEditor.tsx +173 -0
  83. package/components/admin/PublishToggle.tsx +130 -0
  84. package/components/admin/icons.tsx +40 -0
  85. package/components/admin/nav-builder/NavBuilder.tsx +182 -0
  86. package/components/admin/nav-builder/NavBuilderGrid.tsx +326 -0
  87. package/components/admin/nav-builder/NavGeneralSettings.tsx +275 -0
  88. package/components/admin/nav-builder/NavGridCell.tsx +48 -0
  89. package/components/admin/nav-builder/NavGridItem.tsx +189 -0
  90. package/components/admin/nav-builder/NavItemSettings.tsx +288 -0
  91. package/components/admin/nav-builder/NavItemTypePicker.tsx +102 -0
  92. package/components/admin/nav-builder/NavLivePreview.tsx +125 -0
  93. package/components/admin/nav-builder/NavSettingsFields.tsx +248 -0
  94. package/components/admin/nav-builder/NavSettingsPanel.tsx +127 -0
  95. package/components/admin/nav-builder/index.ts +10 -0
  96. package/components/admin/nav-builder/nav-builder-utils.ts +238 -0
  97. package/components/admin/setup-wizard/BrandingStep.tsx +218 -0
  98. package/components/admin/setup-wizard/DatabaseStep.tsx +331 -0
  99. package/components/admin/setup-wizard/DoneStep.tsx +187 -0
  100. package/components/admin/setup-wizard/SetupWizard.tsx +166 -0
  101. package/components/admin/setup-wizard/StorageStep.tsx +308 -0
  102. package/components/admin/setup-wizard/WelcomeStep.tsx +96 -0
  103. package/components/admin/setup-wizard/index.ts +9 -0
  104. package/components/admin/styles/ColorsEditor.tsx +214 -0
  105. package/components/admin/styles/FontsEditor.tsx +258 -0
  106. package/components/admin/styles/GridLayoutEditor.tsx +292 -0
  107. package/components/admin/styles/LinksButtonsEditor.tsx +120 -0
  108. package/components/admin/styles/TypographyEditor.tsx +266 -0
  109. package/components/admin/styles/index.ts +9 -0
  110. package/components/admin/styles/shared.tsx +68 -0
  111. package/components/blocks/BlockRenderer.tsx +404 -0
  112. package/components/blocks/ButtonBlockRenderer.tsx +52 -0
  113. package/components/blocks/CoverBlockRenderer.tsx +239 -0
  114. package/components/blocks/CustomSectionInstanceRenderer.tsx +82 -0
  115. package/components/blocks/EnterAnimationWrapper.tsx +140 -0
  116. package/components/blocks/HoverAnimationWrapper.tsx +308 -0
  117. package/components/blocks/ImageBlockRenderer.tsx +61 -0
  118. package/components/blocks/ImageGridBlockRenderer.tsx +545 -0
  119. package/components/blocks/PageBackground.tsx +28 -0
  120. package/components/blocks/PageNavAnimation.tsx +35 -0
  121. package/components/blocks/PageNavColor.tsx +24 -0
  122. package/components/blocks/PageRenderer.tsx +142 -0
  123. package/components/blocks/ParallaxGroupRenderer.tsx +448 -0
  124. package/components/blocks/ParallaxSlideRenderer.tsx +175 -0
  125. package/components/blocks/ProjectGridBlockRenderer.tsx +556 -0
  126. package/components/blocks/SectionRenderer.tsx +170 -0
  127. package/components/blocks/SectionV2Renderer.tsx +330 -0
  128. package/components/blocks/ShaderCanvas.tsx +392 -0
  129. package/components/blocks/SpacerBlockRenderer.tsx +17 -0
  130. package/components/blocks/TextBlockRenderer.tsx +87 -0
  131. package/components/blocks/TypewriterRichText.tsx +464 -0
  132. package/components/blocks/TypewriterWrapper.tsx +149 -0
  133. package/components/blocks/VideoBlockRenderer.tsx +304 -0
  134. package/components/blocks/index.ts +2 -0
  135. package/components/builder/AssetBrowser.tsx +2 -0
  136. package/components/builder/BlockLivePreview.tsx +101 -0
  137. package/components/builder/BlockTypePicker.tsx +178 -0
  138. package/components/builder/BuilderCanvas.tsx +354 -0
  139. package/components/builder/CanvasMinimap.tsx +200 -0
  140. package/components/builder/CanvasToolbar.tsx +202 -0
  141. package/components/builder/ColorPicker.tsx +243 -0
  142. package/components/builder/ColorSwatchPicker.tsx +274 -0
  143. package/components/builder/ColumnDragContext.tsx +51 -0
  144. package/components/builder/ColumnDragOverlay.tsx +110 -0
  145. package/components/builder/CustomSectionInstanceCard.tsx +97 -0
  146. package/components/builder/DeviceFrame.tsx +123 -0
  147. package/components/builder/DndWrapper.tsx +337 -0
  148. package/components/builder/InsertionLines.tsx +186 -0
  149. package/components/builder/ParallaxGroupCanvas.tsx +228 -0
  150. package/components/builder/ParallaxSlideHeader.tsx +113 -0
  151. package/components/builder/ReadOnlyFrame.tsx +417 -0
  152. package/components/builder/SectionEditorBar.tsx +288 -0
  153. package/components/builder/SectionTypePicker.tsx +422 -0
  154. package/components/builder/SectionV2Canvas.tsx +297 -0
  155. package/components/builder/SectionV2Column.tsx +488 -0
  156. package/components/builder/SettingsPanel.tsx +911 -0
  157. package/components/builder/SortableBlock.tsx +230 -0
  158. package/components/builder/SortableRow.tsx +362 -0
  159. package/components/builder/VirtualAssetGrid.tsx +397 -0
  160. package/components/builder/asset-browser/AssetBrowser.tsx +178 -0
  161. package/components/builder/asset-browser/FileLightbox.tsx +116 -0
  162. package/components/builder/asset-browser/FolderTreeItem.tsx +55 -0
  163. package/components/builder/asset-browser/R2BrowserContent.tsx +436 -0
  164. package/components/builder/asset-browser/R2ContextMenu.tsx +98 -0
  165. package/components/builder/asset-browser/VideoThumbnail.tsx +63 -0
  166. package/components/builder/asset-browser/helpers.ts +88 -0
  167. package/components/builder/asset-browser/index.ts +1 -0
  168. package/components/builder/asset-browser/types.ts +49 -0
  169. package/components/builder/asset-browser/useAssetBrowser.ts +344 -0
  170. package/components/builder/asset-browser/useR2DragDrop.ts +116 -0
  171. package/components/builder/asset-browser/useR2Operations.ts +189 -0
  172. package/components/builder/blockStyles.tsx +295 -0
  173. package/components/builder/editors/ButtonBlockEditor.tsx +184 -0
  174. package/components/builder/editors/CoverBlockEditor.tsx +488 -0
  175. package/components/builder/editors/EnterAnimationPicker.tsx +297 -0
  176. package/components/builder/editors/HoverEffectPicker.tsx +209 -0
  177. package/components/builder/editors/ImageBlockEditor.tsx +206 -0
  178. package/components/builder/editors/ImageGridBlockEditor.tsx +386 -0
  179. package/components/builder/editors/ProjectGridEditor.tsx +648 -0
  180. package/components/builder/editors/SpacerBlockEditor.tsx +167 -0
  181. package/components/builder/editors/StaggerSettings.tsx +108 -0
  182. package/components/builder/editors/TextAlignmentIcons.tsx +39 -0
  183. package/components/builder/editors/TextBlockEditor.tsx +462 -0
  184. package/components/builder/editors/TextStylePicker.tsx +183 -0
  185. package/components/builder/editors/VideoBlockEditor.tsx +278 -0
  186. package/components/builder/editors/index.ts +10 -0
  187. package/components/builder/editors/shared.tsx +345 -0
  188. package/components/builder/hooks/useColumnDrag.ts +472 -0
  189. package/components/builder/hooks/useColumnResize.ts +221 -0
  190. package/components/builder/index.ts +12 -0
  191. package/components/builder/live-preview/LiveButtonPreview.tsx +38 -0
  192. package/components/builder/live-preview/LiveCoverPreview.tsx +146 -0
  193. package/components/builder/live-preview/LiveImageGridPreview.tsx +123 -0
  194. package/components/builder/live-preview/LiveImagePreview.tsx +107 -0
  195. package/components/builder/live-preview/LiveProjectGridPreview.tsx +1010 -0
  196. package/components/builder/live-preview/LiveSpacerPreview.tsx +9 -0
  197. package/components/builder/live-preview/LiveTextEditor.tsx +198 -0
  198. package/components/builder/live-preview/LiveVideoPreview.tsx +98 -0
  199. package/components/builder/live-preview/index.ts +10 -0
  200. package/components/builder/live-preview/shared.tsx +153 -0
  201. package/components/builder/settings-panel/BlockLayoutTab.tsx +532 -0
  202. package/components/builder/settings-panel/BlockSettings.tsx +94 -0
  203. package/components/builder/settings-panel/ColumnV2Settings.tsx +160 -0
  204. package/components/builder/settings-panel/LayoutTab.tsx +310 -0
  205. package/components/builder/settings-panel/PageSettings.tsx +200 -0
  206. package/components/builder/settings-panel/ParallaxGroupSettings.tsx +118 -0
  207. package/components/builder/settings-panel/ParallaxSlideSettings.tsx +178 -0
  208. package/components/builder/settings-panel/SectionV2AnimationTab.tsx +103 -0
  209. package/components/builder/settings-panel/SectionV2LayoutTab.tsx +312 -0
  210. package/components/builder/settings-panel/SectionV2Settings.tsx +323 -0
  211. package/components/builder/settings-panel/TRBLInputs.tsx +51 -0
  212. package/components/builder/settings-panel/index.ts +19 -0
  213. package/components/builder/settings-panel/responsive-helpers.ts +524 -0
  214. package/components/ui/CustomCursor.tsx +118 -0
  215. package/components/ui/NavContentLightbox.tsx +152 -0
  216. package/components/ui/Navbar.tsx +582 -0
  217. package/components/ui/PortfolioTracker.tsx +87 -0
  218. package/components/ui/ScrollToTop.tsx +47 -0
  219. package/lib/animation/enter-presets.ts +147 -0
  220. package/lib/animation/enter-resolve.ts +90 -0
  221. package/lib/animation/enter-types.ts +128 -0
  222. package/lib/animation/hover-effect-presets.ts +210 -0
  223. package/lib/animation/hover-effect-types.ts +126 -0
  224. package/lib/asset-retry.ts +111 -0
  225. package/lib/assets.ts +92 -0
  226. package/lib/audit.ts +35 -0
  227. package/lib/auth-token.ts +94 -0
  228. package/lib/auth.ts +13 -0
  229. package/lib/builder/cascade-helpers.ts +51 -0
  230. package/lib/builder/cascade.ts +533 -0
  231. package/lib/builder/constants.ts +103 -0
  232. package/lib/builder/defaults.ts +182 -0
  233. package/lib/builder/history.ts +48 -0
  234. package/lib/builder/index.ts +21 -0
  235. package/lib/builder/layout-styles.ts +344 -0
  236. package/lib/builder/masonry.ts +166 -0
  237. package/lib/builder/responsive.ts +156 -0
  238. package/lib/builder/serializer.ts +845 -0
  239. package/lib/builder/store-blocks.ts +193 -0
  240. package/lib/builder/store-canvas.ts +319 -0
  241. package/lib/builder/store-helpers.ts +490 -0
  242. package/lib/builder/store-sections.ts +709 -0
  243. package/lib/builder/store.ts +333 -0
  244. package/lib/builder/templates.ts +297 -0
  245. package/lib/builder/types.ts +374 -0
  246. package/lib/builder/utils.ts +37 -0
  247. package/lib/color-utils.ts +116 -0
  248. package/lib/config/index.ts +57 -0
  249. package/lib/config/types.ts +122 -0
  250. package/lib/contexts/AssetContext.tsx +79 -0
  251. package/lib/contexts/NavAnimationContext.tsx +44 -0
  252. package/lib/contexts/NavColorContext.tsx +38 -0
  253. package/lib/contexts/PageExitContext.tsx +194 -0
  254. package/lib/contexts/ThumbStatusContext.tsx +83 -0
  255. package/lib/csrf-client.ts +34 -0
  256. package/lib/csrf.ts +68 -0
  257. package/lib/format-utils.ts +24 -0
  258. package/lib/hooks/useViewport.ts +42 -0
  259. package/lib/logger.ts +81 -0
  260. package/lib/revalidate.ts +23 -0
  261. package/lib/sanitize.ts +91 -0
  262. package/lib/sanity/client.ts +8 -0
  263. package/lib/sanity/queries.ts +486 -0
  264. package/lib/sanity/types.ts +869 -0
  265. package/lib/sanity/writeClient.ts +24 -0
  266. package/lib/security.ts +402 -0
  267. package/lib/setup/detect.ts +156 -0
  268. package/lib/shader/glsl/index.ts +27 -0
  269. package/lib/shader/glsl/pixelate.ts +51 -0
  270. package/lib/shader/glsl/rgb-shift.ts +45 -0
  271. package/lib/shader/glsl/ripple.ts +46 -0
  272. package/lib/shader/glsl/vertex.ts +14 -0
  273. package/lib/storage/index.ts +211 -0
  274. package/lib/storage/r2-adapter.ts +286 -0
  275. package/lib/storage/types.ts +125 -0
  276. package/lib/styles/provider.tsx +267 -0
  277. package/lib/thumbnails/generate.ts +151 -0
  278. package/lib/utils.ts +6 -0
  279. package/package.json +212 -0
  280. package/sanity/compose.ts +65 -0
  281. package/sanity/sanity.config.ts +126 -0
  282. package/sanity/schemas/assetRegistry.ts +301 -0
  283. package/sanity/schemas/blocks/blockLayout.ts +90 -0
  284. package/sanity/schemas/blocks/buttonBlock.ts +82 -0
  285. package/sanity/schemas/blocks/coverBlock.ts +229 -0
  286. package/sanity/schemas/blocks/imageBlock.ts +58 -0
  287. package/sanity/schemas/blocks/imageGridBlock.ts +112 -0
  288. package/sanity/schemas/blocks/index.ts +9 -0
  289. package/sanity/schemas/blocks/projectGridBlock.ts +251 -0
  290. package/sanity/schemas/blocks/spacerBlock.ts +41 -0
  291. package/sanity/schemas/blocks/textBlock.ts +139 -0
  292. package/sanity/schemas/blocks/videoBlock.ts +80 -0
  293. package/sanity/schemas/customSection.ts +69 -0
  294. package/sanity/schemas/customSectionInstance.ts +163 -0
  295. package/sanity/schemas/index.ts +111 -0
  296. package/sanity/schemas/objects/enterAnimationConfig.ts +72 -0
  297. package/sanity/schemas/objects/hoverEffectConfig.ts +90 -0
  298. package/sanity/schemas/objects/parallaxGroup.ts +66 -0
  299. package/sanity/schemas/objects/parallaxSlide.ts +217 -0
  300. package/sanity/schemas/objects/typewriterConfig.ts +38 -0
  301. package/sanity/schemas/page.ts +162 -0
  302. package/sanity/schemas/pageSection.ts +157 -0
  303. package/sanity/schemas/pageSectionV2.ts +269 -0
  304. package/sanity/schemas/siteSettings.ts +256 -0
  305. package/sanity/schemas/siteStyles.ts +210 -0
  306. package/site/error.ts +4 -0
  307. package/site/index.ts +8 -0
  308. package/site/not-found.ts +4 -0
  309. package/site/page.ts +4 -0
  310. package/site/preview.ts +4 -0
  311. package/site/robots.ts +4 -0
  312. package/site/sitemap.ts +4 -0
  313. package/site/work.ts +4 -0
  314. package/studio/index.ts +4 -0
  315. package/styles/admin.css +85 -0
  316. package/styles/animations.css +237 -0
  317. package/styles/base.css +148 -0
  318. package/styles/globals.css +10 -0
  319. package/tsconfig.json +25 -0
@@ -0,0 +1,486 @@
1
+ import { groq } from "next-sanity";
2
+
3
+ // ============================================
4
+ // BLOCK EXPANSION (shared fragment)
5
+ // ============================================
6
+
7
+ // Deep expansion of row → column → block content.
8
+ // Handles Row objects (columns→blocks), PageSection objects (_type: "pageSection"),
9
+ // PageSectionV2 objects (_type: "pageSectionV2"), CustomSectionInstance, and
10
+ // ParallaxGroup objects (_type: "parallaxGroup") with nested slides.
11
+ // GROQ uses conditional projections to handle all types.
12
+ const blockExpansion = `
13
+ content_rows[] {
14
+ _key,
15
+ _type,
16
+ // ── PageSection fields (only present when _type == "pageSection") ──
17
+ section_type,
18
+ block[] {
19
+ _type,
20
+ _key,
21
+ ...,
22
+ "project_ref": project_ref-> {
23
+ _id,
24
+ title,
25
+ slug,
26
+ page_type
27
+ }
28
+ },
29
+ // ── Row fields (columns only present on row objects) ──
30
+ // Note: V2 sections also have "columns" but with different fields.
31
+ // GROQ projections are additive — fields that don't exist on an object are omitted.
32
+ // We include BOTH Row column fields (width, settings, responsive) and V2 column
33
+ // fields (grid_column, grid_row, span) so both types are fully hydrated.
34
+ columns[] {
35
+ _key,
36
+ _type,
37
+ // Row column fields
38
+ width,
39
+ settings,
40
+ responsive,
41
+ // V2 column fields (grid positions)
42
+ grid_column,
43
+ grid_row,
44
+ span,
45
+ // Blocks (shared by both Row columns and V2 columns)
46
+ blocks[] {
47
+ _type,
48
+ _key,
49
+ ...,
50
+ // Expand references in project-related blocks
51
+ "project_ref": project_ref-> {
52
+ _id,
53
+ title,
54
+ slug,
55
+ page_type
56
+ }
57
+ }
58
+ },
59
+ // ── CustomSectionInstance fields (only present when _type == "customSectionInstance") ──
60
+ custom_section_id,
61
+ custom_section_slug,
62
+ custom_section_title,
63
+ settings_overrides,
64
+ responsive_overrides,
65
+ // ── ParallaxGroup fields (only present when _type == "parallaxGroup") ──
66
+ transition_effect,
67
+ snap_enabled,
68
+ parallax_intensity,
69
+ slides[] {
70
+ _key,
71
+ _type,
72
+ background_type,
73
+ background_image,
74
+ background_video,
75
+ background_position,
76
+ background_overlay_color,
77
+ background_overlay_opacity,
78
+ nav_color,
79
+ section_settings,
80
+ columns[] {
81
+ _key,
82
+ _type,
83
+ grid_column,
84
+ grid_row,
85
+ span,
86
+ blocks[] {
87
+ _type,
88
+ _key,
89
+ ...,
90
+ "project_ref": project_ref-> {
91
+ _id,
92
+ title,
93
+ slug,
94
+ page_type
95
+ }
96
+ }
97
+ }
98
+ },
99
+ // ── Settings (shared by Row, PageSection, and PageSectionV2) ──
100
+ settings,
101
+ // ── Responsive overrides (V2 sections store responsive at section level) ──
102
+ responsive
103
+ }
104
+ `;
105
+
106
+ // ============================================
107
+ // PAGE QUERIES
108
+ // ============================================
109
+
110
+ // Get a page by slug
111
+ export const pageBySlugQuery = groq`
112
+ *[_type == "page" && slug.current == $slug][0] {
113
+ _id,
114
+ title,
115
+ slug,
116
+ page_type,
117
+ is_home,
118
+ metadata,
119
+ page_settings,
120
+ published_at,
121
+ draft_mode,
122
+ thumbnail_path,
123
+ cover_video,
124
+ ${blockExpansion}
125
+ }
126
+ `;
127
+
128
+ // Get the home page (is_home == true, non-project, published)
129
+ export const homePageQuery = groq`
130
+ *[_type == "page" && is_home == true && page_type != "project" && draft_mode != true][0] {
131
+ _id,
132
+ title,
133
+ slug,
134
+ page_type,
135
+ is_home,
136
+ metadata,
137
+ page_settings,
138
+ published_at,
139
+ ${blockExpansion}
140
+ }
141
+ `;
142
+
143
+ // Get a published page by slug (for public routes, excludes drafts)
144
+ export const publishedPageBySlugQuery = groq`
145
+ *[_type == "page" && slug.current == $slug && page_type != "project" && draft_mode != true][0] {
146
+ _id,
147
+ title,
148
+ slug,
149
+ page_type,
150
+ is_home,
151
+ metadata,
152
+ page_settings,
153
+ published_at,
154
+ ${blockExpansion}
155
+ }
156
+ `;
157
+
158
+ // List all pages
159
+ export const allPagesQuery = groq`
160
+ *[_type == "page"] | order(is_home desc, title asc) {
161
+ _id,
162
+ title,
163
+ slug,
164
+ page_type,
165
+ is_home,
166
+ draft_mode,
167
+ published_at,
168
+ thumbnail_path,
169
+ cover_video
170
+ }
171
+ `;
172
+
173
+ // List pages by type
174
+ export const pagesByTypeQuery = groq`
175
+ *[_type == "page" && page_type == $pageType] | order(title asc) {
176
+ _id,
177
+ title,
178
+ slug,
179
+ page_type,
180
+ is_home,
181
+ draft_mode,
182
+ published_at
183
+ }
184
+ `;
185
+
186
+ // All project pages (for archive, grid, etc.)
187
+ export const allProjectPagesQuery = groq`
188
+ *[_type == "page" && page_type == "project" && draft_mode != true] | order(published_at desc) {
189
+ _id,
190
+ title,
191
+ slug,
192
+ page_type,
193
+ metadata,
194
+ published_at
195
+ }
196
+ `;
197
+
198
+ // Published project summaries (public, for ProjectGrid + ParallaxShowcase blocks)
199
+ export const publishedProjectSummariesQuery = groq`
200
+ *[_type == "page" && page_type == "project" && draft_mode != true] | order(published_at desc) {
201
+ _id,
202
+ title,
203
+ slug,
204
+ thumbnail_path,
205
+ cover_video,
206
+ "seo_description": metadata.seo_description
207
+ }
208
+ `;
209
+
210
+ // All non-project page slugs (for generateStaticParams on /[slug])
211
+ export const allPageSlugsQuery = groq`
212
+ *[_type == "page" && page_type != "project" && draft_mode != true].slug.current
213
+ `;
214
+
215
+ // Get a published project page by slug (for public /work/[slug] route)
216
+ export const publishedProjectBySlugQuery = groq`
217
+ *[_type == "page" && slug.current == $slug && page_type == "project" && draft_mode != true][0] {
218
+ _id,
219
+ title,
220
+ slug,
221
+ page_type,
222
+ is_home,
223
+ metadata,
224
+ page_settings,
225
+ published_at,
226
+ thumbnail_path,
227
+ cover_video,
228
+ ${blockExpansion}
229
+ }
230
+ `;
231
+
232
+ // All published project slugs (for generateStaticParams on /work/[slug])
233
+ export const allProjectSlugsQuery = groq`
234
+ *[_type == "page" && page_type == "project" && draft_mode != true].slug.current
235
+ `;
236
+
237
+ // ============================================
238
+ // ASSET REGISTRY
239
+ // ============================================
240
+
241
+ // Storage provider configuration (lightweight, for factory/resolution)
242
+ export const storageProviderQuery = groq`
243
+ *[_type == "assetRegistry"][0] {
244
+ storage_provider,
245
+ r2_bucket_url,
246
+ r2_endpoint,
247
+ r2_bucket_name,
248
+ r2_access_key_id,
249
+ r2_secret_access_key,
250
+ r2_connected_at
251
+ }
252
+ `;
253
+
254
+ // Full registry (for admin asset manager)
255
+ export const assetRegistryQuery = groq`
256
+ *[_type == "assetRegistry"][0] {
257
+ _id,
258
+ storage_provider,
259
+ seed_url,
260
+ scan_status,
261
+ last_scanned_at,
262
+ scan_error,
263
+ r2_bucket_url,
264
+ r2_bucket_name,
265
+ r2_connected_at,
266
+ assets[] {
267
+ _key,
268
+ path,
269
+ filename,
270
+ extension,
271
+ file_size,
272
+ mime_type,
273
+ width,
274
+ height,
275
+ file_hash,
276
+ has_thumbnail,
277
+ status,
278
+ last_checked_at,
279
+ used_in,
280
+ previous_paths
281
+ },
282
+ relink_log[] {
283
+ _key,
284
+ date,
285
+ old_seed,
286
+ new_seed,
287
+ assets_relinked,
288
+ assets_missing,
289
+ details
290
+ }
291
+ }
292
+ `;
293
+
294
+ // Lightweight query for the asset browser (just paths and basic metadata)
295
+ export const assetBrowserQuery = groq`
296
+ *[_type == "assetRegistry"][0] {
297
+ seed_url,
298
+ assets[] {
299
+ _key,
300
+ path,
301
+ filename,
302
+ extension,
303
+ file_size,
304
+ mime_type,
305
+ width,
306
+ height,
307
+ has_thumbnail,
308
+ status
309
+ }
310
+ }
311
+ `;
312
+
313
+ // ============================================
314
+ // SITE SETTINGS
315
+ // ============================================
316
+
317
+ // ============================================
318
+ // SITE STYLES
319
+ // ============================================
320
+
321
+ export const siteStylesQuery = groq`
322
+ *[_type == "siteStyles"][0] {
323
+ fonts[] {
324
+ _key,
325
+ family,
326
+ is_builtin,
327
+ variants[] {
328
+ _key,
329
+ weight,
330
+ style,
331
+ file_url,
332
+ file_id,
333
+ original_filename
334
+ }
335
+ },
336
+ typography_h1,
337
+ typography_h2,
338
+ typography_h3,
339
+ typography_h4,
340
+ typography_body,
341
+ typography_small,
342
+ color_palette[] {
343
+ _key,
344
+ name,
345
+ hex
346
+ },
347
+ color_background,
348
+ color_text,
349
+ color_primary,
350
+ color_secondary,
351
+ color_accent,
352
+ color_muted,
353
+ grid_width,
354
+ grid_outer_padding,
355
+ grid_gutter_desktop,
356
+ grid_gutter_responsive,
357
+ grid_gutter_phone,
358
+ spacing_section_padding,
359
+ spacing_content_gap,
360
+ spacing_border_radius,
361
+ link_color,
362
+ link_hover_color,
363
+ link_underline,
364
+ button_primary_bg,
365
+ button_primary_text,
366
+ button_secondary_bg,
367
+ button_secondary_text,
368
+ button_border_radius,
369
+ disable_scroll_animations_mobile
370
+ }
371
+ `;
372
+
373
+ // ============================================
374
+ // SITE SETTINGS
375
+ // ============================================
376
+
377
+ export const siteSettingsQuery = groq`
378
+ *[_type == "siteSettings"][0] {
379
+ nav_items[] {
380
+ _key,
381
+ type,
382
+ label,
383
+ logo_image,
384
+ link_type,
385
+ "internal_page": internal_page-> {
386
+ _id,
387
+ title,
388
+ slug,
389
+ page_type
390
+ },
391
+ external_url,
392
+ content_type,
393
+ content_asset,
394
+ content_url,
395
+ visible,
396
+ grid_column,
397
+ column_span,
398
+ style_overrides
399
+ },
400
+ nav_design,
401
+ default_title,
402
+ default_description,
403
+ default_og_image,
404
+ favicon_path,
405
+ analytics_id,
406
+ seed_url,
407
+ last_scanned_at,
408
+ asset_status
409
+ }
410
+ `;
411
+
412
+ // ============================================
413
+ // CUSTOM SECTIONS (Session 107)
414
+ // ============================================
415
+
416
+ /** All custom sections for the picker */
417
+ export const allCustomSectionsQuery = groq`
418
+ *[_type == "customSection"] | order(title asc) {
419
+ _id, title, slug, description, thumbnail_path, updated_at
420
+ }
421
+ `;
422
+
423
+ /** Single custom section by slug (full data for editing) */
424
+ export const customSectionBySlugQuery = groq`
425
+ *[_type == "customSection" && slug.current == $slug][0] {
426
+ _id,
427
+ title,
428
+ slug,
429
+ description,
430
+ section {
431
+ _key,
432
+ _type,
433
+ section_type,
434
+ columns[] {
435
+ _key,
436
+ _type,
437
+ grid_column,
438
+ grid_row,
439
+ span,
440
+ blocks[] {
441
+ _type,
442
+ _key,
443
+ ...
444
+ }
445
+ },
446
+ settings,
447
+ responsive
448
+ },
449
+ thumbnail_path,
450
+ updated_at
451
+ }
452
+ `;
453
+
454
+ /** Section data only by ID (for instance rendering, lightweight) */
455
+ export const customSectionByIdQuery = groq`
456
+ *[_type == "customSection" && _id == $id][0] {
457
+ section {
458
+ _key,
459
+ _type,
460
+ section_type,
461
+ columns[] {
462
+ _key,
463
+ _type,
464
+ grid_column,
465
+ grid_row,
466
+ span,
467
+ blocks[] {
468
+ _type,
469
+ _key,
470
+ ...
471
+ }
472
+ },
473
+ settings,
474
+ responsive
475
+ }
476
+ }
477
+ `;
478
+
479
+ /** Pages referencing a custom section (for revalidation + delete safety) */
480
+ export const pagesUsingCustomSectionQuery = groq`
481
+ *[_type == "page" && count(content_rows[_type == "customSectionInstance" && custom_section_id == $id]) > 0] {
482
+ _id,
483
+ title,
484
+ slug
485
+ }
486
+ `;