@flickfyi/flkr 0.0.182 → 0.0.185

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 (243) hide show
  1. package/dist/{api-client-CAg1b8Bh.js → api-client-nn4U_Vfn.js} +1 -1
  2. package/dist/{app-DpM5nhb9.js → app-COXGJhrt.js} +3 -3
  3. package/dist/{bundler-DNrDcqyk.js → bundler-CW4YC73e.js} +4 -2
  4. package/dist/cli.js +11 -11
  5. package/dist/{delegate-DcVye0KE.js → delegate-aUVluBjB.js} +2 -2
  6. package/dist/{generate-B1l1z_FZ.js → generate-BeL1QPDi.js} +1 -1
  7. package/dist/{preview-Dqn_Tq6K.js → preview-DTVM8Csb.js} +2 -2
  8. package/dist/{publish-BmDqO1xU.js → publish-BJG-s-w5.js} +4 -4
  9. package/dist/{pull-CO80DMn8.js → pull-B_Yfjpi2.js} +1 -1
  10. package/dist/{save-8crfOeo1.js → save-UrfgmK2-.js} +2 -2
  11. package/dist/{sdk-app-BXWrf_pf.js → sdk-app-BAxznAf9.js} +3 -3
  12. package/dist/{sdk-deploy-CaEonlvx.js → sdk-deploy-D1wgQxse.js} +3 -3
  13. package/dist/{sdk-generation-CF8ATbrL.js → sdk-generation-CLQ-QrVM.js} +1 -1
  14. package/dist/{sdk-project-CKV3U3u9.js → sdk-project-BaO0fqhW.js} +1 -1
  15. package/dist/{use-auth-B6nwU2rp.js → use-auth-CtM4_BAY.js} +1 -1
  16. package/node_modules/@flickfyi/biscuit/.turbo/turbo-build.log +4 -4
  17. package/node_modules/@flickfyi/core/README.md +19 -9
  18. package/node_modules/@flickfyi/core/dist/chunks/{default-CuxDsQoM.js → default-BTmKidHV.js} +1 -1
  19. package/node_modules/@flickfyi/core/dist/chunks/{default-BB6YexEH.cjs → default-JhTq5I_y.cjs} +1 -1
  20. package/node_modules/@flickfyi/core/dist/chunks/{define-CUJRqVKY.cjs → define-BKCRhpuY.cjs} +1 -1
  21. package/node_modules/@flickfyi/core/dist/chunks/{define-e_VqSs4M.js → define-DZXgUsy7.js} +5 -5
  22. package/node_modules/@flickfyi/core/dist/kowalski/catalog.cjs +1 -1
  23. package/node_modules/@flickfyi/core/dist/kowalski/catalog.js +728 -549
  24. package/node_modules/@flickfyi/core/dist/kowalski/index.cjs +5 -5
  25. package/node_modules/@flickfyi/core/dist/kowalski/index.js +4297 -3700
  26. package/node_modules/@flickfyi/core/dist/kowalski/schemas.cjs +1 -0
  27. package/node_modules/@flickfyi/core/dist/kowalski/schemas.js +637 -0
  28. package/node_modules/@flickfyi/core/dist/kowalski-catalog.css +516 -0
  29. package/node_modules/@flickfyi/core/dist/kowalski.css +10 -0
  30. package/node_modules/@flickfyi/core/dist/themes/athletic/athletic.cjs +1 -1
  31. package/node_modules/@flickfyi/core/dist/themes/athletic/athletic.js +1 -1
  32. package/node_modules/@flickfyi/core/dist/themes/compact/compact.cjs +1 -1
  33. package/node_modules/@flickfyi/core/dist/themes/compact/compact.js +1 -1
  34. package/node_modules/@flickfyi/core/dist/themes/default/default.cjs +1 -1
  35. package/node_modules/@flickfyi/core/dist/themes/default/default.js +1 -1
  36. package/node_modules/@flickfyi/core/dist/themes/editorial/editorial.cjs +1 -1
  37. package/node_modules/@flickfyi/core/dist/themes/editorial/editorial.js +1 -1
  38. package/node_modules/@flickfyi/core/dist/themes/handwritten/handwritten.cjs +1 -1
  39. package/node_modules/@flickfyi/core/dist/themes/handwritten/handwritten.js +1 -1
  40. package/node_modules/@flickfyi/core/dist/themes/index.cjs +1 -1
  41. package/node_modules/@flickfyi/core/dist/themes/index.js +1 -1
  42. package/node_modules/@flickfyi/core/dist/themes/kids/kids.cjs +1 -1
  43. package/node_modules/@flickfyi/core/dist/themes/kids/kids.js +1 -1
  44. package/node_modules/@flickfyi/core/dist/themes/rounded/rounded.cjs +1 -1
  45. package/node_modules/@flickfyi/core/dist/themes/rounded/rounded.js +1 -1
  46. package/node_modules/@flickfyi/core/dist/themes/technical/technical.cjs +1 -1
  47. package/node_modules/@flickfyi/core/dist/themes/technical/technical.js +1 -1
  48. package/node_modules/@flickfyi/core/dist-types/hooks/use-feature-store/index.d.ts +43 -0
  49. package/node_modules/@flickfyi/core/dist-types/kowalski/calculations.d.ts +57 -3
  50. package/node_modules/@flickfyi/core/dist-types/kowalski/calculator.d.ts +7 -6
  51. package/node_modules/@flickfyi/core/dist-types/kowalski/catalog.d.cts +524 -809
  52. package/node_modules/@flickfyi/core/dist-types/kowalski/catalog.d.ts +524 -809
  53. package/node_modules/@flickfyi/core/dist-types/kowalski/components/bill-split.d.ts +38 -0
  54. package/node_modules/@flickfyi/core/dist-types/kowalski/components/bookmark.d.ts +48 -0
  55. package/node_modules/@flickfyi/core/dist-types/kowalski/components/budget.d.ts +39 -0
  56. package/node_modules/@flickfyi/core/dist-types/kowalski/components/calculator.d.ts +62 -0
  57. package/node_modules/@flickfyi/core/dist-types/kowalski/components/checklist.d.ts +35 -0
  58. package/node_modules/@flickfyi/core/dist-types/kowalski/components/color-palette.d.ts +32 -0
  59. package/node_modules/@flickfyi/core/dist-types/kowalski/components/contact.d.ts +41 -0
  60. package/node_modules/@flickfyi/core/dist-types/kowalski/components/countdown.d.ts +34 -0
  61. package/node_modules/@flickfyi/core/dist-types/kowalski/components/event.d.ts +43 -0
  62. package/node_modules/@flickfyi/core/dist-types/kowalski/components/expense.d.ts +40 -0
  63. package/node_modules/@flickfyi/core/dist-types/kowalski/components/goal.d.ts +36 -0
  64. package/node_modules/@flickfyi/core/dist-types/kowalski/components/habit.d.ts +57 -0
  65. package/node_modules/@flickfyi/core/dist-types/kowalski/components/ledger.d.ts +43 -0
  66. package/node_modules/@flickfyi/core/dist-types/kowalski/components/note.d.ts +35 -0
  67. package/node_modules/@flickfyi/core/dist-types/kowalski/components/poll.d.ts +41 -0
  68. package/node_modules/@flickfyi/core/dist-types/kowalski/components/random-picker.d.ts +69 -0
  69. package/node_modules/@flickfyi/core/dist-types/kowalski/components/rating.d.ts +33 -0
  70. package/node_modules/@flickfyi/core/dist-types/kowalski/components/reminder.d.ts +48 -0
  71. package/node_modules/@flickfyi/core/dist-types/kowalski/components/rotation.d.ts +39 -0
  72. package/node_modules/@flickfyi/core/dist-types/kowalski/components/scoreboard.d.ts +37 -0
  73. package/node_modules/@flickfyi/core/dist-types/kowalski/components/shopping-list.d.ts +41 -0
  74. package/node_modules/@flickfyi/core/dist-types/kowalski/components/task-board.d.ts +39 -0
  75. package/node_modules/@flickfyi/core/dist-types/kowalski/components/time-zone.d.ts +34 -0
  76. package/node_modules/@flickfyi/core/dist-types/kowalski/components/timer.d.ts +43 -0
  77. package/node_modules/@flickfyi/core/dist-types/kowalski/components/trip.d.ts +61 -0
  78. package/node_modules/@flickfyi/core/dist-types/kowalski/components/unit-converter.d.ts +106 -0
  79. package/node_modules/@flickfyi/core/dist-types/kowalski/create-schemas.d.ts +6 -0
  80. package/node_modules/@flickfyi/core/dist-types/kowalski/date-time.d.ts +1 -1
  81. package/node_modules/@flickfyi/core/dist-types/kowalski/everyday.d.ts +28 -8
  82. package/node_modules/@flickfyi/core/dist-types/kowalski/feature-schema.d.ts +65 -0
  83. package/node_modules/@flickfyi/core/dist-types/kowalski/format.d.ts +4 -0
  84. package/node_modules/@flickfyi/core/dist-types/kowalski/fortune.d.ts +21 -0
  85. package/node_modules/@flickfyi/core/dist-types/kowalski/frame.d.ts +4 -4
  86. package/node_modules/@flickfyi/core/dist-types/kowalski/index.d.cts +31 -7
  87. package/node_modules/@flickfyi/core/dist-types/kowalski/index.d.ts +31 -7
  88. package/node_modules/@flickfyi/core/dist-types/kowalski/lesson.d.ts +89 -0
  89. package/node_modules/@flickfyi/core/dist-types/kowalski/recipe.d.ts +129 -8
  90. package/node_modules/@flickfyi/core/dist-types/kowalski/schemas.d.cts +4 -0
  91. package/node_modules/@flickfyi/core/dist-types/kowalski/schemas.d.ts +4 -0
  92. package/node_modules/@flickfyi/core/dist-types/kowalski/time-since.d.ts +34 -0
  93. package/node_modules/@flickfyi/core/examples/example-metadata.ts +19 -2
  94. package/node_modules/@flickfyi/core/examples/kowalski/bill-split/bill-split.stories.tsx +25 -6
  95. package/node_modules/@flickfyi/core/examples/kowalski/bill-split/bill-split.tsx +6 -12
  96. package/node_modules/@flickfyi/core/examples/kowalski/bookmark/bookmark.stories.tsx +22 -5
  97. package/node_modules/@flickfyi/core/examples/kowalski/bookmark/bookmark.tsx +6 -18
  98. package/node_modules/@flickfyi/core/examples/kowalski/budget/budget.stories.tsx +26 -5
  99. package/node_modules/@flickfyi/core/examples/kowalski/budget/budget.tsx +6 -21
  100. package/node_modules/@flickfyi/core/examples/kowalski/calculator/calculator.stories.tsx +18 -5
  101. package/node_modules/@flickfyi/core/examples/kowalski/calculator/calculator.tsx +6 -19
  102. package/node_modules/@flickfyi/core/examples/kowalski/checklist/checklist.stories.tsx +25 -5
  103. package/node_modules/@flickfyi/core/examples/kowalski/checklist/checklist.tsx +6 -21
  104. package/node_modules/@flickfyi/core/examples/kowalski/color-palette/color-palette.stories.tsx +19 -6
  105. package/node_modules/@flickfyi/core/examples/kowalski/color-palette/color-palette.tsx +6 -17
  106. package/node_modules/@flickfyi/core/examples/kowalski/contact/contact.stories.tsx +30 -5
  107. package/node_modules/@flickfyi/core/examples/kowalski/contact/contact.tsx +6 -18
  108. package/node_modules/@flickfyi/core/examples/kowalski/countdown/countdown.stories.tsx +22 -5
  109. package/node_modules/@flickfyi/core/examples/kowalski/countdown/countdown.tsx +6 -18
  110. package/node_modules/@flickfyi/core/examples/kowalski/event/event.stories.tsx +23 -5
  111. package/node_modules/@flickfyi/core/examples/kowalski/event/event.tsx +6 -19
  112. package/node_modules/@flickfyi/core/examples/kowalski/expense/expense.stories.tsx +23 -5
  113. package/node_modules/@flickfyi/core/examples/kowalski/expense/expense.tsx +6 -18
  114. package/node_modules/@flickfyi/core/examples/kowalski/fortune/fortune.stories.tsx +61 -0
  115. package/node_modules/@flickfyi/core/examples/kowalski/fortune/fortune.tsx +11 -0
  116. package/node_modules/@flickfyi/core/examples/kowalski/goal/goal.stories.tsx +18 -5
  117. package/node_modules/@flickfyi/core/examples/kowalski/goal/goal.tsx +3 -19
  118. package/node_modules/@flickfyi/core/examples/kowalski/habit/habit.stories.tsx +22 -5
  119. package/node_modules/@flickfyi/core/examples/kowalski/habit/habit.tsx +6 -18
  120. package/node_modules/@flickfyi/core/examples/kowalski/ledger/ledger.stories.tsx +25 -5
  121. package/node_modules/@flickfyi/core/examples/kowalski/ledger/ledger.tsx +6 -20
  122. package/node_modules/@flickfyi/core/examples/kowalski/lesson/lesson.stories.tsx +99 -0
  123. package/node_modules/@flickfyi/core/examples/kowalski/lesson/lesson.tsx +11 -0
  124. package/node_modules/@flickfyi/core/examples/kowalski/note/note.stories.tsx +21 -5
  125. package/node_modules/@flickfyi/core/examples/kowalski/note/note.tsx +3 -17
  126. package/node_modules/@flickfyi/core/examples/kowalski/poll/poll.stories.tsx +26 -5
  127. package/node_modules/@flickfyi/core/examples/kowalski/poll/poll.tsx +3 -21
  128. package/node_modules/@flickfyi/core/examples/kowalski/random-picker/random-picker.stories.tsx +37 -6
  129. package/node_modules/@flickfyi/core/examples/kowalski/random-picker/random-picker.tsx +6 -18
  130. package/node_modules/@flickfyi/core/examples/kowalski/rating/rating.stories.tsx +18 -5
  131. package/node_modules/@flickfyi/core/examples/kowalski/rating/rating.tsx +6 -14
  132. package/node_modules/@flickfyi/core/examples/kowalski/recipe/recipe.stories.tsx +117 -5
  133. package/node_modules/@flickfyi/core/examples/kowalski/recipe/recipe.tsx +6 -115
  134. package/node_modules/@flickfyi/core/examples/kowalski/reminder/reminder.stories.tsx +22 -5
  135. package/node_modules/@flickfyi/core/examples/kowalski/reminder/reminder.tsx +6 -18
  136. package/node_modules/@flickfyi/core/examples/kowalski/rotation/rotation.stories.tsx +26 -5
  137. package/node_modules/@flickfyi/core/examples/kowalski/rotation/rotation.tsx +6 -22
  138. package/node_modules/@flickfyi/core/examples/kowalski/scoreboard/scoreboard.stories.tsx +26 -5
  139. package/node_modules/@flickfyi/core/examples/kowalski/scoreboard/scoreboard.tsx +6 -21
  140. package/node_modules/@flickfyi/core/examples/kowalski/shopping-list/shopping-list.stories.tsx +28 -6
  141. package/node_modules/@flickfyi/core/examples/kowalski/shopping-list/shopping-list.tsx +6 -22
  142. package/node_modules/@flickfyi/core/examples/kowalski/task-board/task-board.stories.tsx +27 -6
  143. package/node_modules/@flickfyi/core/examples/kowalski/task-board/task-board.tsx +6 -22
  144. package/node_modules/@flickfyi/core/examples/kowalski/time-since/time-since.stories.tsx +33 -0
  145. package/node_modules/@flickfyi/core/examples/kowalski/time-since/time-since.tsx +12 -0
  146. package/node_modules/@flickfyi/core/examples/kowalski/time-zone/time-zone.stories.tsx +22 -6
  147. package/node_modules/@flickfyi/core/examples/kowalski/time-zone/time-zone.tsx +6 -17
  148. package/node_modules/@flickfyi/core/examples/kowalski/timer/timer.stories.tsx +18 -5
  149. package/node_modules/@flickfyi/core/examples/kowalski/timer/timer.tsx +6 -18
  150. package/node_modules/@flickfyi/core/examples/kowalski/trip/trip.stories.tsx +25 -5
  151. package/node_modules/@flickfyi/core/examples/kowalski/trip/trip.tsx +3 -21
  152. package/node_modules/@flickfyi/core/examples/kowalski/unit-converter/unit-converter.stories.tsx +19 -6
  153. package/node_modules/@flickfyi/core/examples/kowalski/unit-converter/unit-converter.tsx +6 -19
  154. package/node_modules/@flickfyi/core/examples/parrott/calculator/calculator.stories.tsx +10 -3
  155. package/node_modules/@flickfyi/core/examples/parrott/calculator/calculator.tsx +2 -13
  156. package/node_modules/@flickfyi/core/examples/parrott/checklist/checklist.stories.tsx +10 -3
  157. package/node_modules/@flickfyi/core/examples/parrott/checklist/checklist.tsx +0 -8
  158. package/node_modules/@flickfyi/core/examples/parrott/countdown/countdown.stories.tsx +10 -3
  159. package/node_modules/@flickfyi/core/examples/parrott/countdown/countdown.tsx +0 -8
  160. package/node_modules/@flickfyi/core/examples/parrott/counter/counter.stories.tsx +10 -3
  161. package/node_modules/@flickfyi/core/examples/parrott/counter/counter.tsx +0 -8
  162. package/node_modules/@flickfyi/core/examples/parrott/fortune/fortune.stories.tsx +10 -3
  163. package/node_modules/@flickfyi/core/examples/parrott/fortune/fortune.tsx +0 -8
  164. package/node_modules/@flickfyi/core/examples/parrott/grid/grid.stories.tsx +10 -3
  165. package/node_modules/@flickfyi/core/examples/parrott/grid/grid.tsx +4 -9
  166. package/node_modules/@flickfyi/core/examples/parrott/kale-smoothie/kale-smoothie.stories.tsx +10 -3
  167. package/node_modules/@flickfyi/core/examples/parrott/kale-smoothie/kale-smoothie.tsx +0 -8
  168. package/node_modules/@flickfyi/core/examples/parrott/list/list.stories.tsx +10 -3
  169. package/node_modules/@flickfyi/core/examples/parrott/list/list.tsx +0 -8
  170. package/node_modules/@flickfyi/core/examples/parrott/log/log.stories.tsx +10 -3
  171. package/node_modules/@flickfyi/core/examples/parrott/log/log.tsx +0 -8
  172. package/node_modules/@flickfyi/core/examples/parrott/timed-task/timed-task.stories.tsx +10 -3
  173. package/node_modules/@flickfyi/core/examples/parrott/timed-task/timed-task.tsx +0 -8
  174. package/node_modules/@flickfyi/core/examples/parrott/timer/timer.stories.tsx +10 -3
  175. package/node_modules/@flickfyi/core/examples/parrott/timer/timer.tsx +0 -8
  176. package/node_modules/@flickfyi/core/package.json +16 -3
  177. package/node_modules/@flickfyi/core/src/{kowalski/use-configured-feature.ts → hooks/use-configured-feature/index.ts} +1 -1
  178. package/node_modules/@flickfyi/core/src/{kowalski/use-feature-store.ts → hooks/use-feature-store/index.ts} +37 -12
  179. package/node_modules/@flickfyi/core/src/kowalski/README.md +13 -0
  180. package/node_modules/@flickfyi/core/src/kowalski/calculations.ts +36 -8
  181. package/node_modules/@flickfyi/core/src/kowalski/calculator.ts +15 -7
  182. package/node_modules/@flickfyi/core/src/kowalski/catalog.ts +110 -704
  183. package/node_modules/@flickfyi/core/src/kowalski/components/bill-split.tsx +284 -0
  184. package/node_modules/@flickfyi/core/src/kowalski/components/bookmark.tsx +347 -0
  185. package/node_modules/@flickfyi/core/src/kowalski/components/budget.tsx +169 -0
  186. package/node_modules/@flickfyi/core/src/kowalski/components/calculator.tsx +202 -0
  187. package/node_modules/@flickfyi/core/src/kowalski/components/checklist.tsx +119 -0
  188. package/node_modules/@flickfyi/core/src/kowalski/components/color-palette.tsx +302 -0
  189. package/node_modules/@flickfyi/core/src/kowalski/components/contact.tsx +247 -0
  190. package/node_modules/@flickfyi/core/src/kowalski/components/countdown.tsx +173 -0
  191. package/node_modules/@flickfyi/core/src/kowalski/components/event.tsx +260 -0
  192. package/node_modules/@flickfyi/core/src/kowalski/components/expense.tsx +257 -0
  193. package/node_modules/@flickfyi/core/src/kowalski/components/goal.tsx +182 -0
  194. package/node_modules/@flickfyi/core/src/kowalski/components/habit.tsx +272 -0
  195. package/node_modules/@flickfyi/core/src/kowalski/components/ledger.tsx +211 -0
  196. package/node_modules/@flickfyi/core/src/kowalski/components/note.tsx +188 -0
  197. package/node_modules/@flickfyi/core/src/kowalski/components/poll.tsx +242 -0
  198. package/node_modules/@flickfyi/core/src/kowalski/components/random-picker.tsx +308 -0
  199. package/node_modules/@flickfyi/core/src/kowalski/components/rating.tsx +112 -0
  200. package/node_modules/@flickfyi/core/src/kowalski/components/reminder.tsx +298 -0
  201. package/node_modules/@flickfyi/core/src/kowalski/components/rotation.tsx +146 -0
  202. package/node_modules/@flickfyi/core/src/kowalski/components/scoreboard.tsx +139 -0
  203. package/node_modules/@flickfyi/core/src/kowalski/components/shopping-list.tsx +144 -0
  204. package/node_modules/@flickfyi/core/src/kowalski/components/task-board.tsx +146 -0
  205. package/node_modules/@flickfyi/core/src/kowalski/components/time-zone.tsx +240 -0
  206. package/node_modules/@flickfyi/core/src/kowalski/components/timer.tsx +225 -0
  207. package/node_modules/@flickfyi/core/src/kowalski/components/trip.tsx +338 -0
  208. package/node_modules/@flickfyi/core/src/kowalski/components/unit-converter.tsx +285 -0
  209. package/node_modules/@flickfyi/core/src/kowalski/create-schemas.ts +8 -0
  210. package/node_modules/@flickfyi/core/src/kowalski/date-time.tsx +1 -1
  211. package/node_modules/@flickfyi/core/src/kowalski/everyday.tsx +1 -640
  212. package/node_modules/@flickfyi/core/src/kowalski/feature-schema.ts +84 -0
  213. package/node_modules/@flickfyi/core/src/kowalski/format.ts +29 -3
  214. package/node_modules/@flickfyi/core/src/kowalski/fortune.tsx +67 -0
  215. package/node_modules/@flickfyi/core/src/kowalski/frame.tsx +5 -6
  216. package/node_modules/@flickfyi/core/src/kowalski/index.ts +31 -22
  217. package/node_modules/@flickfyi/core/src/kowalski/lesson.tsx +564 -0
  218. package/node_modules/@flickfyi/core/src/kowalski/recipe.tsx +78 -37
  219. package/node_modules/@flickfyi/core/src/kowalski/schemas.ts +67 -0
  220. package/node_modules/@flickfyi/core/src/kowalski/stories/composition.tsx +22 -20
  221. package/node_modules/@flickfyi/core/src/kowalski/time-since.tsx +145 -0
  222. package/node_modules/@flickfyi/core/src/molecules/progress/progress.tsx +4 -1
  223. package/node_modules/@flickfyi/core/src/oklch.ts +1 -6
  224. package/node_modules/@flickfyi/core/src/parrott/theme.ts +3 -1
  225. package/node_modules/@flickfyi/core/src/themes/editorial/editorial.ts +6 -1
  226. package/node_modules/@flickfyi/core/src/themes/palette.ts +5 -5
  227. package/node_modules/@flickfyi/core/src/themes/stories/composition.tsx +11 -9
  228. package/node_modules/@flickfyi/core/src/themes/stories/gallery.tsx +7 -11
  229. package/node_modules/@flickfyi/core/tsgo.bun.lock +7 -7
  230. package/node_modules/@flickfyi/core/tsgo.package.json +1 -1
  231. package/package.json +2 -2
  232. package/node_modules/@flickfyi/core/dist-types/kowalski/clocks.d.ts +0 -4
  233. package/node_modules/@flickfyi/core/dist-types/kowalski/details.d.ts +0 -7
  234. package/node_modules/@flickfyi/core/dist-types/kowalski/productivity.d.ts +0 -5
  235. package/node_modules/@flickfyi/core/dist-types/kowalski/tools.d.ts +0 -7
  236. package/node_modules/@flickfyi/core/dist-types/kowalski/use-feature-store.d.ts +0 -15
  237. package/node_modules/@flickfyi/core/src/kowalski/clocks.tsx +0 -464
  238. package/node_modules/@flickfyi/core/src/kowalski/details.tsx +0 -1387
  239. package/node_modules/@flickfyi/core/src/kowalski/productivity.tsx +0 -575
  240. package/node_modules/@flickfyi/core/src/kowalski/tools.tsx +0 -1213
  241. /package/node_modules/@flickfyi/core/dist-types/{kowalski/use-clock.d.ts → hooks/use-clock/index.d.ts} +0 -0
  242. /package/node_modules/@flickfyi/core/dist-types/{kowalski/use-configured-feature.d.ts → hooks/use-configured-feature/index.d.ts} +0 -0
  243. /package/node_modules/@flickfyi/core/src/{kowalski/use-clock.ts → hooks/use-clock/index.ts} +0 -0
@@ -7,23 +7,26 @@ import {
7
7
  List,
8
8
  Stepper,
9
9
  } from '@flickfyi/core/molecules'
10
+ import { Recipe as RecipeEntity } from '@flickfyi/schemas/recipe'
10
11
  import * as stylex from '@stylexjs/stylex'
11
12
  import { formatQuantity } from 'format-quantity'
12
13
  import { Duration } from 'luxon'
13
14
  import { useState } from 'react'
15
+ import { z } from 'zod/v4'
14
16
 
17
+ import { useClock } from '~/hooks/use-clock'
18
+ import { useConfiguredFeature } from '~/hooks/use-configured-feature'
19
+ import type { CreateSchemas } from '~/kowalski/create-schemas'
15
20
  import { space } from '~/themes/scale.stylex'
16
21
  import { appearance, button, roles } from '~/themes/shared'
17
22
 
18
- import { kowalskiCatalog, type KowalskiInput, type KowalskiProps } from './catalog'
23
+ import { entries, featureFields } from './feature-schema'
19
24
  import { format } from './format'
20
25
  import { FeatureAction, FeatureFacts, FeatureFrame, FeatureWell, layout } from './frame'
21
- import { useClock } from './use-clock'
22
- import { useConfiguredFeature } from './use-configured-feature'
23
26
 
24
- type RecipeProps = KowalskiProps<'recipe'>
25
- type Ingredient = RecipeProps['ingredients'][number]
26
- type Step = RecipeProps['steps'][number]
27
+ type RecipeContent = z.output<typeof RecipeData>
28
+ type Ingredient = RecipeContent['ingredients'][number]
29
+ type Step = RecipeContent['steps'][number]
27
30
 
28
31
  /**
29
32
  * Cooks an RGF recipe in two modes. The overview is for reading: ingredients, servings, and
@@ -31,39 +34,77 @@ type Step = RecipeProps['steps'][number]
31
34
  * the bottom, or the next timer to go off when nothing is ready; above it, in falling order of
32
35
  * attention, the other running timers, the next few steps (greyed until ready), and what's done.
33
36
  */
34
- export function Recipe(input: KowalskiInput<'recipe'>) {
35
- const props = kowalskiCatalog.recipe.props.parse(input)
36
- const schema = kowalskiCatalog.recipe.storeSchema
37
- const baseServings = props.servings ?? null
37
+ /** Recipe Graph Format: ingredients, step outputs, and explicit dependency edges. */
38
+
39
+ const defaultId = 'KowalskiRecipe'
40
+ const defaultScope = 'private'
41
+
42
+ export const RecipeData = RecipeEntity
43
+ export type RecipeData = RecipeEntity
44
+
45
+ export const RecipeProps = z.strictObject({
46
+ data: RecipeData,
47
+ ...featureFields,
48
+ scope: featureFields.scope.default(defaultScope),
49
+ })
50
+ export type RecipeProps = z.input<typeof RecipeProps> & {
51
+ style?: stylex.StyleXArray<stylex.StyleXStyles>
52
+ }
53
+
54
+ export const recipeStoreSchema = entries(
55
+ 'step_',
56
+ z.strictObject({ done: z.boolean(), endsAt: z.number().nullable() }),
57
+ {
58
+ cooking: z.boolean().default(false),
59
+ servings: z.number().default(1),
60
+ }
61
+ )
62
+
63
+ export const createSchemas: CreateSchemas = ({
64
+ id = defaultId,
65
+ scope = defaultScope,
66
+ } = {}) => ({
67
+ [`stores/${scope}/${id}`]: recipeStoreSchema,
68
+ })
69
+
70
+ export function Recipe({
71
+ data,
72
+ id,
73
+ revision = 0,
74
+ scope = defaultScope,
75
+ style,
76
+ }: RecipeProps) {
77
+ const schema = recipeStoreSchema
78
+ const baseServings = data.servings ?? null
38
79
  const store = useConfiguredFeature({
39
- name: props.id ?? 'KowalskiRecipe',
40
- revision: props.revision,
80
+ name: id ?? defaultId,
81
+ revision,
41
82
  schema,
42
- scope: props.scope,
83
+ scope,
43
84
  seed: schema.parse({ servings: baseServings ?? 1 }),
44
85
  })
45
86
  const [prepOpen, setPrepOpen] = useState(false)
46
87
  const [showEarlier, setShowEarlier] = useState(false)
47
88
  const [showLater, setShowLater] = useState(false)
48
- const graph = recipeGraph(props.steps)
89
+ const graph = recipeGraph(data.steps)
49
90
  const checked = (id: string) => store.value[`step_${id}`]?.done
50
91
  const endsAt = (id: string) => store.value[`step_${id}`]?.endsAt ?? null
51
92
  // The clock runs while any unfinished step has a timer, including one whose time is up.
52
93
  // Timer ends are the key, so starting or extending one refreshes the clock before paint.
53
94
  const now = useClock(
54
- props.steps.some(step => endsAt(step.id) !== null && !checked(step.id)),
55
- props.steps.map(step => endsAt(step.id) ?? '').join(',')
95
+ data.steps.some(step => endsAt(step.id) !== null && !checked(step.id)),
96
+ data.steps.map(step => endsAt(step.id) ?? '').join(',')
56
97
  )
57
98
  const factor = baseServings === null ? 1 : store.value.servings / baseServings
58
99
  const waitingOn = (step: Step) =>
59
100
  (graph.prerequisites.get(step.id) ?? []).filter(id => !checked(id))
60
- const done = props.steps.filter(step => checked(step.id))
101
+ const done = data.steps.filter(step => checked(step.id))
61
102
  const history = showEarlier ? done : done.slice(-1)
62
- const active = props.steps
103
+ const active = data.steps
63
104
  .filter(step => !checked(step.id) && endsAt(step.id) !== null)
64
105
  .toSorted((a, b) => (endsAt(a.id) ?? 0) - (endsAt(b.id) ?? 0))
65
106
  // Ready steps first, longest remaining chain first so long waits start early; then waiting steps in order.
66
- const queue = props.steps
107
+ const queue = data.steps
67
108
  .filter(step => !checked(step.id) && endsAt(step.id) === null)
68
109
  .toSorted(
69
110
  (a, b) =>
@@ -71,7 +112,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
71
112
  (waitingOn(a).length > 0
72
113
  ? 0
73
114
  : (graph.chain.get(b.id) ?? 0) - (graph.chain.get(a.id) ?? 0)) ||
74
- props.steps.indexOf(a) - props.steps.indexOf(b)
115
+ data.steps.indexOf(a) - data.steps.indexOf(b)
75
116
  )
76
117
  const [first, ...rest] = queue
77
118
  const current = first && waitingOn(first).length === 0 ? first : undefined
@@ -93,11 +134,11 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
93
134
  step.doneness ? `Time’s up. Done when ${step.doneness}.` : 'Time’s up'
94
135
  // What a step takes: an ingredient with its scaled amount, or an earlier output by name.
95
136
  const uses = (step: Step) =>
96
- step.uses.map(({ id, portion, source }) => {
137
+ (step.uses ?? []).map(({ id, portion, source }) => {
97
138
  if (source.kind === 'output') {
98
139
  return { id, label: graph.outputs.get(source.outputId) ?? '', value: portion }
99
140
  }
100
- const ingredient = props.ingredients.find(item => item.id === source.ingredientId)
141
+ const ingredient = data.ingredients.find(item => item.id === source.ingredientId)
101
142
  return {
102
143
  id,
103
144
  label: ingredient?.label ?? '',
@@ -108,7 +149,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
108
149
  <>
109
150
  <Field label="Ingredients">
110
151
  <FeatureFacts>
111
- {props.ingredients.map(ingredient => (
152
+ {data.ingredients.map(ingredient => (
112
153
  <List.Item
113
154
  description={ingredient.notes?.join(' · ')}
114
155
  key={ingredient.id}
@@ -123,14 +164,12 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
123
164
  <Stepper
124
165
  decrementDisabled={!store.ready || store.value.servings <= 1}
125
166
  decrementLabel="Fewer servings"
126
- incrementDisabled={!store.ready || store.value.servings >= 100}
167
+ incrementDisabled={!store.ready}
127
168
  incrementLabel="More servings"
128
169
  onDecrement={() =>
129
170
  store.set(current => ({ servings: Math.max(1, current.servings - 1) }))
130
171
  }
131
- onIncrement={() =>
132
- store.set(current => ({ servings: Math.min(100, current.servings + 1) }))
133
- }
172
+ onIncrement={() => store.set(current => ({ servings: current.servings + 1 }))}
134
173
  >
135
174
  <Text {...stylex.props(roles.h2, layout.stepperInput)}>
136
175
  {format.formatNumber(store.value.servings)}
@@ -207,11 +246,12 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
207
246
  if (!store.value.cooking) {
208
247
  return (
209
248
  <FeatureFrame
249
+ style={style}
210
250
  onRetry={store.retry}
211
251
  notice={store.error}
212
252
  component="recipe"
213
- title={props.title}
214
- detail={timeSummary(props.steps, graph)}
253
+ title={data.title}
254
+ detail={timeSummary(data.steps, graph)}
215
255
  >
216
256
  {prep}
217
257
  <FeatureAction
@@ -229,13 +269,14 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
229
269
  }
230
270
  return (
231
271
  <FeatureFrame
272
+ style={style}
232
273
  onRetry={store.retry}
233
274
  notice={store.error}
234
275
  component="recipe"
235
- title={props.title}
276
+ title={data.title}
236
277
  trailing={
237
278
  <Text {...stylex.props(roles.muted)}>
238
- {`${format.formatNumber(done.length)} of ${format.formatNumber(props.steps.length)} done`}
279
+ {`${format.formatNumber(done.length)} of ${format.formatNumber(data.steps.length)} done`}
239
280
  </Text>
240
281
  }
241
282
  >
@@ -248,7 +289,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
248
289
  <Disclosure
249
290
  label={[
250
291
  baseServings === null
251
- ? props.yield
292
+ ? data.yield
252
293
  : format.formatMessage(
253
294
  {
254
295
  defaultMessage: '{count, plural, one {# serving} other {# servings}}',
@@ -262,7 +303,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
262
303
  '{count, plural, one {# ingredient} other {# ingredients}}',
263
304
  id: 'kowalski.recipe.ingredients',
264
305
  },
265
- { count: props.ingredients.length }
306
+ { count: data.ingredients.length }
266
307
  ),
267
308
  ]
268
309
  .filter(Boolean)
@@ -323,7 +364,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
323
364
  {current ? (
324
365
  <>
325
366
  <Text {...stylex.props(roles.h2)}>{current.instruction}</Text>
326
- {current.uses.length > 0 && (
367
+ {(current.uses ?? []).length > 0 && (
327
368
  <List>
328
369
  {uses(current).map(use => (
329
370
  <List.Item key={use.id} label={use.label} trailing={use.value} />
@@ -403,7 +444,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
403
444
  store.set(() => ({
404
445
  cooking: false,
405
446
  ...Object.fromEntries(
406
- props.steps.map(step => [
447
+ data.steps.map(step => [
407
448
  `step_${step.id}`,
408
449
  { done: false, endsAt: null },
409
450
  ])
@@ -439,7 +480,7 @@ function Disclosure({
439
480
  )
440
481
  }
441
482
 
442
- const recipeStyles = stylex.create({
483
+ const recipeStyles = /* @__PURE__ */ stylex.create({
443
484
  disclosure: { alignSelf: 'flex-start', paddingLeft: 0, paddingRight: 0 },
444
485
  row: { alignItems: 'center', columnGap: space[3], flexDirection: 'row' },
445
486
  trailing: { flexShrink: 0 },
@@ -489,7 +530,7 @@ function recipeGraph(steps: Step[]) {
489
530
  [
490
531
  ...new Set([
491
532
  ...(step.after ?? []),
492
- ...step.uses.flatMap(use =>
533
+ ...(step.uses ?? []).flatMap(use =>
493
534
  use.source.kind === 'output' ? [producers.get(use.source.outputId) ?? ''] : []
494
535
  ),
495
536
  ]),
@@ -0,0 +1,67 @@
1
+ // Generated from component createSchemas exports. Do not edit.
2
+ import type { CreateSchemas, CreateSchemasInput } from './create-schemas'
3
+ import { createSchemas as generator0 } from "./components/bill-split"
4
+ import { createSchemas as generator1 } from "./components/bookmark"
5
+ import { createSchemas as generator2 } from "./components/budget"
6
+ import { createSchemas as generator3 } from "./components/calculator"
7
+ import { createSchemas as generator4 } from "./components/checklist"
8
+ import { createSchemas as generator5 } from "./components/color-palette"
9
+ import { createSchemas as generator6 } from "./components/contact"
10
+ import { createSchemas as generator7 } from "./components/countdown"
11
+ import { createSchemas as generator8 } from "./components/event"
12
+ import { createSchemas as generator9 } from "./components/expense"
13
+ import { createSchemas as generator10 } from "./components/goal"
14
+ import { createSchemas as generator11 } from "./components/habit"
15
+ import { createSchemas as generator12 } from "./components/ledger"
16
+ import { createSchemas as generator13 } from "./components/note"
17
+ import { createSchemas as generator14 } from "./components/poll"
18
+ import { createSchemas as generator15 } from "./components/random-picker"
19
+ import { createSchemas as generator16 } from "./components/rating"
20
+ import { createSchemas as generator17 } from "./components/reminder"
21
+ import { createSchemas as generator18 } from "./components/rotation"
22
+ import { createSchemas as generator19 } from "./components/scoreboard"
23
+ import { createSchemas as generator20 } from "./components/shopping-list"
24
+ import { createSchemas as generator21 } from "./components/task-board"
25
+ import { createSchemas as generator22 } from "./components/time-zone"
26
+ import { createSchemas as generator23 } from "./components/timer"
27
+ import { createSchemas as generator24 } from "./components/trip"
28
+ import { createSchemas as generator25 } from "./components/unit-converter"
29
+ import { createSchemas as generator26 } from "./lesson"
30
+ import { createSchemas as generator27 } from "./recipe"
31
+ import { createSchemas as generator28 } from "./time-since"
32
+
33
+ const generators = new Map<string, CreateSchemas>([["BillSplit", generator0],
34
+ ["Bookmark", generator1],
35
+ ["Budget", generator2],
36
+ ["Calculator", generator3],
37
+ ["Checklist", generator4],
38
+ ["ColorPalette", generator5],
39
+ ["Contact", generator6],
40
+ ["Countdown", generator7],
41
+ ["Event", generator8],
42
+ ["Expense", generator9],
43
+ ["Goal", generator10],
44
+ ["Habit", generator11],
45
+ ["Ledger", generator12],
46
+ ["Note", generator13],
47
+ ["Poll", generator14],
48
+ ["RandomPicker", generator15],
49
+ ["Rating", generator16],
50
+ ["Reminder", generator17],
51
+ ["Rotation", generator18],
52
+ ["Scoreboard", generator19],
53
+ ["ShoppingList", generator20],
54
+ ["TaskBoard", generator21],
55
+ ["TimeZone", generator22],
56
+ ["Timer", generator23],
57
+ ["Trip", generator24],
58
+ ["UnitConverter", generator25],
59
+ ["Lesson", generator26],
60
+ ["Recipe", generator27],
61
+ ["TimeSince", generator28]])
62
+ export const schemaComponents = [...generators.keys()]
63
+ export { kowalskiFeatureId, kowalskiScope } from './feature-schema'
64
+
65
+ export function componentSchemas(name: string, input?: CreateSchemasInput) {
66
+ return generators.get(name)?.(input) ?? {}
67
+ }
@@ -21,30 +21,27 @@ export function TrainingComposition({ theme = athletic }: { theme?: CompositionT
21
21
  <Flex {...stylex.props(styles.feature)}>
22
22
  <Goal
23
23
  id="TrackDayLaps"
24
- progress={3}
25
- target={8}
26
- title="Your laps"
27
- unit="laps"
24
+ data={{ progress: 3, target: 8, title: 'Your laps', unit: 'laps' }}
28
25
  />
29
26
  </Flex>
30
27
  <Flex {...stylex.props(styles.feature)}>
31
28
  <Timer
32
- durationSeconds={90}
33
29
  id="TrackDayRecovery"
34
- mode="break"
35
- title="Catch your breath"
30
+ data={{ durationSeconds: 90, mode: 'break', title: 'Catch your breath' }}
36
31
  />
37
32
  </Flex>
38
33
  </Flex>
39
34
  <Flex {...stylex.props(styles.preparation)}>
40
35
  <Checklist
41
36
  id="TrackDayPreparation"
42
- items={[
43
- { id: 'water', label: 'Fill your water bottle' },
44
- { id: 'warmup', label: 'Walk a lap and loosen up' },
45
- { id: 'laces', label: 'Check your laces' },
46
- ]}
47
- title="Before the first lap"
37
+ data={{
38
+ items: [
39
+ { id: 'water', label: 'Fill your water bottle' },
40
+ { id: 'warmup', label: 'Walk a lap and loosen up' },
41
+ { id: 'laces', label: 'Check your laces' },
42
+ ],
43
+ title: 'Before the first lap',
44
+ }}
48
45
  />
49
46
  </Flex>
50
47
  </Flex>
@@ -62,15 +59,20 @@ export function FamilyRoutineComposition({ theme = kids }: { theme?: Composition
62
59
  </Flex>
63
60
  <Checklist
64
61
  id="FamilyRoutineEvening"
65
- items={[
66
- { id: 'toys', label: 'Give every toy a home' },
67
- { id: 'bag', label: 'Pack tomorrow’s bag' },
68
- { id: 'teeth', label: 'Brush those teeth' },
69
- ]}
70
- title="Three small things"
62
+ data={{
63
+ items: [
64
+ { id: 'toys', label: 'Give every toy a home' },
65
+ { id: 'bag', label: 'Pack tomorrow’s bag' },
66
+ { id: 'teeth', label: 'Brush those teeth' },
67
+ ],
68
+ title: 'Three small things',
69
+ }}
71
70
  />
72
71
  <Flex {...stylex.props(styles.preparation)}>
73
- <Timer durationSeconds={600} id="FamilyRoutineStory" title="Time for a story" />
72
+ <Timer
73
+ id="FamilyRoutineStory"
74
+ data={{ durationSeconds: 600, title: 'Time for a story' }}
75
+ />
74
76
  </Flex>
75
77
  </Flex>
76
78
  )
@@ -0,0 +1,145 @@
1
+ import { Flex, Text } from '@flickfyi/core'
2
+ import * as stylex from '@stylexjs/stylex'
3
+ import { DateTime } from 'luxon'
4
+ import { z } from 'zod/v4'
5
+
6
+ import { useClock } from '~/hooks/use-clock'
7
+ import { useConfiguredFeature } from '~/hooks/use-configured-feature'
8
+ import type { CreateSchemas } from '~/kowalski/create-schemas'
9
+ import { space, text } from '~/themes/scale.stylex'
10
+ import { appearance, roles } from '~/themes/shared'
11
+
12
+ import { featureFields, store } from './feature-schema'
13
+ import { format } from './format'
14
+ import { FeatureAction, FeatureFrame, FeatureWell, layout } from './frame'
15
+
16
+ const defaultId = 'KowalskiTimeSince'
17
+ const defaultScope = 'public'
18
+
19
+ export const TimeSinceData = /* @__PURE__ */ z
20
+ .strictObject({
21
+ action: z
22
+ .string()
23
+ .describe(
24
+ 'The big button that updates it, as a short command for doing it now, e.g. "Give pill" or "Water plants".'
25
+ ),
26
+ label: z
27
+ .string()
28
+ .describe(
29
+ 'A small line above the title naming the kind of tracker, e.g. "Pill timer". Pass an empty string to hide it.'
30
+ ),
31
+ subject: z
32
+ .string()
33
+ .describe(
34
+ 'What gets done, as a short noun, e.g. "pill" or "watering". With "pill", the timestamp reads "Last pill today at 5:04 PM".'
35
+ ),
36
+ title: z
37
+ .string()
38
+ .describe(
39
+ 'Who or what is being tracked, shown as the heading, e.g. "Winnie" or "Fern".'
40
+ ),
41
+ })
42
+ .describe(
43
+ 'Four short UI strings for an existing TimeSince React component: a heading, tracker label, event noun, and button command. The component already implements the elapsed clock, reset button, and saved state. Supply concise copy for each field, not explanations, implementation instructions, timestamps, or claims about the timer’s current state.'
44
+ )
45
+ export type TimeSinceData = z.input<typeof TimeSinceData>
46
+
47
+ export const TimeSinceProps = z.strictObject({
48
+ data: TimeSinceData,
49
+ ...featureFields,
50
+ scope: featureFields.scope.default(defaultScope),
51
+ })
52
+ export type TimeSinceProps = z.input<typeof TimeSinceProps> & {
53
+ style?: stylex.StyleXArray<stylex.StyleXStyles>
54
+ }
55
+
56
+ export const timeSinceStoreSchema = store({ lastAt: z.number().nullable().default(null) })
57
+
58
+ export const createSchemas: CreateSchemas = ({
59
+ id = defaultId,
60
+ scope = defaultScope,
61
+ } = {}) => ({
62
+ [`stores/${scope}/${id}`]: timeSinceStoreSchema,
63
+ })
64
+
65
+ export function TimeSince({
66
+ data,
67
+ id = defaultId,
68
+ revision = 0,
69
+ scope = defaultScope,
70
+ style,
71
+ }: TimeSinceProps) {
72
+ const schema = timeSinceStoreSchema
73
+ const store = useConfiguredFeature({
74
+ name: id,
75
+ revision,
76
+ schema,
77
+ scope,
78
+ seed: schema.parse({}),
79
+ })
80
+ const lastAt = store.value.lastAt
81
+ const now = useClock(lastAt !== null, String(lastAt))
82
+ const loading = !store.ready && !store.error
83
+ const since = loading
84
+ ? '—'
85
+ : lastAt === null
86
+ ? 'Not yet'
87
+ : DateTime.fromMillis(lastAt).toRelative({
88
+ base: DateTime.fromMillis(now),
89
+ locale: format.locale,
90
+ })
91
+ return (
92
+ <FeatureFrame
93
+ onRetry={store.retry}
94
+ notice={store.error}
95
+ component="timeSince"
96
+ header={
97
+ <Flex {...stylex.props(layout.header)}>
98
+ {data.label && (
99
+ <Text {...stylex.props(roles.caption, appearance.accent)}>{data.label}</Text>
100
+ )}
101
+ <Text {...stylex.props(roles.h1)}>{data.title}</Text>
102
+ </Flex>
103
+ }
104
+ style={style}
105
+ title={data.title}
106
+ >
107
+ <FeatureWell style={timeSinceStyles.well}>
108
+ <Flex {...stylex.props(timeSinceStyles.reading)}>
109
+ <Text
110
+ animated={lastAt === null ? undefined : 'numeric'}
111
+ {...stylex.props(roles.display, timeSinceStyles.since)}
112
+ >
113
+ {since}
114
+ </Text>
115
+ {lastAt !== null && (
116
+ <Text {...stylex.props(roles.caption)}>
117
+ {`Last ${data.subject} ${DateTime.fromMillis(lastAt).toRelativeCalendar({
118
+ base: DateTime.fromMillis(now),
119
+ locale: format.locale,
120
+ unit: 'days',
121
+ })} at ${format.formatTime(lastAt, { hour: 'numeric', minute: '2-digit' })}`}
122
+ </Text>
123
+ )}
124
+ </Flex>
125
+ <FeatureAction
126
+ component="timeSince"
127
+ disabled={!store.ready}
128
+ onClick={() => store.set(() => ({ lastAt: Date.now() }))}
129
+ size="lg"
130
+ variant="primary"
131
+ >
132
+ {data.action}
133
+ </FeatureAction>
134
+ </FeatureWell>
135
+ {store.saving && <Text {...stylex.props(roles.muted)}>Saving…</Text>}
136
+ </FeatureFrame>
137
+ )
138
+ }
139
+
140
+ const timeSinceStyles = /* @__PURE__ */ stylex.create({
141
+ reading: { alignItems: 'flex-start', gap: space[3] },
142
+ // 60px keeps "59 seconds" on one line of a 393pt-wide phone card; "ago" wraps below.
143
+ since: { fontSize: text['6xl'], lineHeight: text['6xlLeading'] },
144
+ well: { alignItems: 'stretch', gap: space[4] },
145
+ })
@@ -24,7 +24,10 @@ export function Progress({
24
24
  const fill = stylex.props(styles.progressFill, fillStyle)
25
25
  return (
26
26
  <Flex {...stylex.props(styles.progressTrack, style)}>
27
- <Flex {...fill} style={{ ...fill.style, width: spring.width.to(value => `${value}%`) }} />
27
+ <Flex
28
+ {...fill}
29
+ style={{ ...fill.style, width: spring.width.to(value => `${value}%`) }}
30
+ />
28
31
  </Flex>
29
32
  )
30
33
  }
@@ -64,12 +64,7 @@ export function parseOklch(css: string): string {
64
64
  return css
65
65
  }
66
66
  const l = Number(m[1]) / (m[2] === '%' ? 100 : 1)
67
- return oklchToRgba(
68
- l,
69
- Number(m[3]),
70
- Number(m[4]),
71
- m[5] === undefined ? 1 : Number(m[5])
72
- )
67
+ return oklchToRgba(l, Number(m[3]), Number(m[4]), m[5] === undefined ? 1 : Number(m[5]))
73
68
  }
74
69
 
75
70
  /**
@@ -22,7 +22,9 @@ type Foreground = NonNullable<NonNullable<Core.TextProps['style']>['color']>
22
22
 
23
23
  /** Opaque styles accepted by the public StyleX composition API. */
24
24
  export type ParrotStyle = stylex.StyleXArray<
25
- stylex.StyleXStyles | stylex.StyleXStyles<{ color: Foreground }> | ReturnType<typeof stylex.createTheme>
25
+ | stylex.StyleXStyles
26
+ | stylex.StyleXStyles<{ color: Foreground }>
27
+ | ReturnType<typeof stylex.createTheme>
26
28
  >
27
29
 
28
30
  export type ParrotTheme = {
@@ -7,7 +7,12 @@ export const spec = {
7
7
  display: { family: '"Instrument Serif"', step: '6xl', weight: '400' },
8
8
  emphasis: { italic: true, weight: '400' },
9
9
  fonts: { body: 'Newsreader', ui: '"Libre Franklin"', uiWeight: '600' },
10
- heading: { family: '"Instrument Serif"', step: '5xl', tracking: 'tight', weight: '400' },
10
+ heading: {
11
+ family: '"Instrument Serif"',
12
+ step: '5xl',
13
+ tracking: 'tight',
14
+ weight: '400',
15
+ },
11
16
  label: { uppercase: true },
12
17
  radius: 0,
13
18
  stroke: 1,
@@ -186,7 +186,7 @@ const palettes: Record<
186
186
  },
187
187
  }),
188
188
  // Newsprint: the paper drifts warm whatever the hue, which becomes a spot ink.
189
- editorial: hue => {
189
+ editorial(hue) {
190
190
  const paper = toward(hue, 85, 0.8)
191
191
  return {
192
192
  dark: {
@@ -218,7 +218,7 @@ const palettes: Record<
218
218
  }
219
219
  },
220
220
  // A legal pad: cream paper, ballpoint ink and ruled lines in the hue.
221
- handwritten: hue => {
221
+ handwritten(hue) {
222
222
  const paper = toward(hue, 95, 0.85)
223
223
  return {
224
224
  dark: {
@@ -249,7 +249,7 @@ const palettes: Record<
249
249
  }
250
250
  },
251
251
  // Candy pairs: the tray takes the hue's far side, the actions take the hue.
252
- kids: hue => {
252
+ kids(hue) {
253
253
  const pop = turn(hue, 150)
254
254
  return {
255
255
  dark: {
@@ -288,7 +288,7 @@ const palettes: Record<
288
288
  }
289
289
  },
290
290
  // Sherbet: the tray warms 40° past the hue and the page cools 25° below it.
291
- rounded: hue => {
291
+ rounded(hue) {
292
292
  const cool = turn(hue, -25)
293
293
  const warm = turn(hue, 40)
294
294
  return {
@@ -323,7 +323,7 @@ const palettes: Record<
323
323
  }
324
324
  },
325
325
  // A bench instrument: cool steel housing, and the hue lights the display.
326
- technical: hue => {
326
+ technical(hue) {
327
327
  const steel = toward(hue, 250, 0.7)
328
328
  return {
329
329
  dark: {
@@ -1,16 +1,14 @@
1
1
  import { Flex, Text } from '@flickfyi/core'
2
2
  import { Button, Container } from '@flickfyi/core/atoms'
3
- import {
4
- Card,
5
- Choice,
6
- completedTaskStyle,
7
- List,
8
- Stat,
9
- } from '@flickfyi/core/molecules'
3
+ import { Card, Choice, completedTaskStyle, List, Stat } from '@flickfyi/core/molecules'
10
4
  import * as stylex from '@stylexjs/stylex'
11
5
  import { useState } from 'react'
12
6
 
13
- import { previewTheme, type ThemeGlobals, themeSelection } from '~/storybook/theme-fixtures'
7
+ import {
8
+ previewTheme,
9
+ type ThemeGlobals,
10
+ themeSelection,
11
+ } from '~/storybook/theme-fixtures'
14
12
  import { space } from '~/themes/scale.stylex'
15
13
  import { colors, shape } from '~/themes/tokens.stylex'
16
14
 
@@ -261,7 +259,11 @@ export function ThemeComposition({ globals }: { globals: Partial<ThemeGlobals> }
261
259
  checked ? [...items, item] : items.filter(value => value !== item)
262
260
  )
263
261
  }
264
- style={[theme.surface, styles.tile, selected.includes(item) && theme.selected]}
262
+ style={[
263
+ theme.surface,
264
+ styles.tile,
265
+ selected.includes(item) && theme.selected,
266
+ ]}
265
267
  >
266
268
  {item}
267
269
  </Choice>