@heyramzi/ui 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/package.json +7 -8
  2. package/scripts/sync-shadcn.mjs +3 -4
  3. package/src/agents/agent-avatar.svelte +604 -575
  4. package/src/agents/agent-cast.svelte +179 -183
  5. package/src/agents/demo.svelte +125 -113
  6. package/src/agents/helpers.ts +23 -17
  7. package/src/agents/index.ts +4 -4
  8. package/src/agents/page-state.ts +6 -6
  9. package/src/agents/types.ts +6 -6
  10. package/src/ai/ai-button/AiButton.svelte +4 -12
  11. package/src/ai/generation-progress/GenerationProgress.svelte +10 -3
  12. package/src/ai/prompt-input/PromptInputTextarea.svelte +1 -2
  13. package/src/ai/response/Response.css +2 -3
  14. package/src/animations/avatar-group-hover.css +2 -16
  15. package/src/animations/card-tilt.css +3 -6
  16. package/src/animations/digit-pop-in.css +2 -15
  17. package/src/animations/dropdown.css +4 -17
  18. package/src/animations/input-clear-dissolve.css +5 -18
  19. package/src/animations/input-shake.css +9 -41
  20. package/src/animations/learn-more-hover.css +17 -9
  21. package/src/animations/like-button.css +2 -4
  22. package/src/animations/page-side-by-side.css +2 -10
  23. package/src/animations/plus-menu-morph.css +2 -5
  24. package/src/animations/shimmer-text.css +5 -18
  25. package/src/animations/spinning-counter.css +2 -6
  26. package/src/animations/success-check.css +2 -15
  27. package/src/animations/thinking-states.css +2 -7
  28. package/src/brand/brand.test.ts +21 -5
  29. package/src/brand/index.ts +4 -10
  30. package/src/canvas/card/card-frame.svelte +43 -39
  31. package/src/canvas/card/resize-handles.svelte +89 -80
  32. package/src/canvas/chrome/chrome-zoom.svelte +101 -100
  33. package/src/canvas/chrome/lock-badge.svelte +8 -8
  34. package/src/canvas/chrome/side-handles.svelte +24 -19
  35. package/src/canvas/chrome/size-chip.svelte +30 -30
  36. package/src/canvas/chrome/snap-guides.svelte +20 -20
  37. package/src/canvas/components/icons/ToolIcon.svelte +8 -8
  38. package/src/canvas/components/shared/svg/PreviewSvg.svelte +19 -19
  39. package/src/canvas/components/shared/svg/ShapeOutline.svelte +71 -48
  40. package/src/canvas/components/shared/svg/StrokeNode.svelte +21 -27
  41. package/src/canvas/components/shared/svg/TextRule.svelte +25 -17
  42. package/src/canvas/edges/bend-handle.svelte +46 -46
  43. package/src/canvas/edges/edge-gradient.svelte +10 -10
  44. package/src/canvas/edges/gradient-edge.svelte +45 -29
  45. package/src/canvas/editor/lock.test.ts +6 -1
  46. package/src/canvas/editor/style.ts +7 -1
  47. package/src/canvas/headless/svg-figure.test.ts +5 -1
  48. package/src/canvas/lod/lod-switch.svelte +111 -106
  49. package/src/canvas/pen/PenField.svelte +87 -81
  50. package/src/canvas/pen/PenOverlay.svelte +127 -127
  51. package/src/canvas/pen/ShapeNode.svelte +31 -32
  52. package/src/canvas/pen/TextNode.svelte +54 -53
  53. package/src/canvas/pen/host-field.test.svelte +7 -7
  54. package/src/canvas/pen/shapes.ts +7 -1
  55. package/src/canvas/screen/GlyphIcon.svelte +22 -17
  56. package/src/canvas/screen/PartView.svelte +138 -72
  57. package/src/canvas/screen/ScreenBody.svelte +81 -60
  58. package/src/canvas/screen/ScreenCard.svelte +20 -20
  59. package/src/canvas/ui/CanvasToolbar.svelte +173 -85
  60. package/src/canvas/ui/FrameLayer.svelte +59 -59
  61. package/src/canvas/ui/PenLayer.svelte +39 -30
  62. package/src/canvas/ui/StylePanel.svelte +119 -102
  63. package/src/canvas/ui/canvas-grid.svelte +137 -129
  64. package/src/charts/animated-value.svelte +1 -1
  65. package/src/charts/area-chart.css +2 -5
  66. package/src/charts/area-chart.svelte +1 -1
  67. package/src/charts/bar-chart.css +2 -3
  68. package/src/charts/bar-chart.svelte +1 -1
  69. package/src/charts/charts.css +5 -17
  70. package/src/charts/crosshair.svelte +1 -1
  71. package/src/charts/dashboard/dashboard-empty.svelte +25 -25
  72. package/src/charts/dashboard/dashboard-section.svelte +24 -24
  73. package/src/charts/dashboard/data-panel.svelte +50 -50
  74. package/src/charts/dashboard/data-sort-head.svelte +56 -56
  75. package/src/charts/dashboard/data-table.svelte +138 -138
  76. package/src/charts/dashboard/panel-grid.svelte +30 -30
  77. package/src/charts/dashboard/period-filter.svelte +25 -25
  78. package/src/charts/dashboard/rating-chip.svelte +19 -19
  79. package/src/charts/dashboard/stat-band.svelte +32 -32
  80. package/src/charts/dashboard/stat-tile.svelte +106 -99
  81. package/src/charts/donut-chart.svelte +1 -1
  82. package/src/charts/edge-fade.svelte +1 -1
  83. package/src/charts/figure.svelte +1 -1
  84. package/src/charts/gauge-chart.css +4 -7
  85. package/src/charts/gauge-chart.svelte +1 -1
  86. package/src/charts/hover-focus.svelte +1 -1
  87. package/src/charts/legend.css +1 -3
  88. package/src/charts/legend.svelte +1 -1
  89. package/src/charts/line-chart.svelte +1 -1
  90. package/src/charts/number-chart.css +6 -9
  91. package/src/charts/number-chart.svelte +1 -1
  92. package/src/charts/reference-line.svelte +19 -19
  93. package/src/charts/reveal.svelte +1 -1
  94. package/src/charts/ring-chart.css +2 -4
  95. package/src/charts/ring-chart.svelte +1 -1
  96. package/src/charts/sparkline.svelte +5 -2
  97. package/src/charts/stat-card.svelte +1 -1
  98. package/src/charts/time-series-chart.css +2 -5
  99. package/src/charts/trend-pill.css +2 -4
  100. package/src/charts/trend-pill.svelte +1 -1
  101. package/src/components/copy/copy-button.svelte +93 -98
  102. package/src/components/copy/copy-button.test.ts +10 -2
  103. package/src/components/data-table/infinite-scroll.svelte +42 -42
  104. package/src/components/data-table/pagination.svelte +34 -22
  105. package/src/components/data-table/row-arrow.svelte +19 -16
  106. package/src/components/data-table/row-context-menu.svelte +52 -52
  107. package/src/components/data-table/sortable-head.svelte +25 -25
  108. package/src/components/data-table/table-skeleton.svelte +41 -36
  109. package/src/components/docs/doc-page.svelte +18 -9
  110. package/src/components/docs/on-this-page.svelte +16 -3
  111. package/src/components/docs/scroll-spy.svelte.ts +2 -3
  112. package/src/components/field-row/field-row.svelte +10 -8
  113. package/src/components/hold-to-confirm/hold-to-confirm.svelte +5 -1
  114. package/src/components/icon/icon.svelte +14 -14
  115. package/src/components/language-flag/language-flag.svelte +3 -1
  116. package/src/components/list-page/detail-empty.svelte +34 -34
  117. package/src/components/list-page/detail-header.svelte +55 -47
  118. package/src/components/list-page/detail-panel.svelte +51 -59
  119. package/src/components/list-page/detail-row.svelte +19 -19
  120. package/src/components/list-page/detail-stack.svelte +21 -21
  121. package/src/components/list-page/empty-state.svelte +30 -30
  122. package/src/components/list-page/filter-item.svelte +20 -20
  123. package/src/components/list-page/filter-popover.svelte +60 -55
  124. package/src/components/list-page/grouped-list.svelte +4 -2
  125. package/src/components/list-page/index.ts +5 -1
  126. package/src/components/list-page/list-page-shell.svelte +2 -5
  127. package/src/components/list-page/master-detail.svelte +87 -88
  128. package/src/components/list-page/notice-bar.svelte +38 -38
  129. package/src/components/list-page/prev-next.svelte +63 -63
  130. package/src/components/list-page/rail-body.svelte +18 -18
  131. package/src/components/list-page/rail-empty.svelte +23 -30
  132. package/src/components/list-page/rail-head.svelte +24 -24
  133. package/src/components/list-page/rail-row.svelte +77 -73
  134. package/src/components/list-page/section-host.ts +2 -3
  135. package/src/components/locale-switch/locale-switch.svelte +41 -41
  136. package/src/components/mark/mark.svelte +34 -38
  137. package/src/components/open-in/index.ts +1 -5
  138. package/src/components/open-in/open-in.svelte +40 -40
  139. package/src/components/picker/mark-picker.svelte +49 -49
  140. package/src/components/picker/picker.svelte +5 -3
  141. package/src/components/section-header/section-header.test.ts +7 -1
  142. package/src/components/section-header/section-label.svelte +20 -20
  143. package/src/components/segmented/animated-tabs.svelte +31 -2
  144. package/src/components/segmented/collapse.test.ts +2 -1
  145. package/src/components/segmented/index.ts +2 -0
  146. package/src/components/segmented/segment.svelte +52 -49
  147. package/src/components/segmented/segmented-filter.svelte +79 -80
  148. package/src/components/segmented/segmented-nav.svelte +34 -40
  149. package/src/components/segmented/segmented-overflow.svelte +53 -50
  150. package/src/components/segmented/segmented-track.svelte +62 -46
  151. package/src/components/segmented/segmented.ts +2 -3
  152. package/src/components/star-rating-input/star-rating-input.svelte +103 -103
  153. package/src/components/svg/svg.svelte +4 -4
  154. package/src/components/table-view/table-view.svelte +17 -2
  155. package/src/components/table-view/table-view.test.ts +7 -1
  156. package/src/components/table-view/types.ts +11 -11
  157. package/src/components/tags-input/index.ts +13 -0
  158. package/src/components/tags-input/tags-input.svelte +305 -0
  159. package/src/components/tags-input/tags.test.ts +64 -0
  160. package/src/components/tags-input/tags.ts +142 -0
  161. package/src/components/theme/index.ts +2 -4
  162. package/src/components/theme/theme-provider.svelte +1 -3
  163. package/src/components/toolbar/toolbar-search.svelte +25 -25
  164. package/src/components/toolbar/toolbar.svelte +11 -7
  165. package/src/components/toolbar/toolbar.test.ts +10 -1
  166. package/src/design/index.css +21 -78
  167. package/src/design/polish.css +26 -35
  168. package/src/editor/editor-toolbar.svelte +104 -99
  169. package/src/editor/editor.svelte +296 -266
  170. package/src/editor/image-toolbar.svelte +20 -22
  171. package/src/editor/index.ts +1 -4
  172. package/src/editor/inline-editor.svelte +280 -238
  173. package/src/editor/markdown.ts +15 -15
  174. package/src/editor/renderer.svelte +71 -71
  175. package/src/editor/slash-menu.svelte +24 -27
  176. package/src/effects/animated-beam/diagrams/BeamSvg.svelte +1 -1
  177. package/src/effects/image-comparison/ImageComparison.svelte +11 -1
  178. package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +59 -46
  179. package/src/effects/magic-card/MagicCard.css +14 -7
  180. package/src/effects/marquee/Marquee.svelte +3 -5
  181. package/src/effects/reveal/observe.ts +0 -3
  182. package/src/effects/spotlight/Spotlight.svelte +1 -1
  183. package/src/effects/theme-toggle/ThemeToggle.css +25 -22
  184. package/src/effects/theme-toggle/ThemeToggle.svelte +6 -7
  185. package/src/gallery.test.ts +14 -4
  186. package/src/inbox/README.md +1 -3
  187. package/src/inbox/inbox.test.ts +181 -138
  188. package/src/inbox/index.ts +20 -20
  189. package/src/inbox/logic.ts +114 -111
  190. package/src/inbox/thread-inbox.svelte +227 -151
  191. package/src/inbox/types.ts +130 -108
  192. package/src/lib/theme-transition.ts +2 -4
  193. package/src/lib/tone.ts +2 -4
  194. package/src/lib/utils.ts +2 -2
  195. package/src/modules.test.ts +79 -69
  196. package/src/onboarding/define-tours.test.ts +55 -40
  197. package/src/onboarding/define-tours.ts +23 -23
  198. package/src/onboarding/demo.svelte +24 -5
  199. package/src/onboarding/index.ts +1 -8
  200. package/src/onboarding/onboarding-provider.svelte +19 -7
  201. package/src/onboarding/onboarding.svelte.ts +16 -16
  202. package/src/onboarding/pick.test.ts +61 -52
  203. package/src/onboarding/pick.ts +16 -13
  204. package/src/onboarding/stores.test.ts +80 -80
  205. package/src/onboarding/stores.ts +41 -39
  206. package/src/onboarding/tour-card.svelte +30 -5
  207. package/src/onboarding/tour-runner.svelte +12 -3
  208. package/src/onboarding/types.ts +20 -12
  209. package/src/onboarding/wait.ts +22 -22
  210. package/src/panel/side-panel.svelte +94 -93
  211. package/src/record/demo-data.ts +291 -225
  212. package/src/record/field-section.svelte +38 -34
  213. package/src/record/fields.ts +148 -96
  214. package/src/record/format.ts +63 -56
  215. package/src/record/index.ts +49 -35
  216. package/src/record/info-list.svelte +145 -114
  217. package/src/record/kinds.ts +31 -31
  218. package/src/record/logic.ts +216 -214
  219. package/src/record/next-up.svelte +45 -34
  220. package/src/record/project-list.svelte +56 -50
  221. package/src/record/record-demo.svelte +130 -110
  222. package/src/record/record-header.svelte +37 -28
  223. package/src/record/record-shell.svelte +54 -54
  224. package/src/record/record-stats.svelte +25 -25
  225. package/src/record/record-timeline.svelte +134 -114
  226. package/src/record/record.test.ts +430 -309
  227. package/src/record/steps-rail.svelte +225 -216
  228. package/src/record/types.ts +234 -215
  229. package/src/record/where-we-are.svelte +62 -58
  230. package/src/shadcn/button/button.svelte +1 -1
  231. package/src/shadcn/card/card-title.svelte +1 -5
  232. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +2 -13
  233. package/src/shadcn/sheet/sheet-content.svelte +2 -4
  234. package/src/shadcn/table/table-cell.svelte +2 -3
  235. package/src/shadcn/utilities.css +3 -8
  236. package/src/slides/Controls.svelte +150 -124
  237. package/src/slides/Deck.svelte +243 -238
  238. package/src/slides/Fragment.svelte +64 -57
  239. package/src/slides/Overview.svelte +106 -101
  240. package/src/slides/Presenter.svelte +300 -266
  241. package/src/slides/Slide.svelte +185 -170
  242. package/src/slides/SlideList.svelte +16 -12
  243. package/src/slides/ambient.d.ts +1 -1
  244. package/src/slides/bridges.ts +42 -23
  245. package/src/slides/deck-controller.svelte.ts +47 -35
  246. package/src/slides/demo-slides.svelte +330 -306
  247. package/src/slides/demo.svelte +164 -160
  248. package/src/slides/export/capture.ts +20 -16
  249. package/src/slides/export/ffmpeg.ts +43 -38
  250. package/src/slides/export/index.ts +5 -5
  251. package/src/slides/export/launch.ts +3 -1
  252. package/src/slides/export/pdf.ts +30 -27
  253. package/src/slides/export/types.ts +10 -8
  254. package/src/slides/index.ts +11 -11
  255. package/src/slides/labels.ts +22 -19
  256. package/src/slides/layout.ts +9 -2
  257. package/src/slides/model.ts +4 -4
  258. package/src/slides/navigation.ts +43 -31
  259. package/src/slides/theme.css +5 -7
  260. package/src/slides/types.ts +9 -10
  261. package/src/status/define-statuses.ts +17 -24
  262. package/src/status/index.ts +5 -5
  263. package/src/status/status-badge.svelte +3 -1
  264. package/src/status/status-dot.svelte +1 -3
  265. package/src/status/status-icon.svelte +1 -1
  266. package/src/status/status-types.ts +21 -21
  267. package/src/tasks/board-order.ts +2 -4
  268. package/src/tasks/demo.svelte +189 -31
  269. package/src/tasks/detail/detail-demo.svelte +73 -13
  270. package/src/tasks/detail/detail-types.ts +45 -45
  271. package/src/tasks/detail/task-detail.svelte +40 -10
  272. package/src/tasks/detail/task-property.svelte +8 -2
  273. package/src/tasks/detail/task-thread.svelte +53 -12
  274. package/src/tasks/gantt/gantt-bar.svelte +17 -6
  275. package/src/tasks/gantt/gantt-grid.svelte +40 -9
  276. package/src/tasks/gantt/gantt-group-row.svelte +8 -2
  277. package/src/tasks/gantt/gantt-header.svelte +9 -3
  278. package/src/tasks/gantt/gantt-task-row.svelte +26 -6
  279. package/src/tasks/gantt/gantt.css +2 -1
  280. package/src/tasks/gantt/gantt.test.ts +3 -1
  281. package/src/tasks/gantt/logic.test.ts +110 -20
  282. package/src/tasks/gantt/logic.ts +42 -6
  283. package/src/tasks/inbox/inbox-card.svelte +13 -5
  284. package/src/tasks/inbox/inbox-draft.svelte +1 -1
  285. package/src/tasks/inbox/inbox-logic.ts +6 -40
  286. package/src/tasks/inbox/inbox-statuses.ts +23 -23
  287. package/src/tasks/inbox/inbox-trace.svelte +9 -3
  288. package/src/tasks/inbox/inbox-types.ts +54 -58
  289. package/src/tasks/inbox/index.ts +22 -21
  290. package/src/tasks/index.ts +49 -52
  291. package/src/tasks/kanban-board.svelte +16 -12
  292. package/src/tasks/kanban-types.ts +2 -3
  293. package/src/tasks/presets/sales.ts +6 -6
  294. package/src/tasks/task-gantt.svelte +28 -8
  295. package/src/tasks/task-list.svelte +41 -17
  296. package/src/tasks/time/duration.ts +40 -40
  297. package/src/tasks/time/time-chip.svelte +9 -2
  298. package/src/tasks/time/time-dot.svelte +1 -1
  299. package/src/tasks/time/time-ring.svelte +11 -3
  300. package/src/tasks/time/time-tracker.svelte +57 -15
  301. package/src/tasks/time/time-types.ts +57 -57
  302. package/src/tasks/use-kanban-dnd.svelte.ts +2 -3
  303. package/src/thread/index.ts +7 -7
  304. package/src/thread/logic.ts +36 -33
  305. package/src/thread/thread.svelte +82 -16
  306. package/src/thread/thread.test.ts +58 -47
  307. package/src/thread/types.ts +68 -68
  308. package/src/tokens/craft.css +17 -53
  309. package/src/tokens/index.css +3 -13
  310. package/src/tokens/palette.css +13 -11
  311. package/src/tokens/primitives.css +10 -23
  312. package/src/tasks/inbox/inbox.svelte +0 -203
@@ -1,292 +1,326 @@
1
1
  <script lang="ts">
2
- import { untrack } from 'svelte';
3
- import Deck from './Deck.svelte';
4
- import type { DeckController } from './deck-controller.svelte.js';
5
- import { resolveLabels } from './labels.js';
6
- import { DEFAULT_CANVAS, type DeckProps } from './types.js';
2
+ import { untrack } from "svelte";
3
+ import Deck from "./Deck.svelte";
4
+ import type { DeckController } from "./deck-controller.svelte.js";
5
+ import { resolveLabels } from "./labels.js";
6
+ import { DEFAULT_CANVAS, type DeckProps } from "./types.js";
7
7
 
8
- interface Props
9
- extends Pick<
10
- DeckProps,
11
- 'id' | 'title' | 'locale' | 'canvas' | 'theme' | 'transition' | 'slides' | 'registry' | 'labels' | 'style' | 'children'
12
- > {
13
- /** The channel name the audience deck uses as its `sync`. */
14
- sync: string;
15
- }
8
+ interface Props extends Pick<
9
+ DeckProps,
10
+ | "id"
11
+ | "title"
12
+ | "locale"
13
+ | "canvas"
14
+ | "theme"
15
+ | "transition"
16
+ | "slides"
17
+ | "registry"
18
+ | "labels"
19
+ | "style"
20
+ | "children"
21
+ > {
22
+ /** The channel name the audience deck uses as its `sync`. */
23
+ sync: string;
24
+ }
16
25
 
17
- let { sync, id, title, locale, canvas = DEFAULT_CANVAS, theme = 'ink', transition, slides, registry, labels: overrides, style, children }: Props =
18
- $props();
26
+ let {
27
+ sync,
28
+ id,
29
+ title,
30
+ locale,
31
+ canvas = DEFAULT_CANVAS,
32
+ theme = "ink",
33
+ transition,
34
+ slides,
35
+ registry,
36
+ labels: overrides,
37
+ style,
38
+ children,
39
+ }: Props = $props();
19
40
 
20
- const labels = $derived(resolveLabels(overrides));
41
+ const labels = $derived(resolveLabels(overrides));
21
42
 
22
- let index = $state(0);
23
- let step = $state(0);
24
- let now = $state<DeckController>();
43
+ let index = $state(0);
44
+ let step = $state(0);
45
+ let now = $state<DeckController>();
25
46
 
26
- const upcoming = $derived(now?.upcoming ?? null);
27
- const notes = $derived(now?.current?.notes);
28
- const steps = $derived(now?.current?.steps ?? 0);
47
+ const upcoming = $derived(now?.upcoming ?? null);
48
+ const notes = $derived(now?.current?.notes);
49
+ const steps = $derived(now?.current?.steps ?? 0);
29
50
 
30
- let elapsed = $state(0);
31
- let running = $state(true);
32
- $effect(() => {
33
- if (!running) return;
34
- const base = untrack(() => elapsed);
35
- const start = Date.now();
36
- const tick = setInterval(() => (elapsed = base + Math.round((Date.now() - start) / 1000)), 250);
37
- return () => clearInterval(tick);
38
- });
51
+ let elapsed = $state(0);
52
+ let running = $state(true);
53
+ $effect(() => {
54
+ if (!running) return;
55
+ const base = untrack(() => elapsed);
56
+ const start = Date.now();
57
+ const tick = setInterval(() => (elapsed = base + Math.round((Date.now() - start) / 1000)), 250);
58
+ return () => clearInterval(tick);
59
+ });
39
60
 
40
- const clock = $derived.by(() => {
41
- const [h, m, s] = [Math.floor(elapsed / 3600), Math.floor(elapsed / 60) % 60, elapsed % 60];
42
- const pad = (n: number) => String(n).padStart(2, '0');
43
- return h ? `${h}:${pad(m)}:${pad(s)}` : `${pad(m)}:${pad(s)}`;
44
- });
61
+ const clock = $derived.by(() => {
62
+ const [h, m, s] = [Math.floor(elapsed / 3600), Math.floor(elapsed / 60) % 60, elapsed % 60];
63
+ const pad = (n: number) => String(n).padStart(2, "0");
64
+ return h ? `${h}:${pad(m)}:${pad(s)}` : `${pad(m)}:${pad(s)}`;
65
+ });
45
66
 
46
- function onkeydown(event: KeyboardEvent) {
47
- if (event.key === 't' && !event.metaKey && !event.ctrlKey && !event.altKey) running = !running;
48
- }
67
+ function onkeydown(event: KeyboardEvent) {
68
+ if (event.key === "t" && !event.metaKey && !event.ctrlKey && !event.altKey) running = !running;
69
+ }
49
70
  </script>
50
71
 
51
72
  <svelte:window {onkeydown} />
52
73
  <svelte:head>
53
- <title>{title ?? labels.deck}</title>
74
+ <title>{title ?? labels.deck}</title>
54
75
  </svelte:head>
55
76
 
56
- <div class="presenter deck-surface deck--{theme}" lang={locale} style:--ratio={canvas.w / canvas.h} {style}>
57
- <header class="presenter__bar">
58
- <h1 class="presenter__title">{title ?? labels.deck}</h1>
59
- {#if now}
60
- <span class="presenter__where">
61
- {labels.slide(now.ordinal.n, now.ordinal.of)}{#if steps > 0}<span class="presenter__steps">{now.position.step}/{steps}</span>{/if}
62
- </span>
63
- {/if}
64
- <div class="presenter__timer" role="timer" aria-label={labels.timer}>
65
- <span class="presenter__clock">{clock}</span>
66
- <button type="button" class="presenter__button" onclick={() => (running = !running)}>
67
- {running ? labels.pauseTimer : labels.startTimer}
68
- </button>
69
- <button type="button" class="presenter__button" onclick={() => (elapsed = 0)}>{labels.resetTimer}</button>
70
- </div>
71
- </header>
77
+ <div
78
+ class="presenter deck-surface deck--{theme}"
79
+ lang={locale}
80
+ style:--ratio={canvas.w / canvas.h}
81
+ {style}
82
+ >
83
+ <header class="presenter__bar">
84
+ <h1 class="presenter__title">{title ?? labels.deck}</h1>
85
+ {#if now}
86
+ <span class="presenter__where">
87
+ {labels.slide(now.ordinal.n, now.ordinal.of)}{#if steps > 0}<span class="presenter__steps"
88
+ >{now.position.step}/{steps}</span
89
+ >{/if}
90
+ </span>
91
+ {/if}
92
+ <div class="presenter__timer" role="timer" aria-label={labels.timer}>
93
+ <span class="presenter__clock">{clock}</span>
94
+ <button type="button" class="presenter__button" onclick={() => (running = !running)}>
95
+ {running ? labels.pauseTimer : labels.startTimer}
96
+ </button>
97
+ <button type="button" class="presenter__button" onclick={() => (elapsed = 0)}
98
+ >{labels.resetTimer}</button
99
+ >
100
+ </div>
101
+ </header>
72
102
 
73
- <main class="presenter__main">
74
- <section class="presenter__now" aria-label={labels.current}>
75
- <div class="presenter__frame" style:aspect-ratio="{canvas.w} / {canvas.h}">
76
- <Deck
77
- bind:index
78
- bind:step
79
- bind:controller={now}
80
- {sync}
81
- {id}
82
- {title}
83
- {locale}
84
- {canvas}
85
- {theme}
86
- {transition}
87
- {slides}
88
- {registry}
89
- {labels}
90
- {style}
91
- controls={false}
92
- >
93
- {@render children?.()}
94
- </Deck>
95
- </div>
96
- </section>
103
+ <main class="presenter__main">
104
+ <section class="presenter__now" aria-label={labels.current}>
105
+ <div class="presenter__frame" style:aspect-ratio="{canvas.w} / {canvas.h}">
106
+ <Deck
107
+ bind:index
108
+ bind:step
109
+ bind:controller={now}
110
+ {sync}
111
+ {id}
112
+ {title}
113
+ {locale}
114
+ {canvas}
115
+ {theme}
116
+ {transition}
117
+ {slides}
118
+ {registry}
119
+ {labels}
120
+ {style}
121
+ controls={false}
122
+ >
123
+ {@render children?.()}
124
+ </Deck>
125
+ </div>
126
+ </section>
97
127
 
98
- <aside class="presenter__side">
99
- <section aria-label={labels.upcoming}>
100
- <h2 class="presenter__heading">{labels.upcoming}</h2>
101
- {#if upcoming !== null}
102
- <div class="presenter__frame presenter__frame--next" style:aspect-ratio="{canvas.w} / {canvas.h}" inert>
103
- <Deck
104
- index={upcoming}
105
- step={Number.MAX_SAFE_INTEGER}
106
- {id}
107
- {canvas}
108
- {theme}
109
- {slides}
110
- {registry}
111
- {labels}
112
- {style}
113
- transition="none"
114
- controls={false}
115
- progress={false}
116
- keyboard={false}
117
- >
118
- {@render children?.()}
119
- </Deck>
120
- </div>
121
- {:else}
122
- <p class="presenter__empty">{labels.endOfDeck}</p>
123
- {/if}
124
- </section>
128
+ <aside class="presenter__side">
129
+ <section aria-label={labels.upcoming}>
130
+ <h2 class="presenter__heading">{labels.upcoming}</h2>
131
+ {#if upcoming !== null}
132
+ <div
133
+ class="presenter__frame presenter__frame--next"
134
+ style:aspect-ratio="{canvas.w} / {canvas.h}"
135
+ inert
136
+ >
137
+ <Deck
138
+ index={upcoming}
139
+ step={Number.MAX_SAFE_INTEGER}
140
+ {id}
141
+ {canvas}
142
+ {theme}
143
+ {slides}
144
+ {registry}
145
+ {labels}
146
+ {style}
147
+ transition="none"
148
+ controls={false}
149
+ progress={false}
150
+ keyboard={false}
151
+ >
152
+ {@render children?.()}
153
+ </Deck>
154
+ </div>
155
+ {:else}
156
+ <p class="presenter__empty">{labels.endOfDeck}</p>
157
+ {/if}
158
+ </section>
125
159
 
126
- <section class="presenter__notes" aria-label={labels.notes}>
127
- <h2 class="presenter__heading">{labels.notes}</h2>
128
- <div class="presenter__notes-body">
129
- {#if typeof notes === 'string'}
130
- <p>{notes}</p>
131
- {:else if notes}
132
- {@render notes()}
133
- {:else}
134
- <p class="presenter__empty">{labels.noNotes}</p>
135
- {/if}
136
- </div>
137
- </section>
138
- </aside>
139
- </main>
160
+ <section class="presenter__notes" aria-label={labels.notes}>
161
+ <h2 class="presenter__heading">{labels.notes}</h2>
162
+ <div class="presenter__notes-body">
163
+ {#if typeof notes === "string"}
164
+ <p>{notes}</p>
165
+ {:else if notes}
166
+ {@render notes()}
167
+ {:else}
168
+ <p class="presenter__empty">{labels.noNotes}</p>
169
+ {/if}
170
+ </div>
171
+ </section>
172
+ </aside>
173
+ </main>
140
174
  </div>
141
175
 
142
176
  <style>
143
- .presenter {
144
- display: grid;
145
- grid-template-rows: auto minmax(0, 1fr);
146
- height: 100dvh;
147
- color: var(--deck-fg);
148
- background: var(--deck-bg);
149
- font-family: var(--deck-font);
150
- }
177
+ .presenter {
178
+ display: grid;
179
+ grid-template-rows: auto minmax(0, 1fr);
180
+ height: 100dvh;
181
+ color: var(--deck-fg);
182
+ background: var(--deck-bg);
183
+ font-family: var(--deck-font);
184
+ }
151
185
 
152
- .presenter__bar {
153
- display: flex;
154
- flex-wrap: wrap;
155
- align-items: center;
156
- gap: 8px 20px;
157
- padding: 12px 20px;
158
- border-bottom: 1px solid var(--deck-line);
159
- }
160
- .presenter__title {
161
- flex: 1;
162
- min-width: 0;
163
- margin: 0;
164
- overflow: hidden;
165
- font: 600 15px/1.2 var(--deck-font);
166
- text-overflow: ellipsis;
167
- white-space: nowrap;
168
- }
169
- .presenter__where {
170
- display: flex;
171
- align-items: center;
172
- gap: 10px;
173
- font: 500 14px/1 var(--deck-font);
174
- color: var(--deck-muted);
175
- }
176
- .presenter__steps {
177
- padding: 3px 7px;
178
- font-size: 12px;
179
- font-variant-numeric: tabular-nums;
180
- color: var(--deck-on-accent);
181
- background: var(--deck-accent);
182
- border-radius: 6px;
183
- }
184
- .presenter__timer {
185
- display: flex;
186
- align-items: center;
187
- gap: 8px;
188
- }
189
- .presenter__clock {
190
- min-width: 5ch;
191
- margin-right: 4px;
192
- font: 700 28px/1 var(--deck-font-display);
193
- font-variant-numeric: tabular-nums;
194
- letter-spacing: -0.02em;
195
- }
196
- .presenter__button {
197
- min-height: 32px;
198
- padding: 0 12px;
199
- font: 500 13px/1 var(--deck-font);
200
- color: var(--deck-fg);
201
- background: var(--deck-surface);
202
- border: 1px solid var(--deck-line);
203
- border-radius: 8px;
204
- cursor: pointer;
205
- transition: background-color var(--deck-t-quick) var(--deck-ease);
206
- }
207
- @media (hover: hover) and (pointer: fine) {
208
- .presenter__button:hover {
209
- background: var(--deck-line);
210
- }
211
- }
212
- .presenter__button:focus-visible {
213
- outline: 2px solid var(--deck-accent);
214
- outline-offset: 2px;
215
- }
186
+ .presenter__bar {
187
+ display: flex;
188
+ flex-wrap: wrap;
189
+ align-items: center;
190
+ gap: 8px 20px;
191
+ padding: 12px 20px;
192
+ border-bottom: 1px solid var(--deck-line);
193
+ }
194
+ .presenter__title {
195
+ flex: 1;
196
+ min-width: 0;
197
+ margin: 0;
198
+ overflow: hidden;
199
+ font: 600 15px/1.2 var(--deck-font);
200
+ text-overflow: ellipsis;
201
+ white-space: nowrap;
202
+ }
203
+ .presenter__where {
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 10px;
207
+ font: 500 14px/1 var(--deck-font);
208
+ color: var(--deck-muted);
209
+ }
210
+ .presenter__steps {
211
+ padding: 3px 7px;
212
+ font-size: 12px;
213
+ font-variant-numeric: tabular-nums;
214
+ color: var(--deck-on-accent);
215
+ background: var(--deck-accent);
216
+ border-radius: 6px;
217
+ }
218
+ .presenter__timer {
219
+ display: flex;
220
+ align-items: center;
221
+ gap: 8px;
222
+ }
223
+ .presenter__clock {
224
+ min-width: 5ch;
225
+ margin-right: 4px;
226
+ font: 700 28px/1 var(--deck-font-display);
227
+ font-variant-numeric: tabular-nums;
228
+ letter-spacing: -0.02em;
229
+ }
230
+ .presenter__button {
231
+ min-height: 32px;
232
+ padding: 0 12px;
233
+ font: 500 13px/1 var(--deck-font);
234
+ color: var(--deck-fg);
235
+ background: var(--deck-surface);
236
+ border: 1px solid var(--deck-line);
237
+ border-radius: 8px;
238
+ cursor: pointer;
239
+ transition: background-color var(--deck-t-quick) var(--deck-ease);
240
+ }
241
+ @media (hover: hover) and (pointer: fine) {
242
+ .presenter__button:hover {
243
+ background: var(--deck-line);
244
+ }
245
+ }
246
+ .presenter__button:focus-visible {
247
+ outline: 2px solid var(--deck-accent);
248
+ outline-offset: 2px;
249
+ }
216
250
 
217
- .presenter__main {
218
- display: grid;
219
- grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
220
- gap: 20px;
221
- min-height: 0;
222
- padding: 20px;
223
- }
224
- .presenter__now {
225
- display: grid;
226
- place-items: center;
227
- min-height: 0;
228
- container-type: size;
229
- }
230
- .presenter__frame {
231
- overflow: hidden;
232
- border-radius: 12px;
233
- box-shadow: 0 0 0 1px var(--deck-line);
234
- }
235
- .presenter__now .presenter__frame {
236
- width: min(100cqw, calc(100cqh * var(--ratio)));
237
- }
238
- .presenter__frame--next {
239
- width: 100%;
240
- }
251
+ .presenter__main {
252
+ display: grid;
253
+ grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
254
+ gap: 20px;
255
+ min-height: 0;
256
+ padding: 20px;
257
+ }
258
+ .presenter__now {
259
+ display: grid;
260
+ place-items: center;
261
+ min-height: 0;
262
+ container-type: size;
263
+ }
264
+ .presenter__frame {
265
+ overflow: hidden;
266
+ border-radius: 12px;
267
+ box-shadow: 0 0 0 1px var(--deck-line);
268
+ }
269
+ .presenter__now .presenter__frame {
270
+ width: min(100cqw, calc(100cqh * var(--ratio)));
271
+ }
272
+ .presenter__frame--next {
273
+ width: 100%;
274
+ }
241
275
 
242
- .presenter__side {
243
- display: grid;
244
- grid-template-rows: auto minmax(0, 1fr);
245
- gap: 20px;
246
- min-height: 0;
247
- }
248
- .presenter__heading {
249
- margin: 0 0 8px;
250
- font: 600 12px/1 var(--deck-font);
251
- letter-spacing: 0.02em;
252
- color: var(--deck-muted);
253
- }
254
- .presenter__notes {
255
- display: flex;
256
- flex-direction: column;
257
- min-height: 0;
258
- }
259
- .presenter__notes-body {
260
- flex: 1;
261
- min-height: 0;
262
- padding-right: 4px;
263
- overflow-y: auto;
264
- font-size: clamp(18px, 1.5vw, 26px);
265
- line-height: 1.5;
266
- white-space: pre-line;
267
- text-wrap: pretty;
268
- }
269
- .presenter__notes-body p {
270
- margin: 0;
271
- }
272
- .presenter__empty {
273
- margin: 0;
274
- color: var(--deck-muted);
275
- }
276
+ .presenter__side {
277
+ display: grid;
278
+ grid-template-rows: auto minmax(0, 1fr);
279
+ gap: 20px;
280
+ min-height: 0;
281
+ }
282
+ .presenter__heading {
283
+ margin: 0 0 8px;
284
+ font: 600 12px/1 var(--deck-font);
285
+ letter-spacing: 0.02em;
286
+ color: var(--deck-muted);
287
+ }
288
+ .presenter__notes {
289
+ display: flex;
290
+ flex-direction: column;
291
+ min-height: 0;
292
+ }
293
+ .presenter__notes-body {
294
+ flex: 1;
295
+ min-height: 0;
296
+ padding-right: 4px;
297
+ overflow-y: auto;
298
+ font-size: clamp(18px, 1.5vw, 26px);
299
+ line-height: 1.5;
300
+ white-space: pre-line;
301
+ text-wrap: pretty;
302
+ }
303
+ .presenter__notes-body p {
304
+ margin: 0;
305
+ }
306
+ .presenter__empty {
307
+ margin: 0;
308
+ color: var(--deck-muted);
309
+ }
276
310
 
277
- @media (max-width: 860px) {
278
- .presenter {
279
- height: auto;
280
- min-height: 100dvh;
281
- }
282
- .presenter__main {
283
- grid-template-columns: minmax(0, 1fr);
284
- }
285
- .presenter__now {
286
- container-type: inline-size;
287
- }
288
- .presenter__now .presenter__frame {
289
- width: 100%;
290
- }
291
- }
311
+ @media (max-width: 860px) {
312
+ .presenter {
313
+ height: auto;
314
+ min-height: 100dvh;
315
+ }
316
+ .presenter__main {
317
+ grid-template-columns: minmax(0, 1fr);
318
+ }
319
+ .presenter__now {
320
+ container-type: inline-size;
321
+ }
322
+ .presenter__now .presenter__frame {
323
+ width: 100%;
324
+ }
325
+ }
292
326
  </style>