led-ticker-core 2.0.0__tar.gz

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 (976) hide show
  1. led_ticker_core-2.0.0/.claude/commands/review-docs.md +171 -0
  2. led_ticker_core-2.0.0/.claude/skills/creating-a-config/SKILL.md +202 -0
  3. led_ticker_core-2.0.0/.claude/skills/creating-a-config/references/asset-handling.md +101 -0
  4. led_ticker_core-2.0.0/.claude/skills/creating-a-config/references/decision-rules.md +267 -0
  5. led_ticker_core-2.0.0/.claude/skills/creating-a-config/references/hardware-guide.md +58 -0
  6. led_ticker_core-2.0.0/.claude/skills/creating-a-config/references/snippets.md +683 -0
  7. led_ticker_core-2.0.0/.claude/skills/creating-a-config/references/transition-selection.md +99 -0
  8. led_ticker_core-2.0.0/.claude/skills/creating-a-config/references/widget-selection.md +109 -0
  9. led_ticker_core-2.0.0/.claude/skills/making-a-gif/SKILL.md +57 -0
  10. led_ticker_core-2.0.0/.claude/skills/making-a-gif/examples/example.md +59 -0
  11. led_ticker_core-2.0.0/.dockerignore +32 -0
  12. led_ticker_core-2.0.0/.env.example +13 -0
  13. led_ticker_core-2.0.0/.github/ISSUE_TEMPLATE/submit-sign.yml +62 -0
  14. led_ticker_core-2.0.0/.github/dependabot.yml +57 -0
  15. led_ticker_core-2.0.0/.github/workflows/ci.yml +195 -0
  16. led_ticker_core-2.0.0/.github/workflows/docs-deploy.yml +143 -0
  17. led_ticker_core-2.0.0/.github/workflows/publish.yml +28 -0
  18. led_ticker_core-2.0.0/.gitignore +167 -0
  19. led_ticker_core-2.0.0/.pre-commit-config.yaml +46 -0
  20. led_ticker_core-2.0.0/.python-version +1 -0
  21. led_ticker_core-2.0.0/CLAUDE.md +305 -0
  22. led_ticker_core-2.0.0/CODE_OF_CONDUCT.md +16 -0
  23. led_ticker_core-2.0.0/CONTRIBUTING.md +57 -0
  24. led_ticker_core-2.0.0/Dockerfile +80 -0
  25. led_ticker_core-2.0.0/LICENSE +21 -0
  26. led_ticker_core-2.0.0/Makefile +196 -0
  27. led_ticker_core-2.0.0/PKG-INFO +134 -0
  28. led_ticker_core-2.0.0/README.md +100 -0
  29. led_ticker_core-2.0.0/SECURITY.md +33 -0
  30. led_ticker_core-2.0.0/compose.yaml +62 -0
  31. led_ticker_core-2.0.0/config/assets/.gitkeep +0 -0
  32. led_ticker_core-2.0.0/config/assets/ATTRIBUTION.md +46 -0
  33. led_ticker_core-2.0.0/config/assets/_src/phoenix-cc0-no-bg.gif +0 -0
  34. led_ticker_core-2.0.0/config/assets/heart-tunnel-opaque.jpg +0 -0
  35. led_ticker_core-2.0.0/config/assets/phoenix.gif +0 -0
  36. led_ticker_core-2.0.0/config/assets/phoenix.png +0 -0
  37. led_ticker_core-2.0.0/config/assets/phoenix.webp +0 -0
  38. led_ticker_core-2.0.0/config/assets/phoenix_transparent.gif +0 -0
  39. led_ticker_core-2.0.0/config/assets/phoenix_transparent.png +0 -0
  40. led_ticker_core-2.0.0/config/assets/pride.gif +0 -0
  41. led_ticker_core-2.0.0/config/assets/pride_trans.gif +0 -0
  42. led_ticker_core-2.0.0/config/config.alternating.toml +118 -0
  43. led_ticker_core-2.0.0/config/config.bands_border_test.example.toml +393 -0
  44. led_ticker_core-2.0.0/config/config.baseball.toml +93 -0
  45. led_ticker_core-2.0.0/config/config.bg_color_test.example.toml +166 -0
  46. led_ticker_core-2.0.0/config/config.bigsign.example.toml +226 -0
  47. led_ticker_core-2.0.0/config/config.bigsign.firebird.example.toml +130 -0
  48. led_ticker_core-2.0.0/config/config.busy_longboi.toml +94 -0
  49. led_ticker_core-2.0.0/config/config.busy_smallsign.toml +85 -0
  50. led_ticker_core-2.0.0/config/config.clock_smoketest.toml +147 -0
  51. led_ticker_core-2.0.0/config/config.example.toml +263 -0
  52. led_ticker_core-2.0.0/config/config.firebird.example.toml +387 -0
  53. led_ticker_core-2.0.0/config/config.forever_scroll.toml +180 -0
  54. led_ticker_core-2.0.0/config/config.gif_test.example.toml +480 -0
  55. led_ticker_core-2.0.0/config/config.gif_text.example.toml +255 -0
  56. led_ticker_core-2.0.0/config/config.hires_emoji_test.example.toml +310 -0
  57. led_ticker_core-2.0.0/config/config.hires_fonts_test.example.toml +122 -0
  58. led_ticker_core-2.0.0/config/config.hires_transitions_test.example.toml +301 -0
  59. led_ticker_core-2.0.0/config/config.image_test.example.toml +301 -0
  60. led_ticker_core-2.0.0/config/config.infini_scroll.toml +140 -0
  61. led_ticker_core-2.0.0/config/config.lightbulb_border_test.example.toml +389 -0
  62. led_ticker_core-2.0.0/config/config.longboi.toml +384 -0
  63. led_ticker_core-2.0.0/config/config.mlb.toml +55 -0
  64. led_ticker_core-2.0.0/config/config.mlb_attendance_test.toml +87 -0
  65. led_ticker_core-2.0.0/config/config.mlb_forever.toml +46 -0
  66. led_ticker_core-2.0.0/config/config.mlb_infini.toml +46 -0
  67. led_ticker_core-2.0.0/config/config.mlb_promotions_test.toml +87 -0
  68. led_ticker_core-2.0.0/config/config.mlb_scoreboard_test.toml +114 -0
  69. led_ticker_core-2.0.0/config/config.mlb_standings.toml +76 -0
  70. led_ticker_core-2.0.0/config/config.mlb_statcast_test.toml +87 -0
  71. led_ticker_core-2.0.0/config/config.mlb_two_row_test.toml +151 -0
  72. led_ticker_core-2.0.0/config/config.nyancat.toml +112 -0
  73. led_ticker_core-2.0.0/config/config.pacman.toml +87 -0
  74. led_ticker_core-2.0.0/config/config.pokeball.toml +91 -0
  75. led_ticker_core-2.0.0/config/config.pool_longboi.toml +76 -0
  76. led_ticker_core-2.0.0/config/config.pool_smallsign.toml +61 -0
  77. led_ticker_core-2.0.0/config/config.presentation_test.example.toml +395 -0
  78. led_ticker_core-2.0.0/config/config.rainbow_border_test.example.toml +610 -0
  79. led_ticker_core-2.0.0/config/config.random_transitions.toml +91 -0
  80. led_ticker_core-2.0.0/config/config.sailor_moon.toml +58 -0
  81. led_ticker_core-2.0.0/config/config.scale_smoketest.toml +159 -0
  82. led_ticker_core-2.0.0/config/config.shimmer_test.bigsign.example.toml +382 -0
  83. led_ticker_core-2.0.0/config/config.showroom-bigsign.example.toml +408 -0
  84. led_ticker_core-2.0.0/config/config.small_sign.toml +305 -0
  85. led_ticker_core-2.0.0/config/config.testing.toml +394 -0
  86. led_ticker_core-2.0.0/config/requirements-plugins.example.txt +52 -0
  87. led_ticker_core-2.0.0/deploy/busy-light-camera-watcher.lua +84 -0
  88. led_ticker_core-2.0.0/deploy/install.sh +97 -0
  89. led_ticker_core-2.0.0/deploy/led-ticker-webui.service +36 -0
  90. led_ticker_core-2.0.0/deploy/led-ticker.service +23 -0
  91. led_ticker_core-2.0.0/docs/DOCS-STYLE.md +189 -0
  92. led_ticker_core-2.0.0/docs/RELEASING.md +174 -0
  93. led_ticker_core-2.0.0/docs/content-source/README.md +24 -0
  94. led_ticker_core-2.0.0/docs/content-source/emoji.md +96 -0
  95. led_ticker_core-2.0.0/docs/content-source/transitions/push.md +22 -0
  96. led_ticker_core-2.0.0/docs/content-source/transitions/special.md +19 -0
  97. led_ticker_core-2.0.0/docs/content-source/transitions/sprite.md +39 -0
  98. led_ticker_core-2.0.0/docs/content-source/transitions/wipe.md +20 -0
  99. led_ticker_core-2.0.0/docs/content-source/widgets/clock.md +13 -0
  100. led_ticker_core-2.0.0/docs/content-source/widgets/countdown.md +13 -0
  101. led_ticker_core-2.0.0/docs/content-source/widgets/gif.md +76 -0
  102. led_ticker_core-2.0.0/docs/content-source/widgets/image.md +76 -0
  103. led_ticker_core-2.0.0/docs/content-source/widgets/message.md +14 -0
  104. led_ticker_core-2.0.0/docs/content-source/widgets/mlb.md +50 -0
  105. led_ticker_core-2.0.0/docs/content-source/widgets/mlb_standings.md +27 -0
  106. led_ticker_core-2.0.0/docs/content-source/widgets/pool.md +25 -0
  107. led_ticker_core-2.0.0/docs/content-source/widgets/rss_feed.md +12 -0
  108. led_ticker_core-2.0.0/docs/content-source/widgets/two_row.md +50 -0
  109. led_ticker_core-2.0.0/docs/content-source/widgets/weather.md +17 -0
  110. led_ticker_core-2.0.0/docs/plugin-system.md +226 -0
  111. led_ticker_core-2.0.0/docs/profiles/2026-05-06-presentation-smoke-bigsign.svg +491 -0
  112. led_ticker_core-2.0.0/docs/profiles/README.md +61 -0
  113. led_ticker_core-2.0.0/docs/site/.gitignore +10 -0
  114. led_ticker_core-2.0.0/docs/site/.npmrc +8 -0
  115. led_ticker_core-2.0.0/docs/site/.prettierignore +6 -0
  116. led_ticker_core-2.0.0/docs/site/.prettierrc +12 -0
  117. led_ticker_core-2.0.0/docs/site/README.md +150 -0
  118. led_ticker_core-2.0.0/docs/site/astro.config.mjs +230 -0
  119. led_ticker_core-2.0.0/docs/site/demos/assets-emoji.toml +17 -0
  120. led_ticker_core-2.0.0/docs/site/demos/concepts-animations.toml +21 -0
  121. led_ticker_core-2.0.0/docs/site/demos/concepts-borders.toml +21 -0
  122. led_ticker_core-2.0.0/docs/site/demos/concepts-color-providers.toml +37 -0
  123. led_ticker_core-2.0.0/docs/site/demos/concepts-fonts-bigsign.toml +47 -0
  124. led_ticker_core-2.0.0/docs/site/demos/concepts-fonts.toml +41 -0
  125. led_ticker_core-2.0.0/docs/site/demos/concepts-shimmer-patterns.toml +52 -0
  126. led_ticker_core-2.0.0/docs/site/demos/message-rainbow.toml +17 -0
  127. led_ticker_core-2.0.0/docs/site/demos/transitions-color_flash.toml +62 -0
  128. led_ticker_core-2.0.0/docs/site/demos/transitions-dissolve.toml +29 -0
  129. led_ticker_core-2.0.0/docs/site/demos/transitions-push.toml +97 -0
  130. led_ticker_core-2.0.0/docs/site/demos/transitions-scroll.toml +29 -0
  131. led_ticker_core-2.0.0/docs/site/demos/transitions-split.toml +29 -0
  132. led_ticker_core-2.0.0/docs/site/demos/transitions-wipe.toml +98 -0
  133. led_ticker_core-2.0.0/docs/site/demos/widget-clock.toml +20 -0
  134. led_ticker_core-2.0.0/docs/site/demos/widget-countdown.toml +18 -0
  135. led_ticker_core-2.0.0/docs/site/demos/widget-gif.toml +34 -0
  136. led_ticker_core-2.0.0/docs/site/demos/widget-image.toml +31 -0
  137. led_ticker_core-2.0.0/docs/site/demos-long/fonts/.gitignore +11 -0
  138. led_ticker_core-2.0.0/docs/site/demos-long/sections-forever_scroll.toml +43 -0
  139. led_ticker_core-2.0.0/docs/site/demos-long/sections-infini_scroll.toml +43 -0
  140. led_ticker_core-2.0.0/docs/site/demos-long/sections-swap.toml +44 -0
  141. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-01-setup.toml +92 -0
  142. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-02-first-config.toml +21 -0
  143. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-03a-sections.toml +56 -0
  144. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-03b-multi-widget.toml +73 -0
  145. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-03c-two_row-basic.toml +44 -0
  146. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-03d-two_row-hires.toml +43 -0
  147. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-04a-font.toml +44 -0
  148. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-04b-image.toml +45 -0
  149. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-04c-image-with-text.toml +64 -0
  150. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-05a-transitions.toml +81 -0
  151. led_ticker_core-2.0.0/docs/site/demos-long/tutorial-05b-final.toml +91 -0
  152. led_ticker_core-2.0.0/docs/site/demos-long/widget-mlb.toml +20 -0
  153. led_ticker_core-2.0.0/docs/site/demos-long/widget-pool-two-row.toml +38 -0
  154. led_ticker_core-2.0.0/docs/site/demos-long/widget-pool.toml +24 -0
  155. led_ticker_core-2.0.0/docs/site/demos-long/widget-two_row.toml +41 -0
  156. led_ticker_core-2.0.0/docs/site/demos-pinned/border-bands-candy-cane.toml +25 -0
  157. led_ticker_core-2.0.0/docs/site/demos-pinned/border-bands-rasta.toml +24 -0
  158. led_ticker_core-2.0.0/docs/site/demos-pinned/border-bands-stacked.toml +26 -0
  159. led_ticker_core-2.0.0/docs/site/demos-pinned/border-color_cycle-range.toml +26 -0
  160. led_ticker_core-2.0.0/docs/site/demos-pinned/border-color_cycle.toml +26 -0
  161. led_ticker_core-2.0.0/docs/site/demos-pinned/border-constant.toml +20 -0
  162. led_ticker_core-2.0.0/docs/site/demos-pinned/border-lightbulbs-alternate.toml +21 -0
  163. led_ticker_core-2.0.0/docs/site/demos-pinned/border-lightbulbs-chase.toml +21 -0
  164. led_ticker_core-2.0.0/docs/site/demos-pinned/border-lightbulbs-rainbow.toml +21 -0
  165. led_ticker_core-2.0.0/docs/site/demos-pinned/border-lightbulbs-unison.toml +21 -0
  166. led_ticker_core-2.0.0/docs/site/demos-pinned/border-rainbow-range.toml +26 -0
  167. led_ticker_core-2.0.0/docs/site/demos-pinned/clock-timezone-abbrev.toml +23 -0
  168. led_ticker_core-2.0.0/docs/site/demos-pinned/clock-timezone-offset.toml +23 -0
  169. led_ticker_core-2.0.0/docs/site/demos-pinned/countdown-brand-color.toml +21 -0
  170. led_ticker_core-2.0.0/docs/site/demos-pinned/countdown-rainbow-border.toml +22 -0
  171. led_ticker_core-2.0.0/docs/site/demos-pinned/countdown-rainbow.toml +21 -0
  172. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-scroll_behind.toml +26 -0
  173. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-scroll_over.toml +26 -0
  174. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-silent.toml +22 -0
  175. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-two_row-scroll_through.toml +33 -0
  176. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-two_row-wrap.toml +34 -0
  177. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-two_row.toml +29 -0
  178. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-typewriter-border.toml +27 -0
  179. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-typewriter.toml +26 -0
  180. led_ticker_core-2.0.0/docs/site/demos-pinned/gif-wrap.toml +34 -0
  181. led_ticker_core-2.0.0/docs/site/demos-pinned/image-scroll_behind.toml +26 -0
  182. led_ticker_core-2.0.0/docs/site/demos-pinned/image-scroll_over.toml +26 -0
  183. led_ticker_core-2.0.0/docs/site/demos-pinned/image-static-logo.toml +22 -0
  184. led_ticker_core-2.0.0/docs/site/demos-pinned/image-two_row-scroll_through.toml +33 -0
  185. led_ticker_core-2.0.0/docs/site/demos-pinned/image-two_row-wrap.toml +36 -0
  186. led_ticker_core-2.0.0/docs/site/demos-pinned/image-two_row.toml +28 -0
  187. led_ticker_core-2.0.0/docs/site/demos-pinned/image-typewriter-border.toml +30 -0
  188. led_ticker_core-2.0.0/docs/site/demos-pinned/image-typewriter.toml +29 -0
  189. led_ticker_core-2.0.0/docs/site/demos-pinned/image-wrap.toml +32 -0
  190. led_ticker_core-2.0.0/docs/site/demos-pinned/message-brand-color.toml +25 -0
  191. led_ticker_core-2.0.0/docs/site/demos-pinned/message-gradient.toml +20 -0
  192. led_ticker_core-2.0.0/docs/site/demos-pinned/message-hires-grand-opening.toml +27 -0
  193. led_ticker_core-2.0.0/docs/site/demos-pinned/message-inline-emoji.toml +23 -0
  194. led_ticker_core-2.0.0/docs/site/demos-pinned/message-typewriter-rainbow.toml +26 -0
  195. led_ticker_core-2.0.0/docs/site/demos-pinned/message-yellow-bg.toml +21 -0
  196. led_ticker_core-2.0.0/docs/site/demos-pinned/two_row-asymmetric.toml +30 -0
  197. led_ticker_core-2.0.0/docs/site/demos-pinned/two_row-bottom_text_loops.toml +34 -0
  198. led_ticker_core-2.0.0/docs/site/demos-pinned/two_row-brand-handle.toml +27 -0
  199. led_ticker_core-2.0.0/docs/site/demos-pinned/two_row-font-hierarchy.toml +28 -0
  200. led_ticker_core-2.0.0/docs/site/demos-pinned/two_row-hires-emoji.toml +42 -0
  201. led_ticker_core-2.0.0/docs/site/demos-pinned/two_row-scroll_through.toml +29 -0
  202. led_ticker_core-2.0.0/docs/site/demos-pinned/two_row-wrap.toml +30 -0
  203. led_ticker_core-2.0.0/docs/site/package.json +33 -0
  204. led_ticker_core-2.0.0/docs/site/pnpm-lock.yaml +5540 -0
  205. led_ticker_core-2.0.0/docs/site/pnpm-workspace.yaml +4 -0
  206. led_ticker_core-2.0.0/docs/site/public/.gitkeep +0 -0
  207. led_ticker_core-2.0.0/docs/site/public/demos/assets-emoji.gif +0 -0
  208. led_ticker_core-2.0.0/docs/site/public/demos/concepts-animations.gif +0 -0
  209. led_ticker_core-2.0.0/docs/site/public/demos/concepts-borders.gif +0 -0
  210. led_ticker_core-2.0.0/docs/site/public/demos/concepts-color-providers.gif +0 -0
  211. led_ticker_core-2.0.0/docs/site/public/demos/concepts-fonts-bigsign.gif +0 -0
  212. led_ticker_core-2.0.0/docs/site/public/demos/concepts-fonts.gif +0 -0
  213. led_ticker_core-2.0.0/docs/site/public/demos/concepts-shimmer-patterns.gif +0 -0
  214. led_ticker_core-2.0.0/docs/site/public/demos/message-rainbow.gif +0 -0
  215. led_ticker_core-2.0.0/docs/site/public/demos/transitions-color_flash.gif +0 -0
  216. led_ticker_core-2.0.0/docs/site/public/demos/transitions-dissolve.gif +0 -0
  217. led_ticker_core-2.0.0/docs/site/public/demos/transitions-push.gif +0 -0
  218. led_ticker_core-2.0.0/docs/site/public/demos/transitions-scroll.gif +0 -0
  219. led_ticker_core-2.0.0/docs/site/public/demos/transitions-split.gif +0 -0
  220. led_ticker_core-2.0.0/docs/site/public/demos/transitions-wipe.gif +0 -0
  221. led_ticker_core-2.0.0/docs/site/public/demos/widget-clock.gif +0 -0
  222. led_ticker_core-2.0.0/docs/site/public/demos/widget-countdown.gif +0 -0
  223. led_ticker_core-2.0.0/docs/site/public/demos/widget-example-counter.gif +0 -0
  224. led_ticker_core-2.0.0/docs/site/public/demos/widget-gif.gif +0 -0
  225. led_ticker_core-2.0.0/docs/site/public/demos/widget-image.gif +0 -0
  226. led_ticker_core-2.0.0/docs/site/public/demos-long/sections-forever_scroll.gif +0 -0
  227. led_ticker_core-2.0.0/docs/site/public/demos-long/sections-infini_scroll.gif +0 -0
  228. led_ticker_core-2.0.0/docs/site/public/demos-long/sections-swap.gif +0 -0
  229. led_ticker_core-2.0.0/docs/site/public/demos-long/transitions-nyancat.gif +0 -0
  230. led_ticker_core-2.0.0/docs/site/public/demos-long/transitions-pacman.gif +0 -0
  231. led_ticker_core-2.0.0/docs/site/public/demos-long/transitions-pokeball.gif +0 -0
  232. led_ticker_core-2.0.0/docs/site/public/demos-long/transitions-pokeball_modes.gif +0 -0
  233. led_ticker_core-2.0.0/docs/site/public/demos-long/transitions-sailor_moon.gif +0 -0
  234. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-01-setup.gif +0 -0
  235. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-02-first-config.gif +0 -0
  236. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-03a-sections.gif +0 -0
  237. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-03b-multi-widget.gif +0 -0
  238. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-03c-two_row-basic.gif +0 -0
  239. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-03d-two_row-hires.gif +0 -0
  240. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-04a-font.gif +0 -0
  241. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-04b-image.gif +0 -0
  242. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-04c-image-with-text.gif +0 -0
  243. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-05a-transitions.gif +0 -0
  244. led_ticker_core-2.0.0/docs/site/public/demos-long/tutorial-05b-final.gif +0 -0
  245. led_ticker_core-2.0.0/docs/site/public/demos-long/widget-crypto-coingecko.gif +0 -0
  246. led_ticker_core-2.0.0/docs/site/public/demos-long/widget-mlb.gif +0 -0
  247. led_ticker_core-2.0.0/docs/site/public/demos-long/widget-pool-two-row.gif +0 -0
  248. led_ticker_core-2.0.0/docs/site/public/demos-long/widget-pool.gif +0 -0
  249. led_ticker_core-2.0.0/docs/site/public/demos-long/widget-rss_feed.gif +0 -0
  250. led_ticker_core-2.0.0/docs/site/public/demos-long/widget-two_row.gif +0 -0
  251. led_ticker_core-2.0.0/docs/site/public/demos-long/widget-weather.gif +0 -0
  252. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-bands-candy-cane.gif +0 -0
  253. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-bands-rasta.gif +0 -0
  254. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-bands-stacked.gif +0 -0
  255. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-color_cycle-range.gif +0 -0
  256. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-color_cycle.gif +0 -0
  257. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-constant.gif +0 -0
  258. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-lightbulbs-alternate.gif +0 -0
  259. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-lightbulbs-chase.gif +0 -0
  260. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-lightbulbs-rainbow.gif +0 -0
  261. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-lightbulbs-unison.gif +0 -0
  262. led_ticker_core-2.0.0/docs/site/public/demos-pinned/border-rainbow-range.gif +0 -0
  263. led_ticker_core-2.0.0/docs/site/public/demos-pinned/clock-timezone-abbrev.gif +0 -0
  264. led_ticker_core-2.0.0/docs/site/public/demos-pinned/clock-timezone-offset.gif +0 -0
  265. led_ticker_core-2.0.0/docs/site/public/demos-pinned/countdown-brand-color.gif +0 -0
  266. led_ticker_core-2.0.0/docs/site/public/demos-pinned/countdown-rainbow-border.gif +0 -0
  267. led_ticker_core-2.0.0/docs/site/public/demos-pinned/countdown-rainbow.gif +0 -0
  268. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-scroll_behind.gif +0 -0
  269. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-scroll_over.gif +0 -0
  270. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-silent.gif +0 -0
  271. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-two_row-scroll_through.gif +0 -0
  272. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-two_row-wrap.gif +0 -0
  273. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-two_row.gif +0 -0
  274. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-typewriter-border.gif +0 -0
  275. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-typewriter.gif +0 -0
  276. led_ticker_core-2.0.0/docs/site/public/demos-pinned/gif-wrap.gif +0 -0
  277. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-scroll_behind.gif +0 -0
  278. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-scroll_over.gif +0 -0
  279. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-static-logo.gif +0 -0
  280. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-two_row-scroll_through.gif +0 -0
  281. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-two_row-wrap.gif +0 -0
  282. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-two_row.gif +0 -0
  283. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-typewriter-border.gif +0 -0
  284. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-typewriter.gif +0 -0
  285. led_ticker_core-2.0.0/docs/site/public/demos-pinned/image-wrap.gif +0 -0
  286. led_ticker_core-2.0.0/docs/site/public/demos-pinned/message-brand-color.gif +0 -0
  287. led_ticker_core-2.0.0/docs/site/public/demos-pinned/message-gradient.gif +0 -0
  288. led_ticker_core-2.0.0/docs/site/public/demos-pinned/message-hires-grand-opening.gif +0 -0
  289. led_ticker_core-2.0.0/docs/site/public/demos-pinned/message-inline-emoji.gif +0 -0
  290. led_ticker_core-2.0.0/docs/site/public/demos-pinned/message-typewriter-rainbow.gif +0 -0
  291. led_ticker_core-2.0.0/docs/site/public/demos-pinned/message-yellow-bg.gif +0 -0
  292. led_ticker_core-2.0.0/docs/site/public/demos-pinned/two_row-asymmetric.gif +0 -0
  293. led_ticker_core-2.0.0/docs/site/public/demos-pinned/two_row-bottom_text_loops.gif +0 -0
  294. led_ticker_core-2.0.0/docs/site/public/demos-pinned/two_row-brand-handle.gif +0 -0
  295. led_ticker_core-2.0.0/docs/site/public/demos-pinned/two_row-font-hierarchy.gif +0 -0
  296. led_ticker_core-2.0.0/docs/site/public/demos-pinned/two_row-hires-emoji.gif +0 -0
  297. led_ticker_core-2.0.0/docs/site/public/demos-pinned/two_row-scroll_through.gif +0 -0
  298. led_ticker_core-2.0.0/docs/site/public/demos-pinned/two_row-wrap.gif +0 -0
  299. led_ticker_core-2.0.0/docs/site/public/emoji/bunny-hi.png +0 -0
  300. led_ticker_core-2.0.0/docs/site/public/emoji/bunny-low.png +0 -0
  301. led_ticker_core-2.0.0/docs/site/public/emoji/cat-hi.png +0 -0
  302. led_ticker_core-2.0.0/docs/site/public/emoji/cat-low.png +0 -0
  303. led_ticker_core-2.0.0/docs/site/public/emoji/cat_black-hi.png +0 -0
  304. led_ticker_core-2.0.0/docs/site/public/emoji/cat_black-low.png +0 -0
  305. led_ticker_core-2.0.0/docs/site/public/emoji/cat_brown-hi.png +0 -0
  306. led_ticker_core-2.0.0/docs/site/public/emoji/cat_brown-low.png +0 -0
  307. led_ticker_core-2.0.0/docs/site/public/emoji/cat_cream-hi.png +0 -0
  308. led_ticker_core-2.0.0/docs/site/public/emoji/cat_cream-low.png +0 -0
  309. led_ticker_core-2.0.0/docs/site/public/emoji/cat_gray-hi.png +0 -0
  310. led_ticker_core-2.0.0/docs/site/public/emoji/cat_gray-low.png +0 -0
  311. led_ticker_core-2.0.0/docs/site/public/emoji/cat_orange-hi.png +0 -0
  312. led_ticker_core-2.0.0/docs/site/public/emoji/cat_orange-low.png +0 -0
  313. led_ticker_core-2.0.0/docs/site/public/emoji/cat_white-hi.png +0 -0
  314. led_ticker_core-2.0.0/docs/site/public/emoji/cat_white-low.png +0 -0
  315. led_ticker_core-2.0.0/docs/site/public/emoji/cloud-hi.png +0 -0
  316. led_ticker_core-2.0.0/docs/site/public/emoji/cloud-low.png +0 -0
  317. led_ticker_core-2.0.0/docs/site/public/emoji/droplet-hi.png +0 -0
  318. led_ticker_core-2.0.0/docs/site/public/emoji/droplet-low.png +0 -0
  319. led_ticker_core-2.0.0/docs/site/public/emoji/email-hi.png +0 -0
  320. led_ticker_core-2.0.0/docs/site/public/emoji/email-low.png +0 -0
  321. led_ticker_core-2.0.0/docs/site/public/emoji/flower-hi.png +0 -0
  322. led_ticker_core-2.0.0/docs/site/public/emoji/flower-low.png +0 -0
  323. led_ticker_core-2.0.0/docs/site/public/emoji/fog-hi.png +0 -0
  324. led_ticker_core-2.0.0/docs/site/public/emoji/fog-low.png +0 -0
  325. led_ticker_core-2.0.0/docs/site/public/emoji/heart-hi.png +0 -0
  326. led_ticker_core-2.0.0/docs/site/public/emoji/heart-low.png +0 -0
  327. led_ticker_core-2.0.0/docs/site/public/emoji/heart_blue-hi.png +0 -0
  328. led_ticker_core-2.0.0/docs/site/public/emoji/heart_blue-low.png +0 -0
  329. led_ticker_core-2.0.0/docs/site/public/emoji/heart_green-hi.png +0 -0
  330. led_ticker_core-2.0.0/docs/site/public/emoji/heart_green-low.png +0 -0
  331. led_ticker_core-2.0.0/docs/site/public/emoji/heart_orange-hi.png +0 -0
  332. led_ticker_core-2.0.0/docs/site/public/emoji/heart_orange-low.png +0 -0
  333. led_ticker_core-2.0.0/docs/site/public/emoji/heart_pink-hi.png +0 -0
  334. led_ticker_core-2.0.0/docs/site/public/emoji/heart_pink-low.png +0 -0
  335. led_ticker_core-2.0.0/docs/site/public/emoji/heart_purple-hi.png +0 -0
  336. led_ticker_core-2.0.0/docs/site/public/emoji/heart_purple-low.png +0 -0
  337. led_ticker_core-2.0.0/docs/site/public/emoji/heart_red-hi.png +0 -0
  338. led_ticker_core-2.0.0/docs/site/public/emoji/heart_red-low.png +0 -0
  339. led_ticker_core-2.0.0/docs/site/public/emoji/heart_yellow-hi.png +0 -0
  340. led_ticker_core-2.0.0/docs/site/public/emoji/heart_yellow-low.png +0 -0
  341. led_ticker_core-2.0.0/docs/site/public/emoji/instagram-hi.png +0 -0
  342. led_ticker_core-2.0.0/docs/site/public/emoji/instagram-low.png +0 -0
  343. led_ticker_core-2.0.0/docs/site/public/emoji/moon-hi.png +0 -0
  344. led_ticker_core-2.0.0/docs/site/public/emoji/moon-low.png +0 -0
  345. led_ticker_core-2.0.0/docs/site/public/emoji/partly_cloudy-hi.png +0 -0
  346. led_ticker_core-2.0.0/docs/site/public/emoji/partly_cloudy-low.png +0 -0
  347. led_ticker_core-2.0.0/docs/site/public/emoji/pride-hi.png +0 -0
  348. led_ticker_core-2.0.0/docs/site/public/emoji/pride-low.png +0 -0
  349. led_ticker_core-2.0.0/docs/site/public/emoji/pride_ace-hi.png +0 -0
  350. led_ticker_core-2.0.0/docs/site/public/emoji/pride_ace-low.png +0 -0
  351. led_ticker_core-2.0.0/docs/site/public/emoji/pride_bi-hi.png +0 -0
  352. led_ticker_core-2.0.0/docs/site/public/emoji/pride_bi-low.png +0 -0
  353. led_ticker_core-2.0.0/docs/site/public/emoji/pride_demi-hi.png +0 -0
  354. led_ticker_core-2.0.0/docs/site/public/emoji/pride_demi-low.png +0 -0
  355. led_ticker_core-2.0.0/docs/site/public/emoji/pride_lesbian-hi.png +0 -0
  356. led_ticker_core-2.0.0/docs/site/public/emoji/pride_lesbian-low.png +0 -0
  357. led_ticker_core-2.0.0/docs/site/public/emoji/pride_nb-hi.png +0 -0
  358. led_ticker_core-2.0.0/docs/site/public/emoji/pride_nb-low.png +0 -0
  359. led_ticker_core-2.0.0/docs/site/public/emoji/pride_rainbow-hi.png +0 -0
  360. led_ticker_core-2.0.0/docs/site/public/emoji/pride_rainbow-low.png +0 -0
  361. led_ticker_core-2.0.0/docs/site/public/emoji/pride_trans-hi.png +0 -0
  362. led_ticker_core-2.0.0/docs/site/public/emoji/pride_trans-low.png +0 -0
  363. led_ticker_core-2.0.0/docs/site/public/emoji/rain-hi.png +0 -0
  364. led_ticker_core-2.0.0/docs/site/public/emoji/rain-low.png +0 -0
  365. led_ticker_core-2.0.0/docs/site/public/emoji/snow-hi.png +0 -0
  366. led_ticker_core-2.0.0/docs/site/public/emoji/snow-low.png +0 -0
  367. led_ticker_core-2.0.0/docs/site/public/emoji/star-hi.png +0 -0
  368. led_ticker_core-2.0.0/docs/site/public/emoji/star-low.png +0 -0
  369. led_ticker_core-2.0.0/docs/site/public/emoji/star_blue-hi.png +0 -0
  370. led_ticker_core-2.0.0/docs/site/public/emoji/star_blue-low.png +0 -0
  371. led_ticker_core-2.0.0/docs/site/public/emoji/star_green-hi.png +0 -0
  372. led_ticker_core-2.0.0/docs/site/public/emoji/star_green-low.png +0 -0
  373. led_ticker_core-2.0.0/docs/site/public/emoji/star_orange-hi.png +0 -0
  374. led_ticker_core-2.0.0/docs/site/public/emoji/star_orange-low.png +0 -0
  375. led_ticker_core-2.0.0/docs/site/public/emoji/star_pink-hi.png +0 -0
  376. led_ticker_core-2.0.0/docs/site/public/emoji/star_pink-low.png +0 -0
  377. led_ticker_core-2.0.0/docs/site/public/emoji/star_purple-hi.png +0 -0
  378. led_ticker_core-2.0.0/docs/site/public/emoji/star_purple-low.png +0 -0
  379. led_ticker_core-2.0.0/docs/site/public/emoji/star_red-hi.png +0 -0
  380. led_ticker_core-2.0.0/docs/site/public/emoji/star_red-low.png +0 -0
  381. led_ticker_core-2.0.0/docs/site/public/emoji/star_yellow-hi.png +0 -0
  382. led_ticker_core-2.0.0/docs/site/public/emoji/star_yellow-low.png +0 -0
  383. led_ticker_core-2.0.0/docs/site/public/emoji/sun-hi.png +0 -0
  384. led_ticker_core-2.0.0/docs/site/public/emoji/sun-low.png +0 -0
  385. led_ticker_core-2.0.0/docs/site/public/emoji/taco-hi.png +0 -0
  386. led_ticker_core-2.0.0/docs/site/public/emoji/taco-low.png +0 -0
  387. led_ticker_core-2.0.0/docs/site/public/emoji/thunder-hi.png +0 -0
  388. led_ticker_core-2.0.0/docs/site/public/emoji/thunder-low.png +0 -0
  389. led_ticker_core-2.0.0/docs/site/public/showcase/firebird/placeholder.svg +5 -0
  390. led_ticker_core-2.0.0/docs/site/scripts/build-demos.mjs +96 -0
  391. led_ticker_core-2.0.0/docs/site/scripts/check-pnpm.mjs +52 -0
  392. led_ticker_core-2.0.0/docs/site/src/components/DemoGif.astro +34 -0
  393. led_ticker_core-2.0.0/docs/site/src/components/OptionsTable.astro +63 -0
  394. led_ticker_core-2.0.0/docs/site/src/components/PluginCatalog.astro +131 -0
  395. led_ticker_core-2.0.0/docs/site/src/components/RelatedPages.astro +39 -0
  396. led_ticker_core-2.0.0/docs/site/src/components/SiteTitle.astro +74 -0
  397. led_ticker_core-2.0.0/docs/site/src/components/TomlExample.astro +26 -0
  398. led_ticker_core-2.0.0/docs/site/src/components/TutorialNav.astro +66 -0
  399. led_ticker_core-2.0.0/docs/site/src/content/docs/assets/emoji.mdx +26 -0
  400. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/animations.mdx +81 -0
  401. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/borders.mdx +407 -0
  402. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/busy-light.mdx +148 -0
  403. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/color-providers.mdx +219 -0
  404. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/display.mdx +162 -0
  405. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/fonts.mdx +98 -0
  406. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/hot-reload.mdx +83 -0
  407. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/how-rendering-works.mdx +69 -0
  408. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/sections-and-modes.mdx +202 -0
  409. led_ticker_core-2.0.0/docs/site/src/content/docs/concepts/web-status-ui.mdx +248 -0
  410. led_ticker_core-2.0.0/docs/site/src/content/docs/getting-started.mdx +104 -0
  411. led_ticker_core-2.0.0/docs/site/src/content/docs/hardware/bigsign.mdx +306 -0
  412. led_ticker_core-2.0.0/docs/site/src/content/docs/hardware/building-your-own.mdx +189 -0
  413. led_ticker_core-2.0.0/docs/site/src/content/docs/hardware/longboi.mdx +111 -0
  414. led_ticker_core-2.0.0/docs/site/src/content/docs/hardware/smallsign.mdx +249 -0
  415. led_ticker_core-2.0.0/docs/site/src/content/docs/index.mdx +107 -0
  416. led_ticker_core-2.0.0/docs/site/src/content/docs/pitfalls.mdx +212 -0
  417. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/api-reference.mdx +213 -0
  418. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/authoring/01-scaffold.mdx +106 -0
  419. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/authoring/02-widget.mdx +239 -0
  420. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/authoring/03-package.mdx +147 -0
  421. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/authoring/04-beyond-widgets.mdx +105 -0
  422. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/available.mdx +85 -0
  423. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/extending/custom-color-provider.mdx +151 -0
  424. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/extending/custom-emoji.mdx +205 -0
  425. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/extending/service-plugins.mdx +185 -0
  426. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/extending/writing-a-transition.mdx +278 -0
  427. led_ticker_core-2.0.0/docs/site/src/content/docs/plugins/index.mdx +72 -0
  428. led_ticker_core-2.0.0/docs/site/src/content/docs/reference/cli.mdx +210 -0
  429. led_ticker_core-2.0.0/docs/site/src/content/docs/reference/config-options.mdx +213 -0
  430. led_ticker_core-2.0.0/docs/site/src/content/docs/reference/frame-counters.mdx +56 -0
  431. led_ticker_core-2.0.0/docs/site/src/content/docs/showcase.mdx +52 -0
  432. led_ticker_core-2.0.0/docs/site/src/content/docs/tools/creating-a-config.mdx +74 -0
  433. led_ticker_core-2.0.0/docs/site/src/content/docs/tools/gif-plan.mdx +54 -0
  434. led_ticker_core-2.0.0/docs/site/src/content/docs/tools/panel-test.mdx +81 -0
  435. led_ticker_core-2.0.0/docs/site/src/content/docs/tools/render-demo.mdx +112 -0
  436. led_ticker_core-2.0.0/docs/site/src/content/docs/tools/validate.mdx +214 -0
  437. led_ticker_core-2.0.0/docs/site/src/content/docs/transitions/index.mdx +69 -0
  438. led_ticker_core-2.0.0/docs/site/src/content/docs/transitions/push.mdx +21 -0
  439. led_ticker_core-2.0.0/docs/site/src/content/docs/transitions/special.mdx +36 -0
  440. led_ticker_core-2.0.0/docs/site/src/content/docs/transitions/sprite.mdx +67 -0
  441. led_ticker_core-2.0.0/docs/site/src/content/docs/transitions/wipe.mdx +29 -0
  442. led_ticker_core-2.0.0/docs/site/src/content/docs/tutorial/01-setup.mdx +117 -0
  443. led_ticker_core-2.0.0/docs/site/src/content/docs/tutorial/02-first-config.mdx +220 -0
  444. led_ticker_core-2.0.0/docs/site/src/content/docs/tutorial/03-multi-widget.mdx +395 -0
  445. led_ticker_core-2.0.0/docs/site/src/content/docs/tutorial/04-custom-branding.mdx +329 -0
  446. led_ticker_core-2.0.0/docs/site/src/content/docs/tutorial/05-polish.mdx +342 -0
  447. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/calendar.mdx +11 -0
  448. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/clock.mdx +198 -0
  449. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/countdown.mdx +86 -0
  450. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/crypto-coingecko.mdx +25 -0
  451. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/gif.mdx +275 -0
  452. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/image.mdx +269 -0
  453. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/index.mdx +48 -0
  454. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/message.mdx +123 -0
  455. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/mlb.mdx +11 -0
  456. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/mlb_standings.mdx +11 -0
  457. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/pool.mdx +11 -0
  458. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/rss_feed.mdx +18 -0
  459. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/two_row.mdx +238 -0
  460. led_ticker_core-2.0.0/docs/site/src/content/docs/widgets/weather.mdx +18 -0
  461. led_ticker_core-2.0.0/docs/site/src/content.config.ts +7 -0
  462. led_ticker_core-2.0.0/docs/site/src/styles/sidebar-toggle.css +62 -0
  463. led_ticker_core-2.0.0/docs/site/tsconfig.json +5 -0
  464. led_ticker_core-2.0.0/docs/superpowers/investigations/2026-06-21-inline-value-tokens.md +87 -0
  465. led_ticker_core-2.0.0/docs/superpowers/plans/2026-04-29-pi5-bigsign-port.md +1607 -0
  466. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-01-gif-widget-review-findings.md +176 -0
  467. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-01-gif-widget-review.md +192 -0
  468. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-01-gif-widget.md +1200 -0
  469. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-02-background-colors.md +1661 -0
  470. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-02-still-image-rereview-findings.md +109 -0
  471. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-02-still-image-review-findings.md +195 -0
  472. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-02-still-image-review.md +201 -0
  473. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-03-hires-fonts.md +1550 -0
  474. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-03-hires-transitions.md +1336 -0
  475. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-04-font-size-unification.md +2026 -0
  476. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-05-codereview-followups.md +353 -0
  477. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-05-presentation-rework.md +2917 -0
  478. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-05-weather-hires-emoji.md +754 -0
  479. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-06-border-followups.md +253 -0
  480. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-06-end-of-scroll-hold-tick.md +185 -0
  481. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-06-end-of-scroll-snap-fix.md +133 -0
  482. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-06-frame-advance-audit.md +356 -0
  483. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-06-hires-partly-cloudy.md +213 -0
  484. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-06-rainbow-border.md +175 -0
  485. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-06-transition-incoming-reset.md +147 -0
  486. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-07-config-validator.md +1108 -0
  487. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-07-creating-a-config-skill.md +1084 -0
  488. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-07-image-borders.md +1499 -0
  489. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-07-image-typewriter.md +772 -0
  490. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-07-per-effect-counters.md +1192 -0
  491. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-07-visit-reset.md +920 -0
  492. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-08-docs-site-infrastructure.md +2204 -0
  493. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-09-demo-gifs-refresh.md +911 -0
  494. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-09-docs-panel-review-fixes.md +1218 -0
  495. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-09-docs-site-content-b1.md +1310 -0
  496. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-09-docs-site-content-b2.md +531 -0
  497. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-09-docs-site-content-b3.md +692 -0
  498. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-09-pnpm-and-pr-only-builds.md +465 -0
  499. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-09-renderer-static-frame-fix.md +614 -0
  500. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-10-docs-site-feedback.md +1290 -0
  501. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-10-row-layout-hires-emoji-centering.md +575 -0
  502. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-11-colors-module-refactor.md +1024 -0
  503. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-11-maybe-wrap-content-height.md +403 -0
  504. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-11-tutorial.md +783 -0
  505. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-13-bottom-text-wrap.md +2587 -0
  506. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-13-forever-scroll-separator.md +873 -0
  507. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-13-hires-circle-separator.md +819 -0
  508. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-13-image-text-wrap.md +1451 -0
  509. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-13-per-section-start-hold.md +728 -0
  510. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-14-bottom-text-loops.md +680 -0
  511. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-14-docs-canonicalization.md +120 -0
  512. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-14-gif-loops-zero.md +296 -0
  513. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-14-unify-hold-time-scroll-through.md +147 -0
  514. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-14-validator-hardening.md +147 -0
  515. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-15-making-a-gif-skill.md +2153 -0
  516. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-18-slim-gif-plan.md +743 -0
  517. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-19-config-coerce-and-warn.md +1808 -0
  518. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-20-batch-1-correctness.md +762 -0
  519. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-20-batch-2-polish.md +631 -0
  520. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-20-batch-3-extension-surface-safety.md +742 -0
  521. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-21-batch-4-config-ux-error-quality.md +822 -0
  522. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-21-batch-5-allowlist-schema-export.md +709 -0
  523. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-21-batch-6-performance-hardening.md +702 -0
  524. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-21-batch-7-widget-contract-hardening.md +613 -0
  525. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-21-batch-8-gap-closure-and-docs.md +634 -0
  526. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-22-large-1-app-split.md +963 -0
  527. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-22-large-5-validate-strict.md +866 -0
  528. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-23-large-2-and-4-ticker-methods.md +1294 -0
  529. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-23-large-3-scaled-canvas-encapsulation.md +640 -0
  530. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-ci-hardening.md +333 -0
  531. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-config-ux-dx-pass.md +1038 -0
  532. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-deep-review-2.md +558 -0
  533. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-dep-hygiene.md +640 -0
  534. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-deploy-security.md +381 -0
  535. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-engine-run-loop.md +704 -0
  536. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-large-build-widget-decomp.md +664 -0
  537. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-post-large-build-widget-review.md +76 -0
  538. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-python-idioms.md +490 -0
  539. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-scaled-canvas-setpixel-perf-findings.md +88 -0
  540. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-shimmer-color-provider.md +919 -0
  541. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-24-test-infra.md +748 -0
  542. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-26-framerate-fraction.md +481 -0
  543. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-26-hold-time-unification.md +578 -0
  544. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-26-lightbulb-border.md +1556 -0
  545. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-26-mlb-scoreboard-layout.md +1125 -0
  546. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-26-mlb-scoreboard-small-font-hires.md +659 -0
  547. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-26-panel-color-test.md +661 -0
  548. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-26-transition-fps.md +771 -0
  549. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-27-display-config-rename-rpi-alignment.md +380 -0
  550. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-27-hardware-panel-tuning-guide.md +439 -0
  551. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-27-longboi-hardware-doc.md +208 -0
  552. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-27-mlb-abs-challenges-live-feed.md +426 -0
  553. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-27-pool-monitor-widget.md +928 -0
  554. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-28-live-container-refresh.md +1116 -0
  555. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-28-mlb-two-row-layout.md +1470 -0
  556. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-28-pool-two-row-layout.md +1441 -0
  557. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-28-rainbow-lightbulbs.md +761 -0
  558. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-29-busy-light-http-trigger.md +866 -0
  559. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-29-busy-light-overlay.md +580 -0
  560. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-29-emoji-scale-anchor.md +464 -0
  561. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-30-docs-mdx-gfm-tables.md +116 -0
  562. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-30-python-314-upgrade.md +501 -0
  563. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-31-plugin-system-phase-b.md +511 -0
  564. led_ticker_core-2.0.0/docs/superpowers/plans/2026-05-31-plugin-system.md +898 -0
  565. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-01-plugin-system-phase-c.md +807 -0
  566. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-02-plugin-system-phase-d.md +786 -0
  567. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-02-plugin-system-phase-e.md +977 -0
  568. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-03-plugin-docs-phase6.md +502 -0
  569. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-03-plugin-requirements-file.md +360 -0
  570. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-03-plugin-system-polish.md +1001 -0
  571. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-03-pool-plugin-extraction.md +516 -0
  572. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-04-docs-home-page.md +231 -0
  573. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-04-docs-style-guide.md +268 -0
  574. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-04-plugin-authoring-guide.md +691 -0
  575. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-05-docs-audit-sweep.md +154 -0
  576. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-05-extending-custom-color-provider.md +396 -0
  577. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-05-extending-custom-emoji.md +547 -0
  578. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-05-extending-service-plugins.md +439 -0
  579. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-05-extending-writing-a-transition.md +480 -0
  580. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-05-how-rendering-works.md +184 -0
  581. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-05-plugin-api-reference.md +557 -0
  582. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-baseball-plugin-extraction.md +753 -0
  583. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-collapsible-sidebar-toggle.md +365 -0
  584. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-docs-d1-omit-legacy-framing.md +106 -0
  585. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-docs-d2-polish.md +94 -0
  586. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-docs-fix-batch-abc.md +148 -0
  587. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-skill-migrate-asset-handling.md +43 -0
  588. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-skill-migrate-decision-rules.md +69 -0
  589. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-skill-migrate-hardware.md +28 -0
  590. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-skill-migrate-transitions.md +62 -0
  591. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-06-skill-migrate-widgets.md +59 -0
  592. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-07-plugin-surface-hardening.md +262 -0
  593. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-10-crypto-cleanup-coingecko-extraction.md +820 -0
  594. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-10-web-status-ui.md +1992 -0
  595. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-11-bands-border.md +848 -0
  596. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-11-coingecko-followups.md +135 -0
  597. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-11-webui-v1.1.md +892 -0
  598. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-12-live-preview.md +1243 -0
  599. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-12-rp1-pio-rename.md +512 -0
  600. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-13-calendar-widget.md +1430 -0
  601. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-13-clock-widget.md +556 -0
  602. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-13-overlay-state-webui.md +531 -0
  603. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-15-catalog-schema-v3.md +815 -0
  604. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-15-hires-transition-plugin-api.md +418 -0
  605. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-15-plugin-surface-extraction-readiness.md +410 -0
  606. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-15-plugin-unknown-name-hints.md +667 -0
  607. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-16-calendar-extraction-phase1-validation-warnings.md +531 -0
  608. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-16-calendar-extraction-phase3-core-removal.md +272 -0
  609. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-16-calendar-extraction-phase4-docs-site.md +234 -0
  610. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-18-pokeball-core-removal.md +223 -0
  611. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-19-monorepo-p3a-engine-cutover.md +500 -0
  612. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-19-monorepo-p3b-docs-site.md +179 -0
  613. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-20-config-hot-reload.md +1206 -0
  614. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-20-display-scheduling.md +1068 -0
  615. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-20-docs-catalog-render.md +441 -0
  616. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-20-widget-circuit-breaker.md +688 -0
  617. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-21-finish-gate1-anonymization.md +453 -0
  618. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-21-firebird-anonymization.md +418 -0
  619. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-21-firebird-asset-sweep.md +434 -0
  620. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-21-secrets-to-env.md +348 -0
  621. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-21-transition-circuit-breaker.md +521 -0
  622. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-21-web-config-editor.md +526 -0
  623. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-22-pypi-trusted-publishing.md +676 -0
  624. led_ticker_core-2.0.0/docs/superpowers/plans/2026-06-22-startup-config-validation.md +455 -0
  625. led_ticker_core-2.0.0/docs/superpowers/reviews/2026-05-20-engine-review.md +248 -0
  626. led_ticker_core-2.0.0/docs/superpowers/specs/2026-04-29-pi5-bigsign-port-design.md +275 -0
  627. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-01-gif-widget-design.md +175 -0
  628. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-02-background-colors-design.md +163 -0
  629. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-03-hires-fonts-design.md +329 -0
  630. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-03-hires-transitions-design.md +259 -0
  631. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-04-font-size-unification-design.md +282 -0
  632. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-05-presentation-rework-design.md +523 -0
  633. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-06-incoming-bg-transition-design.md +243 -0
  634. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-06-tworow-border-design.md +198 -0
  635. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-07-config-validator-design.md +192 -0
  636. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-07-creating-a-config-skill-design.md +315 -0
  637. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-07-image-borders-design.md +305 -0
  638. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-07-image-typewriter-design.md +272 -0
  639. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-07-per-effect-counters-design.md +290 -0
  640. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-07-visit-reset-design.md +249 -0
  641. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-07-wipe-push-random-transitions-design.md +132 -0
  642. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-08-docs-site-design.md +393 -0
  643. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-11-maybe-wrap-content-height-design.md +59 -0
  644. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-11-tutorial-design.md +310 -0
  645. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-13-bottom-text-wrap-design.md +216 -0
  646. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-13-forever-scroll-separator-design.md +221 -0
  647. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-13-hires-circle-separator-design.md +254 -0
  648. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-13-per-section-start-hold-design.md +166 -0
  649. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-14-bottom-text-loops-design.md +184 -0
  650. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-14-docs-canonicalization-design.md +81 -0
  651. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-14-gif-loops-zero-design.md +148 -0
  652. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-14-unify-hold-time-scroll-through-design.md +82 -0
  653. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-14-validator-hardening-design.md +150 -0
  654. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-15-making-a-gif-skill-design.md +258 -0
  655. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-18-gif-plan-reduction-design.md +151 -0
  656. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-19-config-coerce-and-warn-design.md +126 -0
  657. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-24-config-ux-dx-pass-design.md +183 -0
  658. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-24-deep-review-2-design.md +115 -0
  659. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-25-plugin-system-design.md +213 -0
  660. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-26-framerate-fraction-design.md +185 -0
  661. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-26-hold-time-unification-design.md +102 -0
  662. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-26-lightbulb-border-design.md +216 -0
  663. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-26-mlb-scoreboard-layout-design.md +230 -0
  664. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-26-panel-color-test-design.md +179 -0
  665. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-26-transition-fps-design.md +246 -0
  666. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-27-longboi-hardware-doc-design.md +116 -0
  667. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-27-pool-monitor-widget-design.md +247 -0
  668. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-28-mlb-two-row-layout-design.md +209 -0
  669. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-28-pool-two-row-layout-design.md +264 -0
  670. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-28-rainbow-lightbulbs-design.md +160 -0
  671. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-29-busy-light-http-trigger-design.md +214 -0
  672. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-29-busy-light-overlay-design.md +237 -0
  673. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-29-emoji-scale-anchor-design.md +185 -0
  674. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-30-docs-mdx-gfm-tables-design.md +170 -0
  675. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-30-python-314-upgrade-design.md +132 -0
  676. led_ticker_core-2.0.0/docs/superpowers/specs/2026-05-31-plugin-system-design.md +432 -0
  677. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-03-plugin-docs-phase6-design.md +150 -0
  678. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-03-plugin-requirements-file-design.md +189 -0
  679. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-04-docs-home-page-design.md +127 -0
  680. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-04-docs-style-guide-design.md +103 -0
  681. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-04-plugin-authoring-guide-design.md +63 -0
  682. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-05-docs-audit-sweep-design.md +77 -0
  683. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-05-extending-custom-color-provider-design.md +79 -0
  684. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-05-extending-custom-emoji-design.md +107 -0
  685. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-05-extending-service-plugins-design.md +83 -0
  686. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-05-extending-writing-a-transition-design.md +81 -0
  687. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-05-how-rendering-works-design.md +88 -0
  688. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-05-plugin-api-reference-design.md +113 -0
  689. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-baseball-plugin-extraction-design.md +270 -0
  690. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-collapsible-sidebar-toggle-design.md +84 -0
  691. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-docs-audit-findings.md +163 -0
  692. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-docs-d1-omit-legacy-framing-design.md +71 -0
  693. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-docs-d2-polish-design.md +68 -0
  694. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-docs-fix-batch-abc-design.md +82 -0
  695. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-skill-migrate-asset-handling-design.md +40 -0
  696. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-skill-migrate-decision-rules-design.md +53 -0
  697. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-skill-migrate-hardware-design.md +36 -0
  698. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-skill-migrate-transitions-design.md +61 -0
  699. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-06-skill-migrate-widgets-design.md +52 -0
  700. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-07-plugin-surface-hardening-design.md +84 -0
  701. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-10-crypto-cleanup-coingecko-extraction-design.md +177 -0
  702. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-10-web-status-ui-design.md +182 -0
  703. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-11-bands-border-design.md +182 -0
  704. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-11-webui-v1.1-design.md +173 -0
  705. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-12-live-preview-design.md +170 -0
  706. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-13-calendar-widget-design.md +257 -0
  707. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-13-clock-widget-design.md +181 -0
  708. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-13-overlay-state-webui-design.md +215 -0
  709. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-14-calendar-hardening-retrospective.md +88 -0
  710. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-calendar-ics-error-handling.md +111 -0
  711. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-calendar-two-row-layout.md +155 -0
  712. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-calendar-two-tone-colors.md +107 -0
  713. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-catalog-schema-v3-design.md +256 -0
  714. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-hires-transition-plugin-api-design.md +114 -0
  715. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-plugin-catalog-cli.md +195 -0
  716. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-plugin-manifest-management.md +132 -0
  717. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-plugin-surface-extraction-readiness-design.md +130 -0
  718. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-15-plugin-unknown-name-hints-design.md +170 -0
  719. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-16-calendar-extraction-design.md +254 -0
  720. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-18-pokeball-core-removal-design.md +149 -0
  721. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-20-config-hot-reload-design.md +450 -0
  722. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-20-display-scheduling-design.md +312 -0
  723. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-20-docs-catalog-render-design.md +179 -0
  724. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-20-widget-circuit-breaker-design.md +214 -0
  725. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-21-finish-gate1-anonymization-design.md +155 -0
  726. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-21-firebird-anonymization-design.md +147 -0
  727. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-21-firebird-asset-sweep-design.md +139 -0
  728. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-21-secrets-to-env-design.md +59 -0
  729. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-21-transition-circuit-breaker-design.md +236 -0
  730. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-21-web-config-editor-design.md +77 -0
  731. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-22-cc0-heart-tunnel-design.md +123 -0
  732. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-22-pypi-trusted-publishing-design.md +147 -0
  733. led_ticker_core-2.0.0/docs/superpowers/specs/2026-06-22-startup-config-validation-design.md +95 -0
  734. led_ticker_core-2.0.0/docs/superpowers/walkthroughs/2026-05-07-creating-a-config-new-store-window.md +753 -0
  735. led_ticker_core-2.0.0/docs/superpowers/walkthroughs/2026-05-08-creating-a-config-add-section.md +245 -0
  736. led_ticker_core-2.0.0/docs/superpowers/walkthroughs/2026-05-08-creating-a-config-refine.md +307 -0
  737. led_ticker_core-2.0.0/examples/plugins/README.md +14 -0
  738. led_ticker_core-2.0.0/examples/plugins/acme/__init__.py +133 -0
  739. led_ticker_core-2.0.0/examples/plugins/acme/fonts/Brand.ttf +0 -0
  740. led_ticker_core-2.0.0/examples/plugins/example/__init__.py +63 -0
  741. led_ticker_core-2.0.0/examples/plugins/example_colorprovider/__init__.py +35 -0
  742. led_ticker_core-2.0.0/examples/plugins/example_emoji/__init__.py +46 -0
  743. led_ticker_core-2.0.0/examples/plugins/example_service/__init__.py +43 -0
  744. led_ticker_core-2.0.0/examples/plugins/example_transition/__init__.py +49 -0
  745. led_ticker_core-2.0.0/pyproject.toml +77 -0
  746. led_ticker_core-2.0.0/scripts/check-no-foreign-lockfiles.sh +17 -0
  747. led_ticker_core-2.0.0/scripts/check_release_version.py +35 -0
  748. led_ticker_core-2.0.0/scripts/panel_color_test.py +96 -0
  749. led_ticker_core-2.0.0/src/led_ticker/__init__.py +3 -0
  750. led_ticker_core-2.0.0/src/led_ticker/_coerce.py +125 -0
  751. led_ticker_core-2.0.0/src/led_ticker/_compat.py +42 -0
  752. led_ticker_core-2.0.0/src/led_ticker/_plugin_hint.py +37 -0
  753. led_ticker_core-2.0.0/src/led_ticker/_plugin_loader.py +393 -0
  754. led_ticker_core-2.0.0/src/led_ticker/_rgbmatrix_stub.py +132 -0
  755. led_ticker_core-2.0.0/src/led_ticker/_types.py +41 -0
  756. led_ticker_core-2.0.0/src/led_ticker/animations.py +80 -0
  757. led_ticker_core-2.0.0/src/led_ticker/app/__init__.py +83 -0
  758. led_ticker_core-2.0.0/src/led_ticker/app/cli.py +477 -0
  759. led_ticker_core-2.0.0/src/led_ticker/app/coercion.py +800 -0
  760. led_ticker_core-2.0.0/src/led_ticker/app/factories.py +1318 -0
  761. led_ticker_core-2.0.0/src/led_ticker/app/plugin_cmd.py +633 -0
  762. led_ticker_core-2.0.0/src/led_ticker/app/run.py +890 -0
  763. led_ticker_core-2.0.0/src/led_ticker/borders.py +679 -0
  764. led_ticker_core-2.0.0/src/led_ticker/busy_http.py +84 -0
  765. led_ticker_core-2.0.0/src/led_ticker/busy_light.py +87 -0
  766. led_ticker_core-2.0.0/src/led_ticker/color_lut.py +40 -0
  767. led_ticker_core-2.0.0/src/led_ticker/color_providers.py +281 -0
  768. led_ticker_core-2.0.0/src/led_ticker/colors.py +81 -0
  769. led_ticker_core-2.0.0/src/led_ticker/config.py +693 -0
  770. led_ticker_core-2.0.0/src/led_ticker/drawing.py +214 -0
  771. led_ticker_core-2.0.0/src/led_ticker/fonts/5x8.bdf +21422 -0
  772. led_ticker_core-2.0.0/src/led_ticker/fonts/6x10.bdf +31042 -0
  773. led_ticker_core-2.0.0/src/led_ticker/fonts/6x12.bdf +86121 -0
  774. led_ticker_core-2.0.0/src/led_ticker/fonts/7x13.bdf +64553 -0
  775. led_ticker_core-2.0.0/src/led_ticker/fonts/__init__.py +227 -0
  776. led_ticker_core-2.0.0/src/led_ticker/fonts/bdf_parser.py +124 -0
  777. led_ticker_core-2.0.0/src/led_ticker/fonts/hires/Inter-Bold.otf +0 -0
  778. led_ticker_core-2.0.0/src/led_ticker/fonts/hires/Inter-Regular.otf +0 -0
  779. led_ticker_core-2.0.0/src/led_ticker/fonts/hires_loader.py +268 -0
  780. led_ticker_core-2.0.0/src/led_ticker/frame.py +146 -0
  781. led_ticker_core-2.0.0/src/led_ticker/pixel_emoji.py +2904 -0
  782. led_ticker_core-2.0.0/src/led_ticker/plugin.py +427 -0
  783. led_ticker_core-2.0.0/src/led_ticker/plugins_catalog.json +112 -0
  784. led_ticker_core-2.0.0/src/led_ticker/plugins_catalog.py +257 -0
  785. led_ticker_core-2.0.0/src/led_ticker/preview.py +263 -0
  786. led_ticker_core-2.0.0/src/led_ticker/reload.py +140 -0
  787. led_ticker_core-2.0.0/src/led_ticker/render_breaker.py +99 -0
  788. led_ticker_core-2.0.0/src/led_ticker/scaled_canvas.py +178 -0
  789. led_ticker_core-2.0.0/src/led_ticker/schedule.py +172 -0
  790. led_ticker_core-2.0.0/src/led_ticker/status_board.py +354 -0
  791. led_ticker_core-2.0.0/src/led_ticker/text_render.py +189 -0
  792. led_ticker_core-2.0.0/src/led_ticker/ticker.py +1279 -0
  793. led_ticker_core-2.0.0/src/led_ticker/transitions/__init__.py +416 -0
  794. led_ticker_core-2.0.0/src/led_ticker/transitions/_hires_loader.py +305 -0
  795. led_ticker_core-2.0.0/src/led_ticker/transitions/effects.py +217 -0
  796. led_ticker_core-2.0.0/src/led_ticker/transitions/push.py +271 -0
  797. led_ticker_core-2.0.0/src/led_ticker/transitions/wipe.py +240 -0
  798. led_ticker_core-2.0.0/src/led_ticker/validate.py +2120 -0
  799. led_ticker_core-2.0.0/src/led_ticker/webui/__init__.py +415 -0
  800. led_ticker_core-2.0.0/src/led_ticker/webui/_paths.py +45 -0
  801. led_ticker_core-2.0.0/src/led_ticker/webui/inventory.py +80 -0
  802. led_ticker_core-2.0.0/src/led_ticker/webui/redact.py +88 -0
  803. led_ticker_core-2.0.0/src/led_ticker/webui/static/index.html +596 -0
  804. led_ticker_core-2.0.0/src/led_ticker/widget.py +177 -0
  805. led_ticker_core-2.0.0/src/led_ticker/widgets/__init__.py +46 -0
  806. led_ticker_core-2.0.0/src/led_ticker/widgets/_frame_aware.py +156 -0
  807. led_ticker_core-2.0.0/src/led_ticker/widgets/_gif_decode.py +82 -0
  808. led_ticker_core-2.0.0/src/led_ticker/widgets/_image_base.py +1691 -0
  809. led_ticker_core-2.0.0/src/led_ticker/widgets/_image_fit.py +202 -0
  810. led_ticker_core-2.0.0/src/led_ticker/widgets/_row_layout.py +119 -0
  811. led_ticker_core-2.0.0/src/led_ticker/widgets/clock.py +172 -0
  812. led_ticker_core-2.0.0/src/led_ticker/widgets/gif.py +346 -0
  813. led_ticker_core-2.0.0/src/led_ticker/widgets/message.py +383 -0
  814. led_ticker_core-2.0.0/src/led_ticker/widgets/still.py +313 -0
  815. led_ticker_core-2.0.0/src/led_ticker/widgets/two_row.py +641 -0
  816. led_ticker_core-2.0.0/src/led_ticker/widgets/weather_icons.py +262 -0
  817. led_ticker_core-2.0.0/tests/conftest.py +160 -0
  818. led_ticker_core-2.0.0/tests/fixtures/broken-bigsign-config.toml +165 -0
  819. led_ticker_core-2.0.0/tests/golden/list_fields/countdown.txt +18 -0
  820. led_ticker_core-2.0.0/tests/golden/list_fields/gif.txt +49 -0
  821. led_ticker_core-2.0.0/tests/golden/list_fields/message.txt +19 -0
  822. led_ticker_core-2.0.0/tests/golden/list_fields/two_row.txt +41 -0
  823. led_ticker_core-2.0.0/tests/stubs/rgbmatrix/__init__.py +153 -0
  824. led_ticker_core-2.0.0/tests/stubs/rgbmatrix/graphics.py +12 -0
  825. led_ticker_core-2.0.0/tests/test_animations.py +63 -0
  826. led_ticker_core-2.0.0/tests/test_app.py +3220 -0
  827. led_ticker_core-2.0.0/tests/test_app_random_color.py +23 -0
  828. led_ticker_core-2.0.0/tests/test_app_runtime_warnings.py +80 -0
  829. led_ticker_core-2.0.0/tests/test_app_submodule_imports.py +86 -0
  830. led_ticker_core-2.0.0/tests/test_bdf_parser.py +140 -0
  831. led_ticker_core-2.0.0/tests/test_border_surface_drift.py +224 -0
  832. led_ticker_core-2.0.0/tests/test_borders.py +1536 -0
  833. led_ticker_core-2.0.0/tests/test_busy_http.py +208 -0
  834. led_ticker_core-2.0.0/tests/test_busy_light.py +197 -0
  835. led_ticker_core-2.0.0/tests/test_check_release_version.py +46 -0
  836. led_ticker_core-2.0.0/tests/test_coerce.py +130 -0
  837. led_ticker_core-2.0.0/tests/test_coercion_plugin_hint.py +63 -0
  838. led_ticker_core-2.0.0/tests/test_color_providers.py +434 -0
  839. led_ticker_core-2.0.0/tests/test_colors.py +97 -0
  840. led_ticker_core-2.0.0/tests/test_compat.py +45 -0
  841. led_ticker_core-2.0.0/tests/test_config.py +1109 -0
  842. led_ticker_core-2.0.0/tests/test_config_schedule.py +91 -0
  843. led_ticker_core-2.0.0/tests/test_container_refresh.py +243 -0
  844. led_ticker_core-2.0.0/tests/test_demo_config_keys.py +51 -0
  845. led_ticker_core-2.0.0/tests/test_dispatch_drift.py +33 -0
  846. led_ticker_core-2.0.0/tests/test_docs_available_covers_catalog.py +52 -0
  847. led_ticker_core-2.0.0/tests/test_docs_borders_demo_drift.py +75 -0
  848. led_ticker_core-2.0.0/tests/test_docs_config_options_drift.py +337 -0
  849. led_ticker_core-2.0.0/tests/test_docs_plugin_api_drift.py +121 -0
  850. led_ticker_core-2.0.0/tests/test_drawing.py +445 -0
  851. led_ticker_core-2.0.0/tests/test_engine_redraw_contract.py +283 -0
  852. led_ticker_core-2.0.0/tests/test_factories_small_font.py +27 -0
  853. led_ticker_core-2.0.0/tests/test_fonts.py +107 -0
  854. led_ticker_core-2.0.0/tests/test_frame.py +246 -0
  855. led_ticker_core-2.0.0/tests/test_frame_aware.py +350 -0
  856. led_ticker_core-2.0.0/tests/test_gif_path_resolution.py +161 -0
  857. led_ticker_core-2.0.0/tests/test_hires_font_loader.py +531 -0
  858. led_ticker_core-2.0.0/tests/test_hires_loader.py +556 -0
  859. led_ticker_core-2.0.0/tests/test_list_fields_golden.py +26 -0
  860. led_ticker_core-2.0.0/tests/test_no_real_brand.py +261 -0
  861. led_ticker_core-2.0.0/tests/test_phoenix_assets.py +109 -0
  862. led_ticker_core-2.0.0/tests/test_pixel_emoji.py +1609 -0
  863. led_ticker_core-2.0.0/tests/test_plugin_hint.py +35 -0
  864. led_ticker_core-2.0.0/tests/test_plugin_hint_followups.py +29 -0
  865. led_ticker_core-2.0.0/tests/test_plugin_requirements.py +78 -0
  866. led_ticker_core-2.0.0/tests/test_plugin_surface.py +75 -0
  867. led_ticker_core-2.0.0/tests/test_plugin_surface_p3.py +42 -0
  868. led_ticker_core-2.0.0/tests/test_plugin_validation_warnings.py +214 -0
  869. led_ticker_core-2.0.0/tests/test_plugins/__init__.py +0 -0
  870. led_ticker_core-2.0.0/tests/test_plugins/test_acme_plugin.py +153 -0
  871. led_ticker_core-2.0.0/tests/test_plugins/test_animation_plugins.py +117 -0
  872. led_ticker_core-2.0.0/tests/test_plugins/test_border_plugins.py +164 -0
  873. led_ticker_core-2.0.0/tests/test_plugins/test_catalog.py +396 -0
  874. led_ticker_core-2.0.0/tests/test_plugins/test_cli_plugins.py +165 -0
  875. led_ticker_core-2.0.0/tests/test_plugins/test_coerce_color_provider.py +32 -0
  876. led_ticker_core-2.0.0/tests/test_plugins/test_container_surface.py +77 -0
  877. led_ticker_core-2.0.0/tests/test_plugins/test_easing_plugins.py +53 -0
  878. led_ticker_core-2.0.0/tests/test_plugins/test_emoji_plugins.py +288 -0
  879. led_ticker_core-2.0.0/tests/test_plugins/test_example_colorprovider_plugin.py +53 -0
  880. led_ticker_core-2.0.0/tests/test_plugins/test_example_emoji_plugin.py +44 -0
  881. led_ticker_core-2.0.0/tests/test_plugins/test_example_plugin.py +64 -0
  882. led_ticker_core-2.0.0/tests/test_plugins/test_example_service_plugin.py +57 -0
  883. led_ticker_core-2.0.0/tests/test_plugins/test_example_transition_plugin.py +91 -0
  884. led_ticker_core-2.0.0/tests/test_plugins/test_font_plugins.py +158 -0
  885. led_ticker_core-2.0.0/tests/test_plugins/test_hires_transition_plugin.py +53 -0
  886. led_ticker_core-2.0.0/tests/test_plugins/test_hook_plugins.py +215 -0
  887. led_ticker_core-2.0.0/tests/test_plugins/test_loader_config.py +99 -0
  888. led_ticker_core-2.0.0/tests/test_plugins/test_loader_core.py +82 -0
  889. led_ticker_core-2.0.0/tests/test_plugins/test_loader_entrypoints.py +82 -0
  890. led_ticker_core-2.0.0/tests/test_plugins/test_loader_local.py +54 -0
  891. led_ticker_core-2.0.0/tests/test_plugins/test_loader_policy.py +63 -0
  892. led_ticker_core-2.0.0/tests/test_plugins/test_plugin_api.py +160 -0
  893. led_ticker_core-2.0.0/tests/test_plugins/test_plugin_cli.py +785 -0
  894. led_ticker_core-2.0.0/tests/test_plugins/test_plugin_dispatch.py +134 -0
  895. led_ticker_core-2.0.0/tests/test_plugins/test_plugins_config.py +50 -0
  896. led_ticker_core-2.0.0/tests/test_plugins/test_provider_plugins.py +96 -0
  897. led_ticker_core-2.0.0/tests/test_plugins/test_public_surface_boundary.py +30 -0
  898. led_ticker_core-2.0.0/tests/test_plugins/test_run_integration.py +91 -0
  899. led_ticker_core-2.0.0/tests/test_plugins/test_transition_plugins.py +187 -0
  900. led_ticker_core-2.0.0/tests/test_plugins/test_validate_config.py +129 -0
  901. led_ticker_core-2.0.0/tests/test_preview_endpoint.py +85 -0
  902. led_ticker_core-2.0.0/tests/test_preview_tee.py +486 -0
  903. led_ticker_core-2.0.0/tests/test_registry_collision.py +45 -0
  904. led_ticker_core-2.0.0/tests/test_reload.py +268 -0
  905. led_ticker_core-2.0.0/tests/test_render_breaker.py +190 -0
  906. led_ticker_core-2.0.0/tests/test_render_breaker_engine.py +398 -0
  907. led_ticker_core-2.0.0/tests/test_run_gif.py +115 -0
  908. led_ticker_core-2.0.0/tests/test_run_reload_helpers.py +195 -0
  909. led_ticker_core-2.0.0/tests/test_scaled_canvas.py +315 -0
  910. led_ticker_core-2.0.0/tests/test_schedule.py +176 -0
  911. led_ticker_core-2.0.0/tests/test_schedule_ticker.py +191 -0
  912. led_ticker_core-2.0.0/tests/test_secret_token.py +30 -0
  913. led_ticker_core-2.0.0/tests/test_shimmer_provider.py +293 -0
  914. led_ticker_core-2.0.0/tests/test_startup_validation.py +84 -0
  915. led_ticker_core-2.0.0/tests/test_status_board.py +506 -0
  916. led_ticker_core-2.0.0/tests/test_status_instrumentation.py +455 -0
  917. led_ticker_core-2.0.0/tests/test_swap_centralization.py +37 -0
  918. led_ticker_core-2.0.0/tests/test_task_tracking.py +20 -0
  919. led_ticker_core-2.0.0/tests/test_text_render.py +400 -0
  920. led_ticker_core-2.0.0/tests/test_ticker.py +520 -0
  921. led_ticker_core-2.0.0/tests/test_ticker_display.py +1906 -0
  922. led_ticker_core-2.0.0/tests/test_ticker_wraps_forever.py +258 -0
  923. led_ticker_core-2.0.0/tests/test_transition_migration.py +131 -0
  924. led_ticker_core-2.0.0/tests/test_transitions.py +2364 -0
  925. led_ticker_core-2.0.0/tests/test_transitions_registry.py +32 -0
  926. led_ticker_core-2.0.0/tests/test_types.py +41 -0
  927. led_ticker_core-2.0.0/tests/test_validate.py +3464 -0
  928. led_ticker_core-2.0.0/tests/test_validate_schedule.py +125 -0
  929. led_ticker_core-2.0.0/tests/test_validate_text.py +62 -0
  930. led_ticker_core-2.0.0/tests/test_web_config.py +90 -0
  931. led_ticker_core-2.0.0/tests/test_webui_app.py +720 -0
  932. led_ticker_core-2.0.0/tests/test_webui_inventory.py +49 -0
  933. led_ticker_core-2.0.0/tests/test_webui_paths.py +72 -0
  934. led_ticker_core-2.0.0/tests/test_webui_purity.py +69 -0
  935. led_ticker_core-2.0.0/tests/test_webui_redact.py +140 -0
  936. led_ticker_core-2.0.0/tests/test_widget_contracts.py +59 -0
  937. led_ticker_core-2.0.0/tests/test_widget_protocol.py +302 -0
  938. led_ticker_core-2.0.0/tests/test_widget_spawn_sink.py +22 -0
  939. led_ticker_core-2.0.0/tests/test_widget_unknown_hint.py +24 -0
  940. led_ticker_core-2.0.0/tests/test_widgets/__init__.py +0 -0
  941. led_ticker_core-2.0.0/tests/test_widgets/test_clock.py +158 -0
  942. led_ticker_core-2.0.0/tests/test_widgets/test_crypto_migration.py +96 -0
  943. led_ticker_core-2.0.0/tests/test_widgets/test_gif.py +1719 -0
  944. led_ticker_core-2.0.0/tests/test_widgets/test_gif_decode.py +283 -0
  945. led_ticker_core-2.0.0/tests/test_widgets/test_image_base.py +2214 -0
  946. led_ticker_core-2.0.0/tests/test_widgets/test_image_fit.py +218 -0
  947. led_ticker_core-2.0.0/tests/test_widgets/test_image_text_wrap.py +843 -0
  948. led_ticker_core-2.0.0/tests/test_widgets/test_image_two_row_scroll_through.py +230 -0
  949. led_ticker_core-2.0.0/tests/test_widgets/test_image_two_row_wrap.py +562 -0
  950. led_ticker_core-2.0.0/tests/test_widgets/test_message.py +581 -0
  951. led_ticker_core-2.0.0/tests/test_widgets/test_registry.py +34 -0
  952. led_ticker_core-2.0.0/tests/test_widgets/test_row_layout.py +87 -0
  953. led_ticker_core-2.0.0/tests/test_widgets/test_still.py +1298 -0
  954. led_ticker_core-2.0.0/tests/test_widgets/test_two_row.py +1189 -0
  955. led_ticker_core-2.0.0/tests/test_widgets/test_two_row_scroll_through.py +753 -0
  956. led_ticker_core-2.0.0/tests/test_widgets/test_two_row_wrap.py +253 -0
  957. led_ticker_core-2.0.0/tests/test_widgets/test_widget_updates.py +6 -0
  958. led_ticker_core-2.0.0/tools/bench_setpixel.py +107 -0
  959. led_ticker_core-2.0.0/tools/derive_heart_tunnel.py +54 -0
  960. led_ticker_core-2.0.0/tools/derive_phoenix_assets.py +98 -0
  961. led_ticker_core-2.0.0/tools/derive_pride_assets.py +72 -0
  962. led_ticker_core-2.0.0/tools/gif_plan/__init__.py +0 -0
  963. led_ticker_core-2.0.0/tools/gif_plan/conftest.py +16 -0
  964. led_ticker_core-2.0.0/tools/gif_plan/plan.py +146 -0
  965. led_ticker_core-2.0.0/tools/gif_plan/test_plan.py +298 -0
  966. led_ticker_core-2.0.0/tools/render_demo/README.md +31 -0
  967. led_ticker_core-2.0.0/tools/render_demo/__init__.py +0 -0
  968. led_ticker_core-2.0.0/tools/render_demo/placeholder.py +123 -0
  969. led_ticker_core-2.0.0/tools/render_demo/recording.py +58 -0
  970. led_ticker_core-2.0.0/tools/render_demo/render.py +271 -0
  971. led_ticker_core-2.0.0/tools/render_demo/test_placeholder.py +118 -0
  972. led_ticker_core-2.0.0/tools/render_demo/test_recording.py +81 -0
  973. led_ticker_core-2.0.0/tools/render_demo/test_render.py +357 -0
  974. led_ticker_core-2.0.0/tools/render_demo/test_renderer_multiframe.py +105 -0
  975. led_ticker_core-2.0.0/tools/render_emoji_previews.py +67 -0
  976. led_ticker_core-2.0.0/uv.lock +725 -0
@@ -0,0 +1,171 @@
1
+ ---
2
+ description: Multi-persona panel review of the led-ticker docs site (PM, UX, prospective user, technical writer). Sonnet-powered personas in parallel; Opus synthesis in chat.
3
+ ---
4
+
5
+ # Docs site panel review
6
+
7
+ Review the led-ticker docs site with a four-persona panel: a product manager, a UX engineer, a moderately-technical prospective user, and a technical writer. Reviews run against a fresh **local build** of the site (`docs/site/dist/`) — the deployed site at <https://docs.ledticker.dev> sits behind Cloudflare Access, so personas Read rendered HTML files locally instead of WebFetching URLs. Bonus: this works on feature branches before any deploy lands.
8
+
9
+ ## Scope
10
+
11
+ `$ARGUMENTS` may name a subset of personas to run — accepted tokens: `pm`, `ux`, `user`, `writer`. Examples:
12
+
13
+ - `/review-docs` — all four personas + synthesis
14
+ - `/review-docs writer ux` — only the writer + UX engineer (typical re-run after a polish PR)
15
+ - `/review-docs writer` — single-persona run; skip synthesis, surface the writer's review directly
16
+
17
+ If `$ARGUMENTS` is empty, run all four. Otherwise run only the named personas.
18
+
19
+ ## Step 0 — build the site
20
+
21
+ Before dispatching any persona, run `make docs-build` from the repo root to ensure `docs/site/dist/` is fresh. Astro builds incrementally (~3 sec when nothing changed). If the build fails, halt and surface the error to the user — do NOT proceed with a stale or missing dist, and do NOT have personas read source MDX as a fallback (the synthesis depends on rendered output for the user-persona review and on consistent file paths across personas).
22
+
23
+ ```bash
24
+ make docs-build
25
+ ```
26
+
27
+ Confirm the build succeeded by checking that `docs/site/dist/index.html` exists. If `make docs-build` errors out for environment reasons (missing pnpm, etc.), surface the actual error rather than retrying — the build is a real prerequisite, not a soft check.
28
+
29
+ ## Dispatch
30
+
31
+ Spawn the chosen personas as parallel `Agent` calls in a SINGLE message (multiple Agent tool uses → genuine parallelism). Each call uses:
32
+
33
+ - `subagent_type: "general-purpose"`
34
+ - `model: "sonnet"` — these are scoped lens-based reads; Sonnet handles them fine and the cost matters when this gets re-run
35
+ - `description`: short label like `"PM docs review"`
36
+ - `prompt`: the verbatim persona prompt below
37
+
38
+ After all dispatched personas return, do the synthesis pass YOURSELF in this conversation (you're on Opus). Don't dispatch synthesis as a fifth agent — the personas' reviews are already loaded in your context, and synthesis is exactly the cross-persona pattern matching + bumper-sticker thesis judgment that earns Opus's cost. Skip the synthesis section if only one persona was requested.
39
+
40
+ ## Path mapping
41
+
42
+ Personas read rendered HTML from `docs/site/dist/` using the Read tool. URL → file path mapping:
43
+
44
+ | URL | File path |
45
+ |---|---|
46
+ | `/` | `docs/site/dist/index.html` |
47
+ | `/getting-started/` | `docs/site/dist/getting-started/index.html` |
48
+ | `/widgets/message/` | `docs/site/dist/widgets/message/index.html` |
49
+ | `/concepts/fonts/` | `docs/site/dist/concepts/fonts/index.html` |
50
+ | (any path ending `/`) | append `index.html` |
51
+
52
+ The HTML files include the full Starlight chrome (sidebar, nav, theme), so personas see what a deployed visitor would see — minus the actual hosting URL. Internal `<a href="/widgets/message/">` links don't auto-navigate; personas follow them by reading the next file's path.
53
+
54
+ ---
55
+
56
+ ## Persona 1 — Product manager
57
+
58
+ ```
59
+ You're a product manager evaluating whether the led-ticker docs site converts a curious developer into someone who has built + deployed their first sign within an hour. The site is built locally at docs/site/dist/ — read rendered HTML files with the Read tool (the deployed site isn't public).
60
+
61
+ Walk this journey, in order, using Read:
62
+ 1. docs/site/dist/index.html (homepage)
63
+ 2. docs/site/dist/getting-started/index.html
64
+ 3. docs/site/dist/hardware/smallsign/index.html (or hardware/building-your-own/ if that reads as more on-ramp-y)
65
+ 4. docs/site/dist/widgets/message/index.html
66
+ 5. docs/site/dist/reference/cli/index.html
67
+
68
+ After each page, jot what a curious developer would take away vs. what they'd still be unsure about. Then return a single review:
69
+
70
+ - **First impression** (2-3 sentences). What's the dominant feeling — capable / overwhelmed / curious / lost?
71
+ - **Findings** (5-7). For each: severity (showstopper / important / nice-to-have), the page (use URL form like `/widgets/message/` for readability), what's wrong from a conversion-funnel POV (not "this paragraph is unclear" — "a developer at this point would not know whether to buy panels or run the renderer first"), and a concrete suggestion (one sentence).
72
+ - **Friction inventory.** List the moments in the journey where a developer would stall, close the tab, or open Reddit to ask.
73
+ - **Ship-readiness call.** One of: "ready to share with the developer crowd as-is", "polish before sharing widely", or "would lose users in current state". One sentence justifying.
74
+
75
+ If you found nothing in a category, explicitly say "No findings in this lane" rather than inflating. The synthesis step downstream will weight your honest call against three other personas, so soft-positive feedback hurts more than it helps.
76
+ ```
77
+
78
+ ## Persona 2 — UX engineer
79
+
80
+ ```
81
+ You're a UX engineer doing an IA + scannability audit of the led-ticker docs site. The site is built locally at docs/site/dist/ — read rendered HTML files with the Read tool (the deployed site isn't public). The HTML includes the full Starlight chrome (sidebar, nav, theme), so what you see is what a visitor sees.
82
+
83
+ Walk the site like a UX engineer would — meaning: do the sidebar walk first (read `docs/site/dist/index.html` and skim the nav structure, then walk top-level pages from each sidebar group), then go deep on three pages of varied type. URL form like `/widgets/message/` corresponds to `docs/site/dist/widgets/message/index.html`.
84
+
85
+ Lens specifically:
86
+ - **Sidebar IA.** Does the grouping match how the user thinks about the product? Are categories the right size (3-15 items)? Anything that should be promoted to a top-level item, or demoted into a subgroup?
87
+ - **Page structure consistency.** Pick three pages from different sections. Do their headings follow the same pattern? Do components (tables, callouts, code blocks, related-pages clusters) appear in similar positions?
88
+ - **Scannability.** Could someone in a hurry get the gist of each page from headings + bolded leads alone? Where does the prose force linear reading when a table or list would scan better?
89
+ - **Entry-point obviousness.** Where does someone arriving at the homepage / a deep link know to go next? Are CTAs concrete or vague?
90
+
91
+ Return:
92
+ - **First impression** (2-3 sentences) on the IA + scannability story.
93
+ - **Findings** (5-7). Severity-tagged. Page URL + concrete suggestion.
94
+ - **Sidebar audit.** One paragraph specifically on the sidebar, with concrete rename / regroup proposals if any.
95
+ - **Ship-readiness call.** Same scale as the PM.
96
+
97
+ Don't over-weight visual polish (Starlight defaults are out of scope). Focus on structure and information flow.
98
+ ```
99
+
100
+ ## Persona 3 — Moderately-technical prospective user
101
+
102
+ ```
103
+ You are NOT an AI reviewer in this prompt. Stay in character throughout.
104
+
105
+ You're a developer who just saw led-ticker mentioned on Hacker News. You've done embedded / Raspberry Pi work before but never touched an LED matrix panel. You have ~30 minutes to decide: do I want to build one of these for my office? Or move on?
106
+
107
+ Three questions you want the docs to answer:
108
+ 1. Could I actually build this myself, with reasonable effort and parts cost?
109
+ 2. What does the end product look like in real life — would I be proud of it?
110
+ 3. How hard is the config? Will I be writing TOML for hours, or is it a 10-line file?
111
+
112
+ The site is built locally at docs/site/dist/ — read rendered HTML files with the Read tool. The HTML includes the sidebar / nav / theme, so what you see is what a visitor sees. URL form like `/widgets/message/` maps to `docs/site/dist/widgets/message/index.html`. Internal links don't auto-navigate; follow them by reading the next file.
113
+
114
+ Browse however you naturally would — start at `docs/site/dist/index.html`, follow links that look promising, abandon pages that get too dense. Don't be exhaustive — be a real visitor.
115
+
116
+ Return:
117
+ - **What you actually read** (page URLs in URL form `/like-this/`, in the order you read them).
118
+ - **First impression** (2-3 sentences in your own voice — not in marketing-speak).
119
+ - **Where you got hooked.** Specific pages or paragraphs that made you lean in. Quote a sentence or two each.
120
+ - **Where you got bounced or confused.** Specific moments. What would a beginner have to Google to keep going? What jargon went unexplained?
121
+ - **The verdict.** Would you build this? Why or why not? If "no", what would it take to flip you to "yes"? If "yes", what's the first thing you'd do tomorrow?
122
+
123
+ Be honest. The goal of this review is to find the gaps, not to validate the docs. If something rocks, say so once. If something stinks, say so as many times as it deserves.
124
+ ```
125
+
126
+ ## Persona 4 — Technical writer
127
+
128
+ ```
129
+ You're a technical writer doing a copy / voice / style audit of the led-ticker docs site. The site author is specifically worried that parts may sound "AI heavy" — you should weight that concern.
130
+
131
+ The site is built locally at docs/site/dist/ — read rendered HTML files with the Read tool. URL form like `/widgets/message/` maps to `docs/site/dist/widgets/message/index.html`. You may also Read the source MDX at `docs/site/src/content/docs/<slug>.mdx` if you want to verify a copy issue is in the source rather than introduced by Starlight's render.
132
+
133
+ Sample 5-7 pages across types: an index page, a concept page, a widget page, a hardware page, a reference page, a tools page.
134
+
135
+ Specifically scan for AI-heavy tells:
136
+ - **Padded openers.** "This page covers…", "In this guide we'll explore…", "Let's take a look at…"
137
+ - **Hedging language.** "It's worth noting that…", "broadly speaking", "in essence", "generally"
138
+ - **AI-favorite vocabulary.** "comprehensive", "robust", "powerful", "seamlessly", "leverage", "unlock", "explore", "delve into", "navigate"
139
+ - **Em-dash overuse.** Em-dashes are a fingerprint when used to splice every sentence into two clauses.
140
+ - **Mechanical parallel structure.** Three-bullet lists where each bullet starts with the same gerund or imperative and feels rhythmically generated rather than written.
141
+ - **Listicles where prose would flow.** A bullet list of three short items often reads more naturally as one sentence.
142
+ - **Sentences that could be phrases. Phrases that could be words.**
143
+
144
+ Also check:
145
+ - **Voice consistency.** Does the same author appear to have written every page, or do voices drift?
146
+ - **Cognitive load.** Where does a sentence carry too many subclauses? Where do paragraphs run too long without a paragraph break to breathe?
147
+ - **Headings earning their weight.** Are H2s/H3s descriptive, or generic ("Overview", "Usage", "Notes")?
148
+
149
+ Return:
150
+ - **AI-heaviness heat map.** 3-5 specific paragraphs you think read most AI-ish, with the page URL + the original paragraph + a concrete rewrite. The rewrite is the deliverable — "this could be tighter" without showing how is not useful.
151
+ - **Voice consistency note.** One paragraph: do the pages sound like one writer, or many? Where are the seams?
152
+ - **Five general rewrites.** Pick five sentences from anywhere on the site that exemplify a fixable copy issue. Original + rewrite + one-line reason.
153
+ - **Headings audit.** List any H2 / H3 you'd rename or remove.
154
+
155
+ Avoid being precious. Some "AI tells" are just clear technical writing (parallel structure in API docs is fine). Flag the ones that hurt readability or make the docs sound generic, not the ones that just pattern-match.
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Synthesis (when ≥2 personas ran)
161
+
162
+ After the dispatched personas return, compile a single punch list directly in this conversation:
163
+
164
+ 1. **Convergence map.** A table: finding | personas that raised it | severity assigned by each. Items raised by ≥3 personas go to the top.
165
+ 2. **Showstopper section.** Any "would lose users" / "ship-blocker" calls, with cross-references to the personas that raised them.
166
+ 3. **Important section.** Findings raised by ≥2 personas, or one persona with high confidence.
167
+ 4. **Nice-to-have section.** Single-persona polish items.
168
+ 5. **AI-heaviness summary.** Pull the writer's heat map verbatim, plus any "felt mechanical" / "felt generic" comments from the other personas.
169
+ 6. **Recommended sequence.** If we did 3-5 follow-up PRs, what order would address the most weight first?
170
+
171
+ End with one paragraph naming the convergent **thesis** across personas — what's the dominant story the panel is telling about the docs? (E.g. "structurally solid but the on-ramp is too dense" vs "well-paced but some pages drift into AI-generated voice".) That paragraph is the bumper sticker.
@@ -0,0 +1,202 @@
1
+ ---
2
+ name: creating-a-config
3
+ description: Use when a user wants to build, extend, or refine a led-ticker config.toml — handles "new config from scratch", "add a widget to my config", or "tune what's already there". Knows the bigsign vs smallsign tradeoffs, widget/transition catalogs, and the CLAUDE.md gotcha list.
4
+ ---
5
+
6
+ # Creating a led-ticker Config
7
+
8
+ You are guiding the user through building or modifying a `config/config.toml` for the led-ticker. There are three modes: **new**, **add**, **refine**.
9
+
10
+ ## Step 0: Detect mode
11
+
12
+ Determine the user's intent:
13
+
14
+ - `new` — user said "build a config" / "make a sign" / similar. OR no `config/config.toml` exists.
15
+ - `add` — user said "add a widget" / "add a section". `config/config.toml` exists.
16
+ - `refine` — user said "looks too small" / "too fast" / "fix the colors". `config/config.toml` exists.
17
+
18
+ If ambiguous, ask:
19
+ > "Are you starting fresh, adding to an existing config, or tuning what's already there?"
20
+
21
+ Announce: "Using creating-a-config skill in **\<mode\>** mode."
22
+
23
+ ## TOML structure reminder (all modes)
24
+
25
+ Every config has this skeleton:
26
+
27
+ ```toml
28
+ [display]
29
+ rows = 32
30
+ cols = 64
31
+ chain = 8
32
+ default_scale = 4
33
+ # ... hardware knobs
34
+
35
+ [title]
36
+ delay = 5
37
+
38
+ [transitions]
39
+ default = "push_left"
40
+ duration = 0.5
41
+ easing = "ease_in_out"
42
+ between_sections = "dissolve"
43
+
44
+ # Each section is an array entry:
45
+ [[playlist.section]]
46
+ mode = "swap" # or "forever_scroll" or "infini_scroll"
47
+ hold_time = 6
48
+ loop_count = 1
49
+
50
+ [playlist.section.title] # optional title card
51
+ type = "message"
52
+ text = "Weather"
53
+ color = [255, 150, 190]
54
+
55
+ [[playlist.section.widget]] # one or more widgets per section
56
+ type = "weather.current"
57
+ location = "Brooklyn"
58
+ units = "imperial"
59
+
60
+ [[playlist.section.widget]] # additional widgets allowed
61
+ type = "message"
62
+ text = "More info"
63
+ ```
64
+
65
+ The skill produces configs in THIS structure. Never use top-level `[section_name]` headers in place of `[[playlist.section]]`.
66
+
67
+ ---
68
+
69
+ ## `new` mode (3-phase wizard)
70
+
71
+ ### Phase 1: Outline
72
+
73
+ Load `references/hardware-guide.md`.
74
+
75
+ Ask these 7 questions, one at a time. Use multi-choice format where listed.
76
+
77
+ 1. **Sign target:** small (160×16) / bigsign (256×64)
78
+ *(Note: "both" is reserved for future parallel-config support; if the user picks both, explain that's not yet supported and ask them to pick one.)*
79
+ 2. **Use case category:** store window / personal feed / event countdown / sports scoreboard / art piece / mixed
80
+ 3. **Viewing distance:** close (≤6ft) / medium (6–20ft) / far (20ft+)
81
+ *(Drives default font sizes — consult `references/hardware-guide.md` distance table.)*
82
+ 4. **Content sources** (multi-select): rss / weather / custom messages / gifs+images / sports / crypto / countdown
83
+ 5. **Brand presence:** none / colors only / colors+fonts / colors+fonts+logo
84
+ 6. **Tone:** minimal / playful / info-dense / branded-pro
85
+ 7. **Cadence:** always-on continuous loop / scheduled windows
86
+
87
+ After all 7 answers, propose a section list. Load `references/snippets.md`; look up snippets keyed by (use_case × content_source × sign_target); produce one section per content source. Present to the user as section names with widgets, e.g.:
88
+
89
+ ```
90
+ Proposed sections:
91
+ Section 1 (mode=forever_scroll): welcome banner — message widget
92
+ Section 2 (mode=swap): weather — weather widget
93
+ Section 3 (mode=swap): handle — two_row widget
94
+ Section 4 (mode=swap): hours countdown — countdown widget
95
+ ```
96
+
97
+ User confirms or edits the list (add / remove / reorder).
98
+
99
+ ### Phase 2: Per-section pass
100
+
101
+ Load `references/snippets.md`, `references/widget-selection.md`, `references/asset-handling.md`, `references/decision-rules.md`. For each chosen widget's options (field names, types, defaults), read its fact-pack `docs/content-source/widgets/<type>.md` — that is the source of truth for params; author TOML from it.
102
+
103
+ **Brand font defaults (carried across all sections):**
104
+
105
+ If Phase 1 brand presence was `colors+fonts` or `colors+fonts+logo`, the user has already named one or more font files (collected per `references/asset-handling.md`). Pick a per-tier default font_size from the asset-handling viewing-distance table BEFORE entering the per-section loop, e.g. medium-distance bigsign + Inter-Bold → 22. Use this as the default for every text-bearing widget (message, countdown, two_row, weather, image/gif overlay text, plus `[playlist.section.title]` blocks). Don't re-ask per section.
106
+
107
+ Sections-pass loop — for each confirmed section in the outline:
108
+
109
+ 1. Look up the snippet matching (use_case × widget × sign_target) in `references/snippets.md`.
110
+ 2. Ask only the widget-specific questions the snippet's "must customize" list requires. Use AskUserQuestion. **If the user picked a custom brand font in Phase 1, also append `font` / `font_size` / `font_threshold` to every text-bearing widget in this section even if the snippet's must-customize list omits them** — the snippets are pre-fonts and need the brand applied.
111
+ 3. For asset-bearing sections (gif, image, custom font): collect assets per `references/asset-handling.md`. Place fonts in `config/fonts/<file>` and images in `config/assets/<file>`. Verify the path exists before referencing it in TOML. Never fetch URLs silently.
112
+ 4. Write the section's TOML to the in-progress config buffer using the `[[playlist.section]]` / `[[playlist.section.widget]]` structure. If the section has a `[playlist.section.title]` and brand fonts are in play, apply the brand font to the title too.
113
+ 5. Run per-section lint: run `led-ticker validate config/config.toml --json` and surface any `errors` or `warnings` from the output as flag-and-ask items, citing each `rule` and `fix` field. Then check font-size vs viewing distance (see step 5a below) and any remaining issues from `references/decision-rules.md` not caught by the validator.
114
+
115
+ **Additionally** check font-size vs viewing distance: if Phase 1 distance was `medium` and the user picked a `font_size ≥ 24`, OR distance was `far` and `font_size < 22`, flag with: "Phase 1 distance was <X>; recommended `font_size` is <range>; you picked <N>. Want me to align with the recommendation?" Cite `references/asset-handling.md` viewing-distance table.
116
+
117
+ 6. Brief "looks good?" before moving to the next section.
118
+
119
+ ### Phase 3: Polish
120
+
121
+ Load `references/transition-selection.md`, `references/decision-rules.md`. For each transition family's catalog and tuning (durations, easing, sweep colors), read its fact-pack `docs/content-source/transitions/<family>.md` (`push`, `wipe`, `sprite`, `special`).
122
+
123
+ Ask these questions (5–7 total, condensed where possible):
124
+
125
+ 1. **Default transition + duration + easing** — offer 3 picks based on Phase 1 tone. Consult the "Selecting a transition" table in `references/transition-selection.md`:
126
+ - Minimal → `cut` or `wipe_left`
127
+ - Playful → `nyancat.alternating` or `pokeball.alternating`
128
+ - Info-dense → `push_up` or `wipe_up`
129
+ - Branded-pro → `wipe_alternating` with `transition_color` from the brand palette
130
+ 2. **`between_sections` transition** — usually different from the default; suggest `dissolve` for branded-pro, `cut` for minimal.
131
+ 3. **Default `hold_time`** — defaults: continuous loop → 5s, scheduled windows → 10s.
132
+ 4. **Brightness** — defaults: small=60, bigsign=60; ask if user wants different.
133
+ 5. **Bigsign refresh tuning** — only ask if sign=bigsign AND tone=info-dense. Suggest `pwm_bits = 8` — the RIO backend is the library default, no knob needed (consult `references/hardware-guide.md` refresh tuning notes).
134
+ 6. **Save destination** — propose `config/config.<descriptive-slug>.toml` based on Phase 1 answers (e.g. `firebird-bigsign`, `office-rss-small`); ask if user wants to override. After write, ask: "Activate this as the live config? (copies to `config/config.toml`, backs up any existing to `config/config.toml.bak`)"
135
+
136
+ Run final validation: run `led-ticker validate config/config.toml --json`. Surface all `errors` as mandatory fixes and `warnings` as flag-and-ask before writing. Also do a full pass over `references/decision-rules.md` for any issues not caught by the validator.
137
+
138
+ Write the file with all three top-level blocks (`[display]`, `[title]`, `[transitions]`) plus all the `[[playlist.section]]` entries.
139
+
140
+ Print:
141
+ - Path written (and whether it is the live config or a named alternate)
142
+ - Test command: `make test`
143
+ - Hardware run command: `docker compose up` (verify against `Makefile` / `compose.yaml`)
144
+ - Any flagged-but-unfixed violations from validation
145
+
146
+ ---
147
+
148
+ ## `add` mode
149
+
150
+ Load `references/widget-selection.md`, `references/snippets.md`, `references/asset-handling.md`, `references/decision-rules.md`. For each chosen widget's options, read its fact-pack `docs/content-source/widgets/<type>.md` — the source of truth for params.
151
+
152
+ 1. Read `config/config.toml`. Extract: sign target (from `default_scale` + display dims), brand colors (from `bg_color` / common `font_color` values), default transition / hold / easing, existing sections list. Also **infer use_case** from existing widgets — e.g., presence of the `baseball.scores` / `baseball.standings` plugin widgets (`led-ticker-baseball`) → `sports`; multiple `rss.feed` + `weather.current` → `personal_feed`; a single `gif`/`image` filling the panel → `art`; mixed content with brand colors + handle → `store_window`. The inferred use_case drives snippet lookup in step 3. If you're not confident, ask the user: "I'm reading this as a <X> config — does that match?"
153
+ 2. Ask: "What kind of section do you want to add?" — multi-select from `references/widget-selection.md`.
154
+ 3. For each chosen widget: same flow as `new` Phase 2 — look up the snippet by (inferred-use_case × widget × sign) in `references/snippets.md`, ask the snippet's "must customize" questions, collect any assets, write the section TOML, run per-section lint.
155
+ 4. Ask: "Where to insert?" — end / before \<section N\> / after \<section N\>.
156
+ 5. Show full diff. First in-place edit per session creates `config/config.toml.bak` (overwrites any prior `.bak` without prompting).
157
+ 6. Apply edit only on user approval.
158
+
159
+ No Phase 3 — global `[transitions]` and `hold_time` are not re-asked. The new section gets its own `transition` / `transition_color` from the chosen snippet (snippets often pin a per-section transition); for everything not set on the new section, the existing global `[transitions]` config applies.
160
+
161
+ ---
162
+
163
+ ## `refine` mode
164
+
165
+ Load `references/decision-rules.md`, `references/widget-selection.md`, `references/transition-selection.md`.
166
+
167
+ 1. Read `config/config.toml`. Run `led-ticker validate config/config.toml --json` and cache the output as the base violation list (`errors` and `warnings` from the JSON). Also run a full pass over `references/decision-rules.md` for any issues not yet caught by the validator.
168
+ 2. Ask one symptom-style multi-select question:
169
+ - "Too small to read at viewing distance"
170
+ - "Too aggressive / busy"
171
+ - "Too slow / too much dead time"
172
+ - "Too fast / can't read it"
173
+ - "Wrong colors / bad contrast"
174
+ - "Image fit looks bad"
175
+ - "Border / animation feels off"
176
+ - "Other (free text)"
177
+ 3. For each selected symptom, map to specific deltas using this table:
178
+
179
+ | Symptom | Inspect | Propose |
180
+ |---------|---------|---------|
181
+ | Too small at far + bigsign + currently BDF | `font` field on text widgets | Hires Inter at `font_size = 24–32` (consult `references/asset-handling.md` distance table). Migrate from BDF default. |
182
+ | Too small + already hires | `font_size` value | Bump `font_size` up one tier (16→22, 22→28, 28→32). |
183
+ | Too aggressive / busy | `font_color`, `border`, transitions | Swap per-char `rainbow` → `color_cycle`. Replace `wipe_alternating` / `nyancat.alternating` → `cut` or `wipe_left`. Lengthen `hold_time` by 50%. Drop animated `border` to constant or remove. |
184
+ | Too slow / too much dead time | `hold_time`, `transition_duration` | Reduce `hold_time` by 30–50%. If `transition_duration > 1000`, drop to 600. Consider `cut` for inter-widget transitions. |
185
+ | Too fast / can't read it | `hold_time`, `transition_duration` | Raise `hold_time` by 50%. If using fast transitions (`cut`, `push_left` at 400ms), bump duration to 800ms or swap to a wipe. |
186
+ | Wrong colors / bad contrast | `bg_color` vs `font_color` luminance | If both colors are light or both are dark, adjust one for contrast (rough luminance heuristic: sum of RGB channels; push them apart). For brand-locked colors, propose adding a `border` for separation. |
187
+ | Image fit looks bad + `fit="stretch"` + non-matching aspect | `fit`, image dimensions | Propose `fit="pillarbox"` (image wider than panel) or `fit="letterbox"` (image taller than panel) per `references/asset-handling.md` decision tree. Add `image_align` if pillarboxing. |
188
+ | Border / animation feels off | `border.speed`, `border.char_offset`, `border.thickness`, `animation` | If border feels too fast: lower `speed` (default 4 on bigsign; try 2). Too uniform: raise `char_offset`. Too thin from far: increase `thickness` from 1 to 2. Typewriter feels off-pace: tune `frames_per_char` (default 3; raise for slower reveal). |
189
+
190
+ 4. After addressing stated symptoms, surface the step-1 violation list as flag-and-ask. Each item: "I also noticed: \<rule violation\> (severity) — want me to fix? Per `references/decision-rules.md` rule N."
191
+ 5. Show each proposed delta as a unified diff. User approves per delta.
192
+ 6. Apply approved edits. First in-place edit per session backs up to `config/config.toml.bak` (overwrites any prior `.bak` without prompting).
193
+
194
+ ---
195
+
196
+ ## Validation: flag-and-ask philosophy
197
+
198
+ The skill **never silently auto-fixes a violation.** Every flag is presented to the user with the rule cited (`per references/decision-rules.md rule N`). The user decides whether to apply the fix. This applies in all three modes at all three checkpoints:
199
+
200
+ 1. Per-section lint (Phase 2 of `new`, or per-section in `add`)
201
+ 2. Phase 3 final validation (assembled config, `new` mode only)
202
+ 3. Symptom + catch-all flag-and-ask (`refine` mode)
@@ -0,0 +1,101 @@
1
+ <!-- Derived from CLAUDE.md sections: "Hi-res fonts on the bigsign", "Per-widget font_threshold", "Match thresholds within a font family", "Inline Emoji", "GIF widget and Still-image widget". Last synced: 2026-05-07. -->
2
+
3
+ # Asset Handling Playbook
4
+
5
+ ## Brand colors (hex → RGB)
6
+
7
+ The skill solicits hex codes (e.g. `#E5306C`) and converts to `[r,g,b]` lists.
8
+
9
+ **Application sites table:**
10
+
11
+ | Brand role | TOML field |
12
+ |-----------|------------|
13
+ | Background tone (per-section bg) | `bg_color` |
14
+ | Background tone (per-row band on TwoRow / image) | `top_bg_color` / `bottom_bg_color` |
15
+ | Primary text | `font_color` |
16
+ | Per-row text (TwoRow / image two-row mode) | `top_color` / `bottom_color` |
17
+ | Accent / highlight | per-char `gradient` `from`/`to`, or constant on a single section |
18
+ | Transition flash | `transition_color` |
19
+ | Border | `border = [r,g,b]` (constant) or `border = {style="constant", color=[r,g,b]}` |
20
+
21
+ ## Custom fonts
22
+
23
+ **Placement:** `config/fonts/<file>` (flat directory; no family subdir). Files are gitignored — they don't go in the repo.
24
+
25
+ **Font size by viewing distance** (bigsign):
26
+
27
+ | Distance | Inter-Regular | Inter-Bold | Beloved Sans Regular | Beloved Sans Bold |
28
+ |----------|---------------|------------|----------------------|-------------------|
29
+ | Close (≤6 ft) | 16 | 16 | 18 | 18 |
30
+ | Medium (6–20 ft) | 22 | 22 | 24 | 24 |
31
+ | Far (20 ft+) | 28 | 28 | 32 | 32 |
32
+
33
+ **Threshold rule (CRITICAL):** Within a font family, Bold weights MUST use the same `font_threshold` as Regular so weight contrast survives. E.g.:
34
+
35
+ ```toml
36
+ # CORRECT — weight contrast survives
37
+ [hello]
38
+ font = "Beloved-Sans-Regular"
39
+ font_size = 24
40
+ font_threshold = 80
41
+
42
+ [hello_bold]
43
+ font = "Beloved-Sans-Bold"
44
+ font_size = 24
45
+ font_threshold = 80 # same as Regular
46
+
47
+ # WRONG — Bold appears thinner than Regular!
48
+ [hello]
49
+ font_threshold = 80
50
+
51
+ [hello_bold]
52
+ font_threshold = 128 # default — inverts weight contrast
53
+ ```
54
+
55
+ **Threshold defaults:**
56
+ - Inter family at any size: 128 (default)
57
+ - Beloved Sans Regular at 24-32: 80 (thin strokes need lower threshold)
58
+ - Beloved Sans Bold paired with above: 80 (match Regular)
59
+
60
+ **Type:** must be `int` 0-255. Floats and bools are rejected.
61
+
62
+ ## Images / GIFs
63
+
64
+ **Placement:** `config/assets/<file>`. The repository ships two CC0 sample-media families: the Firebird **phoenix** (`phoenix.gif`, `phoenix_transparent.gif`, `phoenix.png`, `phoenix_transparent.png`, `phoenix.webp`), derived via `tools/derive_phoenix_assets.py`; and the **pride** rainbow assets (`pride.gif`, `pride_trans.gif`, `pride.png`, `pride_trans.png`), project-generated CC0 derived via `tools/derive_pride_assets.py` (`make derive-pride`). Both families are documented in `config/assets/ATTRIBUTION.md`. For real-brand / customer-IP / third-party media (logos, band photos, product images), the convention is to NOT commit them — users drop their own assets into `config/assets/` locally. If you need to ship custom assets with a deployment, use a tar.gz bundle alongside the example config: extract on the Pi, override the live config. See the Firebird example config for the pattern.
65
+
66
+ **Fit-mode decision tree:**
67
+
68
+ 1. Image aspect matches panel aspect (ratio within ±10%) → `fit = "stretch"` is fine; `fit = "pillarbox"` works too.
69
+ 2. Image is taller than panel aspect → `fit = "letterbox"` (black bars top/bottom).
70
+ 3. Image is wider than panel aspect → `fit = "pillarbox"` (black bars left/right). Use `image_align = "left" | "center" | "right"` to anchor.
71
+ 4. Image needs to fill the panel and aspect doesn't matter → `fit = "crop"`.
72
+ 5. Image has transparent regions and you want text to walk "behind" the silhouette → any fit EXCEPT stretch (stretch leaves no transparent regions).
73
+
74
+ **Scroll layering** (`text_align` for marquees over images):
75
+
76
+ - `text_align = "scroll"` — text drawn first, image painted on top with skip-black. Text walks BEHIND the image silhouette and is exposed only through transparent / black regions. Use with RGBA images that have meaningful alpha (logos, sprites). Don't use with opaque RGB photos — text will be hidden.
77
+ - `text_align = "scroll_over"` — image painted first, text drawn on top. Text walks IN FRONT, always visible regardless of image content. Use with opaque images (dance video, photos) where there's nothing transparent to peek through, OR when you want guaranteed legibility.
78
+ - `text_align = "auto"` — resolves based on `image_align`: `left` → text starts on right, `right` → starts on left, `center` → `scroll_over`. Good when you don't want to think about it.
79
+
80
+ **Two-row text overlay decision:**
81
+ - One line of text → use single-row knobs (`text`, `text_align`, `text_valign`, `font_size`).
82
+ - Two lines (top held + bottom scrolling) → set `bottom_text` to switch to two-row mode. Single-row knobs are then refused.
83
+
84
+ **Hold time / loops:**
85
+ - Still image: `hold_time` (default 5).
86
+ - GIF: `gif_loops` (default 1) × native frame durations.
87
+ - With `text_loops > 0` on either: `hold_time` becomes a duration FLOOR; the source extends to fit the marquee.
88
+
89
+ ## URLs and handles
90
+
91
+ | User says | Lands as |
92
+ |-----------|----------|
93
+ | "Instagram @handle" | `:instagram: @handle` in `two_row.bottom_text` |
94
+ | "Email me@example.com" | `:email: me@example.com` in `two_row.bottom_text` |
95
+ | "Weather in Brooklyn" | `weather.current` widget with `location = "Brooklyn, NY"` |
96
+ | "RSS feed at <url>" | `rss.feed` widget with `feed_url = "<url>"` |
97
+ | "Mets fan" | `baseball.scores` widget with `team = "NYM"` (needs the `led-ticker-baseball` plugin) |
98
+ | "BTC price" | `crypto.coingecko` widget (via `led-ticker-crypto` plugin) with `symbol_id = "bitcoin"`, `symbol = "BTC"`, `currency = "USD"` |
99
+ | "Countdown to <date>" | `[countdown]` widget with `date = "<YYYY-MM-DD>"` |
100
+
101
+ **No silent network fetches.** If user gives an asset URL, the skill asks them to download and provide the local path.