forgecad 0.7.0 → 0.8.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 (158) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/{AdminPage-DAu1C1ST.js → AdminPage-D4bocK4E.js} +1 -1
  3. package/dist/assets/{DocsPage-Gc_BCdqC.js → DocsPage-D3A_g8V3.js} +85 -45
  4. package/dist/assets/{EditorApp-DG1-oUSV.css → EditorApp-BWYUSpUN.css} +133 -51
  5. package/dist/assets/EditorApp-Cihhqcsq.js +11692 -0
  6. package/dist/assets/{EmbedViewer-CEO8XbV8.js → EmbedViewer-kWjKaC_t.js} +1 -1
  7. package/dist/assets/LandingPageProofDriven-Bg2IUc3l.css +856 -0
  8. package/dist/assets/LandingPageProofDriven-DXkKlyhI.js +601 -0
  9. package/dist/assets/{PricingPage-BSrxu6d7.js → PricingPage-BsU5vzEx.js} +1 -1
  10. package/dist/assets/{SettingsPage-FUCSIRq6.js → SettingsPage-PqvpAKIs.js} +1 -1
  11. package/dist/assets/{evalWorker-KoR0SNKq.js → evalWorker-C-hzNUMy.js} +2218 -286
  12. package/dist/assets/{index-wTEK39at.js → index-Pz321YAt.js} +7416 -1481
  13. package/dist/assets/{index-CyVd1D4D.css → index-ay13WNfa.css} +501 -2
  14. package/dist/assets/{manifold-B1sGWdYk.js → manifold-BcbjWLIo.js} +3 -3
  15. package/dist/assets/{manifold-D7o0N50J.js → manifold-DBckbFgx.js} +1 -1
  16. package/dist/assets/{manifold-G5sBaXzi.js → manifold-O2AAGXyj.js} +1 -1
  17. package/dist/assets/{reportWorker-DYcRHhv9.js → reportWorker-Dxr-5A7w.js} +2003 -259
  18. package/dist/docs/index.html +2 -2
  19. package/dist/docs-raw/CLI.md +488 -0
  20. package/dist/docs-raw/generated/assembly.md +19 -11
  21. package/dist/docs-raw/generated/concepts.md +1023 -360
  22. package/dist/docs-raw/generated/core.md +1165 -264
  23. package/dist/docs-raw/generated/curves.md +168 -1
  24. package/dist/docs-raw/generated/lib.md +10 -5
  25. package/dist/docs-raw/generated/output.md +1 -1
  26. package/dist/docs-raw/generated/sdf.md +208 -0
  27. package/dist/docs-raw/generated/sketch.md +1281 -329
  28. package/dist/docs-raw/generated/viewport.md +29 -2
  29. package/dist/index.html +2 -2
  30. package/dist/landing/proof-ams-adapter.png +0 -0
  31. package/dist/landing/proof-bolt-and-nut.png +0 -0
  32. package/dist/landing/proof-fillet-enclosure.png +0 -0
  33. package/dist/landing/proof-glasses.png +0 -0
  34. package/dist/landing/proof-gyroid.png +0 -0
  35. package/dist/sitemap.xml +6 -6
  36. package/dist-cli/forgecad.js +3148 -555
  37. package/dist-cli/forgecad.js.map +1 -1
  38. package/dist-cli/{solver-FV7TJZGI.js → solver-46FFSK2U.js} +1 -3
  39. package/dist-cli/{solver-FV7TJZGI.js.map → solver-46FFSK2U.js.map} +1 -1
  40. package/dist-skill/CONTEXT.md +3700 -1153
  41. package/dist-skill/SKILL-dev.md +15 -17
  42. package/dist-skill/SKILL.md +14 -9
  43. package/dist-skill/docs/API/core/concepts.md +28 -1
  44. package/dist-skill/docs/CLI.md +488 -0
  45. package/dist-skill/docs/generated/assembly.md +19 -11
  46. package/dist-skill/docs/generated/core.md +1165 -264
  47. package/dist-skill/docs/generated/curves.md +168 -1
  48. package/dist-skill/docs/generated/lib.md +10 -5
  49. package/dist-skill/docs/generated/output.md +1 -1
  50. package/dist-skill/docs/generated/sdf.md +208 -0
  51. package/dist-skill/docs/generated/sketch.md +1281 -329
  52. package/dist-skill/docs/generated/viewport.md +29 -2
  53. package/dist-skill/docs/guides/joint-design.md +78 -0
  54. package/dist-skill/docs-dev/API/core/concepts.md +28 -1
  55. package/dist-skill/docs-dev/CLI.md +488 -0
  56. package/dist-skill/docs-dev/coding.md +1 -1
  57. package/dist-skill/docs-dev/component-model.md +164 -0
  58. package/dist-skill/docs-dev/generated/assembly.md +19 -11
  59. package/dist-skill/docs-dev/generated/core.md +1165 -264
  60. package/dist-skill/docs-dev/generated/curves.md +168 -1
  61. package/dist-skill/docs-dev/generated/lib.md +10 -5
  62. package/dist-skill/docs-dev/generated/output.md +1 -1
  63. package/dist-skill/docs-dev/generated/sdf.md +208 -0
  64. package/dist-skill/docs-dev/generated/sketch.md +1281 -329
  65. package/dist-skill/docs-dev/generated/viewport.md +29 -2
  66. package/dist-skill/docs-dev/guides/joint-design.md +78 -0
  67. package/examples/api/attachTo-basics.forge.js +3 -3
  68. package/examples/api/bill-of-materials.forge.js +9 -9
  69. package/examples/api/bolt-pattern.forge.js +5 -5
  70. package/examples/api/boolean-operations.forge.js +2 -2
  71. package/examples/api/bounding-box-visualizer.forge.js +1 -1
  72. package/examples/api/clone-duplicate.forge.js +1 -1
  73. package/examples/api/connector-assembly.forge.js +4 -2
  74. package/examples/api/connector-basics.forge.js +5 -5
  75. package/examples/api/constrained-sketch-mechanical.forge.js +4 -4
  76. package/examples/api/elbow-test.forge.js +3 -3
  77. package/examples/api/extrude-options.forge.js +4 -4
  78. package/examples/api/fillet-showcase.forge.js +1 -1
  79. package/examples/api/gears-tier1.forge.js +5 -5
  80. package/examples/api/group-test.forge.js +2 -2
  81. package/examples/api/mesh-import-slats.forge.js +3 -3
  82. package/examples/api/patterns.forge.js +3 -3
  83. package/examples/api/pointAlong-orientation.forge.js +2 -2
  84. package/examples/api/profile-2020-b-slot6.forge.js +4 -4
  85. package/examples/api/sketch-rounding-strategies.forge.js +1 -1
  86. package/examples/api/smooth-curve-connections.forge.js +1 -1
  87. package/examples/api/transition-curves.forge.js +3 -3
  88. package/examples/constraints/01-fully-constrained-rect.forge.js +2 -2
  89. package/examples/constraints/02-underconstrained-triangle.forge.js +1 -1
  90. package/examples/constraints/03-redundant-constraints.forge.js +2 -2
  91. package/examples/constraints/05-parallel-with-linedistance.forge.js +2 -2
  92. package/examples/constraints/06-complex-spectrogram.forge.js +1 -1
  93. package/examples/constraints/07-perpendicular-chain.forge.js +4 -4
  94. package/examples/constraints/08-symmetric-bracket.forge.js +4 -4
  95. package/examples/constraints/09-stress-spiral.forge.js +1 -1
  96. package/examples/constraints/10-stress-honeycomb.forge.js +1 -1
  97. package/examples/constraints/11-surface-grid.forge.js +2 -2
  98. package/examples/constraints/12-surface-nested.forge.js +4 -4
  99. package/examples/constraints/13-surface-complex.forge.js +1 -1
  100. package/examples/exact-arc-housing.forge.js +12 -0
  101. package/examples/furniture/adjustable-table.forge.js +13 -13
  102. package/examples/furniture/bathroom.forge.js +15 -15
  103. package/examples/furniture/chair.forge.js +12 -12
  104. package/examples/furniture/picture-frame.forge.js +6 -6
  105. package/examples/furniture/shoe-rack-doors.forge.js +8 -8
  106. package/examples/furniture/shoe-rack.forge.js +7 -7
  107. package/examples/furniture/table-lamp.forge.js +8 -8
  108. package/examples/gcode/lissajous-vase.forge.js +4 -4
  109. package/examples/gcode/math-surface.forge.js +3 -3
  110. package/examples/gcode/parametric-vase.forge.js +4 -4
  111. package/examples/gcode/spiral-tower.forge.js +4 -4
  112. package/examples/generative/crystal-growth.forge.js +7 -7
  113. package/examples/generative/frost-spires.forge.js +6 -6
  114. package/examples/generative/golden-spiral-tower.forge.js +8 -8
  115. package/examples/generative/molten-forge.forge.js +6 -6
  116. package/examples/generative/neon-coral.forge.js +7 -7
  117. package/examples/mechanical/3d-printer.forge.js +9 -9
  118. package/examples/mechanical/5-finger-robot-hand.forge.js +4 -4
  119. package/examples/mechanical/airplane-propeller.forge.js +7 -7
  120. package/examples/mechanical/bolt-and-nut.forge.js +10 -10
  121. package/examples/mechanical/door-with-hinges.forge.js +7 -7
  122. package/examples/mechanical/fillet-enclosure.forge.js +14 -10
  123. package/examples/mechanical/headphone-hanger-v2.forge.js +9 -9
  124. package/examples/mechanical/robot_hand.forge.js +10 -10
  125. package/examples/mechanical/robot_hand_2.forge.js +17 -17
  126. package/examples/nurbs-surface.forge.js +8 -0
  127. package/examples/nurbs-tube.forge.js +7 -0
  128. package/examples/products/bottle.forge.js +7 -7
  129. package/examples/products/chess-set.forge.js +6 -6
  130. package/examples/products/classical-piano.forge.js +9 -9
  131. package/examples/products/clock.forge.js +21 -21
  132. package/examples/products/cup.forge.js +5 -5
  133. package/examples/products/iphone.forge.js +12 -12
  134. package/examples/products/laptop.forge.js +9 -9
  135. package/examples/products/laser-cut-box.forge.js +6 -6
  136. package/examples/products/laser-cut-tray.forge.js +6 -6
  137. package/examples/products/liquid-soap-dispenser.forge.js +5 -5
  138. package/examples/products/origami-fish.forge.js +6 -6
  139. package/examples/products/spiderman-cake.forge.js +2 -2
  140. package/examples/shelf/container.forge.js +5 -5
  141. package/examples/shelf/shelf-unit.forge.js +6 -6
  142. package/examples/toolbox/bolted-joint.forge.js +5 -5
  143. package/package.json +3 -1
  144. package/dist/assets/EditorApp-D9bJvtf7.js +0 -11338
  145. package/dist/assets/LandingPage-CdCuEOdC.js +0 -451
  146. package/dist-cli/chunk-PZ5AY32C.js +0 -10
  147. package/dist-cli/chunk-PZ5AY32C.js.map +0 -1
  148. package/dist-skill/docs/CLI/export.md +0 -91
  149. package/dist-skill/docs/CLI/projects.md +0 -107
  150. package/dist-skill/docs/CLI/studio_publishing.md +0 -52
  151. package/dist-skill/docs/CLI/validation.md +0 -66
  152. package/dist-skill/docs-dev/API/core/sdf-advanced.md +0 -92
  153. package/dist-skill/docs-dev/API/core/sdf-primitives.md +0 -58
  154. package/dist-skill/docs-dev/API/core/sdf-workflow.md +0 -42
  155. package/dist-skill/docs-dev/CLI/export.md +0 -91
  156. package/dist-skill/docs-dev/CLI/projects.md +0 -107
  157. package/dist-skill/docs-dev/CLI/studio_publishing.md +0 -52
  158. package/dist-skill/docs-dev/CLI/validation.md +0 -66
@@ -0,0 +1,601 @@
1
+ import { r as reactExports, j as jsxRuntimeExports, L as Link } from "./vendor-react-CG3i_wp0.js";
2
+ const LINKS = {
3
+ glasses: {
4
+ share: "https://forgecad.io/m/etXaJYSZF4",
5
+ embed: "https://forgecad.io/m/etXaJYSZF4?embed=1"
6
+ },
7
+ ams: {
8
+ share: "https://forgecad.io/m/VDHfnEYV62",
9
+ embed: "https://forgecad.io/m/VDHfnEYV62?embed=1"
10
+ },
11
+ enclosure: {
12
+ share: "https://forgecad.io/m/V35X6pYmnD",
13
+ embed: "https://forgecad.io/m/V35X6pYmnD?embed=1"
14
+ },
15
+ bolt: {
16
+ share: "https://forgecad.io/m/q4hrVFFAYQ",
17
+ embed: "https://forgecad.io/m/q4hrVFFAYQ?embed=1"
18
+ },
19
+ gyroid: {
20
+ share: "https://forgecad.io/m/E5gK32twac",
21
+ embed: "https://forgecad.io/m/E5gK32twac?embed=1"
22
+ }
23
+ };
24
+ const CODE_AMS = `// AMS Lite Spool Adapter (74.5mm to 55mm)
25
+ // Features compressible arms and snap-fit teeth
26
+
27
+ const od = param("Adapter OD", 74.0, { min: 60, max: 90, unit: "mm" });
28
+ const id = param("Adapter ID", 55, { min: 40, max: 70, unit: "mm" });
29
+ const h = param("Spool Depth", 60, { min: 30, max: 100, unit: "mm" });
30
+ const numArms = param("Number of Arms", 2, { min: 2, max: 6, step: 1 });
31
+ const flangeOd = param("Flange OD", 85, { min: 75, max: 110, unit: "mm" });
32
+ const flangeThick = param("Flange Thick", 2, { min: 1, max: 5, unit: "mm" });
33
+
34
+ const totalH = flangeThick + h;
35
+ const baseCyl = circle2d(od / 2).subtract(circle2d(id / 2)).extrude(totalH);
36
+ const flange = circle2d(flangeOd / 2).subtract(circle2d(id / 2)).extrude(flangeThick);
37
+ let body = union(baseCyl, flange).color('#333333');
38
+
39
+ // Trapezoidal cutouts create flexible arms
40
+ const cutProfile = filletCorners(cutPts, [
41
+ { index: 0, radius: 3 }, { index: 1, radius: 3 },
42
+ { index: 2, radius: 3 }, { index: 3, radius: 3 }
43
+ ]);
44
+ const cutter = cutProfile.extrude(cutterDepth).rotateX(90);
45
+ // Pattern cutters around the cylinder, subtract to form arms
46
+ body = body.subtract(union(...cutters));
47
+
48
+ // Snap-fit teeth on each arm tip
49
+ const tooth = box(toothW, toothDepth, toothH)
50
+ .translate(0, rInner + toothDepth / 2, totalH)
51
+ .rotateZ(toothAngle / 2);
52
+
53
+ return union(body, teeth);`;
54
+ const CODE_ENCLOSURE = `// Filleted Electronics Enclosure — practical engineering part
55
+ // Demonstrates: fillet() for professional-looking product design
56
+
57
+ const width = Param.number("Width", 80, { min: 50, max: 120, unit: "mm" });
58
+ const depth = Param.number("Depth", 50, { min: 30, max: 80, unit: "mm" });
59
+ const height = Param.number("Height", 25, { min: 15, max: 40, unit: "mm" });
60
+ const wall = Param.number("Wall", 2.5, { min: 1.5, max: 4, unit: "mm" });
61
+ const outerR = Param.number("Outer Fillet", 4, { min: 1, max: 10, unit: "mm" });
62
+
63
+ // ── Outer shell with rounded vertical edges ─────────────────────────────────
64
+ const outer = box(width, depth, height);
65
+ let enclosure = fillet(outer, outerR, { parallel: [0, 0, 1], convex: true });
66
+
67
+ // ── Hollow interior ─────────────────────────────────────────────────────────
68
+ // box() is XY-centered, Z starts at 0
69
+ const cavity = box(width - wall * 2, depth - wall * 2, height - wall)
70
+ .translate(0, 0, wall + 0.01);
71
+ enclosure = difference(enclosure, cavity);
72
+
73
+ // ── Screw bosses ────────────────────────────────────────────────────────────
74
+ const bossR = 4;
75
+ const bossH = height - wall - 1;
76
+ const inset = wall + bossR + 2;
77
+
78
+ function screwBoss(x, y) {
79
+ const boss = cylinder(bossH, bossR, bossR, 24).translate(x, y, wall);
80
+ const hole = cylinder(bossH + 1, 1.5, 1.5, 16).translate(x, y, wall - 0.5);
81
+ return difference(boss, hole);
82
+ }
83
+
84
+ const hw = width / 2, hd = depth / 2;
85
+ enclosure = union(
86
+ enclosure,
87
+ screwBoss(-hw + inset, -hd + inset),
88
+ screwBoss( hw - inset, -hd + inset),
89
+ screwBoss(-hw + inset, hd - inset),
90
+ screwBoss( hw - inset, hd - inset),
91
+ );
92
+
93
+ return enclosure;`;
94
+ const CODE_BOLT = `const diameter = Param.number("Diameter", 8, { min: 4, max: 20, unit: "mm" });
95
+ const length = Param.number("Length", 30, { min: 10, max: 60, unit: "mm" });
96
+ const pitch = Param.number("Pitch", 1.25, { min: 0.5, max: 3, step: 0.25, unit: "mm" });
97
+
98
+ const boltShape = lib.bolt(diameter, length, {
99
+ pitch,
100
+ headHeight: headH,
101
+ headAcrossFlats: headAF,
102
+ segments,
103
+ });
104
+
105
+ const result = [
106
+ { name: "Bolt", shape: boltShape, color: "#aaaaaa" },
107
+ ];
108
+
109
+ if (showNut >= 1) {
110
+ const nutShape = lib.nut(diameter, {
111
+ pitch, height: nutHeight, acrossFlats: nutAF, segments,
112
+ }).translate(0, 0, -length + nutPos + nutHeight / 2);
113
+ result.push({ name: "Nut", shape: nutShape, color: "#999999" });
114
+ }
115
+
116
+ return result;`;
117
+ const CODE_GYROID = `const bounds = sdf.sphere(22);
118
+ const gyroid = sdf.gyroid({ cellSize: 10, thickness: 1.0 });
119
+
120
+ return gyroid
121
+ .intersect(bounds)
122
+ .toShape({ edgeLength: 0.6 })
123
+ .color('#6b4c9a');`;
124
+ function useWireLinks(rootRef) {
125
+ reactExports.useEffect(() => {
126
+ const root = rootRef.current;
127
+ if (!root) return;
128
+ root.querySelectorAll("[data-link-key]").forEach((node) => {
129
+ const key = node.getAttribute("data-link-key");
130
+ const kind = node.getAttribute("data-link-kind");
131
+ if (LINKS[key] && LINKS[key][kind]) {
132
+ node.href = LINKS[key][kind];
133
+ }
134
+ });
135
+ }, [rootRef]);
136
+ }
137
+ function ProofSection({
138
+ number,
139
+ title,
140
+ description,
141
+ codeFile,
142
+ codeLabel,
143
+ code,
144
+ imageSrc,
145
+ imageAlt,
146
+ visualDescription,
147
+ facts,
148
+ linkKey
149
+ }) {
150
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "lpd-proof", children: [
151
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-proof-header", children: [
152
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-proof-number", children: number }),
153
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-proof-heading", children: [
154
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: title }),
155
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: description })
156
+ ] })
157
+ ] }),
158
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-proof-layout", children: [
159
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-code-card", children: [
160
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-card-bar", children: [
161
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
162
+ "Source · ",
163
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: codeFile })
164
+ ] }),
165
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: codeLabel })
166
+ ] }),
167
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: code }) })
168
+ ] }),
169
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-visual-card", children: [
170
+ /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: imageSrc, alt: imageAlt }),
171
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-visual-copy", children: [
172
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: visualDescription }),
173
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-fact-grid", children: facts.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-fact", children: [
174
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: f.title }),
175
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: f.detail })
176
+ ] }, f.title)) }),
177
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-action-row", children: [
178
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
179
+ "a",
180
+ {
181
+ className: "lpd-action-strong",
182
+ "data-link-key": linkKey,
183
+ "data-link-kind": "share",
184
+ target: "_blank",
185
+ rel: "noopener noreferrer",
186
+ children: "Open model"
187
+ }
188
+ ),
189
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
190
+ "a",
191
+ {
192
+ "data-link-key": linkKey,
193
+ "data-link-kind": "embed",
194
+ target: "_blank",
195
+ rel: "noopener noreferrer",
196
+ children: "Open embed"
197
+ }
198
+ )
199
+ ] })
200
+ ] })
201
+ ] })
202
+ ] })
203
+ ] });
204
+ }
205
+ const DESKTOP_QUERY = "(min-width: 861px)";
206
+ function LandingPageProofDriven() {
207
+ const rootRef = reactExports.useRef(null);
208
+ useWireLinks(rootRef);
209
+ const [isWide, setIsWide] = reactExports.useState(() => window.matchMedia(DESKTOP_QUERY).matches);
210
+ reactExports.useEffect(() => {
211
+ const mql = window.matchMedia(DESKTOP_QUERY);
212
+ const onChange = (e) => setIsWide(e.matches);
213
+ mql.addEventListener("change", onChange);
214
+ return () => mql.removeEventListener("change", onChange);
215
+ }, []);
216
+ reactExports.useEffect(() => {
217
+ const html = document.documentElement;
218
+ const body = document.body;
219
+ const prevHtml = html.style.background;
220
+ const prevBody = body.style.background;
221
+ const bg = "#f3ede4";
222
+ html.style.background = bg;
223
+ body.style.background = bg;
224
+ return () => {
225
+ html.style.background = prevHtml;
226
+ body.style.background = prevBody;
227
+ };
228
+ }, []);
229
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-root", ref: rootRef, children: [
230
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-grid-overlay" }),
231
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-topbar", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-topbar-inner", children: [
232
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Link, { to: "/", className: "lpd-brand", children: [
233
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-brand-mark", "aria-hidden": "true" }),
234
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "ForgeCAD" })
235
+ ] }),
236
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-topnav", children: [
237
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/docs", children: "Docs" }),
238
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/blog", children: "Blog" }),
239
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/app", className: "lpd-topnav-cta", children: "Start Building" })
240
+ ] })
241
+ ] }) }),
242
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { className: "lpd-shell", children: [
243
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "lpd-hero", children: [
244
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-grid", children: [
245
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-copy", children: [
246
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
247
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-eyebrow", children: "Real Models. Real Files." }),
248
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { children: [
249
+ "Parametric CAD ",
250
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "in JavaScript." })
251
+ ] }),
252
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "lpd-hero-lead", children: [
253
+ "Write geometry as code. Every model on this page is a real ",
254
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: ".forge.js" }),
255
+ " file you can open, edit, and 3D-print."
256
+ ] }),
257
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-actions", children: [
258
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/app", className: "lpd-button lpd-button-primary", children: "Open ForgeCAD" }),
259
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/docs", className: "lpd-button lpd-button-secondary", children: "Read the Docs" })
260
+ ] })
261
+ ] }),
262
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-facts", children: [
263
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-fact", children: [
264
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "JavaScript" }),
265
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Full language, not a DSL. Loops, functions, npm." })
266
+ ] }),
267
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-fact", children: [
268
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Parametric" }),
269
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Every dimension is a live slider." })
270
+ ] }),
271
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-fact", children: [
272
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Export" }),
273
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "STL, 3MF, STEP — ready to print or machine." })
274
+ ] })
275
+ ] })
276
+ ] }),
277
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-visual", children: [
278
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-visual-topbar", children: [
279
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "lpd-visual-dots", "aria-hidden": "true", children: [
280
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
281
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
282
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {})
283
+ ] }),
284
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
285
+ isWide ? "Live embed" : "Preview",
286
+ " · ",
287
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "glasses.forge.js" })
288
+ ] })
289
+ ] }),
290
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-hero-frame", children: isWide ? /* @__PURE__ */ jsxRuntimeExports.jsx(
291
+ "iframe",
292
+ {
293
+ src: LINKS.glasses.embed,
294
+ title: "ForgeCAD live embed",
295
+ loading: "lazy"
296
+ }
297
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
298
+ "img",
299
+ {
300
+ src: "/landing/proof-glasses.png",
301
+ alt: "Stylistic glasses model rendered in ForgeCAD",
302
+ className: "lpd-hero-static"
303
+ }
304
+ ) }),
305
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-visual-copy", children: [
306
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: isWide ? "This is a live ForgeCAD model. Drag to orbit. Scroll to zoom. Open the source to edit it." : "A parametric glasses model with 5 frame styles, full color control, and proper sketch construction. Open it to interact." }),
307
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-visual-actions", children: [
308
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
309
+ "a",
310
+ {
311
+ href: LINKS.glasses.share,
312
+ target: "_blank",
313
+ rel: "noopener noreferrer",
314
+ children: "Open this model"
315
+ }
316
+ ),
317
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/app", children: "Open the editor" })
318
+ ] })
319
+ ] })
320
+ ] })
321
+ ] }),
322
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-artifact-strip", children: [
323
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
324
+ "a",
325
+ {
326
+ className: "lpd-artifact-card",
327
+ "data-link-key": "ams",
328
+ "data-link-kind": "share",
329
+ target: "_blank",
330
+ rel: "noopener noreferrer",
331
+ children: [
332
+ /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: "/landing/proof-ams-adapter.png", alt: "Rendered AMS Lite spool adapter" }),
333
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-artifact-copy", children: [
334
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "Printed Part" }),
335
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "AMS Lite adapter" }),
336
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "109 lines of code. Printed and in daily use." }),
337
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "ams_lite_adapter.forge.js" })
338
+ ] })
339
+ ]
340
+ }
341
+ ),
342
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
343
+ "a",
344
+ {
345
+ className: "lpd-artifact-card",
346
+ "data-link-key": "enclosure",
347
+ "data-link-kind": "share",
348
+ target: "_blank",
349
+ rel: "noopener noreferrer",
350
+ children: [
351
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
352
+ "img",
353
+ {
354
+ src: "/landing/proof-fillet-enclosure.png",
355
+ alt: "Rendered filleted electronics enclosure"
356
+ }
357
+ ),
358
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-artifact-copy", children: [
359
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "Everyday Mechanical" }),
360
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Filleted enclosure" }),
361
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Shell, cavity subtraction, screw bosses, edge fillets. A normal engineering part, not demo theater." }),
362
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "fillet-enclosure.forge.js" })
363
+ ] })
364
+ ]
365
+ }
366
+ ),
367
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
368
+ "a",
369
+ {
370
+ className: "lpd-artifact-card",
371
+ "data-link-key": "bolt",
372
+ "data-link-kind": "share",
373
+ target: "_blank",
374
+ rel: "noopener noreferrer",
375
+ children: [
376
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
377
+ "img",
378
+ {
379
+ src: "/landing/proof-bolt-and-nut.png",
380
+ alt: "Rendered threaded bolt and nut"
381
+ }
382
+ ),
383
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-artifact-copy", children: [
384
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "Standard Parts" }),
385
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Bolt and nut" }),
386
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Helical threads from the part library. No hand-modeled mesh, no fake hardware glamour shot." }),
387
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "bolt-and-nut.forge.js" })
388
+ ] })
389
+ ]
390
+ }
391
+ ),
392
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
393
+ "a",
394
+ {
395
+ className: "lpd-artifact-card",
396
+ "data-link-key": "gyroid",
397
+ "data-link-kind": "share",
398
+ target: "_blank",
399
+ rel: "noopener noreferrer",
400
+ children: [
401
+ /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: "/landing/proof-gyroid.png", alt: "Rendered gyroid sphere" }),
402
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-artifact-copy", children: [
403
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "SDF Composition" }),
404
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Gyroid sphere" }),
405
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Seven lines of SDF. One solid mesh. Still the same file format, still the same toolchain." }),
406
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lpd-source-tag", children: "gyroid.forge.js" })
407
+ ] })
408
+ ]
409
+ }
410
+ )
411
+ ] }),
412
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-capability-band", children: [
413
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Live parameter sliders" }),
414
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Public embeds" }),
415
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Assemblies and connectors" }),
416
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Fillets, shells, bosses" }),
417
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Part library and threads" }),
418
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "SDF and solid modeling in one language" })
419
+ ] })
420
+ ] }),
421
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-section-break" }),
422
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
423
+ ProofSection,
424
+ {
425
+ number: "01",
426
+ title: "Real parts, printed and working.",
427
+ description: "A spool adapter with parametric arms, snap-fit teeth, and filleted stress relief. 109 lines. Printed on a Bambu Lab X1C and loaded into an AMS Lite.",
428
+ codeFile: "ams_lite_adapter.forge.js",
429
+ codeLabel: "109 lines",
430
+ code: CODE_AMS,
431
+ imageSrc: "/landing/proof-ams-adapter.png",
432
+ imageAlt: "Rendered AMS Lite spool adapter with flexible arms and snap-fit teeth",
433
+ visualDescription: "Live parameters, patterned cuts, snap-fit geometry — a part that survived contact with the real world.",
434
+ facts: [
435
+ { title: "Printed", detail: "Not a mockup. In use." },
436
+ { title: "11 params", detail: "Real sliders, not pseudo-controls." },
437
+ { title: "85 x 85 x 64 mm", detail: "Measured from the render output." }
438
+ ],
439
+ linkKey: "ams"
440
+ }
441
+ ),
442
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
443
+ ProofSection,
444
+ {
445
+ number: "02",
446
+ title: "Normal engineering parts.",
447
+ description: "Shell, cavity subtraction, screw bosses, edge fillets. The boring, important stuff that real projects need.",
448
+ codeFile: "fillet-enclosure.forge.js",
449
+ codeLabel: "Practical solid modeling",
450
+ code: CODE_ENCLOSURE,
451
+ imageSrc: "/landing/proof-fillet-enclosure.png",
452
+ imageAlt: "Rendered filleted electronics enclosure",
453
+ visualDescription: "Wall thickness, bosses, cavity, fillets — a part you would actually put on a bench.",
454
+ facts: [
455
+ { title: "5 params", detail: "Width, depth, height, wall, outer fillet." },
456
+ { title: "115.5 x 70.5 x 25 mm", detail: "Measured render bounds." },
457
+ { title: "Solid workflow", detail: "Box, subtract, fillet, union." }
458
+ ],
459
+ linkKey: "enclosure"
460
+ }
461
+ ),
462
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
463
+ ProofSection,
464
+ {
465
+ number: "03",
466
+ title: "Standard parts from the library.",
467
+ description: "Helical threads generated by lib.bolt() and lib.nut(). Real geometry from the built-in part library, not imported meshes.",
468
+ codeFile: "bolt-and-nut.forge.js",
469
+ codeLabel: "lib.bolt() and lib.nut()",
470
+ code: CODE_BOLT,
471
+ imageSrc: "/landing/proof-bolt-and-nut.png",
472
+ imageAlt: "Rendered threaded bolt and nut from the part library",
473
+ visualDescription: "One function call generates a fully threaded fastener with configurable pitch, head style, and segment count.",
474
+ facts: [
475
+ { title: "10 params", detail: "Diameter, pitch, nut position, segments, and more." },
476
+ { title: "Helical threads", detail: "From the real library, not mesh art." },
477
+ { title: "15 x 13 x 37.5 mm", detail: "Measured render bounds." }
478
+ ],
479
+ linkKey: "bolt"
480
+ }
481
+ ),
482
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
483
+ ProofSection,
484
+ {
485
+ number: "04",
486
+ title: "SDF and solid modeling in one language.",
487
+ description: "Signed distance fields let you create organic forms that are impossible with traditional B-rep. ForgeCAD meshes them into printable solids.",
488
+ codeFile: "gyroid.forge.js",
489
+ codeLabel: "SDF + solid output",
490
+ code: CODE_GYROID,
491
+ imageSrc: "/landing/proof-gyroid.png",
492
+ imageAlt: "Rendered gyroid sphere",
493
+ visualDescription: "Seven lines of code produce a gyroid lattice intersected with a sphere — ready to export and print.",
494
+ facts: [
495
+ { title: "7 lines of model code", detail: "Enough to explain the result." },
496
+ { title: "44 x 44 x 44 mm", detail: "Measured render bounds." },
497
+ { title: "One language", detail: "SDF and parametric solids still live together." }
498
+ ],
499
+ linkKey: "gyroid"
500
+ }
501
+ ),
502
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-section-break" }),
503
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "lpd-cli", children: [
504
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-header", children: [
505
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-eyebrow", children: "Your Terminal, Your Toolchain" }),
506
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Install. Build. Export. Publish." }),
507
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "ForgeCAD runs anywhere Node does. Install the CLI, write a model, and ship it — all without leaving the terminal. Works with AI coding agents out of the box." })
508
+ ] }),
509
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-steps", children: [
510
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-step", children: [
511
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-cli-step-label", children: "Install" }),
512
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal", children: [
513
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal-bar", children: [
514
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "lpd-visual-dots", "aria-hidden": "true", children: [
515
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
516
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
517
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {})
518
+ ] }),
519
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Terminal" })
520
+ ] }),
521
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "$ npm install -g forgecad" }) })
522
+ ] })
523
+ ] }),
524
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-step", children: [
525
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-cli-step-label", children: "Run" }),
526
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal", children: [
527
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal-bar", children: [
528
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "lpd-visual-dots", "aria-hidden": "true", children: [
529
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
530
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
531
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {})
532
+ ] }),
533
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Terminal" })
534
+ ] }),
535
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: `$ forgecad run bracket.forge.js
536
+ ✓ bracket.forge.js — 85 × 40 × 12 mm — 6 params` }) })
537
+ ] })
538
+ ] }),
539
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-step", children: [
540
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-cli-step-label", children: "Export" }),
541
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal", children: [
542
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal-bar", children: [
543
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "lpd-visual-dots", "aria-hidden": "true", children: [
544
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
545
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
546
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {})
547
+ ] }),
548
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Terminal" })
549
+ ] }),
550
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: `$ forgecad export stl bracket.forge.js
551
+ ✓ bracket.stl — 24.3 KB` }) })
552
+ ] })
553
+ ] }),
554
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-step", children: [
555
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-cli-step-label", children: "Publish" }),
556
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal", children: [
557
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-terminal-bar", children: [
558
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "lpd-visual-dots", "aria-hidden": "true", children: [
559
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
560
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
561
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", {})
562
+ ] }),
563
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Terminal" })
564
+ ] }),
565
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: `$ forgecad publish bracket.forge.js --title "Bracket"
566
+ ✓ Published → forgecad.io/m/xK9f2mQ` }) })
567
+ ] })
568
+ ] })
569
+ ] }),
570
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-cli-ai", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-ai-copy", children: [
571
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "AI agents write models too." }),
572
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
573
+ "Install the ForgeCAD skill (",
574
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "forgecad skill install" }),
575
+ ") and your AI coding agent gets full API knowledge. It writes the model, the CLI validates and exports it."
576
+ ] })
577
+ ] }) }),
578
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-cli-actions", children: [
579
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/docs/cli", className: "lpd-button lpd-button-primary", children: "CLI Docs" }),
580
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/docs", className: "lpd-button lpd-button-secondary", children: "Full API Reference" })
581
+ ] })
582
+ ] }),
583
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-footer-cta", children: [
584
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lpd-eyebrow", children: "Start Building" }),
585
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Your geometry, your code, your toolchain." }),
586
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
587
+ "ForgeCAD is free to use. Open the editor, write a ",
588
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: ".forge.js" }),
589
+ " file, and export to STL, 3MF, or STEP."
590
+ ] }),
591
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lpd-hero-actions", children: [
592
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/app", className: "lpd-button lpd-button-primary", children: "Open ForgeCAD" }),
593
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/docs", className: "lpd-button lpd-button-secondary", children: "Read the Docs" })
594
+ ] })
595
+ ] })
596
+ ] })
597
+ ] });
598
+ }
599
+ export {
600
+ LandingPageProofDriven
601
+ };
@@ -1,5 +1,5 @@
1
1
  import { h as useNavigate, j as jsxRuntimeExports, L as Link } from "./vendor-react-CG3i_wp0.js";
2
- import { a as useAuthStore, b as authFetch } from "./index-wTEK39at.js";
2
+ import { u as useAuthStore, b as authFetch } from "./index-Pz321YAt.js";
3
3
  const PLANS = [
4
4
  {
5
5
  interval: "monthly",
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, L as Link } from "./vendor-react-CG3i_wp0.js";
2
- import { a as useAuthStore, b as authFetch } from "./index-wTEK39at.js";
2
+ import { u as useAuthStore, b as authFetch } from "./index-Pz321YAt.js";
3
3
  function timeAgo(dateStr) {
4
4
  const ms = Date.now() - new Date(dateStr).getTime();
5
5
  const mins = Math.floor(ms / 6e4);