@bettercms-ai/kit 0.1.1 → 2.0.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 (1100) hide show
  1. package/README.md +22 -16
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/adapters/dock-values.d.ts +28 -0
  4. package/dist/adapters/dock-values.js +41 -0
  5. package/dist/adapters/dock-values.js.map +1 -0
  6. package/dist/adapters/icons.d.ts +15 -0
  7. package/dist/adapters/icons.js +27 -0
  8. package/dist/adapters/icons.js.map +1 -0
  9. package/dist/adapters/lossy.d.ts +326 -0
  10. package/dist/adapters/lossy.js +414 -0
  11. package/dist/adapters/lossy.js.map +1 -0
  12. package/dist/adapters/prod-types.d.ts +546 -0
  13. package/dist/adapters/prod-types.js +714 -0
  14. package/dist/adapters/prod-types.js.map +1 -0
  15. package/dist/adapters/schema.d.ts +154 -0
  16. package/dist/adapters/schema.js +3020 -0
  17. package/dist/adapters/schema.js.map +1 -0
  18. package/dist/adapters/values.d.ts +221 -0
  19. package/dist/adapters/values.js +623 -0
  20. package/dist/adapters/values.js.map +1 -0
  21. package/dist/brand/logo.d.ts +17 -0
  22. package/dist/brand/logo.js +96 -0
  23. package/dist/brand/logo.js.map +1 -0
  24. package/dist/context.d.ts +359 -0
  25. package/dist/context.js +217 -0
  26. package/dist/context.js.map +1 -0
  27. package/dist/controls/button.d.ts +72 -0
  28. package/dist/controls/button.js +578 -0
  29. package/dist/controls/button.js.map +1 -0
  30. package/dist/controls/c1.d.ts +11 -0
  31. package/dist/controls/c1.js +24 -0
  32. package/dist/controls/c1.js.map +1 -0
  33. package/dist/controls/c2.d.ts +10 -0
  34. package/dist/controls/c2.js +19 -0
  35. package/dist/controls/c2.js.map +1 -0
  36. package/dist/controls/choice.d.ts +44 -0
  37. package/dist/controls/choice.js +463 -0
  38. package/dist/controls/choice.js.map +1 -0
  39. package/dist/controls/code-register.d.ts +1 -0
  40. package/dist/controls/code-register.js +8 -0
  41. package/dist/controls/code-register.js.map +1 -0
  42. package/dist/controls/code.d.ts +42 -0
  43. package/dist/controls/code.js +397 -0
  44. package/dist/controls/code.js.map +1 -0
  45. package/dist/controls/color.d.ts +5 -0
  46. package/dist/controls/color.js +130 -0
  47. package/dist/controls/color.js.map +1 -0
  48. package/dist/controls/component-services.d.ts +156 -0
  49. package/dist/controls/component-services.js +7 -0
  50. package/dist/controls/component-services.js.map +1 -0
  51. package/dist/controls/date-register.d.ts +1 -0
  52. package/dist/controls/date-register.js +9 -0
  53. package/dist/controls/date-register.js.map +1 -0
  54. package/dist/controls/date-zone.d.ts +104 -0
  55. package/dist/controls/date-zone.js +278 -0
  56. package/dist/controls/date-zone.js.map +1 -0
  57. package/dist/controls/date.d.ts +7 -0
  58. package/dist/controls/date.js +466 -0
  59. package/dist/controls/date.js.map +1 -0
  60. package/dist/controls/form-picker-register.d.ts +1 -0
  61. package/dist/controls/form-picker-register.js +19 -0
  62. package/dist/controls/form-picker-register.js.map +1 -0
  63. package/dist/controls/form-picker.d.ts +43 -0
  64. package/dist/controls/form-picker.js +85 -0
  65. package/dist/controls/form-picker.js.map +1 -0
  66. package/dist/controls/icon-register.d.ts +1 -0
  67. package/dist/controls/icon-register.js +8 -0
  68. package/dist/controls/icon-register.js.map +1 -0
  69. package/dist/controls/icon.d.ts +40 -0
  70. package/dist/controls/icon.js +360 -0
  71. package/dist/controls/icon.js.map +1 -0
  72. package/dist/controls/index.d.ts +5 -0
  73. package/dist/controls/index.js +38 -0
  74. package/dist/controls/index.js.map +1 -0
  75. package/dist/controls/json-register.d.ts +1 -0
  76. package/dist/controls/json-register.js +8 -0
  77. package/dist/controls/json-register.js.map +1 -0
  78. package/dist/controls/json.d.ts +2 -0
  79. package/dist/controls/json.js +82 -0
  80. package/dist/controls/json.js.map +1 -0
  81. package/dist/controls/link.d.ts +260 -0
  82. package/dist/controls/link.js +1186 -0
  83. package/dist/controls/link.js.map +1 -0
  84. package/dist/controls/location-register.d.ts +1 -0
  85. package/dist/controls/location-register.js +8 -0
  86. package/dist/controls/location-register.js.map +1 -0
  87. package/dist/controls/location.d.ts +16 -0
  88. package/dist/controls/location.js +221 -0
  89. package/dist/controls/location.js.map +1 -0
  90. package/dist/controls/media-register.d.ts +1 -0
  91. package/dist/controls/media-register.js +12 -0
  92. package/dist/controls/media-register.js.map +1 -0
  93. package/dist/controls/media-services.d.ts +46 -0
  94. package/dist/controls/media-services.js +0 -0
  95. package/dist/controls/media.d.ts +104 -0
  96. package/dist/controls/media.js +1396 -0
  97. package/dist/controls/media.js.map +1 -0
  98. package/dist/controls/number.d.ts +22 -0
  99. package/dist/controls/number.js +196 -0
  100. package/dist/controls/number.js.map +1 -0
  101. package/dist/controls/reference-register.d.ts +1 -0
  102. package/dist/controls/reference-register.js +10 -0
  103. package/dist/controls/reference-register.js.map +1 -0
  104. package/dist/controls/reference-services.d.ts +58 -0
  105. package/dist/controls/reference-services.js +0 -0
  106. package/dist/controls/reference.d.ts +23 -0
  107. package/dist/controls/reference.js +777 -0
  108. package/dist/controls/reference.js.map +1 -0
  109. package/dist/controls/rich-text/blocks.d.ts +49 -0
  110. package/dist/controls/rich-text/blocks.js +1859 -0
  111. package/dist/controls/rich-text/blocks.js.map +1 -0
  112. package/dist/controls/rich-text/catalog.d.ts +101 -0
  113. package/dist/controls/rich-text/catalog.js +623 -0
  114. package/dist/controls/rich-text/catalog.js.map +1 -0
  115. package/dist/controls/rich-text/codec.d.ts +64 -0
  116. package/dist/controls/rich-text/codec.js +34 -0
  117. package/dist/controls/rich-text/codec.js.map +1 -0
  118. package/dist/controls/rich-text/component-card.d.ts +14 -0
  119. package/dist/controls/rich-text/component-card.js +1024 -0
  120. package/dist/controls/rich-text/component-card.js.map +1 -0
  121. package/dist/controls/rich-text/component-panel.d.ts +47 -0
  122. package/dist/controls/rich-text/component-panel.js +141 -0
  123. package/dist/controls/rich-text/component-panel.js.map +1 -0
  124. package/dist/controls/rich-text/control.d.ts +20 -0
  125. package/dist/controls/rich-text/control.js +296 -0
  126. package/dist/controls/rich-text/control.js.map +1 -0
  127. package/dist/controls/rich-text/dom.d.ts +233 -0
  128. package/dist/controls/rich-text/dom.js +1019 -0
  129. package/dist/controls/rich-text/dom.js.map +1 -0
  130. package/dist/controls/rich-text/editor.d.ts +57 -0
  131. package/dist/controls/rich-text/editor.js +1630 -0
  132. package/dist/controls/rich-text/editor.js.map +1 -0
  133. package/dist/controls/rich-text/floating.d.ts +28 -0
  134. package/dist/controls/rich-text/floating.js +154 -0
  135. package/dist/controls/rich-text/floating.js.map +1 -0
  136. package/dist/controls/rich-text/index.d.ts +1 -0
  137. package/dist/controls/rich-text/index.js +12 -0
  138. package/dist/controls/rich-text/index.js.map +1 -0
  139. package/dist/controls/rich-text/link-form.d.ts +13 -0
  140. package/dist/controls/rich-text/link-form.js +147 -0
  141. package/dist/controls/rich-text/link-form.js.map +1 -0
  142. package/dist/controls/rich-text/markdown.d.ts +6 -0
  143. package/dist/controls/rich-text/markdown.js +181 -0
  144. package/dist/controls/rich-text/markdown.js.map +1 -0
  145. package/dist/controls/rich-text/ops.d.ts +35 -0
  146. package/dist/controls/rich-text/ops.js +316 -0
  147. package/dist/controls/rich-text/ops.js.map +1 -0
  148. package/dist/controls/rich-text/plain.d.ts +17 -0
  149. package/dist/controls/rich-text/plain.js +44 -0
  150. package/dist/controls/rich-text/plain.js.map +1 -0
  151. package/dist/controls/rich-text/toolbar.d.ts +89 -0
  152. package/dist/controls/rich-text/toolbar.js +343 -0
  153. package/dist/controls/rich-text/toolbar.js.map +1 -0
  154. package/dist/controls/scale.d.ts +56 -0
  155. package/dist/controls/scale.js +563 -0
  156. package/dist/controls/scale.js.map +1 -0
  157. package/dist/controls/slot-register.d.ts +1 -0
  158. package/dist/controls/slot-register.js +16 -0
  159. package/dist/controls/slot-register.js.map +1 -0
  160. package/dist/controls/slot-services.d.ts +122 -0
  161. package/dist/controls/slot-services.js +155 -0
  162. package/dist/controls/slot-services.js.map +1 -0
  163. package/dist/controls/slot.d.ts +33 -0
  164. package/dist/controls/slot.js +366 -0
  165. package/dist/controls/slot.js.map +1 -0
  166. package/dist/controls/table/index.d.ts +1 -0
  167. package/dist/controls/table/index.js +12 -0
  168. package/dist/controls/table/index.js.map +1 -0
  169. package/dist/controls/table/prod.d.ts +21 -0
  170. package/dist/controls/table/prod.js +79 -0
  171. package/dist/controls/table/prod.js.map +1 -0
  172. package/dist/controls/table/refs.d.ts +50 -0
  173. package/dist/controls/table/refs.js +79 -0
  174. package/dist/controls/table/refs.js.map +1 -0
  175. package/dist/controls/table/stored.d.ts +15 -0
  176. package/dist/controls/table/stored.js +44 -0
  177. package/dist/controls/table/stored.js.map +1 -0
  178. package/dist/controls/table/table-editor.d.ts +103 -0
  179. package/dist/controls/table/table-editor.js +2725 -0
  180. package/dist/controls/table/table-editor.js.map +1 -0
  181. package/dist/controls/table/table-link.d.ts +24 -0
  182. package/dist/controls/table/table-link.js +180 -0
  183. package/dist/controls/table/table-link.js.map +1 -0
  184. package/dist/controls/table/table.d.ts +9 -0
  185. package/dist/controls/table/table.js +103 -0
  186. package/dist/controls/table/table.js.map +1 -0
  187. package/dist/controls/text.d.ts +17 -0
  188. package/dist/controls/text.js +322 -0
  189. package/dist/controls/text.js.map +1 -0
  190. package/dist/controls/unknown-value.d.ts +17 -0
  191. package/dist/controls/unknown-value.js +66 -0
  192. package/dist/controls/unknown-value.js.map +1 -0
  193. package/dist/core/core.d.ts +63 -0
  194. package/dist/core/core.js +171 -0
  195. package/dist/core/core.js.map +1 -0
  196. package/dist/core/facets.d.ts +347 -0
  197. package/dist/core/facets.js +334 -0
  198. package/dist/core/facets.js.map +1 -0
  199. package/dist/core/index.d.ts +3 -0
  200. package/dist/core/index.js +3 -0
  201. package/dist/engine/array.d.ts +101 -0
  202. package/dist/engine/array.js +906 -0
  203. package/dist/engine/array.js.map +1 -0
  204. package/dist/engine/bits.d.ts +24 -0
  205. package/dist/engine/bits.js +60 -0
  206. package/dist/engine/bits.js.map +1 -0
  207. package/dist/engine/breadcrumb.d.ts +45 -0
  208. package/dist/engine/breadcrumb.js +63 -0
  209. package/dist/engine/breadcrumb.js.map +1 -0
  210. package/dist/engine/expand.d.ts +66 -0
  211. package/dist/engine/expand.js +153 -0
  212. package/dist/engine/expand.js.map +1 -0
  213. package/dist/engine/field-list.d.ts +20 -0
  214. package/dist/engine/field-list.js +19 -0
  215. package/dist/engine/field-list.js.map +1 -0
  216. package/dist/engine/field-shell.d.ts +49 -0
  217. package/dist/engine/field-shell.js +988 -0
  218. package/dist/engine/field-shell.js.map +1 -0
  219. package/dist/engine/frame.d.ts +122 -0
  220. package/dist/engine/frame.js +601 -0
  221. package/dist/engine/frame.js.map +1 -0
  222. package/dist/engine/group-summary.d.ts +5 -0
  223. package/dist/engine/group-summary.js +70 -0
  224. package/dist/engine/group-summary.js.map +1 -0
  225. package/dist/engine/grouping.d.ts +238 -0
  226. package/dist/engine/grouping.js +996 -0
  227. package/dist/engine/grouping.js.map +1 -0
  228. package/dist/engine/item-list.d.ts +99 -0
  229. package/dist/engine/item-list.js +725 -0
  230. package/dist/engine/item-list.js.map +1 -0
  231. package/dist/engine/kit-field.d.ts +72 -0
  232. package/dist/engine/kit-field.js +558 -0
  233. package/dist/engine/kit-field.js.map +1 -0
  234. package/dist/engine/schema-form.d.ts +116 -0
  235. package/dist/engine/schema-form.js +462 -0
  236. package/dist/engine/schema-form.js.map +1 -0
  237. package/dist/engine/slot.d.ts +13 -0
  238. package/dist/engine/slot.js +216 -0
  239. package/dist/engine/slot.js.map +1 -0
  240. package/dist/index.d.ts +45 -3139
  241. package/dist/index.js +47 -2036
  242. package/dist/index.js.map +1 -0
  243. package/dist/kit.css +75 -0
  244. package/dist/lib/cn.d.ts +4 -0
  245. package/dist/lib/cn.js +56 -0
  246. package/dist/lib/cn.js.map +1 -0
  247. package/dist/lib/columns.d.ts +14 -0
  248. package/dist/lib/columns.js +30 -0
  249. package/dist/lib/columns.js.map +1 -0
  250. package/dist/lib/frames.d.ts +36 -0
  251. package/dist/lib/frames.js +214 -0
  252. package/dist/lib/frames.js.map +1 -0
  253. package/dist/lib/icon-image.d.ts +10 -0
  254. package/dist/lib/icon-image.js +8 -0
  255. package/dist/lib/icon-image.js.map +1 -0
  256. package/dist/lib/icons.d.ts +16 -0
  257. package/dist/lib/icons.js +173 -0
  258. package/dist/lib/icons.js.map +1 -0
  259. package/dist/lib/input-modality.d.ts +11 -0
  260. package/dist/lib/input-modality.js +47 -0
  261. package/dist/lib/input-modality.js.map +1 -0
  262. package/dist/lib/key-event.d.ts +11 -0
  263. package/dist/lib/key-event.js +16 -0
  264. package/dist/lib/key-event.js.map +1 -0
  265. package/dist/lib/path.d.ts +29 -0
  266. package/dist/lib/path.js +66 -0
  267. package/dist/lib/path.js.map +1 -0
  268. package/dist/lib/schema.d.ts +80 -0
  269. package/dist/lib/schema.js +384 -0
  270. package/dist/lib/schema.js.map +1 -0
  271. package/dist/lib/utils.d.ts +7 -0
  272. package/dist/lib/utils.js +37 -0
  273. package/dist/lib/utils.js.map +1 -0
  274. package/dist/lib/validate.d.ts +30 -0
  275. package/dist/lib/validate.js +224 -0
  276. package/dist/lib/validate.js.map +1 -0
  277. package/dist/library/analysis.d.ts +23 -0
  278. package/dist/library/analysis.js +160 -0
  279. package/dist/library/analysis.js.map +1 -0
  280. package/dist/library/catalog.d.ts +57 -0
  281. package/dist/library/catalog.js +307 -0
  282. package/dist/library/catalog.js.map +1 -0
  283. package/dist/library/coreNotes.d.ts +8 -0
  284. package/dist/library/coreNotes.js +111 -0
  285. package/dist/library/coreNotes.js.map +1 -0
  286. package/dist/library/coverage.d.ts +40 -0
  287. package/dist/library/coverage.js +59 -0
  288. package/dist/library/coverage.js.map +1 -0
  289. package/dist/library/entries/advanced.entries.d.ts +2 -0
  290. package/dist/library/entries/advanced.entries.js +6579 -0
  291. package/dist/library/entries/advanced.entries.js.map +1 -0
  292. package/dist/library/entries/commerce.entries.d.ts +2 -0
  293. package/dist/library/entries/commerce.entries.js +4140 -0
  294. package/dist/library/entries/commerce.entries.js.map +1 -0
  295. package/dist/library/entries/company.entries.d.ts +2 -0
  296. package/dist/library/entries/company.entries.js +2731 -0
  297. package/dist/library/entries/company.entries.js.map +1 -0
  298. package/dist/library/entries/conversion.entries.d.ts +2 -0
  299. package/dist/library/entries/conversion.entries.js +3707 -0
  300. package/dist/library/entries/conversion.entries.js.map +1 -0
  301. package/dist/library/entries/data.entries.d.ts +7 -0
  302. package/dist/library/entries/data.entries.js +4613 -0
  303. package/dist/library/entries/data.entries.js.map +1 -0
  304. package/dist/library/entries/events.entries.d.ts +2 -0
  305. package/dist/library/entries/events.entries.js +3428 -0
  306. package/dist/library/entries/events.entries.js.map +1 -0
  307. package/dist/library/entries/features.entries.d.ts +2 -0
  308. package/dist/library/entries/features.entries.js +3157 -0
  309. package/dist/library/entries/features.entries.js.map +1 -0
  310. package/dist/library/entries/heroes.entries.d.ts +2 -0
  311. package/dist/library/entries/heroes.entries.js +3401 -0
  312. package/dist/library/entries/heroes.entries.js.map +1 -0
  313. package/dist/library/entries/index.d.ts +3 -0
  314. package/dist/library/entries/index.js +35 -0
  315. package/dist/library/entries/index.js.map +1 -0
  316. package/dist/library/entries/listings.entries.d.ts +2 -0
  317. package/dist/library/entries/listings.entries.js +2976 -0
  318. package/dist/library/entries/listings.entries.js.map +1 -0
  319. package/dist/library/entries/longform.entries.d.ts +2 -0
  320. package/dist/library/entries/longform.entries.js +4227 -0
  321. package/dist/library/entries/longform.entries.js.map +1 -0
  322. package/dist/library/entries/media.entries.d.ts +2 -0
  323. package/dist/library/entries/media.entries.js +2781 -0
  324. package/dist/library/entries/media.entries.js.map +1 -0
  325. package/dist/library/entries/navigation.entries.d.ts +2 -0
  326. package/dist/library/entries/navigation.entries.js +4011 -0
  327. package/dist/library/entries/navigation.entries.js.map +1 -0
  328. package/dist/library/entries/pricing.entries.d.ts +2 -0
  329. package/dist/library/entries/pricing.entries.js +2383 -0
  330. package/dist/library/entries/pricing.entries.js.map +1 -0
  331. package/dist/library/entries/social-proof.entries.d.ts +2 -0
  332. package/dist/library/entries/social-proof.entries.js +2297 -0
  333. package/dist/library/entries/social-proof.entries.js.map +1 -0
  334. package/dist/library/examples/bento.d.ts +92 -0
  335. package/dist/library/examples/bento.js +201 -0
  336. package/dist/library/examples/bento.js.map +1 -0
  337. package/dist/library/examples/blocks.d.ts +14 -0
  338. package/dist/library/examples/blocks.js +313 -0
  339. package/dist/library/examples/blocks.js.map +1 -0
  340. package/dist/library/examples/faq.d.ts +28 -0
  341. package/dist/library/examples/faq.js +230 -0
  342. package/dist/library/examples/faq.js.map +1 -0
  343. package/dist/library/examples/hero.d.ts +43 -0
  344. package/dist/library/examples/hero.js +222 -0
  345. package/dist/library/examples/hero.js.map +1 -0
  346. package/dist/library/examples/index.d.ts +36 -0
  347. package/dist/library/examples/index.js +109 -0
  348. package/dist/library/examples/index.js.map +1 -0
  349. package/dist/library/examples/journalStory.d.ts +93 -0
  350. package/dist/library/examples/journalStory.js +338 -0
  351. package/dist/library/examples/journalStory.js.map +1 -0
  352. package/dist/library/examples/megaMenu.d.ts +134 -0
  353. package/dist/library/examples/megaMenu.js +442 -0
  354. package/dist/library/examples/megaMenu.js.map +1 -0
  355. package/dist/library/examples/pricing.d.ts +103 -0
  356. package/dist/library/examples/pricing.js +479 -0
  357. package/dist/library/examples/pricing.js.map +1 -0
  358. package/dist/library/examples/tabs.d.ts +87 -0
  359. package/dist/library/examples/tabs.js +180 -0
  360. package/dist/library/examples/tabs.js.map +1 -0
  361. package/dist/library/export.d.ts +42 -0
  362. package/dist/library/export.js +80 -0
  363. package/dist/library/export.js.map +1 -0
  364. package/dist/library/index.d.ts +13 -0
  365. package/dist/library/index.js +6 -0
  366. package/dist/library/kit-catalog.json +1510 -0
  367. package/dist/library/types.d.ts +42 -0
  368. package/dist/library/types.js +0 -0
  369. package/dist/schema/adapters.d.ts +28 -0
  370. package/dist/schema/adapters.js +492 -0
  371. package/dist/schema/adapters.js.map +1 -0
  372. package/dist/schema/help.d.ts +27 -0
  373. package/dist/schema/help.js +56 -0
  374. package/dist/schema/help.js.map +1 -0
  375. package/dist/schema/scale.d.ts +69 -0
  376. package/dist/schema/scale.js +250 -0
  377. package/dist/schema/scale.js.map +1 -0
  378. package/dist/schema/sources.d.ts +103 -0
  379. package/dist/schema/sources.js +65 -0
  380. package/dist/schema/sources.js.map +1 -0
  381. package/dist/schema/table.d.ts +319 -0
  382. package/dist/schema/table.js +1199 -0
  383. package/dist/schema/table.js.map +1 -0
  384. package/dist/schema/types.d.ts +297 -0
  385. package/dist/schema/types.js +14 -0
  386. package/dist/schema/types.js.map +1 -0
  387. package/dist/styles.css +2 -0
  388. package/dist/table/table-view.d.ts +14 -0
  389. package/dist/table/table-view.js +140 -0
  390. package/dist/table/table-view.js.map +1 -0
  391. package/dist/table/table.css +73 -0
  392. package/dist/testing/corpus.d.ts +63 -0
  393. package/dist/testing/corpus.js +129 -0
  394. package/dist/testing/corpus.js.map +1 -0
  395. package/dist/testing/test-form.d.ts +11 -0
  396. package/dist/testing/test-form.js +38 -0
  397. package/dist/testing/test-form.js.map +1 -0
  398. package/dist/theme.css +345 -0
  399. package/dist/theme.d.ts +20 -1504
  400. package/dist/theme.js +43 -4126
  401. package/dist/theme.js.map +1 -0
  402. package/dist/tokens.css +542 -0
  403. package/dist/types.d.ts +17 -0
  404. package/dist/types.js +0 -0
  405. package/dist/ui/action-tray.d.ts +54 -0
  406. package/dist/ui/action-tray.js +154 -0
  407. package/dist/ui/action-tray.js.map +1 -0
  408. package/dist/ui/autocomplete.d.ts +30 -0
  409. package/dist/ui/autocomplete.js +139 -0
  410. package/dist/ui/autocomplete.js.map +1 -0
  411. package/dist/ui/button.d.ts +57 -0
  412. package/dist/ui/button.js +201 -0
  413. package/dist/ui/button.js.map +1 -0
  414. package/dist/ui/choice-switch.d.ts +36 -0
  415. package/dist/ui/choice-switch.js +57 -0
  416. package/dist/ui/choice-switch.js.map +1 -0
  417. package/dist/ui/controls.d.ts +83 -0
  418. package/dist/ui/controls.js +331 -0
  419. package/dist/ui/controls.js.map +1 -0
  420. package/dist/ui/display.d.ts +163 -0
  421. package/dist/ui/display.js +455 -0
  422. package/dist/ui/display.js.map +1 -0
  423. package/dist/ui/expanded-editor-modal.d.ts +26 -0
  424. package/dist/ui/expanded-editor-modal.js +140 -0
  425. package/dist/ui/expanded-editor-modal.js.map +1 -0
  426. package/dist/ui/field-context.d.ts +12 -0
  427. package/dist/ui/field-context.js +23 -0
  428. package/dist/ui/field-context.js.map +1 -0
  429. package/dist/ui/floating-panel.d.ts +152 -0
  430. package/dist/ui/floating-panel.js +928 -0
  431. package/dist/ui/floating-panel.js.map +1 -0
  432. package/dist/ui/index.d.ts +16 -0
  433. package/dist/ui/index.js +18 -0
  434. package/dist/ui/input.d.ts +78 -0
  435. package/dist/ui/input.js +250 -0
  436. package/dist/ui/input.js.map +1 -0
  437. package/dist/ui/mode-bar.d.ts +31 -0
  438. package/dist/ui/mode-bar.js +65 -0
  439. package/dist/ui/mode-bar.js.map +1 -0
  440. package/dist/ui/overlay.d.ts +195 -0
  441. package/dist/ui/overlay.js +697 -0
  442. package/dist/ui/overlay.js.map +1 -0
  443. package/dist/ui/path-crumbs.d.ts +90 -0
  444. package/dist/ui/path-crumbs.js +566 -0
  445. package/dist/ui/path-crumbs.js.map +1 -0
  446. package/dist/ui/presence.d.ts +16 -0
  447. package/dist/ui/presence.js +65 -0
  448. package/dist/ui/presence.js.map +1 -0
  449. package/dist/ui/select.d.ts +66 -0
  450. package/dist/ui/select.js +407 -0
  451. package/dist/ui/select.js.map +1 -0
  452. package/dist/ui/shortcut-hint.d.ts +14 -0
  453. package/dist/ui/shortcut-hint.js +35 -0
  454. package/dist/ui/shortcut-hint.js.map +1 -0
  455. package/dist/ui/spinner.d.ts +24 -0
  456. package/dist/ui/spinner.js +42 -0
  457. package/dist/ui/spinner.js.map +1 -0
  458. package/dist/ui/split-button.d.ts +32 -0
  459. package/dist/ui/split-button.js +60 -0
  460. package/dist/ui/split-button.js.map +1 -0
  461. package/dist/ui/surfaces.d.ts +23 -0
  462. package/dist/ui/surfaces.js +26 -0
  463. package/dist/ui/surfaces.js.map +1 -0
  464. package/dist/ui/tab.d.ts +38 -0
  465. package/dist/ui/tab.js +87 -0
  466. package/dist/ui/tab.js.map +1 -0
  467. package/dist/ui/toast.d.ts +20 -0
  468. package/dist/ui/toast.js +115 -0
  469. package/dist/ui/toast.js.map +1 -0
  470. package/dist/ui/tooltip-root.d.ts +13 -0
  471. package/dist/ui/tooltip-root.js +77 -0
  472. package/dist/ui/tooltip-root.js.map +1 -0
  473. package/dist/ui/variants.d.ts +15 -0
  474. package/dist/ui/variants.js +14 -0
  475. package/dist/ui/variants.js.map +1 -0
  476. package/package.json +76 -50
  477. package/LICENSE +0 -21
  478. package/dist/_chunks-cjs/_visual-editing.js +0 -5898
  479. package/dist/_chunks-cjs/refractor.js +0 -22
  480. package/dist/_chunks-es/_visual-editing.mjs +0 -5904
  481. package/dist/_chunks-es/refractor.mjs +0 -25
  482. package/dist/_color.d.mts +0 -119
  483. package/dist/_color.d.ts +0 -119
  484. package/dist/_color.js +0 -1412
  485. package/dist/_color.mjs +0 -1411
  486. package/dist/_visual-editing.d.mts +0 -1126
  487. package/dist/_visual-editing.d.ts +0 -1126
  488. package/dist/_visual-editing.js +0 -30
  489. package/dist/_visual-editing.mjs +0 -30
  490. package/dist/index.d.mts +0 -3140
  491. package/dist/index.mjs +0 -2044
  492. package/dist/theme.d.mts +0 -1506
  493. package/dist/theme.mjs +0 -4126
  494. package/exports/_visual-editing.ts +0 -31
  495. package/exports/index.ts +0 -1
  496. package/exports/theme.ts +0 -1
  497. package/src/color/index.d.mts +0 -119
  498. package/src/color/index.mjs +0 -1411
  499. package/src/core/__workshop__/constants.ts +0 -293
  500. package/src/core/_compat.ts +0 -264
  501. package/src/core/components/autocomplete/__mocks__/apiStore.ts +0 -49
  502. package/src/core/components/autocomplete/__mocks__/countries.ts +0 -245
  503. package/src/core/components/autocomplete/__workshop__/async.tsx +0 -156
  504. package/src/core/components/autocomplete/__workshop__/constrainedHeight.tsx +0 -137
  505. package/src/core/components/autocomplete/__workshop__/custom.tsx +0 -89
  506. package/src/core/components/autocomplete/__workshop__/example.tsx +0 -79
  507. package/src/core/components/autocomplete/__workshop__/focusAndBlur.tsx +0 -36
  508. package/src/core/components/autocomplete/__workshop__/fullscreen.tsx +0 -294
  509. package/src/core/components/autocomplete/__workshop__/index.ts +0 -39
  510. package/src/core/components/autocomplete/__workshop__/types.ts +0 -4
  511. package/src/core/components/autocomplete/autocomplete.styles.tsx +0 -39
  512. package/src/core/components/autocomplete/autocomplete.tsx +0 -767
  513. package/src/core/components/autocomplete/autocompleteOption.tsx +0 -45
  514. package/src/core/components/autocomplete/autocompleteReducer.ts +0 -47
  515. package/src/core/components/autocomplete/constants.ts +0 -28
  516. package/src/core/components/autocomplete/index.ts +0 -2
  517. package/src/core/components/autocomplete/types.ts +0 -108
  518. package/src/core/components/breadcrumbs/__workshop__/example.tsx +0 -62
  519. package/src/core/components/breadcrumbs/__workshop__/index.ts +0 -14
  520. package/src/core/components/breadcrumbs/breadcrumbs.styles.ts +0 -18
  521. package/src/core/components/breadcrumbs/breadcrumbs.test.tsx +0 -51
  522. package/src/core/components/breadcrumbs/breadcrumbs.tsx +0 -133
  523. package/src/core/components/breadcrumbs/index.ts +0 -1
  524. package/src/core/components/dialog/__workshop__/activate.tsx +0 -134
  525. package/src/core/components/dialog/__workshop__/autoFocus.tsx +0 -29
  526. package/src/core/components/dialog/__workshop__/index.ts +0 -19
  527. package/src/core/components/dialog/__workshop__/layering.tsx +0 -41
  528. package/src/core/components/dialog/__workshop__/nested.tsx +0 -72
  529. package/src/core/components/dialog/__workshop__/onScroll.tsx +0 -39
  530. package/src/core/components/dialog/__workshop__/panes.tsx +0 -82
  531. package/src/core/components/dialog/__workshop__/position.tsx +0 -30
  532. package/src/core/components/dialog/__workshop__/props.tsx +0 -75
  533. package/src/core/components/dialog/__workshop__/provider.tsx +0 -11
  534. package/src/core/components/dialog/__workshop__/wrapped.tsx +0 -76
  535. package/src/core/components/dialog/dialog.tsx +0 -430
  536. package/src/core/components/dialog/dialogContext.ts +0 -20
  537. package/src/core/components/dialog/dialogProvider.tsx +0 -35
  538. package/src/core/components/dialog/index.ts +0 -4
  539. package/src/core/components/dialog/styles.ts +0 -77
  540. package/src/core/components/dialog/useDialog.ts +0 -11
  541. package/src/core/components/hotkeys/__workshop__/index.ts +0 -14
  542. package/src/core/components/hotkeys/__workshop__/plain.tsx +0 -9
  543. package/src/core/components/hotkeys/hotkeys.test.tsx +0 -42
  544. package/src/core/components/hotkeys/hotkeys.tsx +0 -66
  545. package/src/core/components/hotkeys/index.ts +0 -1
  546. package/src/core/components/index.ts +0 -9
  547. package/src/core/components/menu/__workshop__/asComponent.tsx +0 -45
  548. package/src/core/components/menu/__workshop__/avatarMenu.tsx +0 -51
  549. package/src/core/components/menu/__workshop__/closableMenuButton.tsx +0 -46
  550. package/src/core/components/menu/__workshop__/constrainedInBoundary.tsx +0 -134
  551. package/src/core/components/menu/__workshop__/customMenuItem.tsx +0 -45
  552. package/src/core/components/menu/__workshop__/customSelectedState.tsx +0 -39
  553. package/src/core/components/menu/__workshop__/disableFocusOnClose.tsx +0 -40
  554. package/src/core/components/menu/__workshop__/groups.tsx +0 -156
  555. package/src/core/components/menu/__workshop__/index.ts +0 -89
  556. package/src/core/components/menu/__workshop__/menuButton.tsx +0 -80
  557. package/src/core/components/menu/__workshop__/menuGroupRight.tsx +0 -58
  558. package/src/core/components/menu/__workshop__/nestedMenu.tsx +0 -22
  559. package/src/core/components/menu/__workshop__/onCloseMenuButton.tsx +0 -41
  560. package/src/core/components/menu/__workshop__/selectedItem.tsx +0 -69
  561. package/src/core/components/menu/__workshop__/shouldFocus.tsx +0 -47
  562. package/src/core/components/menu/__workshop__/tones.tsx +0 -25
  563. package/src/core/components/menu/__workshop__/withoutArrow.tsx +0 -32
  564. package/src/core/components/menu/helpers.ts +0 -82
  565. package/src/core/components/menu/index.ts +0 -5
  566. package/src/core/components/menu/menu.spacing.test.tsx +0 -63
  567. package/src/core/components/menu/menu.test.tsx +0 -125
  568. package/src/core/components/menu/menu.tsx +0 -178
  569. package/src/core/components/menu/menuButton.tsx +0 -268
  570. package/src/core/components/menu/menuContext.ts +0 -18
  571. package/src/core/components/menu/menuDivider.ts +0 -23
  572. package/src/core/components/menu/menuGroup.spacing.test.tsx +0 -63
  573. package/src/core/components/menu/menuGroup.tsx +0 -233
  574. package/src/core/components/menu/menuItem.spacing.test.tsx +0 -59
  575. package/src/core/components/menu/menuItem.tsx +0 -197
  576. package/src/core/components/menu/useMenu.ts +0 -21
  577. package/src/core/components/menu/useMenuController.ts +0 -231
  578. package/src/core/components/skeleton/__workshop__/delay.tsx +0 -70
  579. package/src/core/components/skeleton/__workshop__/index.ts +0 -11
  580. package/src/core/components/skeleton/__workshop__/skeleton.tsx +0 -64
  581. package/src/core/components/skeleton/index.ts +0 -2
  582. package/src/core/components/skeleton/skeleton.tsx +0 -57
  583. package/src/core/components/skeleton/styles.ts +0 -50
  584. package/src/core/components/skeleton/textSkeleton.tsx +0 -122
  585. package/src/core/components/tab/__workshop__/example.tsx +0 -79
  586. package/src/core/components/tab/__workshop__/index.ts +0 -14
  587. package/src/core/components/tab/index.ts +0 -3
  588. package/src/core/components/tab/tab.tsx +0 -101
  589. package/src/core/components/tab/tabList.test.tsx +0 -48
  590. package/src/core/components/tab/tabList.tsx +0 -70
  591. package/src/core/components/tab/tabPanel.tsx +0 -39
  592. package/src/core/components/toast/__workshop__/hook.tsx +0 -71
  593. package/src/core/components/toast/__workshop__/index.ts +0 -19
  594. package/src/core/components/toast/__workshop__/toast.tsx +0 -26
  595. package/src/core/components/toast/index.ts +0 -4
  596. package/src/core/components/toast/styles.ts +0 -77
  597. package/src/core/components/toast/toast.test.tsx +0 -101
  598. package/src/core/components/toast/toast.tsx +0 -198
  599. package/src/core/components/toast/toastContext.ts +0 -7
  600. package/src/core/components/toast/toastLayer.tsx +0 -51
  601. package/src/core/components/toast/toastProvider.tsx +0 -113
  602. package/src/core/components/toast/toastState.ts +0 -6
  603. package/src/core/components/toast/types.ts +0 -26
  604. package/src/core/components/toast/useToast.ts +0 -25
  605. package/src/core/components/tree/__workshop__/basic.perf.ts +0 -19
  606. package/src/core/components/tree/__workshop__/basic.tsx +0 -105
  607. package/src/core/components/tree/__workshop__/index.ts +0 -21
  608. package/src/core/components/tree/__workshop__/tabFromElement.tsx +0 -84
  609. package/src/core/components/tree/helpers.ts +0 -105
  610. package/src/core/components/tree/index.ts +0 -4
  611. package/src/core/components/tree/style.ts +0 -105
  612. package/src/core/components/tree/tree.test.tsx +0 -55
  613. package/src/core/components/tree/tree.tsx +0 -240
  614. package/src/core/components/tree/treeContext.ts +0 -10
  615. package/src/core/components/tree/treeGroup.tsx +0 -28
  616. package/src/core/components/tree/treeItem.test.tsx +0 -65
  617. package/src/core/components/tree/treeItem.tsx +0 -224
  618. package/src/core/components/tree/types.ts +0 -25
  619. package/src/core/components/tree/useTree.ts +0 -17
  620. package/src/core/constants.ts +0 -79
  621. package/src/core/helpers/animation.ts +0 -27
  622. package/src/core/helpers/element.ts +0 -55
  623. package/src/core/helpers/focus.ts +0 -100
  624. package/src/core/helpers/index.ts +0 -4
  625. package/src/core/helpers/scroll.ts +0 -15
  626. package/src/core/hooks/index.ts +0 -12
  627. package/src/core/hooks/useArrayProp.ts +0 -17
  628. package/src/core/hooks/useClickOutside.test.tsx +0 -482
  629. package/src/core/hooks/useClickOutside.ts +0 -118
  630. package/src/core/hooks/useClickOutsideEvent.test.tsx +0 -115
  631. package/src/core/hooks/useClickOutsideEvent.ts +0 -73
  632. package/src/core/hooks/useCustomValidity.ts +0 -13
  633. package/src/core/hooks/useDelayed.test.ts +0 -88
  634. package/src/core/hooks/useDelayedState.ts +0 -36
  635. package/src/core/hooks/useElementRect/__workshop__/example.tsx +0 -32
  636. package/src/core/hooks/useElementRect/__workshop__/index.ts +0 -14
  637. package/src/core/hooks/useElementRect/index.ts +0 -1
  638. package/src/core/hooks/useElementRect/useElementRect.ts +0 -13
  639. package/src/core/hooks/useElementSize.ts +0 -19
  640. package/src/core/hooks/useForwardedRef.ts +0 -19
  641. package/src/core/hooks/useGlobalKeyDown.ts +0 -24
  642. package/src/core/hooks/useIsomorphicEffect.ts +0 -7
  643. package/src/core/hooks/useMatchMedia.ts +0 -28
  644. package/src/core/hooks/useMediaIndex/__workshop__/index.ts +0 -14
  645. package/src/core/hooks/useMediaIndex/__workshop__/test.tsx +0 -14
  646. package/src/core/hooks/useMediaIndex/index.ts +0 -1
  647. package/src/core/hooks/useMediaIndex/useMediaIndex.test.tsx +0 -36
  648. package/src/core/hooks/useMediaIndex/useMediaIndex.ts +0 -102
  649. package/src/core/hooks/useMounted.ts +0 -15
  650. package/src/core/hooks/usePrefersDark.hydration.test.tsx +0 -56
  651. package/src/core/hooks/usePrefersDark.test.tsx +0 -19
  652. package/src/core/hooks/usePrefersDark.ts +0 -16
  653. package/src/core/hooks/usePrefersReducedMotion.hydration.test.tsx +0 -56
  654. package/src/core/hooks/usePrefersReducedMotion.test.tsx +0 -19
  655. package/src/core/hooks/usePrefersReducedMotion.ts +0 -16
  656. package/src/core/index.ts +0 -10
  657. package/src/core/lib/createGlobalScopedContext.ts +0 -36
  658. package/src/core/lib/globalScope.ts +0 -19
  659. package/src/core/lib/isRecord.ts +0 -3
  660. package/src/core/middleware/origin.ts +0 -47
  661. package/src/core/observers/elementSizeObserver.ts +0 -116
  662. package/src/core/observers/index.ts +0 -2
  663. package/src/core/observers/resizeObserver.ts +0 -9
  664. package/src/core/primitives/_selectable/index.ts +0 -1
  665. package/src/core/primitives/_selectable/selectable.tsx +0 -15
  666. package/src/core/primitives/_selectable/style.ts +0 -115
  667. package/src/core/primitives/avatar/__workshop__/asButton.tsx +0 -14
  668. package/src/core/primitives/avatar/__workshop__/index.ts +0 -29
  669. package/src/core/primitives/avatar/__workshop__/stack.tsx +0 -25
  670. package/src/core/primitives/avatar/__workshop__/withinButton.tsx +0 -63
  671. package/src/core/primitives/avatar/__workshop__/withinMenuItem.tsx +0 -70
  672. package/src/core/primitives/avatar/avatar.tsx +0 -200
  673. package/src/core/primitives/avatar/avatarCounter.tsx +0 -91
  674. package/src/core/primitives/avatar/avatarStack.tsx +0 -100
  675. package/src/core/primitives/avatar/index.ts +0 -4
  676. package/src/core/primitives/avatar/styles.ts +0 -167
  677. package/src/core/primitives/avatar/types.ts +0 -17
  678. package/src/core/primitives/badge/__workshop__/index.ts +0 -19
  679. package/src/core/primitives/badge/__workshop__/props.tsx +0 -30
  680. package/src/core/primitives/badge/__workshop__/tones.tsx +0 -21
  681. package/src/core/primitives/badge/badge.test.tsx +0 -16
  682. package/src/core/primitives/badge/badge.tsx +0 -70
  683. package/src/core/primitives/badge/index.ts +0 -1
  684. package/src/core/primitives/badge/styles.ts +0 -20
  685. package/src/core/primitives/badge/types.ts +0 -8
  686. package/src/core/primitives/box/__workshop__/asComponent.tsx +0 -31
  687. package/src/core/primitives/box/__workshop__/index.ts +0 -24
  688. package/src/core/primitives/box/__workshop__/props.tsx +0 -20
  689. package/src/core/primitives/box/__workshop__/responsive.tsx +0 -20
  690. package/src/core/primitives/box/box.test.tsx +0 -142
  691. package/src/core/primitives/box/box.tsx +0 -154
  692. package/src/core/primitives/box/index.ts +0 -1
  693. package/src/core/primitives/button/__workshop__/custom.tsx +0 -51
  694. package/src/core/primitives/button/__workshop__/customIcons.tsx +0 -30
  695. package/src/core/primitives/button/__workshop__/disabled.tsx +0 -74
  696. package/src/core/primitives/button/__workshop__/index.ts +0 -59
  697. package/src/core/primitives/button/__workshop__/labelUploadButton.tsx +0 -36
  698. package/src/core/primitives/button/__workshop__/mixedChildren.tsx +0 -12
  699. package/src/core/primitives/button/__workshop__/props.tsx +0 -55
  700. package/src/core/primitives/button/__workshop__/stacked.tsx +0 -58
  701. package/src/core/primitives/button/__workshop__/styled1.tsx +0 -17
  702. package/src/core/primitives/button/__workshop__/styled2.tsx +0 -19
  703. package/src/core/primitives/button/__workshop__/uploadButton.tsx +0 -28
  704. package/src/core/primitives/button/button.test.tsx +0 -82
  705. package/src/core/primitives/button/button.tsx +0 -210
  706. package/src/core/primitives/button/index.ts +0 -1
  707. package/src/core/primitives/button/styles.ts +0 -117
  708. package/src/core/primitives/card/__workshop__/allTones.tsx +0 -25
  709. package/src/core/primitives/card/__workshop__/asButton.tsx +0 -107
  710. package/src/core/primitives/card/__workshop__/asComponent.tsx +0 -27
  711. package/src/core/primitives/card/__workshop__/checkered.tsx +0 -26
  712. package/src/core/primitives/card/__workshop__/index.ts +0 -18
  713. package/src/core/primitives/card/__workshop__/interactive.tsx +0 -30
  714. package/src/core/primitives/card/__workshop__/listNavigation.tsx +0 -80
  715. package/src/core/primitives/card/__workshop__/props.tsx +0 -53
  716. package/src/core/primitives/card/__workshop__/selected.tsx +0 -94
  717. package/src/core/primitives/card/__workshop__/styled.tsx +0 -14
  718. package/src/core/primitives/card/card.tsx +0 -128
  719. package/src/core/primitives/card/index.ts +0 -2
  720. package/src/core/primitives/card/styles.ts +0 -147
  721. package/src/core/primitives/card/types.ts +0 -11
  722. package/src/core/primitives/checkbox/__workshop__/example.tsx +0 -25
  723. package/src/core/primitives/checkbox/__workshop__/index.ts +0 -13
  724. package/src/core/primitives/checkbox/__workshop__/props.tsx +0 -33
  725. package/src/core/primitives/checkbox/__workshop__/readOnly.tsx +0 -16
  726. package/src/core/primitives/checkbox/__workshop__/tones.tsx +0 -28
  727. package/src/core/primitives/checkbox/checkbox.tsx +0 -73
  728. package/src/core/primitives/checkbox/index.ts +0 -1
  729. package/src/core/primitives/checkbox/styles.ts +0 -128
  730. package/src/core/primitives/code/__workshop__/index.ts +0 -19
  731. package/src/core/primitives/code/__workshop__/opticalAlignment.tsx +0 -48
  732. package/src/core/primitives/code/__workshop__/props.tsx +0 -21
  733. package/src/core/primitives/code/code.tsx +0 -55
  734. package/src/core/primitives/code/index.ts +0 -1
  735. package/src/core/primitives/code/refractor.tsx +0 -20
  736. package/src/core/primitives/code/styles.ts +0 -77
  737. package/src/core/primitives/container/__workshop__/example.tsx +0 -20
  738. package/src/core/primitives/container/__workshop__/index.ts +0 -8
  739. package/src/core/primitives/container/container.tsx +0 -54
  740. package/src/core/primitives/container/index.ts +0 -2
  741. package/src/core/primitives/container/styles.ts +0 -23
  742. package/src/core/primitives/container/types.ts +0 -6
  743. package/src/core/primitives/flex/__workshop__/example.tsx +0 -34
  744. package/src/core/primitives/flex/__workshop__/gap.tsx +0 -25
  745. package/src/core/primitives/flex/__workshop__/index.ts +0 -11
  746. package/src/core/primitives/flex/flex.tsx +0 -64
  747. package/src/core/primitives/flex/index.ts +0 -1
  748. package/src/core/primitives/grid/__workshop__/index.ts +0 -10
  749. package/src/core/primitives/grid/__workshop__/responsive.tsx +0 -54
  750. package/src/core/primitives/grid/grid.test.tsx +0 -80
  751. package/src/core/primitives/grid/grid.tsx +0 -74
  752. package/src/core/primitives/grid/index.ts +0 -1
  753. package/src/core/primitives/heading/__workshop__/index.ts +0 -19
  754. package/src/core/primitives/heading/__workshop__/opticalAlignment.tsx +0 -54
  755. package/src/core/primitives/heading/__workshop__/plain.tsx +0 -32
  756. package/src/core/primitives/heading/heading.tsx +0 -88
  757. package/src/core/primitives/heading/index.ts +0 -1
  758. package/src/core/primitives/heading/styles.ts +0 -64
  759. package/src/core/primitives/heading/types.ts +0 -7
  760. package/src/core/primitives/index.ts +0 -27
  761. package/src/core/primitives/inline/__workshop__/index.ts +0 -8
  762. package/src/core/primitives/inline/__workshop__/plain.tsx +0 -27
  763. package/src/core/primitives/inline/index.ts +0 -1
  764. package/src/core/primitives/inline/inline.test.tsx +0 -51
  765. package/src/core/primitives/inline/inline.tsx +0 -63
  766. package/src/core/primitives/inline/styles.ts +0 -32
  767. package/src/core/primitives/inline/types.ts +0 -6
  768. package/src/core/primitives/kbd/__workshop__/index.ts +0 -8
  769. package/src/core/primitives/kbd/__workshop__/plain.tsx +0 -9
  770. package/src/core/primitives/kbd/index.ts +0 -1
  771. package/src/core/primitives/kbd/kbd.tsx +0 -69
  772. package/src/core/primitives/label/__workshop__/index.ts +0 -19
  773. package/src/core/primitives/label/__workshop__/opticalAlignment.tsx +0 -48
  774. package/src/core/primitives/label/__workshop__/plain.tsx +0 -24
  775. package/src/core/primitives/label/index.ts +0 -1
  776. package/src/core/primitives/label/label.tsx +0 -87
  777. package/src/core/primitives/label/styles.ts +0 -45
  778. package/src/core/primitives/popover/__workshop__/AlignedStory.tsx +0 -77
  779. package/src/core/primitives/popover/__workshop__/MarginsStory.tsx +0 -31
  780. package/src/core/primitives/popover/__workshop__/MatchReferenceWidthStory.tsx +0 -32
  781. package/src/core/primitives/popover/__workshop__/OpenOnMountStory.tsx +0 -11
  782. package/src/core/primitives/popover/__workshop__/PlainStory.tsx +0 -71
  783. package/src/core/primitives/popover/__workshop__/RecursiveStory.tsx +0 -71
  784. package/src/core/primitives/popover/__workshop__/SidePanelStory.tsx +0 -89
  785. package/src/core/primitives/popover/__workshop__/TestStory.tsx +0 -97
  786. package/src/core/primitives/popover/__workshop__/index.ts +0 -49
  787. package/src/core/primitives/popover/constants.ts +0 -22
  788. package/src/core/primitives/popover/floating-ui/size.ts +0 -99
  789. package/src/core/primitives/popover/helpers.ts +0 -31
  790. package/src/core/primitives/popover/index.ts +0 -2
  791. package/src/core/primitives/popover/popover.tsx +0 -511
  792. package/src/core/primitives/popover/popoverCard.tsx +0 -166
  793. package/src/core/primitives/popover/types.ts +0 -7
  794. package/src/core/primitives/radio/__workshop__/example.tsx +0 -63
  795. package/src/core/primitives/radio/__workshop__/index.ts +0 -11
  796. package/src/core/primitives/radio/__workshop__/plain.tsx +0 -28
  797. package/src/core/primitives/radio/index.ts +0 -1
  798. package/src/core/primitives/radio/radio.tsx +0 -51
  799. package/src/core/primitives/radio/styles.ts +0 -117
  800. package/src/core/primitives/select/__workshop__/index.ts +0 -11
  801. package/src/core/primitives/select/__workshop__/plain.tsx +0 -27
  802. package/src/core/primitives/select/__workshop__/readOnly.tsx +0 -23
  803. package/src/core/primitives/select/index.ts +0 -1
  804. package/src/core/primitives/select/select.test.tsx +0 -52
  805. package/src/core/primitives/select/select.tsx +0 -94
  806. package/src/core/primitives/select/styles.ts +0 -166
  807. package/src/core/primitives/spinner/__workshop__/Props.tsx +0 -15
  808. package/src/core/primitives/spinner/__workshop__/index.ts +0 -14
  809. package/src/core/primitives/spinner/index.ts +0 -1
  810. package/src/core/primitives/spinner/spinner.tsx +0 -46
  811. package/src/core/primitives/stack/__workshop__/index.ts +0 -14
  812. package/src/core/primitives/stack/__workshop__/plain.tsx +0 -32
  813. package/src/core/primitives/stack/index.ts +0 -1
  814. package/src/core/primitives/stack/stack.test.tsx +0 -57
  815. package/src/core/primitives/stack/stack.tsx +0 -57
  816. package/src/core/primitives/stack/styles.ts +0 -32
  817. package/src/core/primitives/switch/__workshop__/example.tsx +0 -23
  818. package/src/core/primitives/switch/__workshop__/index.ts +0 -11
  819. package/src/core/primitives/switch/__workshop__/props.tsx +0 -21
  820. package/src/core/primitives/switch/index.ts +0 -1
  821. package/src/core/primitives/switch/styles.ts +0 -173
  822. package/src/core/primitives/switch/switch.tsx +0 -68
  823. package/src/core/primitives/text/__workshop__/colored.tsx +0 -30
  824. package/src/core/primitives/text/__workshop__/example.tsx +0 -39
  825. package/src/core/primitives/text/__workshop__/index.ts +0 -24
  826. package/src/core/primitives/text/__workshop__/opticalAlignment.tsx +0 -48
  827. package/src/core/primitives/text/index.ts +0 -1
  828. package/src/core/primitives/text/styles.ts +0 -74
  829. package/src/core/primitives/text/text.tsx +0 -89
  830. package/src/core/primitives/textArea/__workshop__/index.ts +0 -14
  831. package/src/core/primitives/textArea/__workshop__/plain.tsx +0 -50
  832. package/src/core/primitives/textArea/index.ts +0 -1
  833. package/src/core/primitives/textArea/textArea.tsx +0 -120
  834. package/src/core/primitives/textInput/__workshop__/clearButton.tsx +0 -30
  835. package/src/core/primitives/textInput/__workshop__/customValidity.tsx +0 -17
  836. package/src/core/primitives/textInput/__workshop__/index.ts +0 -44
  837. package/src/core/primitives/textInput/__workshop__/plain.tsx +0 -98
  838. package/src/core/primitives/textInput/__workshop__/readOnly.tsx +0 -9
  839. package/src/core/primitives/textInput/__workshop__/states.tsx +0 -53
  840. package/src/core/primitives/textInput/__workshop__/tones.tsx +0 -277
  841. package/src/core/primitives/textInput/__workshop__/typed.tsx +0 -23
  842. package/src/core/primitives/textInput/index.ts +0 -1
  843. package/src/core/primitives/textInput/textInput.test.tsx +0 -48
  844. package/src/core/primitives/textInput/textInput.tsx +0 -395
  845. package/src/core/primitives/tooltip/__workshop__/customPortal.tsx +0 -102
  846. package/src/core/primitives/tooltip/__workshop__/index.ts +0 -29
  847. package/src/core/primitives/tooltip/__workshop__/overflowingBoundary.tsx +0 -74
  848. package/src/core/primitives/tooltip/__workshop__/props.tsx +0 -107
  849. package/src/core/primitives/tooltip/__workshop__/resizableBoundary.tsx +0 -86
  850. package/src/core/primitives/tooltip/constants.ts +0 -23
  851. package/src/core/primitives/tooltip/index.ts +0 -2
  852. package/src/core/primitives/tooltip/tooltip.test.tsx +0 -452
  853. package/src/core/primitives/tooltip/tooltip.tsx +0 -495
  854. package/src/core/primitives/tooltip/tooltipCard.tsx +0 -109
  855. package/src/core/primitives/tooltip/tooltipDelayGroup/index.ts +0 -4
  856. package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupContext.tsx +0 -11
  857. package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupProvider.tsx +0 -57
  858. package/src/core/primitives/tooltip/tooltipDelayGroup/types.ts +0 -10
  859. package/src/core/primitives/tooltip/tooltipDelayGroup/useTooltipDelayGroup.ts +0 -13
  860. package/src/core/primitives/types.ts +0 -179
  861. package/src/core/styles/border/borderStyle.ts +0 -56
  862. package/src/core/styles/border/index.ts +0 -2
  863. package/src/core/styles/border/types.ts +0 -10
  864. package/src/core/styles/box/boxStyle.ts +0 -69
  865. package/src/core/styles/box/index.ts +0 -2
  866. package/src/core/styles/box/types.ts +0 -11
  867. package/src/core/styles/card/_cardColorStyle.ts +0 -108
  868. package/src/core/styles/card/index.ts +0 -1
  869. package/src/core/styles/flex/flexItemStyle.ts +0 -27
  870. package/src/core/styles/flex/flexStyle.ts +0 -70
  871. package/src/core/styles/flex/index.ts +0 -3
  872. package/src/core/styles/flex/types.ts +0 -25
  873. package/src/core/styles/focusRing/index.ts +0 -25
  874. package/src/core/styles/font/codeFontStyle.ts +0 -13
  875. package/src/core/styles/font/headingFontStyle.ts +0 -13
  876. package/src/core/styles/font/index.ts +0 -6
  877. package/src/core/styles/font/labelFontStyle.ts +0 -13
  878. package/src/core/styles/font/responsiveFont.ts +0 -103
  879. package/src/core/styles/font/textAlignStyle.ts +0 -19
  880. package/src/core/styles/font/textFontStyle.ts +0 -13
  881. package/src/core/styles/font/types.ts +0 -35
  882. package/src/core/styles/grid/gridItemStyle.ts +0 -82
  883. package/src/core/styles/grid/gridStyle.ts +0 -108
  884. package/src/core/styles/grid/index.ts +0 -3
  885. package/src/core/styles/grid/types.ts +0 -37
  886. package/src/core/styles/helpers.ts +0 -72
  887. package/src/core/styles/index.ts +0 -5
  888. package/src/core/styles/input/index.ts +0 -2
  889. package/src/core/styles/input/responsiveInputPaddingStyle.ts +0 -78
  890. package/src/core/styles/input/textInputStyle.ts +0 -263
  891. package/src/core/styles/internal.ts +0 -12
  892. package/src/core/styles/margin/index.ts +0 -2
  893. package/src/core/styles/margin/marginStyle.ts +0 -21
  894. package/src/core/styles/margin/marginsStyle.test.ts +0 -33
  895. package/src/core/styles/margin/types.ts +0 -9
  896. package/src/core/styles/padding/index.ts +0 -2
  897. package/src/core/styles/padding/paddingStyle.test.ts +0 -33
  898. package/src/core/styles/padding/paddingStyle.ts +0 -21
  899. package/src/core/styles/padding/types.ts +0 -12
  900. package/src/core/styles/radius/index.ts +0 -2
  901. package/src/core/styles/radius/radiusStyle.ts +0 -23
  902. package/src/core/styles/radius/types.ts +0 -8
  903. package/src/core/styles/shadow/index.ts +0 -2
  904. package/src/core/styles/shadow/shadowStyle.ts +0 -29
  905. package/src/core/styles/shadow/types.ts +0 -6
  906. package/src/core/styles/types.ts +0 -8
  907. package/src/core/theme/__workshop__/build/Root.tsx +0 -367
  908. package/src/core/theme/__workshop__/build/helpers.ts +0 -46
  909. package/src/core/theme/__workshop__/build/story.tsx +0 -465
  910. package/src/core/theme/__workshop__/canvas.tsx +0 -352
  911. package/src/core/theme/__workshop__/color.tsx +0 -62
  912. package/src/core/theme/__workshop__/debug/story.tsx +0 -408
  913. package/src/core/theme/__workshop__/index.ts +0 -39
  914. package/src/core/theme/__workshop__/layer.tsx +0 -78
  915. package/src/core/theme/__workshop__/nestedProvider.tsx +0 -15
  916. package/src/core/theme/index.ts +0 -5
  917. package/src/core/theme/theme.test.tsx +0 -73
  918. package/src/core/theme/themeColorProvider.tsx +0 -29
  919. package/src/core/theme/themeContext.ts +0 -10
  920. package/src/core/theme/themeProvider.tsx +0 -62
  921. package/src/core/theme/types.ts +0 -12
  922. package/src/core/theme/useRootTheme.ts +0 -17
  923. package/src/core/theme/useTheme.ts +0 -16
  924. package/src/core/types/avatar.ts +0 -14
  925. package/src/core/types/badge.ts +0 -12
  926. package/src/core/types/box.ts +0 -19
  927. package/src/core/types/button.ts +0 -21
  928. package/src/core/types/card.ts +0 -6
  929. package/src/core/types/component.ts +0 -32
  930. package/src/core/types/dialog.ts +0 -4
  931. package/src/core/types/flex.ts +0 -30
  932. package/src/core/types/grid.ts +0 -14
  933. package/src/core/types/gridItem.ts +0 -29
  934. package/src/core/types/index.ts +0 -15
  935. package/src/core/types/placement.ts +0 -18
  936. package/src/core/types/popover.ts +0 -4
  937. package/src/core/types/radius.ts +0 -4
  938. package/src/core/types/selectable.ts +0 -6
  939. package/src/core/types/text.ts +0 -4
  940. package/src/core/utils/arrow/arrow.tsx +0 -123
  941. package/src/core/utils/arrow/cmds.ts +0 -91
  942. package/src/core/utils/arrow/index.ts +0 -1
  943. package/src/core/utils/boundaryElement/__workshop__/index.ts +0 -14
  944. package/src/core/utils/boundaryElement/__workshop__/plain.tsx +0 -19
  945. package/src/core/utils/boundaryElement/boundaryElement.test.tsx +0 -100
  946. package/src/core/utils/boundaryElement/boundaryElementContext.ts +0 -7
  947. package/src/core/utils/boundaryElement/boundaryElementProvider.tsx +0 -24
  948. package/src/core/utils/boundaryElement/index.ts +0 -3
  949. package/src/core/utils/boundaryElement/types.ts +0 -7
  950. package/src/core/utils/boundaryElement/useBoundaryElement.ts +0 -26
  951. package/src/core/utils/conditionalWrapper/conditionalWrapper.tsx +0 -21
  952. package/src/core/utils/conditionalWrapper/index.ts +0 -1
  953. package/src/core/utils/elementQuery/__workshop__/customMedia.tsx +0 -30
  954. package/src/core/utils/elementQuery/__workshop__/index.ts +0 -14
  955. package/src/core/utils/elementQuery/elementQuery.tsx +0 -53
  956. package/src/core/utils/elementQuery/helpers.ts +0 -27
  957. package/src/core/utils/elementQuery/index.ts +0 -1
  958. package/src/core/utils/errorBoundary.tsx +0 -48
  959. package/src/core/utils/getElementRef.ts +0 -26
  960. package/src/core/utils/index.ts +0 -9
  961. package/src/core/utils/layer/__workshop__/_debug.tsx +0 -17
  962. package/src/core/utils/layer/__workshop__/index.ts +0 -24
  963. package/src/core/utils/layer/__workshop__/multipleRoots.tsx +0 -49
  964. package/src/core/utils/layer/__workshop__/nested.tsx +0 -98
  965. package/src/core/utils/layer/__workshop__/responsiveZOffset.tsx +0 -13
  966. package/src/core/utils/layer/getLayerContext.test.ts +0 -30
  967. package/src/core/utils/layer/getLayerContext.ts +0 -21
  968. package/src/core/utils/layer/index.ts +0 -4
  969. package/src/core/utils/layer/layer.test.tsx +0 -108
  970. package/src/core/utils/layer/layer.tsx +0 -98
  971. package/src/core/utils/layer/layerContext.ts +0 -7
  972. package/src/core/utils/layer/layerProvider.tsx +0 -111
  973. package/src/core/utils/layer/types.ts +0 -9
  974. package/src/core/utils/layer/useLayer.ts +0 -26
  975. package/src/core/utils/portal/__workshop__/index.ts +0 -14
  976. package/src/core/utils/portal/__workshop__/named.tsx +0 -63
  977. package/src/core/utils/portal/index.ts +0 -4
  978. package/src/core/utils/portal/portal.test.tsx +0 -103
  979. package/src/core/utils/portal/portal.ts +0 -32
  980. package/src/core/utils/portal/portalContext.ts +0 -31
  981. package/src/core/utils/portal/portalProvider.tsx +0 -47
  982. package/src/core/utils/portal/types.ts +0 -9
  983. package/src/core/utils/portal/usePortal.ts +0 -25
  984. package/src/core/utils/spanWithTextOverflow.tsx +0 -10
  985. package/src/core/utils/srOnly/index.ts +0 -1
  986. package/src/core/utils/srOnly/srOnly.tsx +0 -36
  987. package/src/core/utils/virtualList/__workshop__/changingProps.tsx +0 -36
  988. package/src/core/utils/virtualList/__workshop__/elementScroll.tsx +0 -24
  989. package/src/core/utils/virtualList/__workshop__/index.ts +0 -29
  990. package/src/core/utils/virtualList/__workshop__/infiniteList.tsx +0 -48
  991. package/src/core/utils/virtualList/__workshop__/windowScrolll.tsx +0 -22
  992. package/src/core/utils/virtualList/index.ts +0 -1
  993. package/src/core/utils/virtualList/virtualList.tsx +0 -200
  994. package/src/theme/build/_deprecated/color/_selectable/createSelectableTones.ts +0 -76
  995. package/src/theme/build/_deprecated/color/_solid/createSolidTones.ts +0 -54
  996. package/src/theme/build/_deprecated/color/button/createButtonModes.ts +0 -22
  997. package/src/theme/build/_deprecated/color/button/createButtonTones.ts +0 -55
  998. package/src/theme/build/_deprecated/color/card/createCardStates.ts +0 -60
  999. package/src/theme/build/_deprecated/color/color.test.ts +0 -63
  1000. package/src/theme/build/_deprecated/color/defaults.ts +0 -390
  1001. package/src/theme/build/_deprecated/color/factory.ts +0 -142
  1002. package/src/theme/build/_deprecated/color/index.ts +0 -1
  1003. package/src/theme/build/_deprecated/color/input/createInputModes.ts +0 -81
  1004. package/src/theme/build/_deprecated/color/muted/createMuted.ts +0 -54
  1005. package/src/theme/build/_deprecated/color/spot/createSpot.ts +0 -20
  1006. package/src/theme/build/buildColorTheme.test.ts +0 -183
  1007. package/src/theme/build/buildColorTheme.ts +0 -499
  1008. package/src/theme/build/buildTheme.test.ts +0 -87
  1009. package/src/theme/build/buildTheme.ts +0 -36
  1010. package/src/theme/build/colorToken/colorToken.ts +0 -19
  1011. package/src/theme/build/colorToken/compileColorToken.ts +0 -21
  1012. package/src/theme/build/colorToken/index.ts +0 -2
  1013. package/src/theme/build/colorToken/types.ts +0 -6
  1014. package/src/theme/build/index.ts +0 -3
  1015. package/src/theme/build/lib/color-fns/blend/index.ts +0 -3
  1016. package/src/theme/build/lib/color-fns/blend/mix.ts +0 -21
  1017. package/src/theme/build/lib/color-fns/blend/multiply.ts +0 -18
  1018. package/src/theme/build/lib/color-fns/blend/screen.ts +0 -18
  1019. package/src/theme/build/lib/color-fns/color-fns.test.ts +0 -68
  1020. package/src/theme/build/lib/color-fns/contrastRatio.ts +0 -31
  1021. package/src/theme/build/lib/color-fns/convert.ts +0 -150
  1022. package/src/theme/build/lib/color-fns/index.ts +0 -6
  1023. package/src/theme/build/lib/color-fns/parse.ts +0 -60
  1024. package/src/theme/build/lib/color-fns/rgba.ts +0 -10
  1025. package/src/theme/build/lib/color-fns/types.ts +0 -28
  1026. package/src/theme/build/lib/isRecord.ts +0 -3
  1027. package/src/theme/build/lib/lazy.ts +0 -30
  1028. package/src/theme/build/lib/utils.ts +0 -19
  1029. package/src/theme/build/merge.ts +0 -26
  1030. package/src/theme/build/mixThemeColor.test.ts +0 -21
  1031. package/src/theme/build/mixThemeColor.ts +0 -53
  1032. package/src/theme/build/renderColorTheme.ts +0 -532
  1033. package/src/theme/build/renderColorValue.ts +0 -85
  1034. package/src/theme/build/resolveColorTokens.ts +0 -268
  1035. package/src/theme/build/theme.test.ts +0 -27
  1036. package/src/theme/config/helpers.ts +0 -55
  1037. package/src/theme/config/index.ts +0 -4
  1038. package/src/theme/config/system.ts +0 -115
  1039. package/src/theme/config/tokens/color/index.ts +0 -1
  1040. package/src/theme/config/tokens/color/types.ts +0 -133
  1041. package/src/theme/config/tokens/index.ts +0 -4
  1042. package/src/theme/config/tokens/parseTokenKey.test.ts +0 -64
  1043. package/src/theme/config/tokens/parseTokenKey.ts +0 -67
  1044. package/src/theme/config/tokens/parseTokenValue.test.ts +0 -42
  1045. package/src/theme/config/tokens/parseTokenValue.ts +0 -133
  1046. package/src/theme/config/tokens/types.ts +0 -53
  1047. package/src/theme/config/types.ts +0 -46
  1048. package/src/theme/defaults/colorPalette.ts +0 -5
  1049. package/src/theme/defaults/colorTokens.ts +0 -648
  1050. package/src/theme/defaults/config.ts +0 -84
  1051. package/src/theme/defaults/fonts.ts +0 -227
  1052. package/src/theme/getScopedTheme.ts +0 -98
  1053. package/src/theme/index.ts +0 -5
  1054. package/src/theme/system/avatar.ts +0 -14
  1055. package/src/theme/system/color/_constants.ts +0 -45
  1056. package/src/theme/system/color/_helpers.ts +0 -24
  1057. package/src/theme/system/color/_system.ts +0 -40
  1058. package/src/theme/system/color/avatar.ts +0 -15
  1059. package/src/theme/system/color/badge.ts +0 -16
  1060. package/src/theme/system/color/button.ts +0 -17
  1061. package/src/theme/system/color/color.ts +0 -34
  1062. package/src/theme/system/color/index.ts +0 -13
  1063. package/src/theme/system/color/input.ts +0 -25
  1064. package/src/theme/system/color/kbd.ts +0 -8
  1065. package/src/theme/system/color/selectable.ts +0 -12
  1066. package/src/theme/system/color/shadow.ts +0 -7
  1067. package/src/theme/system/color/state.ts +0 -43
  1068. package/src/theme/system/color/syntax.ts +0 -41
  1069. package/src/theme/system/css.ts +0 -14
  1070. package/src/theme/system/focusRing.ts +0 -7
  1071. package/src/theme/system/font.ts +0 -52
  1072. package/src/theme/system/index.ts +0 -11
  1073. package/src/theme/system/input.ts +0 -33
  1074. package/src/theme/system/layer.ts +0 -8
  1075. package/src/theme/system/shadow.ts +0 -19
  1076. package/src/theme/system/styles.ts +0 -13
  1077. package/src/theme/system/theme.ts +0 -138
  1078. package/src/theme/system/v0/avatar.ts +0 -10
  1079. package/src/theme/system/v0/color/_generic.ts +0 -35
  1080. package/src/theme/system/v0/color/_system.ts +0 -17
  1081. package/src/theme/system/v0/color/base.ts +0 -21
  1082. package/src/theme/system/v0/color/button.ts +0 -42
  1083. package/src/theme/system/v0/color/card.ts +0 -19
  1084. package/src/theme/system/v0/color/color.ts +0 -40
  1085. package/src/theme/system/v0/color/index.ts +0 -11
  1086. package/src/theme/system/v0/color/input.ts +0 -34
  1087. package/src/theme/system/v0/color/muted.ts +0 -26
  1088. package/src/theme/system/v0/color/selectable.ts +0 -31
  1089. package/src/theme/system/v0/color/solid.ts +0 -26
  1090. package/src/theme/system/v0/color/spot.ts +0 -13
  1091. package/src/theme/system/v0/index.ts +0 -3
  1092. package/src/theme/system/v0/input.ts +0 -23
  1093. package/src/theme/versioning/getTheme_v2.ts +0 -57
  1094. package/src/theme/versioning/index.ts +0 -5
  1095. package/src/theme/versioning/is_v0.ts +0 -6
  1096. package/src/theme/versioning/is_v2.ts +0 -6
  1097. package/src/theme/versioning/themeColor_v0_v2.ts +0 -243
  1098. package/src/theme/versioning/themeColor_v2_v2_9.ts +0 -49
  1099. package/src/theme/versioning/v0_v2.ts +0 -94
  1100. package/src/theme/versioning/v2_v0.ts +0 -135
@@ -0,0 +1,3428 @@
1
+ //#region src/library/entries/events.entries.ts
2
+ var pic = (seed, w = 1600, h = 1e3) => `https://picsum.photos/seed/${seed}/${w}/${h}`;
3
+ var image = (seed, alt, w = 1600, h = 1e3) => ({
4
+ url: pic(seed, w, h),
5
+ alt,
6
+ name: `${seed}.jpg`,
7
+ width: w * 2,
8
+ height: h * 2
9
+ });
10
+ var CONTENT = {
11
+ name: "content",
12
+ title: "Content",
13
+ icon: "file-text",
14
+ default: true
15
+ };
16
+ var DESIGN = {
17
+ name: "design",
18
+ title: "Design",
19
+ icon: "palette"
20
+ };
21
+ var TIME = "^([01]\\d|2[0-3]):[0-5]\\d$";
22
+ var TIME_MSG = "Use 24-hour time, like 09:00 or 17:30.";
23
+ var DAYS = [
24
+ {
25
+ value: "mon",
26
+ label: "Monday"
27
+ },
28
+ {
29
+ value: "tue",
30
+ label: "Tuesday"
31
+ },
32
+ {
33
+ value: "wed",
34
+ label: "Wednesday"
35
+ },
36
+ {
37
+ value: "thu",
38
+ label: "Thursday"
39
+ },
40
+ {
41
+ value: "fri",
42
+ label: "Friday"
43
+ },
44
+ {
45
+ value: "sat",
46
+ label: "Saturday"
47
+ },
48
+ {
49
+ value: "sun",
50
+ label: "Sunday"
51
+ }
52
+ ];
53
+ var TIMEZONES = [
54
+ {
55
+ value: "America/Los_Angeles",
56
+ label: "Pacific (Los Angeles)"
57
+ },
58
+ {
59
+ value: "America/Denver",
60
+ label: "Mountain (Denver)"
61
+ },
62
+ {
63
+ value: "America/Chicago",
64
+ label: "Central (Chicago)"
65
+ },
66
+ {
67
+ value: "America/New_York",
68
+ label: "Eastern (New York)"
69
+ },
70
+ {
71
+ value: "Europe/London",
72
+ label: "London"
73
+ },
74
+ {
75
+ value: "Europe/Berlin",
76
+ label: "Berlin"
77
+ }
78
+ ];
79
+ var collectionField = (id, label) => ({
80
+ name: "collection",
81
+ title: "Collection",
82
+ type: "select",
83
+ access: { edit: "schema.manage" },
84
+ lockReason: "The collection is wired to the card template in code.",
85
+ initialValue: id,
86
+ options: [{
87
+ value: id,
88
+ label
89
+ }],
90
+ description: ""
91
+ });
92
+ /** One day of opening hours: closed, or open from → to. `closed` must default to false so the times show. */
93
+ var dayHours = (extra = []) => ({
94
+ name: "day",
95
+ title: "Day",
96
+ type: "object",
97
+ icon: "clock",
98
+ preview: {
99
+ title: "day",
100
+ subtitle: "opens"
101
+ },
102
+ fields: [
103
+ {
104
+ name: "day",
105
+ title: "Day",
106
+ type: "select",
107
+ options: DAYS,
108
+ validation: { required: true },
109
+ description: ""
110
+ },
111
+ {
112
+ name: "isClosed",
113
+ title: "Closed",
114
+ type: "boolean",
115
+ initialValue: false,
116
+ description: ""
117
+ },
118
+ {
119
+ name: "opens",
120
+ title: "Opens",
121
+ type: "string",
122
+ hidden: {
123
+ field: "isClosed",
124
+ equals: false
125
+ },
126
+ validation: {
127
+ required: true,
128
+ pattern: TIME,
129
+ patternMessage: TIME_MSG
130
+ },
131
+ placeholder: "10:00",
132
+ description: ""
133
+ },
134
+ {
135
+ name: "closes",
136
+ title: "Closes",
137
+ type: "string",
138
+ hidden: {
139
+ field: "isClosed",
140
+ equals: false
141
+ },
142
+ validation: {
143
+ required: true,
144
+ pattern: TIME,
145
+ patternMessage: TIME_MSG
146
+ },
147
+ placeholder: "18:00",
148
+ description: "After midnight? Use the next morning's time, e.g. 01:00."
149
+ },
150
+ ...extra
151
+ ]
152
+ });
153
+ var ENTRIES = [
154
+ {
155
+ id: "events-list",
156
+ label: "Events list",
157
+ category: "Events & places",
158
+ brand: "Caldera",
159
+ previewLayout: "list",
160
+ tags: [
161
+ "dynamic-query",
162
+ "conditional",
163
+ "variants",
164
+ "references",
165
+ "a11y"
166
+ ],
167
+ proves: "Upcoming / past split from one query · past events offer recordings · time-zone display rule · list, cards, calendar or map",
168
+ docTitle: "Workshops & cookouts",
169
+ urlPrefix: "caldera.bettercms.site/",
170
+ schema: {
171
+ name: "eventsList",
172
+ title: "Events list",
173
+ kind: "block",
174
+ icon: "calendar-event",
175
+ category: "Events & places",
176
+ description: "Upcoming and past events with filters",
177
+ variants: [
178
+ {
179
+ id: "list",
180
+ name: "Date list"
181
+ },
182
+ {
183
+ id: "cards",
184
+ name: "Cards"
185
+ },
186
+ {
187
+ id: "calendar",
188
+ name: "Month calendar"
189
+ },
190
+ {
191
+ id: "map",
192
+ name: "Map + list"
193
+ }
194
+ ],
195
+ groups: [
196
+ CONTENT,
197
+ {
198
+ name: "query",
199
+ title: "Events",
200
+ icon: "database"
201
+ },
202
+ DESIGN
203
+ ],
204
+ fieldsets: [{
205
+ name: "empty",
206
+ title: "When nothing is scheduled",
207
+ collapsed: true
208
+ }],
209
+ preview: {
210
+ title: "heading",
211
+ subtitle: "show",
212
+ icon: "calendar-event"
213
+ },
214
+ fields: [
215
+ {
216
+ name: "heading",
217
+ title: "Heading",
218
+ type: "string",
219
+ group: "content",
220
+ validation: {
221
+ required: true,
222
+ max: 48
223
+ },
224
+ localized: true
225
+ },
226
+ {
227
+ name: "intro",
228
+ title: "Intro",
229
+ type: "text",
230
+ rows: 2,
231
+ group: "content",
232
+ description: ""
233
+ },
234
+ {
235
+ name: "query",
236
+ title: "Which events",
237
+ type: "object",
238
+ group: "query",
239
+ fields: [
240
+ collectionField("col_events", "Events"),
241
+ {
242
+ name: "types",
243
+ title: "Types",
244
+ type: "multiselect",
245
+ options: [
246
+ {
247
+ value: "workshop",
248
+ label: "Workshops"
249
+ },
250
+ {
251
+ value: "cookout",
252
+ label: "Cookouts"
253
+ },
254
+ {
255
+ value: "popup",
256
+ label: "Pop-ups"
257
+ },
258
+ {
259
+ value: "talk",
260
+ label: "Talks"
261
+ }
262
+ ],
263
+ description: "Leave empty for every type."
264
+ },
265
+ {
266
+ name: "locations",
267
+ title: "Locations",
268
+ type: "array",
269
+ description: "Leave empty for everywhere.",
270
+ of: [{
271
+ name: "location",
272
+ title: "Location",
273
+ type: "reference",
274
+ reference: { to: ["col_locations"] }
275
+ }]
276
+ },
277
+ {
278
+ name: "showOnlineEvents",
279
+ title: "Include online events",
280
+ type: "boolean",
281
+ initialValue: true,
282
+ description: ""
283
+ }
284
+ ]
285
+ },
286
+ {
287
+ name: "show",
288
+ title: "Show",
289
+ type: "select",
290
+ group: "query",
291
+ layout: "radio",
292
+ initialValue: "both",
293
+ options: [
294
+ {
295
+ value: "upcoming",
296
+ label: "Upcoming only"
297
+ },
298
+ {
299
+ value: "both",
300
+ label: "Upcoming, with a Past tab"
301
+ },
302
+ {
303
+ value: "past",
304
+ label: "Past only",
305
+ description: "For an archive page"
306
+ }
307
+ ]
308
+ },
309
+ {
310
+ name: "upcomingLimit",
311
+ title: "Upcoming to show",
312
+ type: "number",
313
+ group: "query",
314
+ layout: "slider",
315
+ hidden: {
316
+ field: "show",
317
+ equals: ["upcoming", "both"]
318
+ },
319
+ numeric: {
320
+ min: 3,
321
+ max: 24,
322
+ step: 1
323
+ },
324
+ initialValue: 12,
325
+ description: ""
326
+ },
327
+ {
328
+ name: "pastLimit",
329
+ title: "Past to show",
330
+ type: "number",
331
+ group: "query",
332
+ layout: "slider",
333
+ hidden: {
334
+ field: "show",
335
+ equals: ["both", "past"]
336
+ },
337
+ numeric: {
338
+ min: 3,
339
+ max: 48,
340
+ step: 3
341
+ },
342
+ initialValue: 12
343
+ },
344
+ {
345
+ name: "hasRecordings",
346
+ title: "Offer recordings",
347
+ type: "boolean",
348
+ group: "query",
349
+ hidden: {
350
+ field: "show",
351
+ equals: ["both", "past"]
352
+ },
353
+ initialValue: true,
354
+ description: "Past events with a recording get a Watch button."
355
+ },
356
+ {
357
+ name: "filters",
358
+ title: "Filters",
359
+ type: "multiselect",
360
+ group: "content",
361
+ layout: "checkbox",
362
+ initialValue: ["type", "location"],
363
+ options: [
364
+ {
365
+ value: "type",
366
+ label: "Type"
367
+ },
368
+ {
369
+ value: "location",
370
+ label: "Location"
371
+ },
372
+ {
373
+ value: "month",
374
+ label: "Month"
375
+ },
376
+ {
377
+ value: "format",
378
+ label: "In person / online"
379
+ }
380
+ ],
381
+ description: ""
382
+ },
383
+ {
384
+ name: "timeDisplay",
385
+ title: "Show times in",
386
+ type: "select",
387
+ group: "content",
388
+ layout: "radio",
389
+ initialValue: "event",
390
+ options: [{
391
+ value: "event",
392
+ label: "The event's local time",
393
+ description: "Best for in-person events"
394
+ }, {
395
+ value: "visitor",
396
+ label: "The visitor's time zone",
397
+ description: "Best for online events"
398
+ }],
399
+ description: ""
400
+ },
401
+ {
402
+ name: "emptyHeading",
403
+ title: "Heading",
404
+ type: "string",
405
+ group: "content",
406
+ fieldset: "empty",
407
+ initialValue: "Nothing on the calendar yet",
408
+ validation: { max: 48 },
409
+ description: ""
410
+ },
411
+ {
412
+ name: "emptyButton",
413
+ title: "Empty button",
414
+ type: "button",
415
+ group: "content",
416
+ fieldset: "empty"
417
+ },
418
+ {
419
+ name: "showDateBadge",
420
+ title: "Show date badge",
421
+ type: "boolean",
422
+ group: "design",
423
+ initialValue: true
424
+ }
425
+ ]
426
+ },
427
+ value: {
428
+ _variant: "list",
429
+ heading: "Workshops & cookouts",
430
+ intro: "Learn to cook over fire with the people who make the pans. Small groups, all gear provided.",
431
+ query: {
432
+ collection: "col_events",
433
+ types: [],
434
+ locations: [],
435
+ showOnlineEvents: true
436
+ },
437
+ show: "both",
438
+ upcomingLimit: 12,
439
+ pastLimit: 12,
440
+ hasRecordings: true,
441
+ filters: ["type", "location"],
442
+ timeDisplay: "event",
443
+ emptyHeading: "Nothing on the calendar yet",
444
+ emptyButton: {
445
+ label: "Get event emails",
446
+ href: "/newsletter",
447
+ type: "page",
448
+ title: "Newsletter",
449
+ style: "secondary"
450
+ },
451
+ showDateBadge: true
452
+ },
453
+ notes: {
454
+ why: "Events are entries (each has a page, a time, a place and Event JSON-LD), so the list is a query with types/locations filters. The upcoming/past split is computed from each event's end time, never a status someone has to flip — the section only decides what to show and how many. Recordings only make sense for past events, so that toggle appears only when past events are shown. Time display is an explicit rule because 'Thursday 6pm' is ambiguous the moment an event is online.",
455
+ sanity: "Sanity: `event` documents with `startDate`/`endDate`; two GROQ queries split by `endDate > now()`. The time-zone rule is frontend code.",
456
+ htmlSignals: [
457
+ "Rows with a big day number + short month (12 NOV), title, time and city",
458
+ "Tabs 'Upcoming' / 'Past', or 'Past events' heading further down",
459
+ "'Register', 'Get tickets' or 'Watch recording' buttons per row",
460
+ "Embedded Eventbrite/Luma/Meetup links or widgets"
461
+ ],
462
+ mcp: "Import each row as an Events entry (follow the link for details — see event-detail). Place one eventsList with show 'both' if a Past section exists. If rows link to Eventbrite/Luma pages, keep the ticket URL on each event as its button link, not on the list. Filters from visible dropdowns.",
463
+ pitfalls: [
464
+ "Past events lingering as 'upcoming' because a status field was never flipped — the split is computed.",
465
+ "Times shown without a zone on online events.",
466
+ "Deleting past events loses their recordings and links — keep them, the list hides them.",
467
+ "Calendar variant with three events looks empty — use the list until there are ~8 a month."
468
+ ]
469
+ }
470
+ },
471
+ {
472
+ id: "event-detail",
473
+ label: "Event detail (conference)",
474
+ category: "Events & places",
475
+ brand: "Signal Summit",
476
+ previewLayout: "table",
477
+ tags: [
478
+ "deep-nesting",
479
+ "references",
480
+ "seo-structured",
481
+ "conditional",
482
+ "commerce",
483
+ "repeater",
484
+ "validation"
485
+ ],
486
+ proves: "Days → sessions → speakers (references) · attendance mode reveals venue or stream · ticket tiers with sale windows · status maps to Event JSON-LD",
487
+ docTitle: "Signal Summit 2027",
488
+ urlPrefix: "signalsummit.com/",
489
+ schema: {
490
+ name: "event",
491
+ title: "Event",
492
+ kind: "entry",
493
+ icon: "calendar-star",
494
+ category: "Events & places",
495
+ description: "A conference or event with agenda, venue and tickets",
496
+ preview: {
497
+ title: "title",
498
+ subtitle: "startDate",
499
+ media: "coverImage"
500
+ },
501
+ groups: [
502
+ {
503
+ name: "overview",
504
+ title: "Overview",
505
+ icon: "file-text",
506
+ default: true
507
+ },
508
+ {
509
+ name: "agenda",
510
+ title: "Agenda",
511
+ icon: "list-details"
512
+ },
513
+ {
514
+ name: "place",
515
+ title: "Venue",
516
+ icon: "map-pin"
517
+ },
518
+ {
519
+ name: "tickets",
520
+ title: "Tickets",
521
+ icon: "ticket"
522
+ }
523
+ ],
524
+ fieldsets: [{
525
+ name: "when",
526
+ title: "When"
527
+ }],
528
+ fields: [
529
+ {
530
+ name: "title",
531
+ title: "Title",
532
+ type: "string",
533
+ group: "overview",
534
+ validation: {
535
+ required: true,
536
+ max: 70
537
+ }
538
+ },
539
+ {
540
+ name: "slug",
541
+ title: "Slug",
542
+ type: "slug",
543
+ group: "overview",
544
+ validation: { required: true }
545
+ },
546
+ {
547
+ name: "tagline",
548
+ title: "Tagline",
549
+ type: "string",
550
+ group: "overview",
551
+ validation: { recommendedMax: 90 }
552
+ },
553
+ {
554
+ name: "startDate",
555
+ title: "Starts",
556
+ type: "datetime",
557
+ group: "overview",
558
+ fieldset: "when",
559
+ validation: { required: true }
560
+ },
561
+ {
562
+ name: "endDate",
563
+ title: "Ends",
564
+ type: "datetime",
565
+ group: "overview",
566
+ fieldset: "when",
567
+ validation: { required: true },
568
+ description: "Must be after the start."
569
+ },
570
+ {
571
+ name: "timezone",
572
+ title: "Time zone",
573
+ type: "select",
574
+ group: "overview",
575
+ fieldset: "when",
576
+ options: TIMEZONES,
577
+ validation: { required: true },
578
+ description: "Agenda times and calendar files use this zone."
579
+ },
580
+ {
581
+ name: "status",
582
+ title: "Status",
583
+ type: "select",
584
+ group: "overview",
585
+ initialValue: "scheduled",
586
+ options: [
587
+ {
588
+ value: "scheduled",
589
+ label: "Scheduled"
590
+ },
591
+ {
592
+ value: "postponed",
593
+ label: "Postponed",
594
+ description: "New date not known yet"
595
+ },
596
+ {
597
+ value: "rescheduled",
598
+ label: "Rescheduled"
599
+ },
600
+ {
601
+ value: "moved-online",
602
+ label: "Moved online"
603
+ },
604
+ {
605
+ value: "cancelled",
606
+ label: "Cancelled"
607
+ }
608
+ ],
609
+ description: "Anything but Scheduled shows a banner and tells Google."
610
+ },
611
+ {
612
+ name: "statusNote",
613
+ title: "Banner text",
614
+ type: "text",
615
+ rows: 2,
616
+ group: "overview",
617
+ hidden: {
618
+ field: "status",
619
+ equals: [
620
+ "postponed",
621
+ "rescheduled",
622
+ "moved-online",
623
+ "cancelled"
624
+ ]
625
+ },
626
+ validation: {
627
+ required: true,
628
+ max: 240
629
+ }
630
+ },
631
+ {
632
+ name: "coverImage",
633
+ title: "Cover image",
634
+ type: "image",
635
+ group: "overview",
636
+ validation: { required: true }
637
+ },
638
+ {
639
+ name: "about",
640
+ title: "About",
641
+ type: "richtext",
642
+ group: "overview",
643
+ validation: { required: true }
644
+ },
645
+ {
646
+ name: "featuredSpeakers",
647
+ title: "Featured speakers",
648
+ type: "array",
649
+ group: "overview",
650
+ validation: {
651
+ max: 8,
652
+ unique: true
653
+ },
654
+ of: [{
655
+ name: "speaker",
656
+ title: "Speaker",
657
+ type: "reference",
658
+ reference: { to: ["col_speakers"] }
659
+ }]
660
+ },
661
+ {
662
+ name: "days",
663
+ title: "Days",
664
+ type: "array",
665
+ group: "agenda",
666
+ itemNoun: "day",
667
+ validation: { max: 7 },
668
+ of: [{
669
+ name: "agendaDay",
670
+ title: "Day",
671
+ type: "object",
672
+ icon: "calendar",
673
+ preview: {
674
+ title: "label",
675
+ subtitle: "date",
676
+ fallback: "Untitled day"
677
+ },
678
+ fields: [
679
+ {
680
+ name: "date",
681
+ title: "Date",
682
+ type: "date",
683
+ validation: { required: true }
684
+ },
685
+ {
686
+ name: "label",
687
+ title: "Label",
688
+ type: "string",
689
+ validation: { max: 32 },
690
+ placeholder: "Day 1 · Build",
691
+ description: ""
692
+ },
693
+ {
694
+ name: "sessions",
695
+ title: "Sessions",
696
+ type: "array",
697
+ itemNoun: "session",
698
+ validation: {
699
+ min: 1,
700
+ max: 40
701
+ },
702
+ of: [{
703
+ name: "session",
704
+ title: "Session",
705
+ type: "object",
706
+ icon: "microphone",
707
+ preview: {
708
+ title: "title",
709
+ subtitle: "start",
710
+ fallback: "Untitled session"
711
+ },
712
+ fields: [
713
+ {
714
+ name: "start",
715
+ title: "Starts",
716
+ type: "string",
717
+ validation: {
718
+ required: true,
719
+ pattern: TIME,
720
+ patternMessage: TIME_MSG
721
+ },
722
+ placeholder: "09:30",
723
+ description: ""
724
+ },
725
+ {
726
+ name: "end",
727
+ title: "Ends",
728
+ type: "string",
729
+ validation: {
730
+ required: true,
731
+ pattern: TIME,
732
+ patternMessage: TIME_MSG
733
+ },
734
+ placeholder: "10:15",
735
+ description: ""
736
+ },
737
+ {
738
+ name: "title",
739
+ title: "Title",
740
+ type: "string",
741
+ validation: {
742
+ required: true,
743
+ max: 100
744
+ }
745
+ },
746
+ {
747
+ name: "format",
748
+ title: "Format",
749
+ type: "select",
750
+ validation: { required: true },
751
+ initialValue: "talk",
752
+ options: [
753
+ {
754
+ value: "keynote",
755
+ label: "Keynote"
756
+ },
757
+ {
758
+ value: "talk",
759
+ label: "Talk"
760
+ },
761
+ {
762
+ value: "panel",
763
+ label: "Panel"
764
+ },
765
+ {
766
+ value: "workshop",
767
+ label: "Workshop"
768
+ },
769
+ {
770
+ value: "break",
771
+ label: "Break"
772
+ },
773
+ {
774
+ value: "meal",
775
+ label: "Meal"
776
+ }
777
+ ],
778
+ description: "Breaks and meals span every track and have no speakers."
779
+ },
780
+ {
781
+ name: "speakers",
782
+ title: "Speakers",
783
+ type: "array",
784
+ hidden: {
785
+ field: "format",
786
+ equals: [
787
+ "keynote",
788
+ "talk",
789
+ "panel",
790
+ "workshop"
791
+ ]
792
+ },
793
+ validation: {
794
+ min: 1,
795
+ max: 6,
796
+ unique: true
797
+ },
798
+ of: [{
799
+ name: "speaker",
800
+ title: "Speaker",
801
+ type: "reference",
802
+ reference: { to: ["col_speakers"] }
803
+ }]
804
+ },
805
+ {
806
+ name: "track",
807
+ title: "Track",
808
+ type: "select",
809
+ hidden: {
810
+ field: "format",
811
+ equals: [
812
+ "talk",
813
+ "panel",
814
+ "workshop"
815
+ ]
816
+ },
817
+ options: [
818
+ {
819
+ value: "main",
820
+ label: "Main stage"
821
+ },
822
+ {
823
+ value: "build",
824
+ label: "Build"
825
+ },
826
+ {
827
+ value: "scale",
828
+ label: "Scale"
829
+ }
830
+ ],
831
+ description: ""
832
+ },
833
+ {
834
+ name: "room",
835
+ title: "Room",
836
+ type: "string",
837
+ validation: { max: 32 }
838
+ },
839
+ {
840
+ name: "abstract",
841
+ title: "Abstract",
842
+ type: "richtext",
843
+ hidden: {
844
+ field: "format",
845
+ equals: [
846
+ "keynote",
847
+ "talk",
848
+ "panel",
849
+ "workshop"
850
+ ]
851
+ }
852
+ },
853
+ {
854
+ name: "level",
855
+ title: "Level",
856
+ type: "select",
857
+ hidden: {
858
+ field: "format",
859
+ equals: ["talk", "workshop"]
860
+ },
861
+ options: [
862
+ {
863
+ value: "intro",
864
+ label: "Introductory"
865
+ },
866
+ {
867
+ value: "intermediate",
868
+ label: "Intermediate"
869
+ },
870
+ {
871
+ value: "advanced",
872
+ label: "Advanced"
873
+ }
874
+ ],
875
+ description: ""
876
+ },
877
+ {
878
+ name: "capacity",
879
+ title: "Seats",
880
+ type: "number",
881
+ hidden: {
882
+ field: "format",
883
+ equals: "workshop"
884
+ },
885
+ numeric: {
886
+ min: 1,
887
+ step: 1
888
+ },
889
+ description: "Caps workshop bookings."
890
+ },
891
+ {
892
+ name: "recording",
893
+ title: "Recording",
894
+ type: "video"
895
+ }
896
+ ]
897
+ }]
898
+ }
899
+ ]
900
+ }]
901
+ },
902
+ {
903
+ name: "attendance",
904
+ title: "Attendance",
905
+ type: "select",
906
+ group: "place",
907
+ layout: "segmented",
908
+ validation: { required: true },
909
+ initialValue: "in-person",
910
+ options: [
911
+ {
912
+ value: "in-person",
913
+ label: "In person"
914
+ },
915
+ {
916
+ value: "online",
917
+ label: "Online"
918
+ },
919
+ {
920
+ value: "hybrid",
921
+ label: "Hybrid"
922
+ }
923
+ ],
924
+ description: ""
925
+ },
926
+ {
927
+ name: "venue",
928
+ title: "Venue",
929
+ type: "reference",
930
+ group: "place",
931
+ reference: { to: ["col_venues"] },
932
+ hidden: {
933
+ field: "attendance",
934
+ equals: ["in-person", "hybrid"]
935
+ },
936
+ validation: { required: true },
937
+ description: "Address, map pin and directions come from the venue."
938
+ },
939
+ {
940
+ name: "gettingThere",
941
+ title: "Getting there",
942
+ type: "richtext",
943
+ group: "place",
944
+ hidden: {
945
+ field: "attendance",
946
+ equals: ["in-person", "hybrid"]
947
+ }
948
+ },
949
+ {
950
+ name: "streamPlatform",
951
+ title: "Stream on",
952
+ type: "select",
953
+ group: "place",
954
+ hidden: {
955
+ field: "attendance",
956
+ equals: ["online", "hybrid"]
957
+ },
958
+ options: [
959
+ {
960
+ value: "youtube",
961
+ label: "YouTube Live"
962
+ },
963
+ {
964
+ value: "zoom",
965
+ label: "Zoom Webinar"
966
+ },
967
+ {
968
+ value: "hopin",
969
+ label: "RingCentral Events"
970
+ },
971
+ {
972
+ value: "custom",
973
+ label: "Our own player"
974
+ }
975
+ ],
976
+ description: ""
977
+ },
978
+ {
979
+ name: "streamUrl",
980
+ title: "Stream link",
981
+ type: "url",
982
+ group: "place",
983
+ hidden: {
984
+ field: "attendance",
985
+ equals: ["online", "hybrid"]
986
+ },
987
+ description: "Shown to ticket holders on the day."
988
+ },
989
+ {
990
+ name: "currency",
991
+ title: "Currency",
992
+ type: "select",
993
+ group: "tickets",
994
+ initialValue: "USD",
995
+ options: [
996
+ {
997
+ value: "USD",
998
+ label: "USD"
999
+ },
1000
+ {
1001
+ value: "EUR",
1002
+ label: "EUR"
1003
+ },
1004
+ {
1005
+ value: "GBP",
1006
+ label: "GBP"
1007
+ }
1008
+ ],
1009
+ description: ""
1010
+ },
1011
+ {
1012
+ name: "tiers",
1013
+ title: "Ticket tiers",
1014
+ type: "array",
1015
+ group: "tickets",
1016
+ itemNoun: "tier",
1017
+ validation: { max: 6 },
1018
+ of: [{
1019
+ name: "tier",
1020
+ title: "Tier",
1021
+ type: "object",
1022
+ icon: "ticket",
1023
+ preview: {
1024
+ title: "name",
1025
+ subtitle: "price",
1026
+ fallback: "Untitled tier"
1027
+ },
1028
+ fields: [
1029
+ {
1030
+ name: "name",
1031
+ title: "Name",
1032
+ type: "string",
1033
+ validation: {
1034
+ required: true,
1035
+ max: 32
1036
+ }
1037
+ },
1038
+ {
1039
+ name: "price",
1040
+ title: "Price",
1041
+ type: "number",
1042
+ numeric: {
1043
+ min: 0,
1044
+ step: 1
1045
+ },
1046
+ validation: { required: true },
1047
+ description: "0 shows as Free."
1048
+ },
1049
+ {
1050
+ name: "salesStart",
1051
+ title: "On sale from",
1052
+ type: "datetime"
1053
+ },
1054
+ {
1055
+ name: "salesEnd",
1056
+ title: "On sale until",
1057
+ type: "datetime",
1058
+ description: "Early-bird tiers switch off on their own at this time."
1059
+ },
1060
+ {
1061
+ name: "availability",
1062
+ title: "Availability",
1063
+ type: "select",
1064
+ layout: "segmented",
1065
+ initialValue: "on-sale",
1066
+ options: [
1067
+ {
1068
+ value: "on-sale",
1069
+ label: "On sale"
1070
+ },
1071
+ {
1072
+ value: "sold-out",
1073
+ label: "Sold out"
1074
+ },
1075
+ {
1076
+ value: "soon",
1077
+ label: "Coming soon"
1078
+ }
1079
+ ],
1080
+ description: ""
1081
+ },
1082
+ {
1083
+ name: "includes",
1084
+ title: "Includes",
1085
+ type: "array",
1086
+ itemNoun: "perk",
1087
+ validation: { max: 8 },
1088
+ of: [{
1089
+ name: "perk",
1090
+ title: "Perk",
1091
+ type: "string",
1092
+ validation: { max: 60 }
1093
+ }]
1094
+ },
1095
+ {
1096
+ name: "button",
1097
+ title: "Button",
1098
+ type: "button",
1099
+ hidden: {
1100
+ field: "availability",
1101
+ equals: "on-sale"
1102
+ },
1103
+ validation: { required: true }
1104
+ },
1105
+ {
1106
+ name: "isHighlighted",
1107
+ title: "Most popular",
1108
+ type: "boolean"
1109
+ }
1110
+ ]
1111
+ }]
1112
+ }
1113
+ ]
1114
+ },
1115
+ value: {
1116
+ title: "Signal Summit 2027",
1117
+ slug: "2027",
1118
+ tagline: "Two days on building and scaling real-time products.",
1119
+ startDate: "2027-04-14T09:00:00-07:00[America/Los_Angeles]",
1120
+ endDate: "2027-04-15T18:00:00-07:00[America/Los_Angeles]",
1121
+ timezone: "America/Los_Angeles",
1122
+ status: "scheduled",
1123
+ coverImage: image("signal-summit-stage", "A packed auditorium facing a stage lit in teal, a speaker mid-talk"),
1124
+ about: "<p>Signal Summit brings 1,200 engineers and product leaders to San Francisco for two days of talks, workshops and hallway conversations about real-time systems.</p>",
1125
+ featuredSpeakers: [
1126
+ "en_spk_kelsey-hightower",
1127
+ "en_spk_mira-tanaka",
1128
+ "en_spk_dev-patel"
1129
+ ],
1130
+ days: [{
1131
+ _key: "d1",
1132
+ date: "2027-04-14",
1133
+ label: "Day 1 · Build",
1134
+ sessions: [
1135
+ {
1136
+ _key: "s1",
1137
+ start: "08:00",
1138
+ end: "09:00",
1139
+ title: "Registration & breakfast",
1140
+ format: "meal",
1141
+ room: "Lobby"
1142
+ },
1143
+ {
1144
+ _key: "s2",
1145
+ start: "09:00",
1146
+ end: "09:45",
1147
+ title: "The latency budget nobody wrote down",
1148
+ format: "keynote",
1149
+ speakers: ["en_spk_mira-tanaka"],
1150
+ room: "Main stage",
1151
+ abstract: "<p>Every real-time product has a latency budget. Most teams discover theirs in an incident review.</p>"
1152
+ },
1153
+ {
1154
+ _key: "s3",
1155
+ start: "10:00",
1156
+ end: "10:40",
1157
+ title: "CRDTs in production: three years in",
1158
+ format: "talk",
1159
+ speakers: ["en_spk_dev-patel"],
1160
+ track: "build",
1161
+ room: "Hall B",
1162
+ level: "advanced",
1163
+ abstract: "<p>What we got wrong about merge semantics, and what we'd do again.</p>"
1164
+ },
1165
+ {
1166
+ _key: "s4",
1167
+ start: "10:00",
1168
+ end: "12:00",
1169
+ title: "Hands-on: a presence layer in 90 minutes",
1170
+ format: "workshop",
1171
+ speakers: ["en_spk_ana-silva", "en_spk_tom-ruiz"],
1172
+ track: "build",
1173
+ room: "Workshop 1",
1174
+ level: "intermediate",
1175
+ capacity: 60
1176
+ },
1177
+ {
1178
+ _key: "s5",
1179
+ start: "12:00",
1180
+ end: "13:00",
1181
+ title: "Lunch",
1182
+ format: "meal",
1183
+ room: "Terrace"
1184
+ }
1185
+ ]
1186
+ }, {
1187
+ _key: "d2",
1188
+ date: "2027-04-15",
1189
+ label: "Day 2 · Scale",
1190
+ sessions: [{
1191
+ _key: "s6",
1192
+ start: "09:30",
1193
+ end: "10:15",
1194
+ title: "Panel: When to stop self-hosting",
1195
+ format: "panel",
1196
+ speakers: [
1197
+ "en_spk_kelsey-hightower",
1198
+ "en_spk_mira-tanaka",
1199
+ "en_spk_lena-fischer"
1200
+ ],
1201
+ track: "main",
1202
+ room: "Main stage"
1203
+ }]
1204
+ }],
1205
+ attendance: "hybrid",
1206
+ venue: "en_venue_sf-masonic",
1207
+ gettingThere: "<p>Enter on California Street. BART to Montgomery, then the 1 bus. A hotel block at the Fairmont holds rates until March 15.</p>",
1208
+ streamPlatform: "youtube",
1209
+ streamUrl: "https://www.youtube.com/live/signalsummit2027",
1210
+ currency: "USD",
1211
+ tiers: [
1212
+ {
1213
+ _key: "t1",
1214
+ name: "Early bird",
1215
+ price: 499,
1216
+ salesEnd: "2027-01-31T23:59:00-08:00[America/Los_Angeles]",
1217
+ availability: "sold-out",
1218
+ includes: [
1219
+ "Both days",
1220
+ "Workshops (first come)",
1221
+ "Recordings"
1222
+ ]
1223
+ },
1224
+ {
1225
+ _key: "t2",
1226
+ name: "General",
1227
+ price: 749,
1228
+ salesStart: "2027-02-01T00:00:00-08:00[America/Los_Angeles]",
1229
+ availability: "on-sale",
1230
+ includes: [
1231
+ "Both days",
1232
+ "Workshops (first come)",
1233
+ "Recordings"
1234
+ ],
1235
+ button: {
1236
+ label: "Get tickets",
1237
+ href: "https://tickets.signalsummit.com/2027/general",
1238
+ type: "url",
1239
+ style: "primary"
1240
+ },
1241
+ isHighlighted: true
1242
+ },
1243
+ {
1244
+ _key: "t3",
1245
+ name: "Online",
1246
+ price: 0,
1247
+ availability: "on-sale",
1248
+ includes: ["Live stream", "Recordings"],
1249
+ button: {
1250
+ label: "Register free",
1251
+ href: "/2027/register-online",
1252
+ type: "page",
1253
+ style: "secondary"
1254
+ }
1255
+ }
1256
+ ]
1257
+ },
1258
+ notes: {
1259
+ why: "An event is an entry: it has a page and emits Event JSON-LD natively (startDate/endDate with the zone, eventStatus from Status, eventAttendanceMode from Attendance, location from the venue reference or a VirtualLocation from the stream, offers from tiers with validFrom/price/availability, performer from speakers). The agenda is days → sessions → speaker references — three nested levels plus the speaker CMS items — and a session's FORMAT reveals speakers, abstract, track and level (breaks have none). Venues and speakers are collections because they recur across years. Ticket tiers are commerce data with sale windows that switch themselves off.",
1260
+ sanity: "Sanity: `event` { schedule: array<object day{date, sessions: array<object{start, end, title, speakers: array<reference→speaker>}>}>, venue: reference→venue, tickets: array<object> }. Time-of-day is also a string in Sanity (no time type).",
1261
+ htmlSignals: [
1262
+ "An agenda table/grid with time ranges (09:00–09:45), rooms/tracks and speaker avatars",
1263
+ "Day tabs (Day 1 / Day 2) or dated headings",
1264
+ "Ticket cards with prices, 'Early bird ends …', 'Sold out' badges",
1265
+ "A venue block with address and map; 'Watch online' or 'Livestream' mentions",
1266
+ "Event JSON-LD with eventStatus / eventAttendanceMode"
1267
+ ],
1268
+ mcp: "Speakers → Speakers entries (photo, name, title, company, bio from the speaker modal). Venue → Venues entry. Agenda: each day tab → day; each row → session (start/end parsed to 24-hour HH:MM in the event's zone, format from labels like 'Keynote'/'Break'/'Lunch', speakers matched by name). Ticket cards → tiers (price as a number; 'Sold out' → availability). If tickets are sold on Tito/Eventbrite, use those URLs as each tier's button link.",
1269
+ pitfalls: [
1270
+ "Agenda times in the visitor's zone instead of the event's — store HH:MM + the event zone.",
1271
+ "Speakers typed into session titles ('… with Mira Tanaka') instead of referenced.",
1272
+ "End time before start (cross-field) — not expressible in validation yet; the renderer must refuse it.",
1273
+ "Cancelled events deleted rather than marked — Google keeps showing the old date.",
1274
+ "Sold-out early-bird tiers left 'On sale' after salesEnd — use the window, not the badge."
1275
+ ]
1276
+ }
1277
+ },
1278
+ {
1279
+ id: "webinar-registration",
1280
+ label: "Webinar registration",
1281
+ category: "Events & places",
1282
+ brand: "Ledgerline",
1283
+ previewLayout: "form",
1284
+ tags: [
1285
+ "form",
1286
+ "conditional",
1287
+ "references",
1288
+ "embed",
1289
+ "validation",
1290
+ "variants"
1291
+ ],
1292
+ proves: "One section across the lifecycle: upcoming (form) → live (stream) → on demand (recording, optionally gated) · CRM campaign locked",
1293
+ docTitle: "Webinar: Closing the books in 3 days",
1294
+ urlPrefix: "ledgerline.com/webinars/",
1295
+ schema: {
1296
+ name: "webinarRegistration",
1297
+ title: "Webinar registration",
1298
+ kind: "block",
1299
+ icon: "presentation",
1300
+ category: "Events & places",
1301
+ description: "Register before, watch live, or watch the recording",
1302
+ variants: [{
1303
+ id: "split",
1304
+ name: "Details + form"
1305
+ }, {
1306
+ id: "centered",
1307
+ name: "Centered"
1308
+ }],
1309
+ groups: [
1310
+ CONTENT,
1311
+ {
1312
+ name: "stage",
1313
+ title: "Before · live · after",
1314
+ icon: "broadcast"
1315
+ },
1316
+ DESIGN
1317
+ ],
1318
+ fieldsets: [{
1319
+ name: "confirm",
1320
+ title: "After registering",
1321
+ collapsed: true
1322
+ }],
1323
+ preview: {
1324
+ title: "heading",
1325
+ subtitle: "stage",
1326
+ icon: "presentation"
1327
+ },
1328
+ fields: [
1329
+ {
1330
+ name: "eyebrow",
1331
+ title: "Eyebrow",
1332
+ type: "string",
1333
+ group: "content",
1334
+ initialValue: "Live webinar",
1335
+ validation: { max: 32 }
1336
+ },
1337
+ {
1338
+ name: "heading",
1339
+ title: "Heading",
1340
+ type: "string",
1341
+ group: "content",
1342
+ validation: {
1343
+ required: true,
1344
+ recommendedMax: 60
1345
+ },
1346
+ ai: true
1347
+ },
1348
+ {
1349
+ name: "summary",
1350
+ title: "Summary",
1351
+ type: "text",
1352
+ rows: 3,
1353
+ group: "content",
1354
+ validation: { recommendedMax: 280 }
1355
+ },
1356
+ {
1357
+ name: "takeaways",
1358
+ title: "You'll learn",
1359
+ type: "array",
1360
+ group: "content",
1361
+ itemNoun: "point",
1362
+ validation: { max: 6 },
1363
+ of: [{
1364
+ name: "point",
1365
+ title: "Point",
1366
+ type: "string",
1367
+ validation: { max: 100 }
1368
+ }]
1369
+ },
1370
+ {
1371
+ name: "speakers",
1372
+ title: "Speakers",
1373
+ type: "array",
1374
+ group: "content",
1375
+ validation: {
1376
+ min: 1,
1377
+ max: 4
1378
+ },
1379
+ of: [{
1380
+ name: "speaker",
1381
+ title: "Speaker",
1382
+ type: "reference",
1383
+ reference: { to: ["col_people"] }
1384
+ }]
1385
+ },
1386
+ {
1387
+ name: "stage",
1388
+ title: "Stage",
1389
+ type: "select",
1390
+ group: "stage",
1391
+ layout: "segmented",
1392
+ initialValue: "upcoming",
1393
+ options: [
1394
+ {
1395
+ value: "upcoming",
1396
+ label: "Upcoming"
1397
+ },
1398
+ {
1399
+ value: "live",
1400
+ label: "Live now"
1401
+ },
1402
+ {
1403
+ value: "on-demand",
1404
+ label: "On demand"
1405
+ }
1406
+ ]
1407
+ },
1408
+ {
1409
+ name: "startsAt",
1410
+ title: "Starts",
1411
+ type: "datetime",
1412
+ group: "stage",
1413
+ hidden: {
1414
+ field: "stage",
1415
+ equals: ["upcoming", "live"]
1416
+ },
1417
+ validation: { required: true },
1418
+ description: "Shown in each visitor's time zone."
1419
+ },
1420
+ {
1421
+ name: "minutes",
1422
+ title: "Length",
1423
+ type: "number",
1424
+ group: "stage",
1425
+ hidden: {
1426
+ field: "stage",
1427
+ equals: ["upcoming", "live"]
1428
+ },
1429
+ numeric: {
1430
+ unit: "min",
1431
+ min: 15,
1432
+ max: 180,
1433
+ step: 15
1434
+ },
1435
+ initialValue: 45,
1436
+ description: ""
1437
+ },
1438
+ {
1439
+ name: "form",
1440
+ title: "Registration form",
1441
+ type: "reference",
1442
+ group: "stage",
1443
+ reference: { to: ["form"] },
1444
+ hidden: {
1445
+ field: "stage",
1446
+ equals: "upcoming"
1447
+ },
1448
+ validation: { required: true }
1449
+ },
1450
+ {
1451
+ name: "showCalendarLinks",
1452
+ title: "Show add-to-calendar links",
1453
+ type: "boolean",
1454
+ group: "stage",
1455
+ hidden: {
1456
+ field: "stage",
1457
+ equals: "upcoming"
1458
+ },
1459
+ initialValue: true
1460
+ },
1461
+ {
1462
+ name: "streamUrl",
1463
+ title: "Stream",
1464
+ type: "url",
1465
+ group: "stage",
1466
+ hidden: {
1467
+ field: "stage",
1468
+ equals: "live"
1469
+ },
1470
+ validation: { required: true },
1471
+ description: "A YouTube Live, Vimeo or Zoom webinar link."
1472
+ },
1473
+ {
1474
+ name: "recording",
1475
+ title: "Recording",
1476
+ type: "video",
1477
+ group: "stage",
1478
+ hidden: {
1479
+ field: "stage",
1480
+ equals: "on-demand"
1481
+ },
1482
+ validation: { required: true }
1483
+ },
1484
+ {
1485
+ name: "isGated",
1486
+ title: "Ask for details first",
1487
+ type: "boolean",
1488
+ group: "stage",
1489
+ hidden: {
1490
+ field: "stage",
1491
+ equals: "on-demand"
1492
+ }
1493
+ },
1494
+ {
1495
+ name: "slides",
1496
+ title: "Slides",
1497
+ type: "file",
1498
+ group: "stage",
1499
+ hidden: {
1500
+ field: "stage",
1501
+ equals: "on-demand"
1502
+ }
1503
+ },
1504
+ {
1505
+ name: "confirmHeading",
1506
+ title: "Heading",
1507
+ type: "string",
1508
+ group: "stage",
1509
+ fieldset: "confirm",
1510
+ initialValue: "You're in",
1511
+ validation: { max: 40 },
1512
+ description: ""
1513
+ },
1514
+ {
1515
+ name: "confirmBody",
1516
+ title: "Text",
1517
+ type: "text",
1518
+ rows: 2,
1519
+ group: "stage",
1520
+ fieldset: "confirm"
1521
+ },
1522
+ {
1523
+ name: "campaign",
1524
+ title: "CRM campaign",
1525
+ type: "string",
1526
+ group: "stage",
1527
+ access: { edit: "schema.manage" },
1528
+ advanced: true,
1529
+ lockReason: "Set by marketing ops; registrations sync to it.",
1530
+ description: "Registrations sync to this campaign."
1531
+ }
1532
+ ]
1533
+ },
1534
+ value: {
1535
+ _variant: "split",
1536
+ eyebrow: "Live webinar",
1537
+ heading: "Closing the books in 3 days, without the overtime",
1538
+ summary: "Northbeam's controller walks through the exact checklist, bank rules and review cadence that cut their close from 11 days to 3.",
1539
+ takeaways: [
1540
+ "The 40-item close checklist, trimmed to 18",
1541
+ "Bank rules that match 92% of transactions",
1542
+ "How to run review without a war room",
1543
+ "Live Q&A"
1544
+ ],
1545
+ speakers: ["en_p_dana-whitfield", "en_p_priya-raman"],
1546
+ stage: "upcoming",
1547
+ startsAt: "2026-10-22T13:00:00-04:00[America/New_York]",
1548
+ minutes: 45,
1549
+ form: "form_webinar-registration",
1550
+ showCalendarLinks: true,
1551
+ isGated: false,
1552
+ confirmHeading: "You're in",
1553
+ confirmBody: "We've emailed your join link. We'll send the recording to the same address, even if you can't make it live.",
1554
+ campaign: "701Hp00000ClOse3D"
1555
+ },
1556
+ notes: {
1557
+ why: "A webinar page lives through three states, and the same URL must work in each: before (time + registration form), during (embedded stream), after (recording, optionally behind the same form). One STAGE select reveals the fields each state needs, so nobody builds a second page for the replay. The form is a reference (submissions land in Forms and sync to the locked CRM campaign). Speakers are People references. Webinars with many sessions graduate to the Event entry (event-detail).",
1558
+ sanity: "Sanity: `webinar` document { status: string, startsAt: datetime, registrationForm: reference (or an external HubSpot form id), recording: mux.video } with `hidden: ({document}) => document.status !== 'onDemand'`.",
1559
+ htmlSignals: [
1560
+ "A date/time with time zone and a registration form beside a speaker list",
1561
+ "'Register now', 'Save my seat', 'Watch on demand', 'Watch the recording'",
1562
+ "HubSpot/Marketo/Pardot form embeds; Zoom/ON24/Livestorm links",
1563
+ "'What you'll learn' bullet list"
1564
+ ],
1565
+ mcp: "Stage from the page: a form + future date → upcoming; a video + 'on demand' → on-demand (isGated true if a form shows first). Rebuild the embedded HubSpot/Marketo form as a BetterCMS form with the same fields and reference it; keep the original campaign id for the developer. Bullets → takeaways. Speaker cards → People.",
1566
+ pitfalls: [
1567
+ "A second '/webinar-replay' page splits links and SEO — switch the stage instead.",
1568
+ "Times without a zone ('Thursday 10am').",
1569
+ "Leaving stage 'live' after the event — the page shows a dead stream.",
1570
+ "Gating on-demand recordings of public talks lowers reach; gate deliberately."
1571
+ ]
1572
+ }
1573
+ },
1574
+ {
1575
+ id: "locations-directory",
1576
+ label: "Locations directory",
1577
+ category: "Events & places",
1578
+ brand: "Caldera",
1579
+ previewLayout: "media",
1580
+ tags: [
1581
+ "dynamic-query",
1582
+ "conditional",
1583
+ "repeater",
1584
+ "deep-nesting",
1585
+ "validation",
1586
+ "a11y",
1587
+ "responsive-layout"
1588
+ ],
1589
+ proves: "Map + list from a Locations query or written here · per-day hours array (isClosed reveals nothing) · services filter · near-me search",
1590
+ docTitle: "Stores & workshops",
1591
+ urlPrefix: "caldera.bettercms.site/",
1592
+ schema: {
1593
+ name: "locationsDirectory",
1594
+ title: "Locations directory",
1595
+ kind: "block",
1596
+ icon: "map-pins",
1597
+ category: "Events & places",
1598
+ description: "Every store or workshop on a map and in a list",
1599
+ variants: [
1600
+ {
1601
+ id: "map-left",
1602
+ name: "Map beside list"
1603
+ },
1604
+ {
1605
+ id: "map-top",
1606
+ name: "Map above list"
1607
+ },
1608
+ {
1609
+ id: "list",
1610
+ name: "List only"
1611
+ }
1612
+ ],
1613
+ groups: [
1614
+ CONTENT,
1615
+ {
1616
+ name: "map",
1617
+ title: "Map",
1618
+ icon: "map"
1619
+ },
1620
+ DESIGN
1621
+ ],
1622
+ preview: {
1623
+ title: "heading",
1624
+ subtitle: "source",
1625
+ icon: "map-pins"
1626
+ },
1627
+ fields: [
1628
+ {
1629
+ name: "heading",
1630
+ title: "Heading",
1631
+ type: "string",
1632
+ group: "content",
1633
+ validation: {
1634
+ required: true,
1635
+ max: 48
1636
+ },
1637
+ localized: true
1638
+ },
1639
+ {
1640
+ name: "intro",
1641
+ title: "Intro",
1642
+ type: "text",
1643
+ rows: 2,
1644
+ group: "content",
1645
+ description: ""
1646
+ },
1647
+ {
1648
+ name: "source",
1649
+ title: "Locations come from",
1650
+ type: "select",
1651
+ group: "content",
1652
+ layout: "segmented",
1653
+ initialValue: "collection",
1654
+ options: [{
1655
+ value: "collection",
1656
+ label: "Locations collection"
1657
+ }, {
1658
+ value: "inline",
1659
+ label: "Written here"
1660
+ }]
1661
+ },
1662
+ {
1663
+ name: "query",
1664
+ title: "Which locations",
1665
+ type: "object",
1666
+ group: "content",
1667
+ openMode: "inline",
1668
+ hidden: {
1669
+ field: "source",
1670
+ equals: "collection"
1671
+ },
1672
+ fields: [
1673
+ collectionField("col_locations", "Locations"),
1674
+ {
1675
+ name: "types",
1676
+ title: "Types",
1677
+ type: "multiselect",
1678
+ options: [
1679
+ {
1680
+ value: "flagship",
1681
+ label: "Flagship stores"
1682
+ },
1683
+ {
1684
+ value: "workshop",
1685
+ label: "Workshops"
1686
+ },
1687
+ {
1688
+ value: "stockist",
1689
+ label: "Stockists"
1690
+ }
1691
+ ],
1692
+ description: "Leave empty for every type."
1693
+ },
1694
+ {
1695
+ name: "regions",
1696
+ title: "Regions",
1697
+ type: "multiselect",
1698
+ options: [
1699
+ {
1700
+ value: "pnw",
1701
+ label: "Pacific Northwest"
1702
+ },
1703
+ {
1704
+ value: "mountain",
1705
+ label: "Mountain"
1706
+ },
1707
+ {
1708
+ value: "northeast",
1709
+ label: "Northeast"
1710
+ }
1711
+ ],
1712
+ description: ""
1713
+ }
1714
+ ]
1715
+ },
1716
+ {
1717
+ name: "locations",
1718
+ title: "Locations",
1719
+ type: "array",
1720
+ group: "content",
1721
+ itemNoun: "location",
1722
+ hidden: {
1723
+ field: "source",
1724
+ equals: "inline"
1725
+ },
1726
+ validation: {
1727
+ min: 1,
1728
+ max: 30
1729
+ },
1730
+ of: [{
1731
+ name: "location",
1732
+ title: "Location",
1733
+ type: "object",
1734
+ icon: "map-pin",
1735
+ preview: {
1736
+ title: "name",
1737
+ subtitle: "address",
1738
+ media: "image",
1739
+ fallback: "Untitled location"
1740
+ },
1741
+ fields: [
1742
+ {
1743
+ name: "name",
1744
+ title: "Name",
1745
+ type: "string",
1746
+ validation: {
1747
+ required: true,
1748
+ max: 48
1749
+ }
1750
+ },
1751
+ {
1752
+ name: "type",
1753
+ title: "Type",
1754
+ type: "select",
1755
+ options: [
1756
+ {
1757
+ value: "flagship",
1758
+ label: "Flagship store"
1759
+ },
1760
+ {
1761
+ value: "workshop",
1762
+ label: "Workshop"
1763
+ },
1764
+ {
1765
+ value: "stockist",
1766
+ label: "Stockist"
1767
+ }
1768
+ ],
1769
+ description: ""
1770
+ },
1771
+ {
1772
+ name: "address",
1773
+ title: "Address",
1774
+ type: "text",
1775
+ rows: 3,
1776
+ validation: { required: true },
1777
+ description: "As it should appear, one line per row."
1778
+ },
1779
+ {
1780
+ name: "pin",
1781
+ title: "Map pin",
1782
+ type: "geopoint",
1783
+ validation: { required: true },
1784
+ description: "Drop it on the entrance."
1785
+ },
1786
+ {
1787
+ name: "phone",
1788
+ title: "Phone",
1789
+ type: "string",
1790
+ validation: {
1791
+ pattern: "^\\+?[0-9 ()-]{7,20}$",
1792
+ patternMessage: "Use digits, spaces and + ( ) -, like +1 (541) 555-0182."
1793
+ }
1794
+ },
1795
+ {
1796
+ name: "hours",
1797
+ title: "Opening hours",
1798
+ type: "array",
1799
+ itemNoun: "day",
1800
+ openMode: "inline",
1801
+ validation: { max: 7 },
1802
+ description: "Days left out show as closed.",
1803
+ of: [dayHours()]
1804
+ },
1805
+ {
1806
+ name: "services",
1807
+ title: "Services",
1808
+ type: "multiselect",
1809
+ options: [
1810
+ {
1811
+ value: "workshops",
1812
+ label: "Workshops"
1813
+ },
1814
+ {
1815
+ value: "reseasoning",
1816
+ label: "Re-seasoning"
1817
+ },
1818
+ {
1819
+ value: "engraving",
1820
+ label: "Engraving"
1821
+ },
1822
+ {
1823
+ value: "pickup",
1824
+ label: "Click & collect"
1825
+ },
1826
+ {
1827
+ value: "repairs",
1828
+ label: "Warranty repairs"
1829
+ }
1830
+ ]
1831
+ },
1832
+ {
1833
+ name: "image",
1834
+ title: "Image",
1835
+ type: "image"
1836
+ },
1837
+ {
1838
+ name: "page",
1839
+ title: "Location page",
1840
+ type: "link"
1841
+ }
1842
+ ]
1843
+ }]
1844
+ },
1845
+ {
1846
+ name: "searchPlaceholder",
1847
+ title: "Search placeholder",
1848
+ type: "string",
1849
+ group: "content",
1850
+ initialValue: "City or ZIP code",
1851
+ validation: { max: 32 },
1852
+ description: ""
1853
+ },
1854
+ {
1855
+ name: "showNearMe",
1856
+ title: "Show Near me button",
1857
+ type: "boolean",
1858
+ group: "content",
1859
+ initialValue: true
1860
+ },
1861
+ {
1862
+ name: "showServiceFilter",
1863
+ title: "Show services filter",
1864
+ type: "boolean",
1865
+ group: "content",
1866
+ initialValue: true,
1867
+ description: ""
1868
+ },
1869
+ {
1870
+ name: "center",
1871
+ title: "Starting view",
1872
+ type: "geopoint",
1873
+ group: "map",
1874
+ description: "Leave empty to fit all pins."
1875
+ },
1876
+ {
1877
+ name: "zoom",
1878
+ title: "Starting zoom",
1879
+ type: "number",
1880
+ group: "map",
1881
+ layout: "slider",
1882
+ numeric: {
1883
+ min: 3,
1884
+ max: 15,
1885
+ step: 1
1886
+ },
1887
+ initialValue: 5,
1888
+ description: "3 shows a continent, 15 a few streets."
1889
+ },
1890
+ {
1891
+ name: "useClustering",
1892
+ title: "Group nearby pins",
1893
+ type: "boolean",
1894
+ group: "map",
1895
+ initialValue: true
1896
+ },
1897
+ {
1898
+ name: "mobileView",
1899
+ title: "On phones show",
1900
+ type: "select",
1901
+ group: "design",
1902
+ layout: "segmented",
1903
+ initialValue: "list",
1904
+ options: [{
1905
+ value: "list",
1906
+ label: "List first"
1907
+ }, {
1908
+ value: "map",
1909
+ label: "Map first"
1910
+ }]
1911
+ }
1912
+ ]
1913
+ },
1914
+ value: {
1915
+ _variant: "map-left",
1916
+ heading: "Stores & workshops",
1917
+ intro: "Pick up a pan, get yours re-seasoned, or book a fire-cooking class.",
1918
+ source: "inline",
1919
+ query: {
1920
+ collection: "col_locations",
1921
+ types: [],
1922
+ regions: []
1923
+ },
1924
+ locations: [
1925
+ {
1926
+ _key: "l1",
1927
+ name: "Caldera Bend — Foundry Store",
1928
+ type: "flagship",
1929
+ address: "1180 SE Centennial Ct\nBend, OR 97702",
1930
+ pin: {
1931
+ label: "Caldera Foundry Store, Bend",
1932
+ lat: 44.0471,
1933
+ lng: -121.2831
1934
+ },
1935
+ phone: "+1 541 555 0142",
1936
+ hours: [
1937
+ {
1938
+ _key: "h1",
1939
+ day: "mon",
1940
+ isClosed: true
1941
+ },
1942
+ {
1943
+ _key: "h2",
1944
+ day: "tue",
1945
+ isClosed: false,
1946
+ opens: "10:00",
1947
+ closes: "18:00"
1948
+ },
1949
+ {
1950
+ _key: "h3",
1951
+ day: "wed",
1952
+ isClosed: false,
1953
+ opens: "10:00",
1954
+ closes: "18:00"
1955
+ },
1956
+ {
1957
+ _key: "h4",
1958
+ day: "thu",
1959
+ isClosed: false,
1960
+ opens: "10:00",
1961
+ closes: "19:00"
1962
+ },
1963
+ {
1964
+ _key: "h5",
1965
+ day: "fri",
1966
+ isClosed: false,
1967
+ opens: "10:00",
1968
+ closes: "19:00"
1969
+ },
1970
+ {
1971
+ _key: "h6",
1972
+ day: "sat",
1973
+ isClosed: false,
1974
+ opens: "09:00",
1975
+ closes: "17:00"
1976
+ },
1977
+ {
1978
+ _key: "h7",
1979
+ day: "sun",
1980
+ isClosed: false,
1981
+ opens: "11:00",
1982
+ closes: "16:00"
1983
+ }
1984
+ ],
1985
+ services: [
1986
+ "workshops",
1987
+ "reseasoning",
1988
+ "engraving",
1989
+ "repairs"
1990
+ ],
1991
+ image: image("caldera-bend-store", "The Caldera Foundry Store: skillets on a long timber wall, the foundry visible through glass", 1200, 800),
1992
+ page: {
1993
+ type: "page",
1994
+ href: "/stores/bend",
1995
+ title: "Bend store"
1996
+ }
1997
+ },
1998
+ {
1999
+ _key: "l2",
2000
+ name: "Caldera Portland",
2001
+ type: "flagship",
2002
+ address: "2235 NW Thurman St\nPortland, OR 97210",
2003
+ pin: {
2004
+ label: "Caldera Portland",
2005
+ lat: 45.5354,
2006
+ lng: -122.6982
2007
+ },
2008
+ phone: "+1 503 555 0198",
2009
+ hours: [
2010
+ {
2011
+ _key: "h8",
2012
+ day: "tue",
2013
+ isClosed: false,
2014
+ opens: "11:00",
2015
+ closes: "19:00"
2016
+ },
2017
+ {
2018
+ _key: "h9",
2019
+ day: "wed",
2020
+ isClosed: false,
2021
+ opens: "11:00",
2022
+ closes: "19:00"
2023
+ },
2024
+ {
2025
+ _key: "h10",
2026
+ day: "sat",
2027
+ isClosed: false,
2028
+ opens: "10:00",
2029
+ closes: "18:00"
2030
+ }
2031
+ ],
2032
+ services: ["reseasoning", "pickup"]
2033
+ },
2034
+ {
2035
+ _key: "l3",
2036
+ name: "Basecamp Outfitters (stockist)",
2037
+ type: "stockist",
2038
+ address: "1420 Pearl St\nBoulder, CO 80302",
2039
+ pin: {
2040
+ label: "Basecamp Outfitters, Boulder",
2041
+ lat: 40.0189,
2042
+ lng: -105.2747
2043
+ },
2044
+ services: ["pickup"]
2045
+ }
2046
+ ],
2047
+ searchPlaceholder: "City or ZIP code",
2048
+ showNearMe: true,
2049
+ showServiceFilter: true,
2050
+ zoom: 5,
2051
+ useClustering: true,
2052
+ mobileView: "list"
2053
+ },
2054
+ notes: {
2055
+ why: "Each location is a pin, an address, a phone, per-day hours and services. Small brands write them right in the section; once a location needs its own page (location-page) or appears in events and job posts, the source flips to the Locations collection with the same item shape. Hours are an array of day objects where `isClosed` reveals or hides open/close times — the item shape both the directory and LocalBusiness openingHoursSpecification need. Map behavior (view, zoom, clustering) is its own group; phone layout is design.",
2056
+ sanity: "Sanity: `location` documents { geo: geopoint, address, hours: array<object{day, closed, opens, closes}>, services: array<string> } rendered with a map lib; the directory is GROQ + client-side distance sort.",
2057
+ htmlSignals: [
2058
+ "A map (Google Maps / Mapbox / Leaflet container) beside a scrollable list of addresses",
2059
+ "'Find a store', 'Store locator', 'Stockists', 'Locations' headings; a ZIP/city search box",
2060
+ "Hours tables Mon–Sun, 'Closed' on some days, 'Open now' badges",
2061
+ "data-lat / data-lng attributes or a locations JSON blob in a <script>",
2062
+ "'Get directions' links to maps.google.com"
2063
+ ],
2064
+ mcp: "Look for the locations JSON the map is fed (script tag or XHR) — it usually has lat/lng, hours and services; prefer it over scraping. Each location → an item (or a Locations entry if it has its own page; then use source 'collection'). Parse hours into seven day objects: 'Mon–Fri 10–6' expands to five days with 10:00/18:00; 'Closed' → isClosed true. Pin = lat/lng from data attributes or geocode the address.",
2065
+ pitfalls: [
2066
+ "closed must default to false or the time fields stay hidden on new rows.",
2067
+ "Hours as one text line ('Tue–Sat 10–6') can't drive 'Open now' or JSON-LD.",
2068
+ "Overnight hours (18:00–02:00): closes earlier than opens means next day — say so in help, handle in the renderer.",
2069
+ "Pins at the geocoded centroid of a mall instead of the door.",
2070
+ "A map without a list fails keyboard and screen-reader users — the list is the primary UI."
2071
+ ]
2072
+ }
2073
+ },
2074
+ {
2075
+ id: "restaurant-menu",
2076
+ label: "Restaurant menu",
2077
+ category: "Events & places",
2078
+ brand: "Fiamma",
2079
+ previewLayout: "tabs",
2080
+ tags: [
2081
+ "deep-nesting",
2082
+ "repeater",
2083
+ "commerce",
2084
+ "conditional",
2085
+ "variants",
2086
+ "localized",
2087
+ "validation",
2088
+ "seo-structured"
2089
+ ],
2090
+ proves: "Menus → sections → items → price variants (4 levels) · fixed, variant or market price · dietary and allergen tags · 86'd items gray out",
2091
+ docTitle: "Menu — Fiamma Mission",
2092
+ urlPrefix: "fiamma.co/",
2093
+ schema: {
2094
+ name: "restaurantMenu",
2095
+ title: "Restaurant menu",
2096
+ kind: "block",
2097
+ icon: "tools-kitchen-2",
2098
+ category: "Events & places",
2099
+ description: "Lunch, dinner and drinks with prices and dietary tags",
2100
+ variants: [
2101
+ {
2102
+ id: "tabs",
2103
+ name: "Menus as tabs"
2104
+ },
2105
+ {
2106
+ id: "stacked",
2107
+ name: "All menus stacked"
2108
+ },
2109
+ {
2110
+ id: "two-column",
2111
+ name: "Two columns"
2112
+ }
2113
+ ],
2114
+ groups: [CONTENT, DESIGN],
2115
+ fieldsets: [{
2116
+ name: "small",
2117
+ title: "Small print"
2118
+ }],
2119
+ preview: {
2120
+ title: "heading",
2121
+ icon: "tools-kitchen-2"
2122
+ },
2123
+ fields: [
2124
+ {
2125
+ name: "heading",
2126
+ title: "Heading",
2127
+ type: "string",
2128
+ group: "content",
2129
+ validation: { max: 48 },
2130
+ localized: true
2131
+ },
2132
+ {
2133
+ name: "locations",
2134
+ title: "Served at",
2135
+ type: "array",
2136
+ group: "content",
2137
+ description: "Leave empty if every restaurant serves this menu.",
2138
+ of: [{
2139
+ name: "location",
2140
+ title: "Restaurant",
2141
+ type: "reference",
2142
+ reference: { to: ["col_locations"] }
2143
+ }]
2144
+ },
2145
+ {
2146
+ name: "currency",
2147
+ title: "Currency",
2148
+ type: "select",
2149
+ group: "content",
2150
+ initialValue: "USD",
2151
+ options: [
2152
+ {
2153
+ value: "USD",
2154
+ label: "$ USD"
2155
+ },
2156
+ {
2157
+ value: "EUR",
2158
+ label: "€ EUR"
2159
+ },
2160
+ {
2161
+ value: "GBP",
2162
+ label: "£ GBP"
2163
+ }
2164
+ ],
2165
+ description: ""
2166
+ },
2167
+ {
2168
+ name: "menus",
2169
+ title: "Menus",
2170
+ type: "array",
2171
+ group: "content",
2172
+ itemNoun: "menu",
2173
+ validation: {
2174
+ min: 1,
2175
+ max: 6
2176
+ },
2177
+ of: [{
2178
+ name: "menu",
2179
+ title: "Menu",
2180
+ type: "object",
2181
+ icon: "book-2",
2182
+ preview: {
2183
+ title: "name",
2184
+ subtitle: "servedFrom",
2185
+ fallback: "Untitled menu"
2186
+ },
2187
+ fields: [
2188
+ {
2189
+ name: "name",
2190
+ title: "Name",
2191
+ type: "string",
2192
+ validation: {
2193
+ required: true,
2194
+ max: 24
2195
+ },
2196
+ localized: true,
2197
+ placeholder: "Dinner"
2198
+ },
2199
+ {
2200
+ name: "servedFrom",
2201
+ title: "From",
2202
+ type: "string",
2203
+ validation: {
2204
+ pattern: TIME,
2205
+ patternMessage: TIME_MSG
2206
+ },
2207
+ placeholder: "17:00",
2208
+ description: ""
2209
+ },
2210
+ {
2211
+ name: "servedUntil",
2212
+ title: "Until",
2213
+ type: "string",
2214
+ validation: {
2215
+ pattern: TIME,
2216
+ patternMessage: TIME_MSG
2217
+ },
2218
+ placeholder: "22:00",
2219
+ description: ""
2220
+ },
2221
+ {
2222
+ name: "days",
2223
+ title: "Days",
2224
+ type: "multiselect",
2225
+ options: DAYS,
2226
+ description: "Leave empty for every day we're open."
2227
+ },
2228
+ {
2229
+ name: "note",
2230
+ title: "Note",
2231
+ type: "string",
2232
+ validation: { max: 120 },
2233
+ localized: true,
2234
+ placeholder: "Kitchen closes 30 minutes before the restaurant"
2235
+ },
2236
+ {
2237
+ name: "sections",
2238
+ title: "Sections",
2239
+ type: "array",
2240
+ itemNoun: "section",
2241
+ validation: {
2242
+ min: 1,
2243
+ max: 12
2244
+ },
2245
+ of: [{
2246
+ name: "menuSection",
2247
+ title: "Section",
2248
+ type: "object",
2249
+ icon: "list",
2250
+ preview: {
2251
+ title: "title",
2252
+ subtitle: "description",
2253
+ fallback: "Untitled section"
2254
+ },
2255
+ fields: [
2256
+ {
2257
+ name: "title",
2258
+ title: "Title",
2259
+ type: "string",
2260
+ validation: {
2261
+ required: true,
2262
+ max: 32
2263
+ },
2264
+ localized: true,
2265
+ placeholder: "Antipasti"
2266
+ },
2267
+ {
2268
+ name: "description",
2269
+ title: "Description",
2270
+ type: "string",
2271
+ validation: { max: 120 },
2272
+ localized: true
2273
+ },
2274
+ {
2275
+ name: "items",
2276
+ title: "Dishes",
2277
+ type: "array",
2278
+ itemNoun: "dish",
2279
+ validation: {
2280
+ min: 1,
2281
+ max: 30
2282
+ },
2283
+ of: [{
2284
+ name: "menuItem",
2285
+ title: "Dish",
2286
+ type: "object",
2287
+ icon: "salad",
2288
+ preview: {
2289
+ title: "name",
2290
+ subtitle: "description",
2291
+ media: "image",
2292
+ fallback: "Untitled dish"
2293
+ },
2294
+ fields: [
2295
+ {
2296
+ name: "name",
2297
+ title: "Name",
2298
+ type: "string",
2299
+ validation: {
2300
+ required: true,
2301
+ max: 60
2302
+ },
2303
+ localized: true
2304
+ },
2305
+ {
2306
+ name: "description",
2307
+ title: "Description",
2308
+ type: "text",
2309
+ rows: 2,
2310
+ validation: { recommendedMax: 140 },
2311
+ localized: true,
2312
+ description: "Ingredients, lowercase, comma-separated."
2313
+ },
2314
+ {
2315
+ name: "priceType",
2316
+ title: "Price",
2317
+ type: "select",
2318
+ layout: "segmented",
2319
+ initialValue: "fixed",
2320
+ options: [
2321
+ {
2322
+ value: "fixed",
2323
+ label: "One price"
2324
+ },
2325
+ {
2326
+ value: "variants",
2327
+ label: "Sizes"
2328
+ },
2329
+ {
2330
+ value: "market",
2331
+ label: "Market price"
2332
+ }
2333
+ ],
2334
+ description: ""
2335
+ },
2336
+ {
2337
+ name: "price",
2338
+ title: "Price",
2339
+ type: "number",
2340
+ hidden: {
2341
+ field: "priceType",
2342
+ equals: "fixed"
2343
+ },
2344
+ numeric: {
2345
+ min: 0,
2346
+ step: .5
2347
+ },
2348
+ validation: { required: true }
2349
+ },
2350
+ {
2351
+ name: "variants",
2352
+ title: "Sizes",
2353
+ type: "array",
2354
+ itemNoun: "size",
2355
+ openMode: "inline",
2356
+ hidden: {
2357
+ field: "priceType",
2358
+ equals: "variants"
2359
+ },
2360
+ validation: {
2361
+ min: 2,
2362
+ max: 4
2363
+ },
2364
+ of: [{
2365
+ name: "variant",
2366
+ title: "Size",
2367
+ type: "object",
2368
+ icon: "ruler",
2369
+ preview: {
2370
+ title: "label",
2371
+ subtitle: "price"
2372
+ },
2373
+ fields: [{
2374
+ name: "label",
2375
+ title: "Label",
2376
+ type: "string",
2377
+ validation: {
2378
+ required: true,
2379
+ max: 16
2380
+ },
2381
+ placeholder: "Glass"
2382
+ }, {
2383
+ name: "price",
2384
+ title: "Price",
2385
+ type: "number",
2386
+ numeric: {
2387
+ min: 0,
2388
+ step: .5
2389
+ },
2390
+ validation: { required: true }
2391
+ }]
2392
+ }]
2393
+ },
2394
+ {
2395
+ name: "dietary",
2396
+ title: "Dietary",
2397
+ type: "multiselect",
2398
+ options: [
2399
+ {
2400
+ value: "v",
2401
+ label: "Vegetarian"
2402
+ },
2403
+ {
2404
+ value: "vg",
2405
+ label: "Vegan"
2406
+ },
2407
+ {
2408
+ value: "gf",
2409
+ label: "Gluten-free"
2410
+ },
2411
+ {
2412
+ value: "df",
2413
+ label: "Dairy-free"
2414
+ }
2415
+ ],
2416
+ description: "Shown as letters after the name, with a key at the bottom."
2417
+ },
2418
+ {
2419
+ name: "allergens",
2420
+ title: "Contains",
2421
+ type: "multiselect",
2422
+ options: [
2423
+ {
2424
+ value: "gluten",
2425
+ label: "Gluten"
2426
+ },
2427
+ {
2428
+ value: "dairy",
2429
+ label: "Milk"
2430
+ },
2431
+ {
2432
+ value: "egg",
2433
+ label: "Egg"
2434
+ },
2435
+ {
2436
+ value: "nuts",
2437
+ label: "Tree nuts"
2438
+ },
2439
+ {
2440
+ value: "peanut",
2441
+ label: "Peanut"
2442
+ },
2443
+ {
2444
+ value: "fish",
2445
+ label: "Fish"
2446
+ },
2447
+ {
2448
+ value: "shellfish",
2449
+ label: "Shellfish"
2450
+ },
2451
+ {
2452
+ value: "sesame",
2453
+ label: "Sesame"
2454
+ },
2455
+ {
2456
+ value: "soy",
2457
+ label: "Soy"
2458
+ }
2459
+ ]
2460
+ },
2461
+ {
2462
+ name: "spice",
2463
+ title: "Heat",
2464
+ type: "number",
2465
+ layout: "slider",
2466
+ numeric: {
2467
+ min: 0,
2468
+ max: 3,
2469
+ step: 1
2470
+ },
2471
+ initialValue: 0,
2472
+ description: "0 is none. Shown as chilli icons."
2473
+ },
2474
+ {
2475
+ name: "image",
2476
+ title: "Image",
2477
+ type: "image"
2478
+ },
2479
+ {
2480
+ name: "isSignature",
2481
+ title: "House favorite",
2482
+ type: "boolean"
2483
+ },
2484
+ {
2485
+ name: "isAvailable",
2486
+ title: "Available today",
2487
+ type: "boolean",
2488
+ initialValue: true,
2489
+ description: "Off shows it grayed out as \"Sold out\"."
2490
+ }
2491
+ ]
2492
+ }]
2493
+ }
2494
+ ]
2495
+ }]
2496
+ }
2497
+ ]
2498
+ }]
2499
+ },
2500
+ {
2501
+ name: "showLegend",
2502
+ title: "Show dietary key",
2503
+ type: "boolean",
2504
+ group: "content",
2505
+ fieldset: "small",
2506
+ initialValue: true
2507
+ },
2508
+ {
2509
+ name: "footnote",
2510
+ title: "Footnote",
2511
+ type: "text",
2512
+ rows: 2,
2513
+ group: "content",
2514
+ fieldset: "small",
2515
+ localized: true
2516
+ },
2517
+ {
2518
+ name: "showPhotos",
2519
+ title: "Dish photos",
2520
+ type: "boolean",
2521
+ group: "design"
2522
+ },
2523
+ {
2524
+ name: "pdf",
2525
+ title: "Printable PDF",
2526
+ type: "file",
2527
+ group: "design",
2528
+ description: "Adds a \"Download menu\" link."
2529
+ }
2530
+ ]
2531
+ },
2532
+ value: {
2533
+ _variant: "tabs",
2534
+ heading: "Menu",
2535
+ locations: ["en_loc_fiamma-mission"],
2536
+ currency: "USD",
2537
+ menus: [{
2538
+ _key: "m1",
2539
+ name: "Dinner",
2540
+ servedFrom: "17:00",
2541
+ servedUntil: "22:00",
2542
+ days: [],
2543
+ note: "Kitchen closes 30 minutes before the restaurant.",
2544
+ sections: [
2545
+ {
2546
+ _key: "s1",
2547
+ title: "Antipasti",
2548
+ items: [{
2549
+ _key: "i1",
2550
+ name: "Burrata",
2551
+ description: "charred stone fruit, basil, aged balsamic, wood-fired bread",
2552
+ priceType: "fixed",
2553
+ price: 19,
2554
+ dietary: ["v"],
2555
+ allergens: ["dairy", "gluten"],
2556
+ spice: 0,
2557
+ isSignature: true,
2558
+ isAvailable: true,
2559
+ image: image("fiamma-burrata", "Burrata torn open over grilled peaches on a speckled plate", 1200, 900)
2560
+ }, {
2561
+ _key: "i2",
2562
+ name: "Calamari alla griglia",
2563
+ description: "Calabrian chilli, lemon, parsley",
2564
+ priceType: "fixed",
2565
+ price: 18,
2566
+ dietary: ["gf", "df"],
2567
+ allergens: ["shellfish"],
2568
+ spice: 2,
2569
+ isAvailable: true
2570
+ }]
2571
+ },
2572
+ {
2573
+ _key: "s2",
2574
+ title: "Pizze",
2575
+ description: "48-hour dough, baked at 480°C in our wood oven.",
2576
+ items: [{
2577
+ _key: "i3",
2578
+ name: "Margherita",
2579
+ description: "San Marzano, fior di latte, basil, olive oil",
2580
+ priceType: "fixed",
2581
+ price: 17,
2582
+ dietary: ["v"],
2583
+ allergens: ["gluten", "dairy"],
2584
+ spice: 0,
2585
+ isAvailable: true
2586
+ }, {
2587
+ _key: "i4",
2588
+ name: "Diavola",
2589
+ description: "spicy salami, fior di latte, hot honey",
2590
+ priceType: "fixed",
2591
+ price: 21,
2592
+ dietary: [],
2593
+ allergens: ["gluten", "dairy"],
2594
+ spice: 2,
2595
+ isAvailable: false
2596
+ }]
2597
+ },
2598
+ {
2599
+ _key: "s3",
2600
+ title: "Pesce",
2601
+ items: [{
2602
+ _key: "i5",
2603
+ name: "Whole branzino",
2604
+ description: "salsa verde, roasted fennel",
2605
+ priceType: "market",
2606
+ dietary: ["gf", "df"],
2607
+ allergens: ["fish"],
2608
+ spice: 0,
2609
+ isAvailable: true
2610
+ }]
2611
+ }
2612
+ ]
2613
+ }, {
2614
+ _key: "m2",
2615
+ name: "Wine",
2616
+ servedFrom: "12:00",
2617
+ servedUntil: "23:00",
2618
+ sections: [{
2619
+ _key: "s4",
2620
+ title: "Rosso",
2621
+ items: [{
2622
+ _key: "i6",
2623
+ name: "Nebbiolo, G.D. Vajra 2022",
2624
+ description: "Piedmont · rose petal, red cherry, fine tannin",
2625
+ priceType: "variants",
2626
+ variants: [{
2627
+ _key: "v1",
2628
+ label: "Glass",
2629
+ price: 17
2630
+ }, {
2631
+ _key: "v2",
2632
+ label: "Bottle",
2633
+ price: 68
2634
+ }],
2635
+ dietary: ["vg"],
2636
+ allergens: [],
2637
+ spice: 0,
2638
+ isAvailable: true
2639
+ }]
2640
+ }]
2641
+ }],
2642
+ showLegend: true,
2643
+ footnote: "Please tell your server about any allergies. A 20% service charge is added to parties of 6 or more and goes entirely to our staff.",
2644
+ showPhotos: false,
2645
+ pdf: {
2646
+ url: "https://fiamma.co/media/menus/fiamma-mission-dinner-oct-2026.pdf",
2647
+ name: "fiamma-mission-dinner-oct-2026.pdf",
2648
+ size: 412e3
2649
+ }
2650
+ },
2651
+ notes: {
2652
+ why: "A menu is the canonical deep repeater: menus → sections → dishes → size variants. Price is a MODE (one price, sizes, or market price) so 'MP' never sits in a number field and sizes never get crammed into a description. Dietary and allergen values are fixed option lists (legend + filter + Menu JSON-LD suitableForDiet). 'Available today' grays a dish out instead of deleting it, so a sold-out special comes back tomorrow with one tap. It stays a section shared to restaurants by reference; a group with many locations and shared dishes would promote dishes to a collection.",
2653
+ sanity: "Sanity: `menu` document { sections: array<object{title, items: array<object{name, description, price, variants: array<object{label, price}>, dietary: array<string>}>}> } — usually exactly this shape, with dietary as a string list.",
2654
+ htmlSignals: [
2655
+ "Section headings (Antipasti, Mains, Wine) with dish name + price on the same line, dotted leaders",
2656
+ "Small letter codes after names (V, VG, GF) and a key at the bottom",
2657
+ "Two prices per row with labels ('Glass / Bottle', 'Small / Large')",
2658
+ "'MP' or 'Market price' instead of a number",
2659
+ "Tabs or anchors for Lunch / Dinner / Drinks; a 'Download PDF menu' link"
2660
+ ],
2661
+ mcp: "Tabs/anchors → menus (copy service hours if shown). Headings → sections. Each row → dish: name, description (the smaller line), price (strip currency symbols; 'MP' → priceType market; two labeled prices → variants), dietary from the letter codes via the page's key, spice from chilli icons. A PDF-only menu: extract its text the same way and attach the PDF. Never keep prices inside descriptions.",
2662
+ pitfalls: [
2663
+ "'$18 / $32' in one field — sizes must be variants.",
2664
+ "Allergen data that disagrees with the kitchen sheet is a safety issue — owners must sign off.",
2665
+ "Deleting sold-out dishes loses them; use available.",
2666
+ "Prices typed with symbols ('$18') break sorting and JSON-LD.",
2667
+ "Four nesting levels: keep sizes inline (openMode inline) so the deepest level isn't another drill."
2668
+ ]
2669
+ }
2670
+ },
2671
+ {
2672
+ id: "location-page",
2673
+ label: "Single location page",
2674
+ category: "Events & places",
2675
+ brand: "Fiamma",
2676
+ previewLayout: "split",
2677
+ tags: [
2678
+ "seo-structured",
2679
+ "repeater",
2680
+ "conditional",
2681
+ "references",
2682
+ "media-heavy",
2683
+ "a11y",
2684
+ "validation",
2685
+ "deep-nesting"
2686
+ ],
2687
+ proves: "Address object + pin · per-day hours with split shifts · holiday overrides · booking provider reveals its own fields · Restaurant JSON-LD",
2688
+ docTitle: "Fiamma Mission",
2689
+ urlPrefix: "fiamma.co/locations/",
2690
+ schema: {
2691
+ name: "restaurantLocation",
2692
+ title: "Restaurant location",
2693
+ kind: "entry",
2694
+ icon: "building-store",
2695
+ category: "Events & places",
2696
+ description: "One restaurant: where, when, how to book",
2697
+ preview: {
2698
+ title: "name",
2699
+ subtitle: "city",
2700
+ media: "coverImage"
2701
+ },
2702
+ groups: [
2703
+ {
2704
+ name: "overview",
2705
+ title: "Overview",
2706
+ icon: "file-text",
2707
+ default: true
2708
+ },
2709
+ {
2710
+ name: "hours",
2711
+ title: "Hours",
2712
+ icon: "clock"
2713
+ },
2714
+ {
2715
+ name: "booking",
2716
+ title: "Booking",
2717
+ icon: "calendar-plus"
2718
+ },
2719
+ {
2720
+ name: "media",
2721
+ title: "Media",
2722
+ icon: "photo"
2723
+ }
2724
+ ],
2725
+ fieldsets: [
2726
+ {
2727
+ name: "address",
2728
+ title: "Address"
2729
+ },
2730
+ {
2731
+ name: "contact",
2732
+ title: "Contact"
2733
+ },
2734
+ {
2735
+ name: "private",
2736
+ title: "Private dining",
2737
+ collapsed: true
2738
+ }
2739
+ ],
2740
+ fields: [
2741
+ {
2742
+ name: "name",
2743
+ title: "Name",
2744
+ type: "string",
2745
+ group: "overview",
2746
+ validation: {
2747
+ required: true,
2748
+ max: 48
2749
+ }
2750
+ },
2751
+ {
2752
+ name: "slug",
2753
+ title: "Slug",
2754
+ type: "slug",
2755
+ group: "overview",
2756
+ validation: { required: true }
2757
+ },
2758
+ {
2759
+ name: "tagline",
2760
+ title: "Tagline",
2761
+ type: "string",
2762
+ group: "overview",
2763
+ validation: { recommendedMax: 90 },
2764
+ localized: true
2765
+ },
2766
+ {
2767
+ name: "about",
2768
+ title: "About",
2769
+ type: "richtext",
2770
+ group: "overview",
2771
+ localized: true
2772
+ },
2773
+ {
2774
+ name: "street",
2775
+ title: "Street",
2776
+ type: "string",
2777
+ group: "overview",
2778
+ fieldset: "address",
2779
+ validation: { required: true }
2780
+ },
2781
+ {
2782
+ name: "city",
2783
+ title: "City",
2784
+ type: "string",
2785
+ group: "overview",
2786
+ fieldset: "address",
2787
+ validation: { required: true }
2788
+ },
2789
+ {
2790
+ name: "region",
2791
+ title: "State / region",
2792
+ type: "string",
2793
+ group: "overview",
2794
+ fieldset: "address"
2795
+ },
2796
+ {
2797
+ name: "postalCode",
2798
+ title: "Postal code",
2799
+ type: "string",
2800
+ group: "overview",
2801
+ fieldset: "address",
2802
+ validation: { required: true }
2803
+ },
2804
+ {
2805
+ name: "country",
2806
+ title: "Country",
2807
+ type: "select",
2808
+ group: "overview",
2809
+ fieldset: "address",
2810
+ initialValue: "US",
2811
+ options: [
2812
+ {
2813
+ value: "US",
2814
+ label: "United States"
2815
+ },
2816
+ {
2817
+ value: "CA",
2818
+ label: "Canada"
2819
+ },
2820
+ {
2821
+ value: "GB",
2822
+ label: "United Kingdom"
2823
+ },
2824
+ {
2825
+ value: "IT",
2826
+ label: "Italy"
2827
+ }
2828
+ ],
2829
+ description: ""
2830
+ },
2831
+ {
2832
+ name: "pin",
2833
+ title: "Map pin",
2834
+ type: "geopoint",
2835
+ group: "overview",
2836
+ validation: { required: true },
2837
+ description: "Drop it on the entrance."
2838
+ },
2839
+ {
2840
+ name: "phone",
2841
+ title: "Phone",
2842
+ type: "string",
2843
+ group: "overview",
2844
+ fieldset: "contact",
2845
+ validation: {
2846
+ required: true,
2847
+ pattern: "^\\+?[0-9 ()-]{7,20}$",
2848
+ patternMessage: "Use digits, spaces and + ( ) -, like +1 (541) 555-0182."
2849
+ }
2850
+ },
2851
+ {
2852
+ name: "email",
2853
+ title: "Email",
2854
+ type: "email",
2855
+ group: "overview",
2856
+ fieldset: "contact"
2857
+ },
2858
+ {
2859
+ name: "services",
2860
+ title: "Services",
2861
+ type: "multiselect",
2862
+ group: "overview",
2863
+ options: [
2864
+ {
2865
+ value: "dine-in",
2866
+ label: "Dine-in"
2867
+ },
2868
+ {
2869
+ value: "takeout",
2870
+ label: "Takeout"
2871
+ },
2872
+ {
2873
+ value: "delivery",
2874
+ label: "Delivery"
2875
+ },
2876
+ {
2877
+ value: "outdoor",
2878
+ label: "Outdoor seating"
2879
+ },
2880
+ {
2881
+ value: "bar",
2882
+ label: "Bar seating"
2883
+ },
2884
+ {
2885
+ value: "private",
2886
+ label: "Private dining"
2887
+ }
2888
+ ],
2889
+ description: ""
2890
+ },
2891
+ {
2892
+ name: "priceRange",
2893
+ title: "Price range",
2894
+ type: "select",
2895
+ group: "overview",
2896
+ layout: "segmented",
2897
+ options: [
2898
+ {
2899
+ value: "$",
2900
+ label: "$"
2901
+ },
2902
+ {
2903
+ value: "$$",
2904
+ label: "$$"
2905
+ },
2906
+ {
2907
+ value: "$$$",
2908
+ label: "$$$"
2909
+ },
2910
+ {
2911
+ value: "$$$$",
2912
+ label: "$$$$"
2913
+ }
2914
+ ],
2915
+ description: "Per person with a drink, roughly. Shown in search results."
2916
+ },
2917
+ {
2918
+ name: "menus",
2919
+ title: "Menus",
2920
+ type: "array",
2921
+ group: "overview",
2922
+ validation: { max: 6 },
2923
+ of: [{
2924
+ name: "menu",
2925
+ title: "Menu",
2926
+ type: "reference",
2927
+ reference: { to: ["col_menus"] }
2928
+ }]
2929
+ },
2930
+ {
2931
+ name: "chef",
2932
+ title: "Head chef",
2933
+ type: "reference",
2934
+ group: "overview",
2935
+ reference: { to: ["col_people"] }
2936
+ },
2937
+ {
2938
+ name: "accessibility",
2939
+ title: "Accessibility",
2940
+ type: "text",
2941
+ rows: 2,
2942
+ group: "overview"
2943
+ },
2944
+ {
2945
+ name: "parking",
2946
+ title: "Getting here",
2947
+ type: "text",
2948
+ rows: 2,
2949
+ group: "overview"
2950
+ },
2951
+ {
2952
+ name: "hours",
2953
+ title: "Weekly hours",
2954
+ type: "array",
2955
+ group: "hours",
2956
+ itemNoun: "day",
2957
+ validation: {
2958
+ min: 1,
2959
+ max: 7
2960
+ },
2961
+ description: "One row per day. Lunch and dinner are two shifts on the same day.",
2962
+ of: [{
2963
+ name: "day",
2964
+ title: "Day",
2965
+ type: "object",
2966
+ icon: "clock",
2967
+ preview: {
2968
+ title: "day",
2969
+ fallback: "Untitled day"
2970
+ },
2971
+ fields: [
2972
+ {
2973
+ name: "day",
2974
+ title: "Day",
2975
+ type: "select",
2976
+ options: DAYS,
2977
+ validation: {
2978
+ required: true,
2979
+ unique: true
2980
+ },
2981
+ description: ""
2982
+ },
2983
+ {
2984
+ name: "isClosed",
2985
+ title: "Closed",
2986
+ type: "boolean",
2987
+ initialValue: false
2988
+ },
2989
+ {
2990
+ name: "shifts",
2991
+ title: "Open",
2992
+ type: "array",
2993
+ itemNoun: "shift",
2994
+ openMode: "inline",
2995
+ hidden: {
2996
+ field: "isClosed",
2997
+ equals: false
2998
+ },
2999
+ validation: {
3000
+ min: 1,
3001
+ max: 3
3002
+ },
3003
+ of: [{
3004
+ name: "shift",
3005
+ title: "Shift",
3006
+ type: "object",
3007
+ icon: "clock-hour-4",
3008
+ preview: {
3009
+ title: "opens",
3010
+ subtitle: "closes"
3011
+ },
3012
+ fields: [
3013
+ {
3014
+ name: "label",
3015
+ title: "Label",
3016
+ type: "string",
3017
+ validation: { max: 16 },
3018
+ placeholder: "Dinner",
3019
+ description: ""
3020
+ },
3021
+ {
3022
+ name: "opens",
3023
+ title: "Opens",
3024
+ type: "string",
3025
+ validation: {
3026
+ required: true,
3027
+ pattern: TIME,
3028
+ patternMessage: TIME_MSG
3029
+ },
3030
+ placeholder: "17:00",
3031
+ description: ""
3032
+ },
3033
+ {
3034
+ name: "closes",
3035
+ title: "Closes",
3036
+ type: "string",
3037
+ validation: {
3038
+ required: true,
3039
+ pattern: TIME,
3040
+ patternMessage: TIME_MSG
3041
+ },
3042
+ placeholder: "22:00",
3043
+ description: ""
3044
+ }
3045
+ ]
3046
+ }]
3047
+ }
3048
+ ]
3049
+ }]
3050
+ },
3051
+ {
3052
+ name: "specialHours",
3053
+ title: "Holidays & special hours",
3054
+ type: "array",
3055
+ group: "hours",
3056
+ itemNoun: "date",
3057
+ validation: { max: 30 },
3058
+ description: "Overrides the weekly hours on these dates.",
3059
+ of: [{
3060
+ name: "special",
3061
+ title: "Date",
3062
+ type: "object",
3063
+ icon: "calendar-exclamation",
3064
+ preview: {
3065
+ title: "label",
3066
+ subtitle: "date"
3067
+ },
3068
+ fields: [
3069
+ {
3070
+ name: "date",
3071
+ title: "Date",
3072
+ type: "date",
3073
+ validation: { required: true }
3074
+ },
3075
+ {
3076
+ name: "label",
3077
+ title: "Label",
3078
+ type: "string",
3079
+ validation: { max: 32 },
3080
+ placeholder: "Thanksgiving"
3081
+ },
3082
+ {
3083
+ name: "isClosed",
3084
+ title: "Closed all day",
3085
+ type: "boolean",
3086
+ initialValue: false
3087
+ },
3088
+ {
3089
+ name: "opens",
3090
+ title: "Opens",
3091
+ type: "string",
3092
+ hidden: {
3093
+ field: "isClosed",
3094
+ equals: false
3095
+ },
3096
+ validation: {
3097
+ required: true,
3098
+ pattern: TIME,
3099
+ patternMessage: TIME_MSG
3100
+ },
3101
+ description: ""
3102
+ },
3103
+ {
3104
+ name: "closes",
3105
+ title: "Closes",
3106
+ type: "string",
3107
+ hidden: {
3108
+ field: "isClosed",
3109
+ equals: false
3110
+ },
3111
+ validation: {
3112
+ required: true,
3113
+ pattern: TIME,
3114
+ patternMessage: TIME_MSG
3115
+ },
3116
+ description: ""
3117
+ }
3118
+ ]
3119
+ }]
3120
+ },
3121
+ {
3122
+ name: "bookingProvider",
3123
+ title: "Reservations",
3124
+ type: "select",
3125
+ group: "booking",
3126
+ layout: "radio",
3127
+ initialValue: "resy",
3128
+ options: [
3129
+ {
3130
+ value: "resy",
3131
+ label: "Resy"
3132
+ },
3133
+ {
3134
+ value: "opentable",
3135
+ label: "OpenTable"
3136
+ },
3137
+ {
3138
+ value: "tock",
3139
+ label: "Tock"
3140
+ },
3141
+ {
3142
+ value: "phone",
3143
+ label: "By phone"
3144
+ },
3145
+ {
3146
+ value: "none",
3147
+ label: "Walk-ins only"
3148
+ }
3149
+ ],
3150
+ description: ""
3151
+ },
3152
+ {
3153
+ name: "venueId",
3154
+ title: "Venue ID",
3155
+ type: "string",
3156
+ group: "booking",
3157
+ hidden: {
3158
+ field: "bookingProvider",
3159
+ equals: [
3160
+ "resy",
3161
+ "opentable",
3162
+ "tock"
3163
+ ]
3164
+ },
3165
+ validation: { required: true },
3166
+ description: "From the provider's widget code."
3167
+ },
3168
+ {
3169
+ name: "bookButton",
3170
+ title: "Book button",
3171
+ type: "button",
3172
+ group: "booking",
3173
+ hidden: {
3174
+ field: "bookingProvider",
3175
+ equals: [
3176
+ "resy",
3177
+ "opentable",
3178
+ "tock",
3179
+ "phone"
3180
+ ]
3181
+ },
3182
+ description: "Phone bookings use a tel: link."
3183
+ },
3184
+ {
3185
+ name: "walkInNote",
3186
+ title: "Walk-in note",
3187
+ type: "string",
3188
+ group: "booking",
3189
+ validation: { max: 100 },
3190
+ placeholder: "The bar is always kept for walk-ins"
3191
+ },
3192
+ {
3193
+ name: "hasPrivateDining",
3194
+ title: "Offers private dining",
3195
+ type: "boolean",
3196
+ group: "booking",
3197
+ fieldset: "private"
3198
+ },
3199
+ {
3200
+ name: "privateCapacity",
3201
+ title: "Seats up to",
3202
+ type: "number",
3203
+ group: "booking",
3204
+ fieldset: "private",
3205
+ hidden: {
3206
+ field: "hasPrivateDining",
3207
+ equals: true
3208
+ },
3209
+ numeric: {
3210
+ unit: "guests",
3211
+ min: 2,
3212
+ step: 1
3213
+ },
3214
+ validation: { required: true }
3215
+ },
3216
+ {
3217
+ name: "privateForm",
3218
+ title: "Enquiry form",
3219
+ type: "reference",
3220
+ group: "booking",
3221
+ fieldset: "private",
3222
+ hidden: {
3223
+ field: "hasPrivateDining",
3224
+ equals: true
3225
+ },
3226
+ reference: { to: ["form"] },
3227
+ validation: { required: true }
3228
+ },
3229
+ {
3230
+ name: "privateBrochure",
3231
+ title: "Brochure",
3232
+ type: "file",
3233
+ group: "booking",
3234
+ fieldset: "private",
3235
+ hidden: {
3236
+ field: "hasPrivateDining",
3237
+ equals: true
3238
+ }
3239
+ },
3240
+ {
3241
+ name: "coverImage",
3242
+ title: "Cover image",
3243
+ type: "image",
3244
+ group: "media",
3245
+ validation: { required: true }
3246
+ },
3247
+ {
3248
+ name: "gallery",
3249
+ title: "Gallery",
3250
+ type: "array",
3251
+ group: "media",
3252
+ arrayLayout: "grid",
3253
+ validation: { max: 12 },
3254
+ of: [{
3255
+ name: "photo",
3256
+ title: "Photo",
3257
+ type: "image"
3258
+ }]
3259
+ }
3260
+ ]
3261
+ },
3262
+ value: {
3263
+ name: "Fiamma Mission",
3264
+ slug: "mission",
3265
+ tagline: "Wood-fired pizza and Ligurian seafood on Valencia Street.",
3266
+ about: "<p>Our first restaurant, opened in 2016 around a 4-ton oven built by hand in Naples. Chef Giulia Ferraro cooks almost everything over oak.</p>",
3267
+ street: "742 Valencia St",
3268
+ city: "San Francisco",
3269
+ region: "CA",
3270
+ postalCode: "94110",
3271
+ country: "US",
3272
+ pin: {
3273
+ label: "Fiamma Mission, 742 Valencia St",
3274
+ lat: 37.7609,
3275
+ lng: -122.4216
3276
+ },
3277
+ phone: "+1 415 555 0173",
3278
+ email: "mission@fiamma.co",
3279
+ services: [
3280
+ "dine-in",
3281
+ "takeout",
3282
+ "bar",
3283
+ "private"
3284
+ ],
3285
+ priceRange: "$$$",
3286
+ menus: ["en_menu_dinner", "en_menu_wine"],
3287
+ chef: "en_p_giulia-ferraro",
3288
+ accessibility: "Step-free entrance on Valencia St, accessible restroom at the back of the dining room, high chairs on request.",
3289
+ parking: "Street parking is tight after 6pm. 16th St BART is a 6-minute walk; bike racks out front.",
3290
+ hours: [
3291
+ {
3292
+ _key: "h1",
3293
+ day: "mon",
3294
+ isClosed: true
3295
+ },
3296
+ {
3297
+ _key: "h2",
3298
+ day: "tue",
3299
+ isClosed: false,
3300
+ shifts: [{
3301
+ _key: "a",
3302
+ label: "Dinner",
3303
+ opens: "17:00",
3304
+ closes: "22:00"
3305
+ }]
3306
+ },
3307
+ {
3308
+ _key: "h3",
3309
+ day: "wed",
3310
+ isClosed: false,
3311
+ shifts: [{
3312
+ _key: "a",
3313
+ label: "Dinner",
3314
+ opens: "17:00",
3315
+ closes: "22:00"
3316
+ }]
3317
+ },
3318
+ {
3319
+ _key: "h4",
3320
+ day: "thu",
3321
+ isClosed: false,
3322
+ shifts: [{
3323
+ _key: "a",
3324
+ label: "Dinner",
3325
+ opens: "17:00",
3326
+ closes: "22:00"
3327
+ }]
3328
+ },
3329
+ {
3330
+ _key: "h5",
3331
+ day: "fri",
3332
+ isClosed: false,
3333
+ shifts: [{
3334
+ _key: "a",
3335
+ label: "Lunch",
3336
+ opens: "11:30",
3337
+ closes: "14:30"
3338
+ }, {
3339
+ _key: "b",
3340
+ label: "Dinner",
3341
+ opens: "17:00",
3342
+ closes: "23:00"
3343
+ }]
3344
+ },
3345
+ {
3346
+ _key: "h6",
3347
+ day: "sat",
3348
+ isClosed: false,
3349
+ shifts: [{
3350
+ _key: "a",
3351
+ label: "Lunch",
3352
+ opens: "11:30",
3353
+ closes: "14:30"
3354
+ }, {
3355
+ _key: "b",
3356
+ label: "Dinner",
3357
+ opens: "17:00",
3358
+ closes: "23:00"
3359
+ }]
3360
+ },
3361
+ {
3362
+ _key: "h7",
3363
+ day: "sun",
3364
+ isClosed: false,
3365
+ shifts: [{
3366
+ _key: "a",
3367
+ label: "All day",
3368
+ opens: "12:00",
3369
+ closes: "21:00"
3370
+ }]
3371
+ }
3372
+ ],
3373
+ specialHours: [{
3374
+ _key: "sp1",
3375
+ date: "2026-11-26",
3376
+ label: "Thanksgiving",
3377
+ isClosed: true
3378
+ }, {
3379
+ _key: "sp2",
3380
+ date: "2026-12-31",
3381
+ label: "New Year's Eve",
3382
+ isClosed: false,
3383
+ opens: "17:00",
3384
+ closes: "01:00"
3385
+ }],
3386
+ bookingProvider: "resy",
3387
+ venueId: "58231",
3388
+ walkInNote: "The bar and the counter by the oven are always kept for walk-ins.",
3389
+ hasPrivateDining: true,
3390
+ privateCapacity: 24,
3391
+ privateForm: "form_private-dining-mission",
3392
+ privateBrochure: {
3393
+ url: "https://fiamma.co/media/private-dining-mission.pdf",
3394
+ name: "private-dining-mission.pdf",
3395
+ size: 24e5
3396
+ },
3397
+ coverImage: image("fiamma-mission-oven", "The dining room at Fiamma Mission, a tiled wood oven glowing at the back"),
3398
+ gallery: [
3399
+ pic("fiamma-mission-bar", 900, 900),
3400
+ pic("fiamma-mission-pizza", 900, 900),
3401
+ pic("fiamma-mission-terrace", 900, 900)
3402
+ ]
3403
+ },
3404
+ notes: {
3405
+ why: "Each restaurant is an entry because it has its own page and emits Restaurant JSON-LD natively: address (PostalAddress from the address fields), geo, telephone, priceRange, servesCuisine, hasMenu (menu references), acceptsReservations (from the provider), and openingHoursSpecification from the hours array — with special dates mapped to specialOpeningHoursSpecification. Hours are days → shifts, so lunch + dinner and 'closed Mondays' are both data, and a day's shifts appear only when it isn't closed. The booking provider reveals exactly the field it needs (a venue ID for Resy/OpenTable/Tock, a tel: button for phone). Address parts are separate fields because search engines and maps need them separately.",
3406
+ sanity: "Sanity: `location` { address: object, geo: geopoint, openingHours: array<object{day, closed, slots: array<object{open, close}>}>, specialHours: array<object>, reservation: object{provider, id} }. Same shape.",
3407
+ htmlSignals: [
3408
+ "An address block, phone link (tel:), and a map or 'Get directions' link",
3409
+ "An hours table with day names and one or two time ranges per day; 'Closed' on some days",
3410
+ "A Resy/OpenTable/Tock widget or button (resy.com, opentable.com, exploretock.com URLs)",
3411
+ "'Holiday hours' notices; 'Private dining' section with a form or PDF",
3412
+ "LocalBusiness / Restaurant JSON-LD in the source"
3413
+ ],
3414
+ mcp: "Prefer the page's Restaurant JSON-LD for address, geo, phone, priceRange and openingHoursSpecification. Expand compressed hours ('Tue–Thu 5–10pm' → three days, one shift each; 'Fri–Sat 11:30–2:30, 5–11' → two shifts). Holiday notices → specialHours. Booking widget host → bookingProvider and venue ID from its URL/params. Menus → Menus entries/sections (see restaurant-menu) referenced here. Photos → gallery with alt.",
3415
+ pitfalls: [
3416
+ "Overnight closes (01:00) read as earlier than opens — mean next day; the renderer must handle it.",
3417
+ "Hours duplicated on Google Business Profile drift — this entry should be the source you sync from.",
3418
+ "Special hours never cleaned up — past dates hide themselves but stay as history.",
3419
+ "A booking widget without a phone fallback excludes people who can't use it.",
3420
+ "closed defaults to false or new days hide their shifts."
3421
+ ]
3422
+ }
3423
+ }
3424
+ ];
3425
+ //#endregion
3426
+ export { ENTRIES };
3427
+
3428
+ //# sourceMappingURL=events.entries.js.map