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
package/README.md CHANGED
@@ -264,7 +264,7 @@ All CLI tools use the same runtime as the browser (`src/forge/headless.ts`), so
264
264
  | Task | Command |
265
265
  | --- | --- |
266
266
  | Validate a script | `forgecad run examples/cup.forge.js` |
267
- | Render PNG views | `forgecad render examples/cup.forge.js` |
267
+ | Render PNG views | `forgecad render 3d examples/cup.forge.js` |
268
268
  | Render orbit GIF (solid + wireframe) | `forgecad capture gif examples/cup.forge.js` |
269
269
  | Export sketch SVG | `forgecad export svg examples/constraints/01-fully-constrained-rect.forge.js` |
270
270
  | Export exact STEP (supported subset only) | `forgecad export step examples/api/brep-exportable.forge.js` |
@@ -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 } from "./index-wTEK39at.js";
2
+ import { u as useAuthStore } from "./index-Pz321YAt.js";
3
3
  function formatUptime(seconds) {
4
4
  const d = Math.floor(seconds / 86400);
5
5
  const h = Math.floor(seconds % 86400 / 3600);
@@ -4,6 +4,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4
4
  var _a;
5
5
  import { u as useParams, h as useNavigate, r as reactExports, j as jsxRuntimeExports, L as Link } from "./vendor-react-CG3i_wp0.js";
6
6
  import { H as HighlightJS, j as javascript$1 } from "./javascript-DAl8Gmyo.js";
7
+ import { a as applyTheme } from "./index-Pz321YAt.js";
7
8
  function M() {
8
9
  return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
9
10
  }
@@ -3776,9 +3777,10 @@ const DOC_SECTIONS = [
3776
3777
  { slug: "lib", title: "Library", description: "Gears, fasteners, pipes" },
3777
3778
  { slug: "sheet-metal", title: "Sheet Metal", description: "Bends, flat patterns" },
3778
3779
  { slug: "viewport", title: "Viewport", description: "Camera, animation, scenes" },
3780
+ { slug: "sdf", title: "SDF (Experimental)", description: "Organic forms, smooth booleans, TPMS" },
3779
3781
  { slug: "concepts", title: "Concepts", description: "Semantic data structures" }
3780
3782
  ];
3781
- const CLI_SECTIONS = [{ slug: "cli", title: "CLI Reference", description: "Command-line tools and options" }];
3783
+ const CLI_SECTIONS = [{ slug: "cli", title: "CLI", description: "Install, run, export, publish — from your terminal" }];
3782
3784
  const ALL_SECTIONS = [...DOC_SECTIONS, ...CLI_SECTIONS];
3783
3785
  function buildSearchEntries(slug, sectionTitle, md) {
3784
3786
  const entries = [];
@@ -3836,6 +3838,19 @@ function SidebarToggle({ side, open, onClick }) {
3836
3838
  }
3837
3839
  );
3838
3840
  }
3841
+ function ThemeToggle() {
3842
+ const [dark, setDark] = reactExports.useState(() => (localStorage.getItem("fc-theme") || "dark") !== "light");
3843
+ const toggle = reactExports.useCallback(() => {
3844
+ const next = dark ? "light" : "dark";
3845
+ applyTheme(next);
3846
+ localStorage.setItem("fc-theme", next);
3847
+ setDark(!dark);
3848
+ }, [dark]);
3849
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "fc-docs-theme-toggle", onClick: toggle, type: "button", title: dark ? "Switch to light mode" : "Switch to dark mode", children: dark ? /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
3850
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "5" }),
3851
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" })
3852
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }) });
3853
+ }
3839
3854
  function SiteNav({
3840
3855
  onSearchOpen,
3841
3856
  showSidebar,
@@ -3864,39 +3879,51 @@ function SiteNav({
3864
3879
  /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/docs", className: "fc-docs-nav-active", children: "Docs" }),
3865
3880
  false,
3866
3881
  /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: "/", className: "fc-docs-nav-cta", children: "Back to Editor" }),
3882
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ThemeToggle, {}),
3867
3883
  hasToc && /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarToggle, { side: "right", open: showToc, onClick: onToggleToc })
3868
3884
  ] })
3869
3885
  ] });
3870
3886
  }
3871
- function Sidebar({ activeSlug }) {
3887
+ function Sidebar({ activeSlug, open, onClose }) {
3872
3888
  const activeRef = reactExports.useRef(null);
3873
3889
  reactExports.useEffect(() => {
3874
3890
  var _a2;
3875
3891
  (_a2 = activeRef.current) == null ? void 0 : _a2.scrollIntoView({ block: "nearest" });
3876
3892
  }, [activeSlug]);
3877
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: "fc-docs-sidebar", children: [
3878
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fc-docs-sidebar-group-title", children: "API Reference" }),
3879
- DOC_SECTIONS.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(
3880
- Link,
3881
- {
3882
- ref: activeSlug === s.slug ? activeRef : void 0,
3883
- to: `/docs/${s.slug}`,
3884
- className: `fc-docs-sidebar-link${activeSlug === s.slug ? " active" : ""}`,
3885
- children: s.title
3886
- },
3887
- s.slug
3888
- )),
3889
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fc-docs-sidebar-group-title", style: { marginTop: 16 }, children: "Tools" }),
3890
- CLI_SECTIONS.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(
3891
- Link,
3893
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
3894
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
3895
+ "div",
3892
3896
  {
3893
- ref: activeSlug === s.slug ? activeRef : void 0,
3894
- to: `/docs/${s.slug}`,
3895
- className: `fc-docs-sidebar-link${activeSlug === s.slug ? " active" : ""}`,
3896
- children: s.title
3897
- },
3898
- s.slug
3899
- ))
3897
+ className: `fc-docs-sidebar-backdrop${open ? " open" : ""}`,
3898
+ onClick: onClose
3899
+ }
3900
+ ),
3901
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: `fc-docs-sidebar${open ? " open" : ""}`, children: [
3902
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fc-docs-sidebar-group-title", children: "API Reference" }),
3903
+ DOC_SECTIONS.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(
3904
+ Link,
3905
+ {
3906
+ ref: activeSlug === s.slug ? activeRef : void 0,
3907
+ to: `/docs/${s.slug}`,
3908
+ className: `fc-docs-sidebar-link${activeSlug === s.slug ? " active" : ""}`,
3909
+ onClick: onClose,
3910
+ children: s.title
3911
+ },
3912
+ s.slug
3913
+ )),
3914
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fc-docs-sidebar-group-title", style: { marginTop: 16 }, children: "Tools" }),
3915
+ CLI_SECTIONS.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(
3916
+ Link,
3917
+ {
3918
+ ref: activeSlug === s.slug ? activeRef : void 0,
3919
+ to: `/docs/${s.slug}`,
3920
+ className: `fc-docs-sidebar-link${activeSlug === s.slug ? " active" : ""}`,
3921
+ onClick: onClose,
3922
+ children: s.title
3923
+ },
3924
+ s.slug
3925
+ ))
3926
+ ] })
3900
3927
  ] });
3901
3928
  }
3902
3929
  function SearchOverlay({ open, onClose, searchIndex }) {
@@ -4042,7 +4069,7 @@ function extractTocEntries(container) {
4042
4069
  }
4043
4070
  return entries;
4044
4071
  }
4045
- function OnThisPage({ contentRef, html }) {
4072
+ function OnThisPage({ contentRef, html, open, onClose }) {
4046
4073
  const [entries, setEntries] = reactExports.useState([]);
4047
4074
  const [activeId, setActiveId] = reactExports.useState("");
4048
4075
  reactExports.useEffect(() => {
@@ -4074,26 +4101,37 @@ function OnThisPage({ contentRef, html }) {
4074
4101
  return () => scrollContainer.removeEventListener("scroll", handleScroll);
4075
4102
  }, [entries, contentRef]);
4076
4103
  if (entries.length === 0) return null;
4077
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: "fc-docs-toc", children: [
4078
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fc-docs-toc-title", children: "On this page" }),
4079
- entries.map((e) => /* @__PURE__ */ jsxRuntimeExports.jsx(
4080
- "a",
4104
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
4105
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4106
+ "div",
4081
4107
  {
4082
- href: `#${e.id}`,
4083
- className: `fc-docs-toc-link${e.depth === 3 ? " indent" : ""}${activeId === e.id ? " active" : ""}`,
4084
- onClick: (ev) => {
4085
- var _a2;
4086
- ev.preventDefault();
4087
- const target = (_a2 = contentRef.current) == null ? void 0 : _a2.querySelector(`#${CSS.escape(e.id)}`);
4088
- if (target) {
4089
- target.scrollIntoView({ behavior: "smooth", block: "start" });
4090
- history.replaceState(null, "", `#${e.id}`);
4091
- }
4108
+ className: `fc-docs-toc-backdrop${open ? " open" : ""}`,
4109
+ onClick: onClose
4110
+ }
4111
+ ),
4112
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: `fc-docs-toc${open ? " open" : ""}`, children: [
4113
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fc-docs-toc-handle" }),
4114
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fc-docs-toc-title", children: "On this page" }),
4115
+ entries.map((e) => /* @__PURE__ */ jsxRuntimeExports.jsx(
4116
+ "a",
4117
+ {
4118
+ href: `#${e.id}`,
4119
+ className: `fc-docs-toc-link${e.depth === 3 ? " indent" : ""}${activeId === e.id ? " active" : ""}`,
4120
+ onClick: (ev) => {
4121
+ var _a2;
4122
+ ev.preventDefault();
4123
+ onClose();
4124
+ const target = (_a2 = contentRef.current) == null ? void 0 : _a2.querySelector(`#${CSS.escape(e.id)}`);
4125
+ if (target) {
4126
+ target.scrollIntoView({ behavior: "smooth", block: "start" });
4127
+ history.replaceState(null, "", `#${e.id}`);
4128
+ }
4129
+ },
4130
+ children: e.text
4092
4131
  },
4093
- children: e.text
4094
- },
4095
- e.id
4096
- ))
4132
+ e.id
4133
+ ))
4134
+ ] })
4097
4135
  ] });
4098
4136
  }
4099
4137
  function DocContent({ slug, contentRef, onHtml }) {
@@ -4243,6 +4281,8 @@ function DocsPage() {
4243
4281
  document.addEventListener("keydown", handler);
4244
4282
  return () => document.removeEventListener("keydown", handler);
4245
4283
  }, [slug, openSearch, navigate]);
4284
+ const closeSidebar = reactExports.useCallback(() => setShowSidebar(false), []);
4285
+ const closeToc = reactExports.useCallback(() => setShowToc(false), []);
4246
4286
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fc-docs-layout", children: [
4247
4287
  /* @__PURE__ */ jsxRuntimeExports.jsx(
4248
4288
  SiteNav,
@@ -4256,9 +4296,9 @@ function DocsPage() {
4256
4296
  }
4257
4297
  ),
4258
4298
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fc-docs-body", children: [
4259
- showSidebar && /* @__PURE__ */ jsxRuntimeExports.jsx(Sidebar, { activeSlug: slug }),
4299
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Sidebar, { activeSlug: slug, open: showSidebar, onClose: closeSidebar }),
4260
4300
  /* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "fc-docs-main", children: slug ? /* @__PURE__ */ jsxRuntimeExports.jsx(DocContent, { slug, contentRef, onHtml: setDocHtml }) : /* @__PURE__ */ jsxRuntimeExports.jsx(DocsIndex, {}) }),
4261
- slug && showToc && /* @__PURE__ */ jsxRuntimeExports.jsx(OnThisPage, { contentRef, html: docHtml })
4301
+ slug && /* @__PURE__ */ jsxRuntimeExports.jsx(OnThisPage, { contentRef, html: docHtml, open: showToc, onClose: closeToc })
4262
4302
  ] }),
4263
4303
  /* @__PURE__ */ jsxRuntimeExports.jsx(SearchOverlay, { open: searchOpen, onClose: () => setSearchOpen(false), searchIndex })
4264
4304
  ] });
@@ -58,7 +58,7 @@
58
58
 
59
59
  .fc-mobile-viewport-fabs {
60
60
  position: absolute;
61
- top: calc(env(safe-area-inset-top, 0px) + 60px);
61
+ top: calc(env(safe-area-inset-top, 0px) + 8px);
62
62
  right: 14px;
63
63
  display: flex;
64
64
  flex-direction: column;
@@ -246,49 +246,6 @@
246
246
  background: #ff4757;
247
247
  }
248
248
 
249
- /* ════════════════════════════════════
250
- CORNER BUTTONS — top-right export
251
- ════════════════════════════════════ */
252
-
253
- .fc-m-corners {
254
- position: absolute;
255
- top: calc(env(safe-area-inset-top, 0px) + 8px);
256
- right: 14px;
257
- display: flex;
258
- flex-direction: column;
259
- gap: 8px;
260
- z-index: 30;
261
- }
262
-
263
- .fc-m-corner-btn {
264
- width: 38px;
265
- height: 38px;
266
- border-radius: 11px;
267
- background: color-mix(in srgb, var(--fc-bgPanel) 88%, transparent);
268
- backdrop-filter: blur(16px);
269
- -webkit-backdrop-filter: blur(16px);
270
- border: 1px solid var(--fc-border);
271
- display: flex;
272
- align-items: center;
273
- justify-content: center;
274
- cursor: pointer;
275
- color: var(--fc-textMuted);
276
- }
277
-
278
- .fc-m-corner-btn:active {
279
- background: var(--fc-bgHover);
280
- }
281
-
282
- .fc-m-corner-btn svg {
283
- width: 16px;
284
- height: 16px;
285
- stroke: currentColor;
286
- fill: none;
287
- stroke-width: 2;
288
- stroke-linecap: round;
289
- stroke-linejoin: round;
290
- }
291
-
292
249
  /* ════════════════════════════════════
293
250
  PARAM CHIPS — floating row above command bar
294
251
  ════════════════════════════════════ */
@@ -439,14 +396,23 @@
439
396
  }
440
397
 
441
398
  .fc-m-cmdbar-filename {
399
+ display: flex;
400
+ align-items: center;
401
+ gap: 6px;
442
402
  font-size: 13px;
443
403
  color: var(--fc-textMuted);
444
- white-space: nowrap;
445
- overflow: hidden;
446
- text-overflow: ellipsis;
447
404
  width: 100%;
448
405
  font-weight: 500;
449
406
  line-height: 1.3;
407
+ min-width: 0;
408
+ }
409
+
410
+ .fc-m-cmdbar-filename-text {
411
+ flex: 1;
412
+ min-width: 0;
413
+ white-space: nowrap;
414
+ overflow: hidden;
415
+ text-overflow: ellipsis;
450
416
  }
451
417
 
452
418
  /* Legacy — keep for any old references */
@@ -1423,6 +1389,119 @@
1423
1389
  font-weight: 600;
1424
1390
  }
1425
1391
 
1392
+ /* ── Share sheet ── */
1393
+ .fc-m-share-sheet {
1394
+ max-height: 78vh;
1395
+ }
1396
+
1397
+ .fc-m-share-section {
1398
+ padding: 14px 16px;
1399
+ border-bottom: 1px solid var(--fc-border);
1400
+ }
1401
+
1402
+ .fc-m-share-section:last-child {
1403
+ border-bottom: none;
1404
+ }
1405
+
1406
+ .fc-m-share-label {
1407
+ margin-bottom: 8px;
1408
+ font-size: 11px;
1409
+ font-weight: 700;
1410
+ color: var(--fc-textDim);
1411
+ text-transform: uppercase;
1412
+ letter-spacing: 0.6px;
1413
+ }
1414
+
1415
+ .fc-m-share-card {
1416
+ display: block;
1417
+ width: 100%;
1418
+ padding: 14px;
1419
+ background: var(--fc-bgCard, var(--fc-bgInput, var(--fc-bg)));
1420
+ border: 1px solid var(--fc-border);
1421
+ border-radius: 12px;
1422
+ color: var(--fc-text);
1423
+ text-align: left;
1424
+ cursor: pointer;
1425
+ font-family: inherit;
1426
+ }
1427
+
1428
+ .fc-m-share-card:active {
1429
+ background: var(--fc-bgHover);
1430
+ }
1431
+
1432
+ .fc-m-share-card-title {
1433
+ display: block;
1434
+ font-size: 14px;
1435
+ font-weight: 600;
1436
+ }
1437
+
1438
+ .fc-m-share-card-desc {
1439
+ display: block;
1440
+ margin-top: 4px;
1441
+ font-size: 12px;
1442
+ line-height: 1.4;
1443
+ color: var(--fc-textDim);
1444
+ }
1445
+
1446
+ .fc-m-share-url {
1447
+ width: 100%;
1448
+ padding: 11px 12px;
1449
+ background: var(--fc-bgCard, var(--fc-bgInput, var(--fc-bg)));
1450
+ border: 1px solid var(--fc-border);
1451
+ border-radius: 10px;
1452
+ color: var(--fc-text);
1453
+ font-size: 12px;
1454
+ font-family: var(--fc-mono, "SF Mono", "Menlo", monospace);
1455
+ box-sizing: border-box;
1456
+ }
1457
+
1458
+ .fc-m-share-meta,
1459
+ .fc-m-share-note {
1460
+ margin-top: 10px;
1461
+ font-size: 12px;
1462
+ line-height: 1.4;
1463
+ color: var(--fc-textDim);
1464
+ }
1465
+
1466
+ .fc-m-share-actions {
1467
+ display: grid;
1468
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1469
+ gap: 8px;
1470
+ margin-top: 10px;
1471
+ }
1472
+
1473
+ .fc-m-share-btn {
1474
+ min-width: 0;
1475
+ height: 38px;
1476
+ padding: 0 12px;
1477
+ border-radius: 10px;
1478
+ background: var(--fc-bgCard, var(--fc-bgInput, var(--fc-bg)));
1479
+ border: 1px solid var(--fc-border);
1480
+ color: var(--fc-text);
1481
+ font-size: 13px;
1482
+ font-weight: 600;
1483
+ cursor: pointer;
1484
+ font-family: inherit;
1485
+ }
1486
+
1487
+ .fc-m-share-btn:active {
1488
+ background: var(--fc-bgHover);
1489
+ }
1490
+
1491
+ .fc-m-share-btn--primary {
1492
+ background: color-mix(in srgb, var(--fc-accent) 14%, transparent);
1493
+ border-color: color-mix(in srgb, var(--fc-accent) 28%, transparent);
1494
+ color: var(--fc-accent);
1495
+ }
1496
+
1497
+ .fc-m-share-btn--danger {
1498
+ color: var(--fc-error, #e74c3c);
1499
+ }
1500
+
1501
+ .fc-m-share-btn--full {
1502
+ grid-column: 1 / -1;
1503
+ }
1504
+
1426
1505
  /* ── File picker: project section + new file ── */
1427
1506
  .fc-m-filepicker-projects {
1428
1507
  padding: 4px 0 0;
@@ -1976,12 +2055,14 @@
1976
2055
  align-items: center;
1977
2056
  gap: 5px;
1978
2057
  flex-shrink: 0;
2058
+ line-height: 1;
2059
+ transform: translateY(-0.5px);
1979
2060
  }
1980
2061
 
1981
2062
  .fc-m-status-inline-dot {
1982
- width: 6px;
1983
- height: 6px;
1984
- border-radius: 3px;
2063
+ width: 7px;
2064
+ height: 7px;
2065
+ border-radius: 999px;
1985
2066
  flex-shrink: 0;
1986
2067
  }
1987
2068
 
@@ -2019,10 +2100,11 @@
2019
2100
  font-size: 9px;
2020
2101
  color: #f06b6b;
2021
2102
  opacity: 0.8;
2103
+ min-width: 0;
2022
2104
  white-space: nowrap;
2023
2105
  overflow: hidden;
2024
2106
  text-overflow: ellipsis;
2025
- max-width: 180px;
2107
+ max-width: 10ch;
2026
2108
  }
2027
2109
 
2028
2110
  /* ════════════════════════════════════