@morphika/andami 0.1.2 → 0.1.5

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 (85) hide show
  1. package/app/(site)/[slug]/page.tsx +2 -2
  2. package/app/(site)/layout.tsx +1 -0
  3. package/app/(site)/page.tsx +2 -2
  4. package/app/(site)/preview/page.tsx +4 -4
  5. package/app/(site)/work/[slug]/page.tsx +2 -2
  6. package/app/admin/layout.tsx +2 -2
  7. package/app/admin/login/page.tsx +5 -5
  8. package/app/admin/navigation/page.tsx +255 -157
  9. package/app/api/admin/assets/relink/confirm/route.ts +1 -1
  10. package/app/api/admin/pages/[slug]/route.ts +1 -1
  11. package/app/api/admin/settings/route.ts +40 -15
  12. package/app/api/admin/setup/complete/route.ts +1 -1
  13. package/app/api/admin/setup/route.ts +6 -3
  14. package/components/admin/index.ts +7 -0
  15. package/components/admin/nav-builder/NavGeneralSettings.tsx +11 -15
  16. package/components/admin/nav-builder/NavItemSettings.tsx +29 -5
  17. package/components/admin/nav-builder/NavLivePreview.tsx +4 -1
  18. package/components/admin/nav-builder/NavMobileLivePreview.tsx +226 -0
  19. package/components/admin/nav-builder/NavMobileSettings.tsx +223 -0
  20. package/components/admin/nav-builder/index.ts +2 -0
  21. package/components/blocks/BlockRenderer.tsx +65 -13
  22. package/components/blocks/ButtonBlockRenderer.tsx +29 -6
  23. package/components/blocks/CoverBlockRenderer.tsx +36 -14
  24. package/components/blocks/ImageBlockRenderer.tsx +5 -3
  25. package/components/blocks/ImageGridBlockRenderer.tsx +13 -6
  26. package/components/blocks/PageRenderer.tsx +4 -2
  27. package/components/blocks/ProjectGridBlockRenderer.tsx +18 -3
  28. package/components/blocks/SectionRenderer.tsx +9 -8
  29. package/components/blocks/SectionV2Renderer.tsx +8 -8
  30. package/components/blocks/SpacerBlockRenderer.tsx +4 -2
  31. package/components/blocks/TextBlockRenderer.tsx +9 -4
  32. package/components/builder/BuilderCanvas.tsx +10 -4
  33. package/components/builder/ColorPicker.tsx +51 -243
  34. package/components/builder/ColorSwatchPicker.tsx +214 -274
  35. package/components/builder/DndWrapper.tsx +5 -2
  36. package/components/builder/SectionV2Canvas.tsx +15 -4
  37. package/components/builder/asset-browser/useAssetBrowser.ts +9 -1
  38. package/components/builder/color-picker/AlphaSlider.tsx +141 -0
  39. package/components/builder/color-picker/AngleControl.tsx +138 -0
  40. package/components/builder/color-picker/ColorInputs.tsx +105 -0
  41. package/components/builder/color-picker/EyedropperButton.tsx +74 -0
  42. package/components/builder/color-picker/GradientBar.tsx +222 -0
  43. package/components/builder/color-picker/GradientPreview.tsx +53 -0
  44. package/components/builder/color-picker/HueSlider.tsx +124 -0
  45. package/components/builder/color-picker/MeshCanvas.tsx +172 -0
  46. package/components/builder/color-picker/MeshPointEditor.tsx +133 -0
  47. package/components/builder/color-picker/MeshPointList.tsx +200 -0
  48. package/components/builder/color-picker/PositionControl.tsx +158 -0
  49. package/components/builder/color-picker/SaturationCanvas.tsx +142 -0
  50. package/components/builder/color-picker/StopEditor.tsx +178 -0
  51. package/components/builder/color-picker/SwatchBar.tsx +93 -0
  52. package/components/builder/color-picker/UnifiedColorPicker.tsx +713 -0
  53. package/components/builder/color-picker/index.ts +62 -0
  54. package/components/builder/color-picker/types.ts +115 -0
  55. package/components/builder/color-picker/utils.ts +138 -0
  56. package/components/builder/editors/CoverBlockEditor.tsx +86 -32
  57. package/components/builder/editors/ProjectGridEditor.tsx +51 -4
  58. package/components/builder/hooks/useColumnDrag.ts +25 -27
  59. package/components/builder/settings-panel/BlockLayoutTab.tsx +29 -7
  60. package/components/builder/settings-panel/LayoutTab.tsx +382 -310
  61. package/components/builder/settings-panel/PageSettings.tsx +6 -4
  62. package/components/builder/settings-panel/ParallaxSlideSettings.tsx +2 -2
  63. package/components/builder/settings-panel/SectionV2LayoutTab.tsx +392 -312
  64. package/components/builder/settings-panel/SectionV2Settings.tsx +65 -35
  65. package/components/ui/Navbar.tsx +95 -25
  66. package/components/ui/PortfolioTracker.tsx +3 -3
  67. package/lib/assets.ts +1 -1
  68. package/lib/auth.ts +1 -1
  69. package/lib/builder/gradient-presets.ts +128 -0
  70. package/lib/builder/layout-styles.ts +16 -10
  71. package/lib/builder/serializer.ts +1 -0
  72. package/lib/builder/store-blocks.ts +48 -61
  73. package/lib/builder/store-helpers.ts +31 -14
  74. package/lib/builder/store.ts +59 -41
  75. package/lib/builder/types.ts +14 -0
  76. package/lib/color-utils.ts +200 -0
  77. package/lib/config/index.ts +14 -43
  78. package/lib/revalidate.ts +2 -2
  79. package/lib/sanity/queries.ts +4 -3
  80. package/lib/sanity/types.ts +76 -1
  81. package/lib/setup/detect.ts +1 -1
  82. package/package.json +8 -12
  83. package/sanity/schemas/siteSettings.ts +34 -0
  84. package/styles/base.css +7 -51
  85. package/app/globals.css +0 -7
@@ -209,7 +209,7 @@ export const publishedProjectSummariesQuery = groq`
209
209
 
210
210
  // All non-project page slugs (for generateStaticParams on /[slug])
211
211
  export const allPageSlugsQuery = groq`
212
- *[_type == "page" && page_type != "project" && draft_mode != true].slug.current
212
+ *[_type == "page" && page_type != "project" && draft_mode != true && defined(slug.current)].slug.current
213
213
  `;
214
214
 
215
215
  // Get a published project page by slug (for public /work/[slug] route)
@@ -231,7 +231,7 @@ export const publishedProjectBySlugQuery = groq`
231
231
 
232
232
  // All published project slugs (for generateStaticParams on /work/[slug])
233
233
  export const allProjectSlugsQuery = groq`
234
- *[_type == "page" && page_type == "project" && draft_mode != true].slug.current
234
+ *[_type == "page" && page_type == "project" && draft_mode != true && defined(slug.current)].slug.current
235
235
  `;
236
236
 
237
237
  // ============================================
@@ -375,7 +375,7 @@ export const siteStylesQuery = groq`
375
375
  // ============================================
376
376
 
377
377
  export const siteSettingsQuery = groq`
378
- *[_type == "siteSettings"][0] {
378
+ *[_id == "siteSettings"][0] {
379
379
  nav_items[] {
380
380
  _key,
381
381
  type,
@@ -398,6 +398,7 @@ export const siteSettingsQuery = groq`
398
398
  style_overrides
399
399
  },
400
400
  nav_design,
401
+ nav_mobile_design,
401
402
  default_title,
402
403
  default_description,
403
404
  default_og_image,
@@ -232,6 +232,9 @@ export interface CoverBlock {
232
232
  // Overlay
233
233
  overlay?: "none" | "dark" | "light" | "gradient-bottom" | "gradient-top";
234
234
  overlay_opacity?: number;
235
+ /** Custom overlay gradient (Phase 4). JSON-serialized ColorField.
236
+ * When set, takes precedence over overlay + overlay_opacity. */
237
+ overlay_gradient?: string;
235
238
  // Layout
236
239
  content_align_h?: "left" | "center" | "right";
237
240
  content_align_v?: "top" | "center" | "bottom";
@@ -676,7 +679,8 @@ export interface NavItem {
676
679
 
677
680
  export interface NavDesign {
678
681
  logo_text?: string;
679
- color?: NavColorVariant;
682
+ /** Nav text color — legacy NavColorVariant preset OR hex string (e.g. "#d4ff00"). */
683
+ color?: NavColorVariant | string;
680
684
  position?: "fixed" | "sticky" | "static";
681
685
  hide_on_scroll?: boolean;
682
686
  font_size?: number;
@@ -702,6 +706,31 @@ export interface NavDesign {
702
706
  entrance_stagger_delay?: number; // ms between items, default 80
703
707
  }
704
708
 
709
+ // ============================================
710
+ // Mobile Nav Design — independent mobile menu styles (Session 158)
711
+ // ============================================
712
+ // These styles apply ONLY to the hamburger mobile menu.
713
+ // Page-level nav_color and parallax slide color overrides do NOT
714
+ // affect the mobile menu — it always uses these dedicated values
715
+ // (with fallback to desktop NavDesign where noted).
716
+
717
+ export interface MobileNavDesign {
718
+ // ── Overlay (expanded fullscreen menu) ──
719
+ overlay_bg?: string; // hex color, default "#0a0a0a" (brand-dark)
720
+ text_color?: string; // hex color, empty = inherit from desktop design.color
721
+ font_size?: number; // px, default 24
722
+ text_transform?: "none" | "uppercase" | "lowercase" | "capitalize";
723
+ items_gap?: number; // px, default 32
724
+ items_align?: "left" | "center" | "right";
725
+
726
+ // ── Navbar bar (logo + hamburger row, visible before menu opens) ──
727
+ navbar_bg?: string; // hex color, empty = transparent
728
+ navbar_bg_opacity?: number; // 0–100, default 0
729
+ hamburger_color?: string; // hex color, empty = inherit from desktop design.color
730
+ padding_h?: number; // px, default 24
731
+ padding_v?: number; // px, default 27
732
+ }
733
+
705
734
  // ============================================
706
735
  // Storage Provider
707
736
  // ============================================
@@ -765,6 +794,7 @@ export interface AssetRegistry {
765
794
  export interface SiteSettings {
766
795
  nav_items?: NavItem[];
767
796
  nav_design?: NavDesign;
797
+ nav_mobile_design?: MobileNavDesign;
768
798
  default_title?: string;
769
799
  default_description?: string;
770
800
  default_og_image?: string;
@@ -811,6 +841,51 @@ export interface ColorSwatch {
811
841
  hex: string;
812
842
  }
813
843
 
844
+ // ─── Color Field (Phase 2 — gradient-ready) ───
845
+
846
+ /** A stop in a linear or radial gradient */
847
+ export interface GradientStop {
848
+ color: string; // hex #RRGGBB
849
+ alpha: number; // 0-1
850
+ position: number; // 0-100 (%)
851
+ }
852
+
853
+ /** A point in a mesh gradient */
854
+ export interface MeshPoint {
855
+ color: string; // hex #RRGGBB
856
+ x: number; // 0-100 (%)
857
+ y: number; // 0-100 (%)
858
+ }
859
+
860
+ export interface LinearGradient {
861
+ type: "linear";
862
+ stops: GradientStop[]; // min 2
863
+ angle: number; // 0-360
864
+ }
865
+
866
+ export interface RadialGradient {
867
+ type: "radial";
868
+ stops: GradientStop[]; // min 2
869
+ position: { x: number; y: number }; // center, 0-100
870
+ shape: "circle" | "ellipse";
871
+ }
872
+
873
+ export interface MeshGradient {
874
+ type: "mesh";
875
+ points: MeshPoint[]; // min 2
876
+ background: string; // hex
877
+ }
878
+
879
+ /** Gradient value — only for fields that support gradients */
880
+ export type GradientValue = LinearGradient | RadialGradient | MeshGradient;
881
+
882
+ /**
883
+ * Color field value in Sanity.
884
+ * - string: solid hex color (backward compatible with existing data)
885
+ * - GradientValue: gradient (Phase 3 UI, renderers ready now)
886
+ */
887
+ export type ColorField = string | GradientValue;
888
+
814
889
  export interface ColorPalette {
815
890
  swatches: ColorSwatch[];
816
891
  // Legacy fields (backward compat, may be empty)
@@ -103,7 +103,7 @@ export async function isSetupMarkedComplete(): Promise<boolean> {
103
103
 
104
104
  try {
105
105
  const result = await client.fetch<{ complete: boolean }>(
106
- `*[_type == "siteSettings"][0]{ "complete": setup_complete == true }`
106
+ `*[_id == "siteSettings"][0]{ "complete": setup_complete == true }`
107
107
  );
108
108
  return !!result?.complete;
109
109
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morphika/andami",
3
- "version": "0.1.2",
3
+ "version": "0.1.5",
4
4
  "description": "Visual Page Builder — core library. A reusable website builder with visual editing, CMS integration, and asset management.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,7 +46,6 @@
46
46
  "exports": {
47
47
  "./config": "./lib/config/index.ts",
48
48
  "./config/types": "./lib/config/types.ts",
49
-
50
49
  "./components/blocks": "./components/blocks/index.ts",
51
50
  "./components/blocks/*": "./components/blocks/*.tsx",
52
51
  "./components/builder": "./components/builder/index.ts",
@@ -54,18 +53,24 @@
54
53
  "./components/builder/editors/*": "./components/builder/editors/*.tsx",
55
54
  "./components/builder/settings-panel": "./components/builder/settings-panel/index.ts",
56
55
  "./components/builder/settings-panel/*": "./components/builder/settings-panel/*.tsx",
56
+ "./components/builder/settings-panel/responsive-helpers": "./components/builder/settings-panel/responsive-helpers.ts",
57
57
  "./components/builder/asset-browser": "./components/builder/asset-browser/index.ts",
58
58
  "./components/builder/asset-browser/*": "./components/builder/asset-browser/*.tsx",
59
+ "./components/builder/asset-browser/helpers": "./components/builder/asset-browser/helpers.ts",
60
+ "./components/builder/asset-browser/types": "./components/builder/asset-browser/types.ts",
61
+ "./components/builder/asset-browser/useAssetBrowser": "./components/builder/asset-browser/useAssetBrowser.ts",
62
+ "./components/builder/asset-browser/useR2DragDrop": "./components/builder/asset-browser/useR2DragDrop.ts",
63
+ "./components/builder/asset-browser/useR2Operations": "./components/builder/asset-browser/useR2Operations.ts",
59
64
  "./components/builder/live-preview": "./components/builder/live-preview/index.ts",
60
65
  "./components/builder/live-preview/*": "./components/builder/live-preview/*.tsx",
61
66
  "./components/admin": "./components/admin/index.ts",
62
67
  "./components/admin/*": "./components/admin/*.tsx",
63
68
  "./components/admin/nav-builder": "./components/admin/nav-builder/index.ts",
64
69
  "./components/admin/nav-builder/*": "./components/admin/nav-builder/*.tsx",
70
+ "./components/admin/nav-builder/nav-builder-utils": "./components/admin/nav-builder/nav-builder-utils.ts",
65
71
  "./components/admin/styles": "./components/admin/styles/index.ts",
66
72
  "./components/admin/styles/*": "./components/admin/styles/*.tsx",
67
73
  "./components/ui/*": "./components/ui/*.tsx",
68
-
69
74
  "./lib/builder": "./lib/builder/index.ts",
70
75
  "./lib/builder/*": "./lib/builder/*.ts",
71
76
  "./lib/sanity/client": "./lib/sanity/client.ts",
@@ -94,7 +99,6 @@
94
99
  "./lib/format-utils": "./lib/format-utils.ts",
95
100
  "./lib/utils": "./lib/utils.ts",
96
101
  "./lib/asset-retry": "./lib/asset-retry.ts",
97
-
98
102
  "./sanity/schemas": "./sanity/schemas/index.ts",
99
103
  "./sanity/schemas/*": "./sanity/schemas/*.ts",
100
104
  "./sanity/schemas/blocks": "./sanity/schemas/blocks/index.ts",
@@ -102,12 +106,10 @@
102
106
  "./sanity/schemas/objects/*": "./sanity/schemas/objects/*.ts",
103
107
  "./sanity/compose": "./sanity/compose.ts",
104
108
  "./sanity/config": "./sanity/sanity.config.ts",
105
-
106
109
  "./styles/base.css": "./styles/base.css",
107
110
  "./styles/animations.css": "./styles/animations.css",
108
111
  "./styles/admin.css": "./styles/admin.css",
109
112
  "./styles/globals.css": "./styles/globals.css",
110
-
111
113
  "./site": "./site/index.ts",
112
114
  "./site/page": "./site/page.ts",
113
115
  "./site/work": "./site/work.ts",
@@ -116,7 +118,6 @@
116
118
  "./site/error": "./site/error.ts",
117
119
  "./site/robots": "./site/robots.ts",
118
120
  "./site/sitemap": "./site/sitemap.ts",
119
-
120
121
  "./admin": "./admin/index.ts",
121
122
  "./admin/login": "./admin/login.ts",
122
123
  "./admin/pages": "./admin/pages.ts",
@@ -130,14 +131,10 @@
130
131
  "./admin/database": "./admin/database.ts",
131
132
  "./admin/settings": "./admin/settings.ts",
132
133
  "./admin/setup": "./admin/setup.ts",
133
-
134
134
  "./components/admin/setup-wizard": "./components/admin/setup-wizard/index.ts",
135
135
  "./components/admin/setup-wizard/*": "./components/admin/setup-wizard/*.tsx",
136
-
137
136
  "./lib/setup/detect": "./lib/setup/detect.ts",
138
-
139
137
  "./studio": "./studio/index.ts",
140
-
141
138
  "./api/admin/auth": "./app/api/admin/auth/route.ts",
142
139
  "./api/admin/pages": "./app/api/admin/pages/route.ts",
143
140
  "./api/admin/pages/slug": "./app/api/admin/pages/[slug]/route.ts",
@@ -183,7 +180,6 @@
183
180
  "@aws-sdk/client-s3": "^3.1021.0",
184
181
  "@aws-sdk/s3-request-presigner": "^3.1021.0",
185
182
  "@dnd-kit/core": "^6.3.1",
186
- "@dnd-kit/modifiers": "^9.0.0",
187
183
  "@dnd-kit/sortable": "^10.0.0",
188
184
  "@dnd-kit/utilities": "^3.2.2",
189
185
  "next-sanity": "^12.1.5",
@@ -213,6 +213,40 @@ export default defineType({
213
213
  ],
214
214
  }),
215
215
 
216
+ // === MOBILE NAV DESIGN (Session 158) ===
217
+ defineField({
218
+ name: "nav_mobile_design",
219
+ title: "Mobile Navigation Design",
220
+ type: "object",
221
+ group: "nav_design",
222
+ description: "Independent styles for the mobile hamburger menu",
223
+ fields: [
224
+ defineField({ name: "overlay_bg", title: "Overlay Background", type: "string", description: "Hex color for fullscreen menu background" }),
225
+ defineField({ name: "text_color", title: "Text Color", type: "string", description: "Hex color, empty = inherit from desktop" }),
226
+ defineField({ name: "font_size", title: "Font Size (px)", type: "number", initialValue: 24 }),
227
+ defineField({
228
+ name: "text_transform",
229
+ title: "Text Transform",
230
+ type: "string",
231
+ options: { list: [{ title: "None", value: "none" }, { title: "Uppercase", value: "uppercase" }, { title: "Lowercase", value: "lowercase" }, { title: "Capitalize", value: "capitalize" }] },
232
+ initialValue: "uppercase",
233
+ }),
234
+ defineField({ name: "items_gap", title: "Items Gap (px)", type: "number", initialValue: 32 }),
235
+ defineField({
236
+ name: "items_align",
237
+ title: "Items Align",
238
+ type: "string",
239
+ options: { list: [{ title: "Left", value: "left" }, { title: "Center", value: "center" }, { title: "Right", value: "right" }] },
240
+ initialValue: "center",
241
+ }),
242
+ defineField({ name: "navbar_bg", title: "Navbar Bar Background", type: "string", description: "Hex color for the logo+hamburger bar" }),
243
+ defineField({ name: "navbar_bg_opacity", title: "Navbar Bar BG Opacity (%)", type: "number", initialValue: 0 }),
244
+ defineField({ name: "hamburger_color", title: "Hamburger Icon Color", type: "string", description: "Hex color, empty = inherit from desktop" }),
245
+ defineField({ name: "padding_h", title: "Horizontal Padding (px)", type: "number", initialValue: 24 }),
246
+ defineField({ name: "padding_v", title: "Vertical Padding (px)", type: "number", initialValue: 27 }),
247
+ ],
248
+ }),
249
+
216
250
  // === METADATA ===
217
251
  defineField({ name: "default_title", title: "Default Title", type: "string", group: "meta", initialValue: _cfg.defaults.metaTitle }),
218
252
  defineField({ name: "default_description", title: "Default Description", type: "text", rows: 3, group: "meta" }),
package/styles/base.css CHANGED
@@ -1,17 +1,14 @@
1
- @import "tailwindcss";
2
-
3
- /* ============================================
1
+ /* ============================================
4
2
  Brand Design Tokens
5
3
  Values come from site.config.ts palette.
6
4
  Tailwind generates classes: bg-brand-*, text-brand-*, etc.
5
+
6
+ NOTE: @import "tailwindcss" is NOT included here.
7
+ Each instance must add it in their own globals.css BEFORE
8
+ importing this file.
7
9
  ============================================ */
8
10
 
9
11
  @theme inline {
10
- /* Brand Colors — semantic tokens.
11
- Initial values are neutral placeholders for Tailwind class generation.
12
- Actual colors are injected at runtime by StylesProvider from the admin
13
- palette, with site.config.ts palette as fallback.
14
- See lib/styles/provider.tsx → generateBrandTokens(). */
15
12
  --color-brand-accent: var(--brand-accent, #888888);
16
13
  --color-brand-accent-alt: var(--brand-accent-alt, #888888);
17
14
  --color-brand-secondary: var(--brand-secondary, #888888);
@@ -21,11 +18,9 @@
21
18
  --color-brand-muted: var(--brand-muted, #888888);
22
19
  --color-brand-dark: var(--brand-dark, #111111);
23
20
 
24
- /* Fonts — placeholders, overridden by StylesProvider */
25
21
  --font-mono: var(--brand-font-mono, ui-monospace, monospace);
26
22
  --font-sans: "Inter", system-ui, sans-serif;
27
23
 
28
- /* Breakpoints — matching original Semplice grid */
29
24
  --breakpoint-xs: 0px;
30
25
  --breakpoint-sm: 544px;
31
26
  --breakpoint-md: 768px;
@@ -33,20 +28,6 @@
33
28
  --breakpoint-xl: 1170px;
34
29
  }
35
30
 
36
- /* ============================================
37
- @font-face — Instance Default Font
38
- No hardcoded @font-face here. The default/fallback font is loaded
39
- by StylesProvider at runtime based on site.config.ts typography
40
- settings and admin-uploaded fonts. For the initial render before
41
- JS loads, the --font-mono stack in @theme provides the fallback.
42
- ============================================ */
43
-
44
- /* ============================================
45
- Admin UI Tokens
46
- Used across all builder/admin components.
47
- JS constants in lib/builder/constants.ts mirror these.
48
- ============================================ */
49
-
50
31
  :root {
51
32
  --admin-accent: #076bff;
52
33
  --admin-accent-dark: #0559d4;
@@ -56,10 +37,6 @@
56
37
  --admin-success: #22c55e;
57
38
  }
58
39
 
59
- /* ============================================
60
- Base styles
61
- ============================================ */
62
-
63
40
  html {
64
41
  scroll-behavior: smooth;
65
42
  overflow-x: clip;
@@ -69,24 +46,17 @@ html {
69
46
  body {
70
47
  background: var(--color-brand-dark);
71
48
  color: var(--color-brand-text);
72
- font-family: var(--font-mono);
49
+ font-family: var(--font-sans);
73
50
  overflow-x: clip;
74
51
  width: 100%;
75
- /* Smooth body bg transition when navigating between pages with different
76
- backgrounds. PageBackground component syncs this via inline style. */
77
52
  transition: background-color 300ms ease;
78
53
  }
79
54
 
80
- /* Public site wrapper:
81
- - overflow-x:clip prevents horizontal scroll (iOS WebKit fix, stricter than hidden)
82
- - max-width:100vw constrains all children to viewport width */
83
55
  [data-site] {
84
56
  max-width: 100vw;
85
57
  overflow-x: clip;
86
58
  }
87
59
 
88
- /* Custom cursor: hide native cursor when enabled via data attribute.
89
- Controlled by site.config.ts features.customCursor → site layout. */
90
60
  [data-custom-cursor] {
91
61
  cursor: none;
92
62
  }
@@ -96,37 +66,23 @@ body {
96
66
  cursor: none;
97
67
  }
98
68
 
99
- /* Restore cursor inside Sanity Studio */
100
69
  [data-sanity-studio], [data-sanity-studio] *, [data-ui], [data-ui] * {
101
70
  cursor: auto !important;
102
71
  }
103
72
 
104
- /* Selection color */
105
73
  ::selection {
106
74
  background: var(--color-brand-primary);
107
75
  color: var(--color-brand-text);
108
76
  }
109
77
 
110
- /* ============================================
111
- Failed Asset Placeholder
112
- Replaces the browser's broken image icon with a subtle,
113
- clickable placeholder that invites retry. Applied automatically
114
- by lib/asset-retry.ts after exhausting retries.
115
- ============================================ */
116
-
117
78
  img[data-asset-failed] {
118
- /* Hide the browser's broken image icon */
119
79
  color: transparent;
120
- /* Show a neutral placeholder background */
121
80
  background: linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 100%);
122
- /* Ensure it has visible dimensions even without intrinsic size */
123
81
  min-height: 60px;
124
82
  min-width: 60px;
125
- /* Position the "tap to retry" pseudo-element */
126
83
  position: relative;
127
84
  }
128
85
 
129
- /* "Tap to retry" overlay text — uses outline trick for pseudo on img */
130
86
  img[data-asset-failed]::after {
131
87
  content: "Tap to retry";
132
88
  position: absolute;
@@ -135,7 +91,7 @@ img[data-asset-failed]::after {
135
91
  align-items: center;
136
92
  justify-content: center;
137
93
  font-size: 11px;
138
- font-family: var(--font-mono);
94
+ font-family: var(--font-sans);
139
95
  letter-spacing: 0.05em;
140
96
  text-transform: uppercase;
141
97
  color: rgba(255, 255, 255, 0.7);
package/app/globals.css DELETED
@@ -1,7 +0,0 @@
1
- /* Morphika instance — imports all core styles.
2
- This is the monolith entry point; equivalent to:
3
- @import "@morphika/andami/styles/globals.css";
4
- but uses relative paths since we're inside the monorepo. */
5
- @import "../packages/core/styles/base.css";
6
- @import "../packages/core/styles/animations.css";
7
- @import "../packages/core/styles/admin.css";