@ai-matrx/capture 0.3.1 → 0.4.2

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.
package/dist/react.js CHANGED
@@ -2,17 +2,158 @@
2
2
 
3
3
  // src/components/CameraCapture.tsx
4
4
  import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef3, useState as useState5 } from "react";
5
- import {
6
- Grip,
7
- Grid3x3,
8
- Proportions,
9
- SunMedium,
10
- Timer,
11
- X as X4,
12
- Zap,
13
- ZapOff,
14
- RefreshCw
15
- } from "lucide-react";
5
+
6
+ // src/components/icons.tsx
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function svgProps(props) {
9
+ return {
10
+ xmlns: "http://www.w3.org/2000/svg",
11
+ viewBox: "0 0 24 24",
12
+ width: 24,
13
+ height: 24,
14
+ fill: "none",
15
+ stroke: "currentColor",
16
+ strokeWidth: 2,
17
+ strokeLinecap: "round",
18
+ strokeLinejoin: "round",
19
+ "aria-hidden": true,
20
+ ...props
21
+ };
22
+ }
23
+ function CheckIcon(props) {
24
+ return /* @__PURE__ */ jsx("svg", { ...svgProps(props), children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
25
+ }
26
+ function ChevronLeftIcon(props) {
27
+ return /* @__PURE__ */ jsx("svg", { ...svgProps(props), children: /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" }) });
28
+ }
29
+ function ChevronRightIcon(props) {
30
+ return /* @__PURE__ */ jsx("svg", { ...svgProps(props), children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) });
31
+ }
32
+ function FlipHorizontal2Icon(props) {
33
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
34
+ /* @__PURE__ */ jsx("path", { d: "m3 7 5 5-5 5V7" }),
35
+ /* @__PURE__ */ jsx("path", { d: "m21 7-5 5 5 5V7" }),
36
+ /* @__PURE__ */ jsx("path", { d: "M12 20v2" }),
37
+ /* @__PURE__ */ jsx("path", { d: "M12 14v2" }),
38
+ /* @__PURE__ */ jsx("path", { d: "M12 8v2" }),
39
+ /* @__PURE__ */ jsx("path", { d: "M12 2v2" })
40
+ ] });
41
+ }
42
+ function Grid3x3Icon(props) {
43
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
44
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
45
+ /* @__PURE__ */ jsx("path", { d: "M3 9h18" }),
46
+ /* @__PURE__ */ jsx("path", { d: "M3 15h18" }),
47
+ /* @__PURE__ */ jsx("path", { d: "M9 3v18" }),
48
+ /* @__PURE__ */ jsx("path", { d: "M15 3v18" })
49
+ ] });
50
+ }
51
+ function GripIcon(props) {
52
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
53
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "5", r: "1" }),
54
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "5", r: "1" }),
55
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "1" }),
56
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1" }),
57
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "1" }),
58
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "12", r: "1" }),
59
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "19", r: "1" }),
60
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "19", r: "1" }),
61
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "19", r: "1" })
62
+ ] });
63
+ }
64
+ function ImagesIcon(props) {
65
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
66
+ /* @__PURE__ */ jsx("path", { d: "m22 11-1.296-1.296a2.4 2.4 0 0 0-3.408 0L11 16" }),
67
+ /* @__PURE__ */ jsx("path", { d: "M4 8a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2" }),
68
+ /* @__PURE__ */ jsx("circle", { cx: "13", cy: "7", r: "1", fill: "currentColor" }),
69
+ /* @__PURE__ */ jsx("rect", { x: "8", y: "2", width: "14", height: "14", rx: "2" })
70
+ ] });
71
+ }
72
+ function Loader2Icon(props) {
73
+ return /* @__PURE__ */ jsx("svg", { ...svgProps(props), children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
74
+ }
75
+ function LockIcon(props) {
76
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
77
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2" }),
78
+ /* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
79
+ ] });
80
+ }
81
+ function PencilIcon(props) {
82
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
83
+ /* @__PURE__ */ jsx("path", { d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" }),
84
+ /* @__PURE__ */ jsx("path", { d: "m15 5 4 4" })
85
+ ] });
86
+ }
87
+ function PlayIcon(props) {
88
+ return /* @__PURE__ */ jsx("svg", { ...svgProps(props), children: /* @__PURE__ */ jsx("path", { d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" }) });
89
+ }
90
+ function ProportionsIcon(props) {
91
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
92
+ /* @__PURE__ */ jsx("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" }),
93
+ /* @__PURE__ */ jsx("path", { d: "M12 9v11" }),
94
+ /* @__PURE__ */ jsx("path", { d: "M2 9h13a2 2 0 0 1 2 2v9" })
95
+ ] });
96
+ }
97
+ function RefreshCwIcon(props) {
98
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
99
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
100
+ /* @__PURE__ */ jsx("path", { d: "M21 3v5h-5" }),
101
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
102
+ /* @__PURE__ */ jsx("path", { d: "M8 16H3v5" })
103
+ ] });
104
+ }
105
+ function RotateCcwIcon(props) {
106
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
107
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
108
+ /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" })
109
+ ] });
110
+ }
111
+ function SunMediumIcon(props) {
112
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
113
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "4" }),
114
+ /* @__PURE__ */ jsx("path", { d: "M12 3v1" }),
115
+ /* @__PURE__ */ jsx("path", { d: "M12 20v1" }),
116
+ /* @__PURE__ */ jsx("path", { d: "M3 12h1" }),
117
+ /* @__PURE__ */ jsx("path", { d: "M20 12h1" }),
118
+ /* @__PURE__ */ jsx("path", { d: "m18.364 5.636-.707.707" }),
119
+ /* @__PURE__ */ jsx("path", { d: "m6.343 17.657-.707.707" }),
120
+ /* @__PURE__ */ jsx("path", { d: "m5.636 5.636.707.707" }),
121
+ /* @__PURE__ */ jsx("path", { d: "m17.657 17.657.707.707" })
122
+ ] });
123
+ }
124
+ function TimerIcon(props) {
125
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
126
+ /* @__PURE__ */ jsx("line", { x1: "10", x2: "14", y1: "2", y2: "2" }),
127
+ /* @__PURE__ */ jsx("line", { x1: "12", x2: "15", y1: "14", y2: "11" }),
128
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "14", r: "8" })
129
+ ] });
130
+ }
131
+ function Trash2Icon(props) {
132
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
133
+ /* @__PURE__ */ jsx("path", { d: "M10 11v6" }),
134
+ /* @__PURE__ */ jsx("path", { d: "M14 11v6" }),
135
+ /* @__PURE__ */ jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }),
136
+ /* @__PURE__ */ jsx("path", { d: "M3 6h18" }),
137
+ /* @__PURE__ */ jsx("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
138
+ ] });
139
+ }
140
+ function XIcon(props) {
141
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
142
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
143
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
144
+ ] });
145
+ }
146
+ function ZapIcon(props) {
147
+ return /* @__PURE__ */ jsx("svg", { ...svgProps(props), children: /* @__PURE__ */ jsx("path", { d: "M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" }) });
148
+ }
149
+ function ZapOffIcon(props) {
150
+ return /* @__PURE__ */ jsxs("svg", { ...svgProps(props), children: [
151
+ /* @__PURE__ */ jsx("path", { d: "M10.513 4.856 13.12 2.17a.5.5 0 0 1 .86.46l-1.377 4.317" }),
152
+ /* @__PURE__ */ jsx("path", { d: "M15.656 10H20a1 1 0 0 1 .78 1.63l-1.72 1.773" }),
153
+ /* @__PURE__ */ jsx("path", { d: "M16.273 16.273 10.88 21.83a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14H4a1 1 0 0 1-.78-1.63l4.507-4.643" }),
154
+ /* @__PURE__ */ jsx("path", { d: "m2 2 20 20" })
155
+ ] });
156
+ }
16
157
 
17
158
  // src/cn.ts
18
159
  import { twMerge } from "tailwind-merge";
@@ -145,14 +286,14 @@ function useTrackControls(stream) {
145
286
  }
146
287
 
147
288
  // src/components/ShutterButton.tsx
148
- import { jsx } from "react/jsx-runtime";
289
+ import { jsx as jsx2 } from "react/jsx-runtime";
149
290
  function ShutterButton({
150
291
  mode,
151
292
  recording,
152
293
  disabled = false,
153
294
  onPress
154
295
  }) {
155
- return /* @__PURE__ */ jsx(
296
+ return /* @__PURE__ */ jsx2(
156
297
  "button",
157
298
  {
158
299
  type: "button",
@@ -164,7 +305,7 @@ function ShutterButton({
164
305
  "border-[3.5px] border-white transition-opacity",
165
306
  disabled && "opacity-30"
166
307
  ),
167
- children: /* @__PURE__ */ jsx(
308
+ children: /* @__PURE__ */ jsx2(
168
309
  "span",
169
310
  {
170
311
  className: cn(
@@ -178,7 +319,7 @@ function ShutterButton({
178
319
  }
179
320
 
180
321
  // src/components/ModeSelector.tsx
181
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
322
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
182
323
  var SPRING_EASING = "linear(0, 0.0047 0.71%, 0.0189 1.44%, 0.0755 2.93%, 0.1692 4.49%, 0.3921 7.55%, 0.8121 12.94%, 0.9804 15.49%, 1.0946 18.14%, 1.1423 20.16%, 1.1568 21.62%, 1.1541 23.03%, 1.1113 26.4%, 1.0322 31.83%, 0.9902 36.25%, 0.9769 40.24%, 0.9844 45.87%, 1.0028 55.35%, 1.0075 63.42%, 1.0006 85.48%, 1)";
183
324
  var LABEL_BASE = "relative z-10 flex h-8 min-w-0 touch-manipulation items-center justify-center rounded-full px-3 text-[11px] font-semibold uppercase tracking-[0.12em] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/70 disabled:opacity-40";
184
325
  function ModeSelector({
@@ -191,7 +332,7 @@ function ModeSelector({
191
332
  }) {
192
333
  const segments = 3 + extraModes.length;
193
334
  const activeIndex = mode === "video" ? 0 : 1;
194
- return /* @__PURE__ */ jsxs(
335
+ return /* @__PURE__ */ jsxs2(
195
336
  "div",
196
337
  {
197
338
  role: "tablist",
@@ -199,7 +340,7 @@ function ModeSelector({
199
340
  className: "relative inline-grid rounded-full bg-white/10 p-1",
200
341
  style: { gridTemplateColumns: `repeat(${segments}, minmax(0, 1fr))` },
201
342
  children: [
202
- /* @__PURE__ */ jsx2(
343
+ /* @__PURE__ */ jsx3(
203
344
  "div",
204
345
  {
205
346
  "aria-hidden": true,
@@ -211,7 +352,7 @@ function ModeSelector({
211
352
  }
212
353
  }
213
354
  ),
214
- /* @__PURE__ */ jsx2(
355
+ /* @__PURE__ */ jsx3(
215
356
  "button",
216
357
  {
217
358
  type: "button",
@@ -226,7 +367,7 @@ function ModeSelector({
226
367
  children: "Video"
227
368
  }
228
369
  ),
229
- /* @__PURE__ */ jsx2(
370
+ /* @__PURE__ */ jsx3(
230
371
  "button",
231
372
  {
232
373
  type: "button",
@@ -241,7 +382,7 @@ function ModeSelector({
241
382
  children: "Photo"
242
383
  }
243
384
  ),
244
- /* @__PURE__ */ jsx2(
385
+ /* @__PURE__ */ jsx3(
245
386
  "button",
246
387
  {
247
388
  type: "button",
@@ -252,7 +393,7 @@ function ModeSelector({
252
393
  children: "Upload"
253
394
  }
254
395
  ),
255
- extraModes.map((extra) => /* @__PURE__ */ jsx2(
396
+ extraModes.map((extra) => /* @__PURE__ */ jsx3(
256
397
  "button",
257
398
  {
258
399
  type: "button",
@@ -270,7 +411,7 @@ function ModeSelector({
270
411
  }
271
412
 
272
413
  // src/components/ZoomRow.tsx
273
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
414
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
274
415
  function formatFactor(factor) {
275
416
  return factor < 1 ? `.${String(Math.round(factor * 10))}` : String(Math.round(factor * 10) / 10);
276
417
  }
@@ -279,9 +420,9 @@ function ZoomRow({ options, value, onSelect }) {
279
420
  const active = options.reduce(
280
421
  (best, opt) => Math.abs(opt - value) < Math.abs(best - value) ? opt : best
281
422
  );
282
- return /* @__PURE__ */ jsx3("div", { className: "flex items-center justify-center gap-3", children: options.map((opt) => {
423
+ return /* @__PURE__ */ jsx4("div", { className: "flex items-center justify-center gap-3", children: options.map((opt) => {
283
424
  const isActive = opt === active;
284
- return /* @__PURE__ */ jsxs2(
425
+ return /* @__PURE__ */ jsxs3(
285
426
  "button",
286
427
  {
287
428
  type: "button",
@@ -294,7 +435,7 @@ function ZoomRow({ options, value, onSelect }) {
294
435
  ),
295
436
  children: [
296
437
  formatFactor(opt),
297
- isActive && /* @__PURE__ */ jsx3("span", { className: "text-[10px]", children: "\xD7" })
438
+ isActive && /* @__PURE__ */ jsx4("span", { className: "text-[10px]", children: "\xD7" })
298
439
  ]
299
440
  },
300
441
  opt
@@ -303,15 +444,15 @@ function ZoomRow({ options, value, onSelect }) {
303
444
  }
304
445
 
305
446
  // src/components/OptionsGridPanel.tsx
306
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
447
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
307
448
  function OptionsGridPanel({
308
449
  open,
309
450
  onClose,
310
451
  tiles
311
452
  }) {
312
453
  if (!open) return null;
313
- return /* @__PURE__ */ jsxs3("div", { className: "absolute inset-0 z-40", children: [
314
- /* @__PURE__ */ jsx4(
454
+ return /* @__PURE__ */ jsxs4("div", { className: "absolute inset-0 z-40", children: [
455
+ /* @__PURE__ */ jsx5(
315
456
  "button",
316
457
  {
317
458
  type: "button",
@@ -320,13 +461,13 @@ function OptionsGridPanel({
320
461
  className: "absolute inset-0 bg-black/70"
321
462
  }
322
463
  ),
323
- /* @__PURE__ */ jsx4(
464
+ /* @__PURE__ */ jsx5(
324
465
  "div",
325
466
  {
326
467
  className: "absolute inset-x-3 bottom-3 rounded-[2.5rem] bg-[#3a3a3c]/95 px-6 py-8 shadow-2xl",
327
468
  style: { marginBottom: "env(safe-area-inset-bottom, 0px)" },
328
- children: /* @__PURE__ */ jsx4("div", { className: "grid grid-cols-3 gap-x-4 gap-y-7", children: tiles.map((tile) => /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center gap-2.5", children: [
329
- /* @__PURE__ */ jsx4(
469
+ children: /* @__PURE__ */ jsx5("div", { className: "grid grid-cols-3 gap-x-4 gap-y-7", children: tiles.map((tile) => /* @__PURE__ */ jsxs4("div", { className: "flex flex-col items-center gap-2.5", children: [
470
+ /* @__PURE__ */ jsx5(
330
471
  "button",
331
472
  {
332
473
  type: "button",
@@ -342,7 +483,7 @@ function OptionsGridPanel({
342
483
  children: tile.icon
343
484
  }
344
485
  ),
345
- /* @__PURE__ */ jsx4("span", { className: "text-[13px] font-semibold uppercase tracking-[0.14em] text-white", children: tile.valueLabel ? `${tile.label} ${tile.valueLabel}` : tile.label })
486
+ /* @__PURE__ */ jsx5("span", { className: "text-[13px] font-semibold uppercase tracking-[0.14em] text-white", children: tile.valueLabel ? `${tile.label} ${tile.valueLabel}` : tile.label })
346
487
  ] }, tile.id)) })
347
488
  }
348
489
  )
@@ -350,8 +491,7 @@ function OptionsGridPanel({
350
491
  }
351
492
 
352
493
  // src/components/CaptureSheet.tsx
353
- import { Loader2, X } from "lucide-react";
354
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
494
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
355
495
  function CaptureSheet({
356
496
  open,
357
497
  onClose,
@@ -363,8 +503,8 @@ function CaptureSheet({
363
503
  busyLabel = "Working\u2026"
364
504
  }) {
365
505
  if (!open) return null;
366
- return /* @__PURE__ */ jsxs4("div", { className: "absolute inset-0 z-50 flex flex-col justify-end", children: [
367
- /* @__PURE__ */ jsx5(
506
+ return /* @__PURE__ */ jsxs5("div", { className: "absolute inset-0 z-50 flex flex-col justify-end", children: [
507
+ /* @__PURE__ */ jsx6(
368
508
  "button",
369
509
  {
370
510
  type: "button",
@@ -373,30 +513,30 @@ function CaptureSheet({
373
513
  className: "absolute inset-0 bg-black/30"
374
514
  }
375
515
  ),
376
- /* @__PURE__ */ jsxs4(
516
+ /* @__PURE__ */ jsxs5(
377
517
  "div",
378
518
  {
379
519
  className: "relative mx-2 mb-2 rounded-[2rem] bg-[#f2f2f7] px-6 pb-6 pt-5 text-black shadow-2xl",
380
520
  style: { marginBottom: "calc(0.5rem + env(safe-area-inset-bottom, 0px))" },
381
521
  children: [
382
- /* @__PURE__ */ jsx5(
522
+ /* @__PURE__ */ jsx6(
383
523
  "button",
384
524
  {
385
525
  type: "button",
386
526
  onClick: onClose,
387
527
  "aria-label": "Close",
388
528
  className: "absolute right-4 top-4 flex h-9 w-9 items-center justify-center rounded-full bg-black/5 text-black/70 transition-colors hover:bg-black/10",
389
- children: /* @__PURE__ */ jsx5(X, { className: "h-5 w-5", strokeWidth: 2.5 })
529
+ children: /* @__PURE__ */ jsx6(XIcon, { className: "h-5 w-5", strokeWidth: 2.5 })
390
530
  }
391
531
  ),
392
- variant === "busy" ? /* @__PURE__ */ jsxs4("div", { className: "flex min-h-[220px] items-center justify-center gap-2.5", children: [
393
- /* @__PURE__ */ jsx5(Loader2, { className: "h-5 w-5 animate-spin text-black/50" }),
394
- /* @__PURE__ */ jsx5("span", { className: "text-[17px] font-medium text-black/80", children: busyLabel })
395
- ] }) : /* @__PURE__ */ jsxs4("div", { className: "pt-4", children: [
396
- icon && /* @__PURE__ */ jsx5("div", { className: "mb-5 text-[#0a84ff]", children: icon }),
397
- title && /* @__PURE__ */ jsx5("h2", { className: "mb-2 text-[26px] font-bold leading-tight", children: title }),
398
- body && /* @__PURE__ */ jsx5("div", { className: "text-[17px] leading-snug text-black/85", children: body }),
399
- actions.length > 0 && /* @__PURE__ */ jsx5("div", { className: "mt-7 flex flex-col gap-3", children: actions.map((action) => /* @__PURE__ */ jsx5(
532
+ variant === "busy" ? /* @__PURE__ */ jsxs5("div", { className: "flex min-h-[220px] items-center justify-center gap-2.5", children: [
533
+ /* @__PURE__ */ jsx6(Loader2Icon, { className: "h-5 w-5 animate-spin text-black/50" }),
534
+ /* @__PURE__ */ jsx6("span", { className: "text-[17px] font-medium text-black/80", children: busyLabel })
535
+ ] }) : /* @__PURE__ */ jsxs5("div", { className: "pt-4", children: [
536
+ icon && /* @__PURE__ */ jsx6("div", { className: "mb-5 text-[#0a84ff]", children: icon }),
537
+ title && /* @__PURE__ */ jsx6("h2", { className: "mb-2 text-[26px] font-bold leading-tight", children: title }),
538
+ body && /* @__PURE__ */ jsx6("div", { className: "text-[17px] leading-snug text-black/85", children: body }),
539
+ actions.length > 0 && /* @__PURE__ */ jsx6("div", { className: "mt-7 flex flex-col gap-3", children: actions.map((action) => /* @__PURE__ */ jsx6(
400
540
  "button",
401
541
  {
402
542
  type: "button",
@@ -417,22 +557,22 @@ function CaptureSheet({
417
557
  }
418
558
 
419
559
  // src/components/GridOverlay.tsx
420
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
560
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
421
561
  function GridOverlay({ visible }) {
422
562
  if (!visible) return null;
423
- return /* @__PURE__ */ jsxs5("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-0 z-10", children: [
424
- /* @__PURE__ */ jsx6("div", { className: "absolute inset-y-0 left-1/3 w-px bg-white/40" }),
425
- /* @__PURE__ */ jsx6("div", { className: "absolute inset-y-0 left-2/3 w-px bg-white/40" }),
426
- /* @__PURE__ */ jsx6("div", { className: "absolute inset-x-0 top-1/3 h-px bg-white/40" }),
427
- /* @__PURE__ */ jsx6("div", { className: "absolute inset-x-0 top-2/3 h-px bg-white/40" })
563
+ return /* @__PURE__ */ jsxs6("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-0 z-10", children: [
564
+ /* @__PURE__ */ jsx7("div", { className: "absolute inset-y-0 left-1/3 w-px bg-white/40" }),
565
+ /* @__PURE__ */ jsx7("div", { className: "absolute inset-y-0 left-2/3 w-px bg-white/40" }),
566
+ /* @__PURE__ */ jsx7("div", { className: "absolute inset-x-0 top-1/3 h-px bg-white/40" }),
567
+ /* @__PURE__ */ jsx7("div", { className: "absolute inset-x-0 top-2/3 h-px bg-white/40" })
428
568
  ] });
429
569
  }
430
570
 
431
571
  // src/components/CountdownOverlay.tsx
432
- import { jsx as jsx7 } from "react/jsx-runtime";
572
+ import { jsx as jsx8 } from "react/jsx-runtime";
433
573
  function CountdownOverlay({ seconds }) {
434
574
  if (seconds === null || seconds <= 0) return null;
435
- return /* @__PURE__ */ jsx7("div", { className: "pointer-events-none absolute inset-0 z-30 flex items-center justify-center", children: /* @__PURE__ */ jsx7(
575
+ return /* @__PURE__ */ jsx8("div", { className: "pointer-events-none absolute inset-0 z-30 flex items-center justify-center", children: /* @__PURE__ */ jsx8(
436
576
  "span",
437
577
  {
438
578
  className: "text-[120px] font-light text-white drop-shadow-lg [@starting-style]:scale-125 [@starting-style]:opacity-0 transition-all duration-300",
@@ -445,35 +585,43 @@ function CountdownOverlay({ seconds }) {
445
585
  // src/media/media-cache.ts
446
586
  import { useEffect as useEffect2, useState as useState2 } from "react";
447
587
  var MAX_ENTRIES = 80;
448
- var cache = /* @__PURE__ */ new Map();
449
- var listeners = /* @__PURE__ */ new Map();
588
+ var STATE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.capture.media-cache-state");
589
+ function getState() {
590
+ const holder = globalThis;
591
+ let state = holder[STATE_SLOT];
592
+ if (!state) {
593
+ state = { cache: /* @__PURE__ */ new Map(), listeners: /* @__PURE__ */ new Map() };
594
+ holder[STATE_SLOT] = state;
595
+ }
596
+ return state;
597
+ }
450
598
  function notify(key) {
451
- listeners.get(key)?.forEach((fn) => fn());
599
+ getState().listeners.get(key)?.forEach((fn) => fn());
452
600
  }
453
601
  function evictIfNeeded() {
454
- while (cache.size > MAX_ENTRIES) {
455
- const oldest = cache.keys().next().value;
602
+ while (getState().cache.size > MAX_ENTRIES) {
603
+ const oldest = getState().cache.keys().next().value;
456
604
  if (oldest === void 0) return;
457
- const entry = cache.get(oldest);
458
- cache.delete(oldest);
605
+ const entry = getState().cache.get(oldest);
606
+ getState().cache.delete(oldest);
459
607
  if (entry?.revoke && entry.url) URL.revokeObjectURL(entry.url);
460
608
  }
461
609
  }
462
610
  function touch(key, entry) {
463
- cache.delete(key);
464
- cache.set(key, entry);
611
+ getState().cache.delete(key);
612
+ getState().cache.set(key, entry);
465
613
  }
466
614
  function getMediaUrl(item) {
467
615
  if (item.src) return item.src;
468
616
  if (!item.resolve) return null;
469
- const existing = cache.get(item.key);
617
+ const existing = getState().cache.get(item.key);
470
618
  if (existing) {
471
619
  touch(item.key, existing);
472
620
  if (existing.url || existing.error) return existing.url;
473
621
  return null;
474
622
  }
475
623
  const entry = { url: null, revoke: false, promise: null, error: false };
476
- cache.set(item.key, entry);
624
+ getState().cache.set(item.key, entry);
477
625
  evictIfNeeded();
478
626
  entry.promise = item.resolve().then((resolved) => {
479
627
  const url = typeof resolved === "string" ? resolved : resolved.url;
@@ -491,8 +639,8 @@ function getMediaUrl(item) {
491
639
  return null;
492
640
  }
493
641
  function invalidateMedia(key) {
494
- const entry = cache.get(key);
495
- cache.delete(key);
642
+ const entry = getState().cache.get(key);
643
+ getState().cache.delete(key);
496
644
  if (entry?.revoke && entry.url) URL.revokeObjectURL(entry.url);
497
645
  notify(key);
498
646
  }
@@ -501,13 +649,13 @@ function useMediaUrl(item) {
501
649
  const key = item?.key ?? null;
502
650
  useEffect2(() => {
503
651
  if (!key) return;
504
- const set = listeners.get(key) ?? /* @__PURE__ */ new Set();
652
+ const set = getState().listeners.get(key) ?? /* @__PURE__ */ new Set();
505
653
  const fn = () => bump((n) => n + 1);
506
654
  set.add(fn);
507
- listeners.set(key, set);
655
+ getState().listeners.set(key, set);
508
656
  return () => {
509
657
  set.delete(fn);
510
- if (set.size === 0) listeners.delete(key);
658
+ if (set.size === 0) getState().listeners.delete(key);
511
659
  };
512
660
  }, [key]);
513
661
  if (!item) return null;
@@ -520,14 +668,14 @@ function primeMedia(items) {
520
668
  }
521
669
 
522
670
  // src/components/CaptureFilmstrip.tsx
523
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
671
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
524
672
  function CaptureFilmstrip({
525
673
  items,
526
674
  onOpen,
527
675
  limit = 12
528
676
  }) {
529
677
  if (items.length === 0) return null;
530
- return /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-1.5 overflow-x-auto py-1", children: items.slice(-limit).map((item) => /* @__PURE__ */ jsxs6(
678
+ return /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-1.5 overflow-x-auto py-1", children: items.slice(-limit).map((item) => /* @__PURE__ */ jsxs7(
531
679
  "button",
532
680
  {
533
681
  type: "button",
@@ -538,9 +686,9 @@ function CaptureFilmstrip({
538
686
  item.accent && "ring-2 ring-inset ring-amber-400"
539
687
  ),
540
688
  children: [
541
- /* @__PURE__ */ jsx8(FilmstripThumb, { item }),
542
- item.status === "uploading" && /* @__PURE__ */ jsx8("span", { className: "absolute inset-0 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ jsx8("span", { className: "h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/40 border-t-white" }) }),
543
- item.status === "error" && /* @__PURE__ */ jsx8("span", { className: "absolute inset-0 rounded ring-2 ring-inset ring-red-500" })
689
+ /* @__PURE__ */ jsx9(FilmstripThumb, { item }),
690
+ item.status === "uploading" && /* @__PURE__ */ jsx9("span", { className: "absolute inset-0 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ jsx9("span", { className: "h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/40 border-t-white" }) }),
691
+ item.status === "error" && /* @__PURE__ */ jsx9("span", { className: "absolute inset-0 rounded ring-2 ring-inset ring-red-500" })
544
692
  ]
545
693
  },
546
694
  item.key
@@ -549,7 +697,7 @@ function CaptureFilmstrip({
549
697
  function FilmstripThumb({ item }) {
550
698
  const url = useMediaUrl(item);
551
699
  if (item.kind === "audio") {
552
- return /* @__PURE__ */ jsx8("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsxs6(
700
+ return /* @__PURE__ */ jsx9("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsxs7(
553
701
  "svg",
554
702
  {
555
703
  viewBox: "0 0 24 24",
@@ -559,17 +707,17 @@ function FilmstripThumb({ item }) {
559
707
  strokeLinecap: "round",
560
708
  "aria-hidden": true,
561
709
  children: [
562
- /* @__PURE__ */ jsx8("path", { d: "M12 3v10" }),
563
- /* @__PURE__ */ jsx8("path", { d: "M8 7v4M16 7v4M4 9v1M20 9v1" }),
564
- /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "17", r: "3" })
710
+ /* @__PURE__ */ jsx9("path", { d: "M12 3v10" }),
711
+ /* @__PURE__ */ jsx9("path", { d: "M8 7v4M16 7v4M4 9v1M20 9v1" }),
712
+ /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "17", r: "3" })
565
713
  ]
566
714
  }
567
715
  ) });
568
716
  }
569
- if (!url) return /* @__PURE__ */ jsx8("span", { className: "block h-full w-full bg-white/5" });
717
+ if (!url) return /* @__PURE__ */ jsx9("span", { className: "block h-full w-full bg-white/5" });
570
718
  if (item.kind === "video") {
571
- return /* @__PURE__ */ jsxs6("span", { className: "relative block h-full w-full", children: [
572
- /* @__PURE__ */ jsx8(
719
+ return /* @__PURE__ */ jsxs7("span", { className: "relative block h-full w-full", children: [
720
+ /* @__PURE__ */ jsx9(
573
721
  "video",
574
722
  {
575
723
  src: url,
@@ -579,18 +727,18 @@ function FilmstripThumb({ item }) {
579
727
  className: "h-full w-full object-cover"
580
728
  }
581
729
  ),
582
- /* @__PURE__ */ jsx8(
730
+ /* @__PURE__ */ jsx9(
583
731
  "svg",
584
732
  {
585
733
  viewBox: "0 0 24 24",
586
734
  className: "absolute inset-0 m-auto h-4 w-4 fill-white drop-shadow",
587
735
  "aria-hidden": true,
588
- children: /* @__PURE__ */ jsx8("path", { d: "M8 5v14l11-7z" })
736
+ children: /* @__PURE__ */ jsx9("path", { d: "M8 5v14l11-7z" })
589
737
  }
590
738
  )
591
739
  ] });
592
740
  }
593
- return /* @__PURE__ */ jsx8("img", { src: url, alt: "", className: "h-full w-full object-cover" });
741
+ return /* @__PURE__ */ jsx9("img", { src: url, alt: "", className: "h-full w-full object-cover" });
594
742
  }
595
743
 
596
744
  // src/components/MediaViewer.tsx
@@ -601,8 +749,7 @@ import {
601
749
  useRef,
602
750
  useState as useState3
603
751
  } from "react";
604
- import { ChevronLeft, ChevronRight, Pencil, Trash2, X as X2 } from "lucide-react";
605
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
752
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
606
753
  var SWIPE_TRIGGER_PX = 40;
607
754
  var SWIPE_TRIGGER_VELOCITY = 0.25;
608
755
  var DISMISS_TRIGGER_PX = 110;
@@ -624,6 +771,7 @@ function MediaViewer({
624
771
  const clamped = Math.min(index, count - 1);
625
772
  const current = count > 0 ? items[clamped] : void 0;
626
773
  const [confirmingDelete, setConfirmingDelete] = useState3(false);
774
+ const activeVideoRef = useRef(null);
627
775
  const dragRef = useRef(null);
628
776
  const [drag, setDrag] = useState3(null);
629
777
  const [settling, setSettling] = useState3(false);
@@ -664,7 +812,7 @@ function MediaViewer({
664
812
  return () => window.removeEventListener("keydown", onKey);
665
813
  }, [go, onClose, keysDisabled]);
666
814
  const onPointerDown = useCallback2((e) => {
667
- if (e.target.closest("video, audio")) return;
815
+ if (e.target.closest("audio")) return;
668
816
  dragRef.current = {
669
817
  x0: e.clientX,
670
818
  y0: e.clientY,
@@ -711,6 +859,14 @@ function MediaViewer({
711
859
  return;
712
860
  }
713
861
  }
862
+ if (d.axis === null) {
863
+ const video = activeVideoRef.current;
864
+ if (video) {
865
+ if (video.paused) void video.play().catch(() => {
866
+ });
867
+ else video.pause();
868
+ }
869
+ }
714
870
  setDrag(null);
715
871
  setSettling(true);
716
872
  },
@@ -726,55 +882,55 @@ function MediaViewer({
726
882
  }, [items, clamped]);
727
883
  if (!current) return null;
728
884
  const canEdit = onEdit && current.kind === "photo";
729
- return /* @__PURE__ */ jsxs7("div", { className: "absolute inset-0 z-40 flex flex-col bg-black", children: [
730
- /* @__PURE__ */ jsxs7(
885
+ return /* @__PURE__ */ jsxs8("div", { className: "absolute inset-0 z-40 flex flex-col bg-black", children: [
886
+ /* @__PURE__ */ jsxs8(
731
887
  "div",
732
888
  {
733
889
  className: "absolute inset-x-0 top-0 z-20 flex items-center justify-between bg-gradient-to-b from-black/70 to-transparent p-3",
734
890
  style: safeTop,
735
891
  children: [
736
- /* @__PURE__ */ jsx9(
892
+ /* @__PURE__ */ jsx10(
737
893
  "button",
738
894
  {
739
895
  type: "button",
740
896
  onClick: onClose,
741
897
  "aria-label": "Close viewer",
742
898
  className: "flex h-10 w-10 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
743
- children: /* @__PURE__ */ jsx9(X2, { className: "h-5 w-5" })
899
+ children: /* @__PURE__ */ jsx10(XIcon, { className: "h-5 w-5" })
744
900
  }
745
901
  ),
746
- /* @__PURE__ */ jsxs7("span", { className: "rounded-full bg-black/50 px-3 py-1 text-sm tabular-nums text-white/90", children: [
902
+ /* @__PURE__ */ jsxs8("span", { className: "rounded-full bg-black/50 px-3 py-1 text-sm tabular-nums text-white/90", children: [
747
903
  clamped + 1,
748
904
  " / ",
749
905
  count
750
906
  ] }),
751
- /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-1", children: [
752
- canEdit ? /* @__PURE__ */ jsx9(
907
+ /* @__PURE__ */ jsxs8("span", { className: "flex items-center gap-1", children: [
908
+ canEdit ? /* @__PURE__ */ jsx10(
753
909
  "button",
754
910
  {
755
911
  type: "button",
756
912
  onClick: () => onEdit(current),
757
913
  "aria-label": "Edit this photo",
758
914
  className: "flex h-10 w-10 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
759
- children: /* @__PURE__ */ jsx9(Pencil, { className: "h-5 w-5" })
915
+ children: /* @__PURE__ */ jsx10(PencilIcon, { className: "h-5 w-5" })
760
916
  }
761
917
  ) : null,
762
- onDelete ? /* @__PURE__ */ jsx9(
918
+ onDelete ? /* @__PURE__ */ jsx10(
763
919
  "button",
764
920
  {
765
921
  type: "button",
766
922
  onClick: () => setConfirmingDelete(true),
767
923
  "aria-label": "Delete this file",
768
924
  className: "flex h-10 w-10 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
769
- children: /* @__PURE__ */ jsx9(Trash2, { className: "h-5 w-5" })
925
+ children: /* @__PURE__ */ jsx10(Trash2Icon, { className: "h-5 w-5" })
770
926
  }
771
- ) : /* @__PURE__ */ jsx9("span", { className: "h-10 w-10", "aria-hidden": true })
927
+ ) : /* @__PURE__ */ jsx10("span", { className: "h-10 w-10", "aria-hidden": true })
772
928
  ] })
773
929
  ]
774
930
  }
775
931
  ),
776
- /* @__PURE__ */ jsxs7("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [
777
- /* @__PURE__ */ jsx9(
932
+ /* @__PURE__ */ jsxs8("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [
933
+ /* @__PURE__ */ jsx10(
778
934
  "div",
779
935
  {
780
936
  className: "absolute inset-0 touch-none",
@@ -787,39 +943,47 @@ function MediaViewer({
787
943
  onPointerMove,
788
944
  onPointerUp: endDrag,
789
945
  onPointerCancel: endDrag,
790
- children: /* @__PURE__ */ jsx9(ViewerSlide, { item: current, active: true }, current.key)
946
+ children: /* @__PURE__ */ jsx10(
947
+ ViewerSlide,
948
+ {
949
+ item: current,
950
+ active: true,
951
+ videoRef: activeVideoRef
952
+ },
953
+ current.key
954
+ )
791
955
  }
792
956
  ),
793
- /* @__PURE__ */ jsx9(
957
+ /* @__PURE__ */ jsx10(
794
958
  "div",
795
959
  {
796
960
  "aria-hidden": true,
797
961
  className: "pointer-events-none absolute inset-0 opacity-0",
798
- children: neighborKeys.map((m) => /* @__PURE__ */ jsx9("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx9(ViewerSlide, { item: m, active: false }) }, m.key))
962
+ children: neighborKeys.map((m) => /* @__PURE__ */ jsx10("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx10(ViewerSlide, { item: m, active: false }) }, m.key))
799
963
  }
800
964
  ),
801
- clamped > 0 && /* @__PURE__ */ jsx9(
965
+ clamped > 0 && /* @__PURE__ */ jsx10(
802
966
  "button",
803
967
  {
804
968
  type: "button",
805
969
  onClick: () => go(-1),
806
970
  "aria-label": "Previous file",
807
971
  className: "absolute left-2 top-1/2 z-20 hidden h-11 w-11 -translate-y-1/2 items-center justify-center rounded-full bg-black/40 text-white hover:bg-black/60 sm:flex",
808
- children: /* @__PURE__ */ jsx9(ChevronLeft, { className: "h-6 w-6" })
972
+ children: /* @__PURE__ */ jsx10(ChevronLeftIcon, { className: "h-6 w-6" })
809
973
  }
810
974
  ),
811
- clamped < count - 1 && /* @__PURE__ */ jsx9(
975
+ clamped < count - 1 && /* @__PURE__ */ jsx10(
812
976
  "button",
813
977
  {
814
978
  type: "button",
815
979
  onClick: () => go(1),
816
980
  "aria-label": "Next file",
817
981
  className: "absolute right-2 top-1/2 z-20 hidden h-11 w-11 -translate-y-1/2 items-center justify-center rounded-full bg-black/40 text-white hover:bg-black/60 sm:flex",
818
- children: /* @__PURE__ */ jsx9(ChevronRight, { className: "h-6 w-6" })
982
+ children: /* @__PURE__ */ jsx10(ChevronRightIcon, { className: "h-6 w-6" })
819
983
  }
820
984
  )
821
985
  ] }),
822
- confirmingDelete && onDelete && /* @__PURE__ */ jsxs7(
986
+ confirmingDelete && onDelete && /* @__PURE__ */ jsxs8(
823
987
  "div",
824
988
  {
825
989
  className: "absolute inset-x-0 bottom-0 z-30 bg-black/85 px-4 pt-4 backdrop-blur-sm",
@@ -827,14 +991,14 @@ function MediaViewer({
827
991
  paddingBottom: "calc(1rem + env(safe-area-inset-bottom, 0px))"
828
992
  },
829
993
  children: [
830
- /* @__PURE__ */ jsxs7("p", { className: "pb-3 text-center text-sm text-white/85", children: [
994
+ /* @__PURE__ */ jsxs8("p", { className: "pb-3 text-center text-sm text-white/85", children: [
831
995
  "Delete this ",
832
996
  current.kind === "video" ? "video" : current.kind === "audio" ? "voice note" : "photo",
833
997
  "? ",
834
998
  deleteConsequence
835
999
  ] }),
836
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-center gap-3", children: [
837
- /* @__PURE__ */ jsx9(
1000
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-center gap-3", children: [
1001
+ /* @__PURE__ */ jsx10(
838
1002
  "button",
839
1003
  {
840
1004
  type: "button",
@@ -843,7 +1007,7 @@ function MediaViewer({
843
1007
  children: "Keep it"
844
1008
  }
845
1009
  ),
846
- /* @__PURE__ */ jsx9(
1010
+ /* @__PURE__ */ jsx10(
847
1011
  "button",
848
1012
  {
849
1013
  type: "button",
@@ -859,12 +1023,12 @@ function MediaViewer({
859
1023
  ]
860
1024
  }
861
1025
  ),
862
- count > 1 && count <= 12 && /* @__PURE__ */ jsx9(
1026
+ count > 1 && count <= 12 && /* @__PURE__ */ jsx10(
863
1027
  "div",
864
1028
  {
865
1029
  className: "pointer-events-none absolute inset-x-0 bottom-4 z-20 flex justify-center gap-1.5",
866
1030
  style: safeMarginBottom,
867
- children: items.map((m, i) => /* @__PURE__ */ jsx9(
1031
+ children: items.map((m, i) => /* @__PURE__ */ jsx10(
868
1032
  "span",
869
1033
  {
870
1034
  className: cn(
@@ -880,16 +1044,17 @@ function MediaViewer({
880
1044
  }
881
1045
  function ViewerSlide({
882
1046
  item,
883
- active
1047
+ active,
1048
+ videoRef
884
1049
  }) {
885
1050
  const url = useMediaUrl(item);
886
1051
  if (!url) {
887
- return active ? /* @__PURE__ */ jsx9("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx9("span", { className: "h-8 w-8 animate-spin rounded-full border-2 border-white/30 border-t-white" }) }) : null;
1052
+ return active ? /* @__PURE__ */ jsx10("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx10("span", { className: "h-8 w-8 animate-spin rounded-full border-2 border-white/30 border-t-white" }) }) : null;
888
1053
  }
889
1054
  if (item.kind === "audio") {
890
1055
  if (!active) return null;
891
- return /* @__PURE__ */ jsxs7("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-6 px-8", children: [
892
- /* @__PURE__ */ jsxs7(
1056
+ return /* @__PURE__ */ jsxs8("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-6 px-8", children: [
1057
+ /* @__PURE__ */ jsxs8(
893
1058
  "svg",
894
1059
  {
895
1060
  viewBox: "0 0 24 24",
@@ -899,32 +1064,19 @@ function ViewerSlide({
899
1064
  strokeLinecap: "round",
900
1065
  "aria-hidden": true,
901
1066
  children: [
902
- /* @__PURE__ */ jsx9("path", { d: "M12 2v12" }),
903
- /* @__PURE__ */ jsx9("path", { d: "M7 6v6M17 6v6M2 9v2M22 9v2" }),
904
- /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "19", r: "3" })
1067
+ /* @__PURE__ */ jsx10("path", { d: "M12 2v12" }),
1068
+ /* @__PURE__ */ jsx10("path", { d: "M7 6v6M17 6v6M2 9v2M22 9v2" }),
1069
+ /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "19", r: "3" })
905
1070
  ]
906
1071
  }
907
1072
  ),
908
- /* @__PURE__ */ jsx9("audio", { src: url, controls: true, className: "w-full max-w-sm" })
1073
+ /* @__PURE__ */ jsx10("audio", { src: url, controls: true, className: "w-full max-w-sm" })
909
1074
  ] });
910
1075
  }
911
1076
  if (item.kind === "video") {
912
- return /* @__PURE__ */ jsx9(
913
- "video",
914
- {
915
- src: url,
916
- controls: active,
917
- playsInline: true,
918
- preload: active ? "auto" : "metadata",
919
- muted: !active,
920
- className: cn(
921
- "absolute inset-0 h-full w-full object-contain",
922
- active ? "pointer-events-auto" : "pointer-events-none"
923
- )
924
- }
925
- );
1077
+ return /* @__PURE__ */ jsx10(VideoSlide, { url, active, videoRef });
926
1078
  }
927
- return /* @__PURE__ */ jsx9(
1079
+ return /* @__PURE__ */ jsx10(
928
1080
  "img",
929
1081
  {
930
1082
  src: url,
@@ -935,6 +1087,51 @@ function ViewerSlide({
935
1087
  }
936
1088
  );
937
1089
  }
1090
+ function VideoSlide({
1091
+ url,
1092
+ active,
1093
+ videoRef
1094
+ }) {
1095
+ const [paused, setPaused] = useState3(true);
1096
+ const [progress, setProgress] = useState3(0);
1097
+ const localRef = useRef(null);
1098
+ useEffect3(() => {
1099
+ if (!active || !videoRef) return;
1100
+ videoRef.current = localRef.current;
1101
+ return () => {
1102
+ if (videoRef.current === localRef.current) videoRef.current = null;
1103
+ };
1104
+ }, [active, videoRef]);
1105
+ return /* @__PURE__ */ jsxs8("div", { className: "pointer-events-none absolute inset-0", children: [
1106
+ /* @__PURE__ */ jsx10(
1107
+ "video",
1108
+ {
1109
+ ref: localRef,
1110
+ src: url,
1111
+ playsInline: true,
1112
+ preload: active ? "auto" : "metadata",
1113
+ muted: !active,
1114
+ loop: false,
1115
+ onPlay: () => setPaused(false),
1116
+ onPause: () => setPaused(true),
1117
+ onEnded: () => setPaused(true),
1118
+ onTimeUpdate: (e) => {
1119
+ const v = e.currentTarget;
1120
+ setProgress(v.duration > 0 ? v.currentTime / v.duration : 0);
1121
+ },
1122
+ className: "absolute inset-0 h-full w-full object-contain"
1123
+ }
1124
+ ),
1125
+ active && paused && /* @__PURE__ */ jsx10("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx10("span", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-black/45", children: /* @__PURE__ */ jsx10(PlayIcon, { className: "ml-1 h-8 w-8 fill-white text-white" }) }) }),
1126
+ active && !paused && /* @__PURE__ */ jsx10("span", { className: "absolute inset-x-4 bottom-2 h-0.5 overflow-hidden rounded-full bg-white/25", children: /* @__PURE__ */ jsx10(
1127
+ "span",
1128
+ {
1129
+ className: "block h-full rounded-full bg-white",
1130
+ style: { width: `${Math.round(progress * 100)}%` }
1131
+ }
1132
+ ) })
1133
+ ] });
1134
+ }
938
1135
 
939
1136
  // src/components/ImageEditSheet.tsx
940
1137
  import {
@@ -943,8 +1140,7 @@ import {
943
1140
  useRef as useRef2,
944
1141
  useState as useState4
945
1142
  } from "react";
946
- import { Check, FlipHorizontal2, RotateCcw, X as X3 } from "lucide-react";
947
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1143
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
948
1144
  var ASPECTS = [
949
1145
  { id: "free", label: "Free", ratio: null },
950
1146
  { id: "1:1", label: "Square", ratio: 1 },
@@ -1124,14 +1320,14 @@ function ImageEditSheet({
1124
1320
  }
1125
1321
  }, [crop, onSave, onClose]);
1126
1322
  if (!open || !src) return null;
1127
- return /* @__PURE__ */ jsxs8("div", { className: "absolute inset-0 z-50 flex flex-col bg-black", children: [
1128
- /* @__PURE__ */ jsxs8(
1323
+ return /* @__PURE__ */ jsxs9("div", { className: "absolute inset-0 z-50 flex flex-col bg-black", children: [
1324
+ /* @__PURE__ */ jsxs9(
1129
1325
  "div",
1130
1326
  {
1131
1327
  className: "flex shrink-0 items-center justify-between px-4",
1132
1328
  style: { paddingTop: "env(safe-area-inset-top, 0px)" },
1133
1329
  children: [
1134
- /* @__PURE__ */ jsxs8(
1330
+ /* @__PURE__ */ jsxs9(
1135
1331
  "button",
1136
1332
  {
1137
1333
  type: "button",
@@ -1139,13 +1335,13 @@ function ImageEditSheet({
1139
1335
  "aria-label": "Cancel editing",
1140
1336
  className: "flex h-11 items-center gap-1.5 rounded-full px-3 text-[15px] font-medium text-white",
1141
1337
  children: [
1142
- /* @__PURE__ */ jsx10(X3, { className: "h-5 w-5" }),
1338
+ /* @__PURE__ */ jsx11(XIcon, { className: "h-5 w-5" }),
1143
1339
  "Cancel"
1144
1340
  ]
1145
1341
  }
1146
1342
  ),
1147
- /* @__PURE__ */ jsx10("span", { className: "text-[15px] font-semibold text-white/90", children: "Edit" }),
1148
- /* @__PURE__ */ jsxs8(
1343
+ /* @__PURE__ */ jsx11("span", { className: "text-[15px] font-semibold text-white/90", children: "Edit" }),
1344
+ /* @__PURE__ */ jsxs9(
1149
1345
  "button",
1150
1346
  {
1151
1347
  type: "button",
@@ -1154,7 +1350,7 @@ function ImageEditSheet({
1154
1350
  "aria-label": "Save edited image",
1155
1351
  className: "flex h-11 items-center gap-1.5 rounded-full px-3 text-[15px] font-semibold text-[#FFCC00] disabled:opacity-50",
1156
1352
  children: [
1157
- /* @__PURE__ */ jsx10(Check, { className: "h-5 w-5" }),
1353
+ /* @__PURE__ */ jsx11(CheckIcon, { className: "h-5 w-5" }),
1158
1354
  "Save"
1159
1355
  ]
1160
1356
  }
@@ -1162,7 +1358,7 @@ function ImageEditSheet({
1162
1358
  ]
1163
1359
  }
1164
1360
  ),
1165
- /* @__PURE__ */ jsx10(
1361
+ /* @__PURE__ */ jsx11(
1166
1362
  "div",
1167
1363
  {
1168
1364
  ref: stageRef,
@@ -1170,8 +1366,8 @@ function ImageEditSheet({
1170
1366
  onPointerMove,
1171
1367
  onPointerUp,
1172
1368
  onPointerCancel: onPointerUp,
1173
- children: /* @__PURE__ */ jsxs8("div", { className: "relative max-h-full max-w-full", children: [
1174
- /* @__PURE__ */ jsx10(
1369
+ children: /* @__PURE__ */ jsxs9("div", { className: "relative max-h-full max-w-full", children: [
1370
+ /* @__PURE__ */ jsx11(
1175
1371
  "img",
1176
1372
  {
1177
1373
  ref: imgRef,
@@ -1181,7 +1377,7 @@ function ImageEditSheet({
1181
1377
  className: "max-h-[62dvh] max-w-full select-none object-contain"
1182
1378
  }
1183
1379
  ),
1184
- /* @__PURE__ */ jsx10(
1380
+ /* @__PURE__ */ jsx11(
1185
1381
  "div",
1186
1382
  {
1187
1383
  role: "presentation",
@@ -1193,7 +1389,7 @@ function ImageEditSheet({
1193
1389
  width: `${crop.w * 100}%`,
1194
1390
  height: `${crop.h * 100}%`
1195
1391
  },
1196
- children: ["nw", "ne", "sw", "se"].map((corner) => /* @__PURE__ */ jsx10(
1392
+ children: ["nw", "ne", "sw", "se"].map((corner) => /* @__PURE__ */ jsx11(
1197
1393
  "span",
1198
1394
  {
1199
1395
  role: "presentation",
@@ -1214,9 +1410,9 @@ function ImageEditSheet({
1214
1410
  ] })
1215
1411
  }
1216
1412
  ),
1217
- /* @__PURE__ */ jsxs8("div", { className: "shrink-0", style: { paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
1218
- editError && /* @__PURE__ */ jsx10("p", { className: "px-6 pb-2 text-center text-sm text-[#FF6961]", children: editError }),
1219
- /* @__PURE__ */ jsx10("div", { className: "flex items-center justify-center gap-2 pb-2", children: ASPECTS.map((a) => /* @__PURE__ */ jsx10(
1413
+ /* @__PURE__ */ jsxs9("div", { className: "shrink-0", style: { paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
1414
+ editError && /* @__PURE__ */ jsx11("p", { className: "px-6 pb-2 text-center text-sm text-[#FF6961]", children: editError }),
1415
+ /* @__PURE__ */ jsx11("div", { className: "flex items-center justify-center gap-2 pb-2", children: ASPECTS.map((a) => /* @__PURE__ */ jsx11(
1220
1416
  "button",
1221
1417
  {
1222
1418
  type: "button",
@@ -1230,25 +1426,25 @@ function ImageEditSheet({
1230
1426
  },
1231
1427
  a.id
1232
1428
  )) }),
1233
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-center gap-6 pb-4", children: [
1234
- /* @__PURE__ */ jsx10(
1429
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-center gap-6 pb-4", children: [
1430
+ /* @__PURE__ */ jsx11(
1235
1431
  "button",
1236
1432
  {
1237
1433
  type: "button",
1238
1434
  onClick: () => bake("rotate-left"),
1239
1435
  "aria-label": "Rotate left",
1240
1436
  className: "flex h-12 w-12 touch-manipulation items-center justify-center rounded-full bg-white/10 text-white",
1241
- children: /* @__PURE__ */ jsx10(RotateCcw, { className: "h-5 w-5" })
1437
+ children: /* @__PURE__ */ jsx11(RotateCcwIcon, { className: "h-5 w-5" })
1242
1438
  }
1243
1439
  ),
1244
- /* @__PURE__ */ jsx10(
1440
+ /* @__PURE__ */ jsx11(
1245
1441
  "button",
1246
1442
  {
1247
1443
  type: "button",
1248
1444
  onClick: () => bake("flip"),
1249
1445
  "aria-label": "Flip horizontally",
1250
1446
  className: "flex h-12 w-12 touch-manipulation items-center justify-center rounded-full bg-white/10 text-white",
1251
- children: /* @__PURE__ */ jsx10(FlipHorizontal2, { className: "h-5 w-5" })
1447
+ children: /* @__PURE__ */ jsx11(FlipHorizontal2Icon, { className: "h-5 w-5" })
1252
1448
  }
1253
1449
  )
1254
1450
  ] })
@@ -1257,7 +1453,7 @@ function ImageEditSheet({
1257
1453
  }
1258
1454
 
1259
1455
  // src/components/CameraCapture.tsx
1260
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1456
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1261
1457
  function formatElapsed(totalSeconds) {
1262
1458
  const m = Math.floor(totalSeconds / 60);
1263
1459
  const s = String(totalSeconds % 60).padStart(2, "0");
@@ -1336,7 +1532,7 @@ function CameraCapture({
1336
1532
  {
1337
1533
  id: "flash",
1338
1534
  label: "Flash",
1339
- icon: controls.torchOn ? /* @__PURE__ */ jsx11(Zap, { className: "h-6 w-6", fill: "currentColor" }) : /* @__PURE__ */ jsx11(ZapOff, { className: "h-6 w-6" }),
1535
+ icon: controls.torchOn ? /* @__PURE__ */ jsx12(ZapIcon, { className: "h-6 w-6", fill: "currentColor" }) : /* @__PURE__ */ jsx12(ZapOffIcon, { className: "h-6 w-6" }),
1340
1536
  active: controls.torchOn,
1341
1537
  onPress: controls.toggleTorch
1342
1538
  }
@@ -1344,7 +1540,7 @@ function CameraCapture({
1344
1540
  {
1345
1541
  id: "timer",
1346
1542
  label: "Timer",
1347
- icon: /* @__PURE__ */ jsx11(Timer, { className: "h-6 w-6" }),
1543
+ icon: /* @__PURE__ */ jsx12(TimerIcon, { className: "h-6 w-6" }),
1348
1544
  active: timerSetting !== 0,
1349
1545
  valueLabel: timerSetting === 0 ? void 0 : `${timerSetting}s`,
1350
1546
  onPress: cycleTimer
@@ -1352,7 +1548,7 @@ function CameraCapture({
1352
1548
  {
1353
1549
  id: "grid",
1354
1550
  label: "Grid",
1355
- icon: /* @__PURE__ */ jsx11(Grid3x3, { className: "h-6 w-6" }),
1551
+ icon: /* @__PURE__ */ jsx12(Grid3x3Icon, { className: "h-6 w-6" }),
1356
1552
  active: gridOn,
1357
1553
  onPress: () => setGridOn((g) => !g)
1358
1554
  },
@@ -1360,7 +1556,7 @@ function CameraCapture({
1360
1556
  {
1361
1557
  id: "aspect",
1362
1558
  label: "Aspect",
1363
- icon: /* @__PURE__ */ jsx11(Proportions, { className: "h-6 w-6" }),
1559
+ icon: /* @__PURE__ */ jsx12(ProportionsIcon, { className: "h-6 w-6" }),
1364
1560
  active: aspect !== "full",
1365
1561
  valueLabel: aspect === "full" ? void 0 : aspect,
1366
1562
  onPress: () => setAspect(
@@ -1371,7 +1567,7 @@ function CameraCapture({
1371
1567
  {
1372
1568
  id: "exposure",
1373
1569
  label: "Exposure",
1374
- icon: /* @__PURE__ */ jsx11(SunMedium, { className: "h-6 w-6" }),
1570
+ icon: /* @__PURE__ */ jsx12(SunMediumIcon, { className: "h-6 w-6" }),
1375
1571
  active: controls.exposure !== 0 || exposureOpen,
1376
1572
  valueLabel: controls.exposure === 0 ? void 0 : `${controls.exposure > 0 ? "+" : ""}${controls.exposure}`,
1377
1573
  onPress: () => setExposureOpen((o) => !o)
@@ -1380,15 +1576,15 @@ function CameraCapture({
1380
1576
  ];
1381
1577
  const tiles = [...coreTiles, ...slots.optionTiles ?? []];
1382
1578
  const blocked = engine.blocked !== null;
1383
- return /* @__PURE__ */ jsxs9("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
1384
- /* @__PURE__ */ jsx11("div", { className: "absolute inset-0", children: preview }),
1385
- /* @__PURE__ */ jsx11(GridOverlay, { visible: gridOn && !blocked }),
1386
- mode === "photo" && aspect !== "full" && !blocked && /* @__PURE__ */ jsx11(
1579
+ return /* @__PURE__ */ jsxs10("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
1580
+ /* @__PURE__ */ jsx12("div", { className: "absolute inset-0", children: preview }),
1581
+ /* @__PURE__ */ jsx12(GridOverlay, { visible: gridOn && !blocked }),
1582
+ mode === "photo" && aspect !== "full" && !blocked && /* @__PURE__ */ jsx12(
1387
1583
  "div",
1388
1584
  {
1389
1585
  "aria-hidden": true,
1390
1586
  className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center",
1391
- children: /* @__PURE__ */ jsx11(
1587
+ children: /* @__PURE__ */ jsx12(
1392
1588
  "div",
1393
1589
  {
1394
1590
  className: "shadow-[0_0_0_9999px_rgba(0,0,0,0.45)]",
@@ -1403,25 +1599,25 @@ function CameraCapture({
1403
1599
  )
1404
1600
  }
1405
1601
  ),
1406
- /* @__PURE__ */ jsx11(CountdownOverlay, { seconds: countdown }),
1407
- !controlsHidden && /* @__PURE__ */ jsx11(
1602
+ /* @__PURE__ */ jsx12(CountdownOverlay, { seconds: countdown }),
1603
+ !controlsHidden && /* @__PURE__ */ jsx12(
1408
1604
  "div",
1409
1605
  {
1410
1606
  className: "absolute inset-x-0 top-0 z-20 bg-black/65 backdrop-blur-[2px]",
1411
1607
  style: safeTop,
1412
- children: /* @__PURE__ */ jsxs9("div", { className: "flex h-11 items-center gap-0.5 px-1.5", children: [
1413
- onClose ? /* @__PURE__ */ jsx11(
1608
+ children: /* @__PURE__ */ jsxs10("div", { className: "flex h-11 items-center gap-0.5 px-1.5", children: [
1609
+ onClose ? /* @__PURE__ */ jsx12(
1414
1610
  "button",
1415
1611
  {
1416
1612
  type: "button",
1417
1613
  onClick: onClose,
1418
1614
  "aria-label": "Close camera",
1419
1615
  className: "flex h-10 w-10 shrink-0 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
1420
- children: /* @__PURE__ */ jsx11(X4, { className: "h-5 w-5" })
1616
+ children: /* @__PURE__ */ jsx12(XIcon, { className: "h-5 w-5" })
1421
1617
  }
1422
- ) : /* @__PURE__ */ jsx11("span", { className: "w-10 shrink-0" }),
1423
- /* @__PURE__ */ jsx11("div", { className: "min-w-0 flex-1", children: slots.topBarCenter }),
1424
- controls.torchSupported && /* @__PURE__ */ jsx11(
1618
+ ) : /* @__PURE__ */ jsx12("span", { className: "w-10 shrink-0" }),
1619
+ /* @__PURE__ */ jsx12("div", { className: "min-w-0 flex-1", children: slots.topBarCenter }),
1620
+ controls.torchSupported && /* @__PURE__ */ jsx12(
1425
1621
  "button",
1426
1622
  {
1427
1623
  type: "button",
@@ -1432,8 +1628,8 @@ function CameraCapture({
1432
1628
  "flex h-10 w-10 shrink-0 touch-manipulation items-center justify-center rounded-full transition-colors",
1433
1629
  controls.torchOn ? "text-[#FFCC00]" : "text-white hover:bg-white/10"
1434
1630
  ),
1435
- children: /* @__PURE__ */ jsx11(
1436
- Zap,
1631
+ children: /* @__PURE__ */ jsx12(
1632
+ ZapIcon,
1437
1633
  {
1438
1634
  className: "h-5 w-5",
1439
1635
  fill: controls.torchOn ? "currentColor" : "none"
@@ -1442,7 +1638,7 @@ function CameraCapture({
1442
1638
  }
1443
1639
  ),
1444
1640
  slots.topBarTrailing,
1445
- /* @__PURE__ */ jsx11(
1641
+ /* @__PURE__ */ jsx12(
1446
1642
  "button",
1447
1643
  {
1448
1644
  type: "button",
@@ -1453,28 +1649,28 @@ function CameraCapture({
1453
1649
  "flex h-10 w-10 shrink-0 touch-manipulation items-center justify-center rounded-full transition-colors",
1454
1650
  optionsOpen ? "bg-white/20 text-white" : "text-white hover:bg-white/10"
1455
1651
  ),
1456
- children: /* @__PURE__ */ jsx11(Grip, { className: "h-5 w-5" })
1652
+ children: /* @__PURE__ */ jsx12(GripIcon, { className: "h-5 w-5" })
1457
1653
  }
1458
1654
  )
1459
1655
  ] })
1460
1656
  }
1461
1657
  ),
1462
- /* @__PURE__ */ jsxs9(
1658
+ /* @__PURE__ */ jsxs10(
1463
1659
  "div",
1464
1660
  {
1465
1661
  className: "pointer-events-none absolute inset-x-0 top-[50px] z-20 flex flex-col items-center gap-1.5",
1466
1662
  style: safeMarginTop,
1467
1663
  children: [
1468
- engine.recording && /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2 rounded-full bg-black/60 px-3 py-1.5 text-sm font-medium text-white", children: [
1469
- /* @__PURE__ */ jsx11("span", { className: "h-2.5 w-2.5 animate-pulse rounded-full bg-[#FF3B30]" }),
1664
+ engine.recording && /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-2 rounded-full bg-black/60 px-3 py-1.5 text-sm font-medium text-white", children: [
1665
+ /* @__PURE__ */ jsx12("span", { className: "h-2.5 w-2.5 animate-pulse rounded-full bg-[#FF3B30]" }),
1470
1666
  formatElapsed(engine.recordElapsedSeconds)
1471
1667
  ] }),
1472
1668
  slots.statusChips
1473
1669
  ]
1474
1670
  }
1475
1671
  ),
1476
- !controlsHidden && /* @__PURE__ */ jsxs9("div", { className: "absolute inset-x-0 bottom-0 z-20", children: [
1477
- !blocked && controls.zoomOptions.length >= 2 && /* @__PURE__ */ jsx11("div", { className: "mb-2", children: /* @__PURE__ */ jsx11(
1672
+ !controlsHidden && /* @__PURE__ */ jsxs10("div", { className: "absolute inset-x-0 bottom-0 z-20", children: [
1673
+ !blocked && controls.zoomOptions.length >= 2 && /* @__PURE__ */ jsx12("div", { className: "mb-2", children: /* @__PURE__ */ jsx12(
1478
1674
  ZoomRow,
1479
1675
  {
1480
1676
  options: controls.zoomOptions,
@@ -1482,17 +1678,17 @@ function CameraCapture({
1482
1678
  onSelect: controls.setZoom
1483
1679
  }
1484
1680
  ) }),
1485
- media && media.items.length > 0 && /* @__PURE__ */ jsx11("div", { className: "mb-1.5 px-2", children: /* @__PURE__ */ jsx11(
1681
+ media && media.items.length > 0 && /* @__PURE__ */ jsx12("div", { className: "mb-1.5 px-2", children: /* @__PURE__ */ jsx12(
1486
1682
  CaptureFilmstrip,
1487
1683
  {
1488
1684
  items: media.items,
1489
1685
  onOpen: (item) => setViewerKey(item.key)
1490
1686
  }
1491
1687
  ) }),
1492
- slots.aboveBar && /* @__PURE__ */ jsx11("div", { className: "mb-1.5 px-2", children: slots.aboveBar }),
1493
- exposureOpen && controls.exposureSupported && controls.exposureRange && /* @__PURE__ */ jsxs9("div", { className: "mx-auto mb-3 flex w-64 items-center gap-3 rounded-full bg-black/55 px-4 py-2", children: [
1494
- /* @__PURE__ */ jsx11(SunMedium, { className: "h-4 w-4 shrink-0 text-[#FFCC00]" }),
1495
- /* @__PURE__ */ jsx11(
1688
+ slots.aboveBar && /* @__PURE__ */ jsx12("div", { className: "mb-1.5 px-2", children: slots.aboveBar }),
1689
+ exposureOpen && controls.exposureSupported && controls.exposureRange && /* @__PURE__ */ jsxs10("div", { className: "mx-auto mb-3 flex w-64 items-center gap-3 rounded-full bg-black/55 px-4 py-2", children: [
1690
+ /* @__PURE__ */ jsx12(SunMediumIcon, { className: "h-4 w-4 shrink-0 text-[#FFCC00]" }),
1691
+ /* @__PURE__ */ jsx12(
1496
1692
  "input",
1497
1693
  {
1498
1694
  type: "range",
@@ -1505,20 +1701,20 @@ function CameraCapture({
1505
1701
  className: "w-full accent-[#FFCC00]"
1506
1702
  }
1507
1703
  ),
1508
- /* @__PURE__ */ jsxs9("span", { className: "w-8 shrink-0 text-right text-xs tabular-nums text-white", children: [
1704
+ /* @__PURE__ */ jsxs10("span", { className: "w-8 shrink-0 text-right text-xs tabular-nums text-white", children: [
1509
1705
  controls.exposure > 0 ? "+" : "",
1510
1706
  controls.exposure
1511
1707
  ] })
1512
1708
  ] }),
1513
- /* @__PURE__ */ jsxs9(
1709
+ /* @__PURE__ */ jsxs10(
1514
1710
  "div",
1515
1711
  {
1516
1712
  className: "bg-black/65 px-3 backdrop-blur-[2px]",
1517
1713
  style: safeBottom,
1518
1714
  children: [
1519
1715
  slots.aboveModeSelector,
1520
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-center gap-2 py-1.5", children: [
1521
- /* @__PURE__ */ jsx11(
1716
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-center gap-2 py-1.5", children: [
1717
+ /* @__PURE__ */ jsx12(
1522
1718
  ModeSelector,
1523
1719
  {
1524
1720
  mode,
@@ -1529,20 +1725,20 @@ function CameraCapture({
1529
1725
  extraModes: slots.extraModes
1530
1726
  }
1531
1727
  ),
1532
- slots.modeRowTrailing && /* @__PURE__ */ jsx11("div", { className: "shrink-0", children: slots.modeRowTrailing })
1728
+ slots.modeRowTrailing && /* @__PURE__ */ jsx12("div", { className: "shrink-0", children: slots.modeRowTrailing })
1533
1729
  ] }),
1534
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between px-2 pb-1.5 pt-0.5", children: [
1535
- /* @__PURE__ */ jsx11("div", { className: "flex w-14 justify-start", children: /* @__PURE__ */ jsx11(
1730
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between px-2 pb-1.5 pt-0.5", children: [
1731
+ /* @__PURE__ */ jsx12("div", { className: "flex w-14 justify-start", children: /* @__PURE__ */ jsx12(
1536
1732
  "button",
1537
1733
  {
1538
1734
  type: "button",
1539
1735
  onClick: cloud.onOpenLibrary,
1540
1736
  "aria-label": "Open your media library",
1541
1737
  className: "h-11 w-11 touch-manipulation overflow-hidden rounded-xl bg-white/10 ring-1 ring-white/25 transition-transform active:scale-95",
1542
- children: cloud.recentsThumb ?? /* @__PURE__ */ jsx11("span", { className: "block h-full w-full bg-white/5" })
1738
+ children: cloud.recentsThumb ?? /* @__PURE__ */ jsx12("span", { className: "block h-full w-full bg-white/5" })
1543
1739
  }
1544
1740
  ) }),
1545
- /* @__PURE__ */ jsx11(
1741
+ /* @__PURE__ */ jsx12(
1546
1742
  ShutterButton,
1547
1743
  {
1548
1744
  mode,
@@ -1551,22 +1747,22 @@ function CameraCapture({
1551
1747
  onPress: onShutter
1552
1748
  }
1553
1749
  ),
1554
- /* @__PURE__ */ jsx11("div", { className: "flex w-14 justify-end", children: engine.onFlipCamera ? /* @__PURE__ */ jsx11(
1750
+ /* @__PURE__ */ jsx12("div", { className: "flex w-14 justify-end", children: engine.onFlipCamera ? /* @__PURE__ */ jsx12(
1555
1751
  "button",
1556
1752
  {
1557
1753
  type: "button",
1558
1754
  onClick: engine.onFlipCamera,
1559
1755
  "aria-label": "Switch camera",
1560
1756
  className: "flex h-11 w-11 touch-manipulation items-center justify-center rounded-full bg-white/15 text-white transition-transform active:rotate-180 active:scale-95 duration-300",
1561
- children: /* @__PURE__ */ jsx11(RefreshCw, { className: "h-5 w-5" })
1757
+ children: /* @__PURE__ */ jsx12(RefreshCwIcon, { className: "h-5 w-5" })
1562
1758
  }
1563
- ) : /* @__PURE__ */ jsx11("span", { className: "h-11 w-11" }) })
1759
+ ) : /* @__PURE__ */ jsx12("span", { className: "h-11 w-11" }) })
1564
1760
  ] })
1565
1761
  ]
1566
1762
  }
1567
1763
  )
1568
1764
  ] }),
1569
- /* @__PURE__ */ jsx11(
1765
+ /* @__PURE__ */ jsx12(
1570
1766
  OptionsGridPanel,
1571
1767
  {
1572
1768
  open: optionsOpen && !controlsHidden,
@@ -1574,7 +1770,7 @@ function CameraCapture({
1574
1770
  tiles
1575
1771
  }
1576
1772
  ),
1577
- blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ jsx11(
1773
+ blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ jsx12(
1578
1774
  CaptureSheet,
1579
1775
  {
1580
1776
  open: true,
@@ -1584,7 +1780,7 @@ function CameraCapture({
1584
1780
  actions: blockedSheet.actions
1585
1781
  }
1586
1782
  ),
1587
- media && viewerKey !== null && /* @__PURE__ */ jsx11(
1783
+ media && viewerKey !== null && /* @__PURE__ */ jsx12(
1588
1784
  MediaViewer,
1589
1785
  {
1590
1786
  items: media.items,
@@ -1601,7 +1797,7 @@ function CameraCapture({
1601
1797
  } : void 0
1602
1798
  }
1603
1799
  ),
1604
- media?.onReplacePhoto && /* @__PURE__ */ jsx11(
1800
+ media?.onReplacePhoto && /* @__PURE__ */ jsx12(
1605
1801
  ImageEditSheet,
1606
1802
  {
1607
1803
  open: editTarget !== null,
@@ -1624,21 +1820,10 @@ function CameraCapture({
1624
1820
 
1625
1821
  // src/components/CameraCaptureV3.tsx
1626
1822
  import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef5, useState as useState8 } from "react";
1627
- import {
1628
- Grid3x3 as Grid3x32,
1629
- Images,
1630
- Proportions as Proportions2,
1631
- RefreshCw as RefreshCw2,
1632
- SunMedium as SunMedium2,
1633
- Timer as Timer2,
1634
- X as X5,
1635
- Zap as Zap2,
1636
- ZapOff as ZapOff2
1637
- } from "lucide-react";
1638
1823
 
1639
1824
  // src/components/CaptureRail.tsx
1640
1825
  import { useState as useState6 } from "react";
1641
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1826
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1642
1827
  function CaptureRail({
1643
1828
  actions,
1644
1829
  defaultExpanded = false,
@@ -1650,7 +1835,7 @@ function CaptureRail({
1650
1835
  const shown = primary.length === 0 ? actions : expanded ? actions : primary;
1651
1836
  const collapsible = primary.length > 0 && extra.length > 0;
1652
1837
  if (actions.length === 0) return null;
1653
- return /* @__PURE__ */ jsxs10(
1838
+ return /* @__PURE__ */ jsxs11(
1654
1839
  "div",
1655
1840
  {
1656
1841
  className: cn(
@@ -1658,8 +1843,8 @@ function CaptureRail({
1658
1843
  className
1659
1844
  ),
1660
1845
  children: [
1661
- shown.map((action) => /* @__PURE__ */ jsx12(RailButton, { action }, action.id)),
1662
- collapsible ? /* @__PURE__ */ jsx12(
1846
+ shown.map((action) => /* @__PURE__ */ jsx13(RailButton, { action }, action.id)),
1847
+ collapsible ? /* @__PURE__ */ jsx13(
1663
1848
  "button",
1664
1849
  {
1665
1850
  type: "button",
@@ -1670,7 +1855,7 @@ function CaptureRail({
1670
1855
  "mt-0.5 flex h-9 w-9 touch-manipulation items-center justify-center",
1671
1856
  "rounded-full text-white/90 transition-colors hover:bg-white/10"
1672
1857
  ),
1673
- children: /* @__PURE__ */ jsx12(
1858
+ children: /* @__PURE__ */ jsx13(
1674
1859
  Chevron,
1675
1860
  {
1676
1861
  className: cn(
@@ -1686,7 +1871,7 @@ function CaptureRail({
1686
1871
  );
1687
1872
  }
1688
1873
  function RailButton({ action }) {
1689
- return /* @__PURE__ */ jsxs10(
1874
+ return /* @__PURE__ */ jsxs11(
1690
1875
  "button",
1691
1876
  {
1692
1877
  type: "button",
@@ -1701,14 +1886,14 @@ function RailButton({ action }) {
1701
1886
  action.disabled ? "opacity-40" : "hover:bg-white/10 active:bg-white/15"
1702
1887
  ),
1703
1888
  children: [
1704
- /* @__PURE__ */ jsx12("span", { className: "drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", children: action.icon }),
1705
- action.valueLabel ? /* @__PURE__ */ jsx12("span", { className: "text-[10px] font-semibold leading-none tabular-nums drop-shadow-[0_1px_2px_rgba(0,0,0,0.7)]", children: action.valueLabel }) : null
1889
+ /* @__PURE__ */ jsx13("span", { className: "drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", children: action.icon }),
1890
+ action.valueLabel ? /* @__PURE__ */ jsx13("span", { className: "text-[10px] font-semibold leading-none tabular-nums drop-shadow-[0_1px_2px_rgba(0,0,0,0.7)]", children: action.valueLabel }) : null
1706
1891
  ]
1707
1892
  }
1708
1893
  );
1709
1894
  }
1710
1895
  function Chevron({ className }) {
1711
- return /* @__PURE__ */ jsx12(
1896
+ return /* @__PURE__ */ jsx13(
1712
1897
  "svg",
1713
1898
  {
1714
1899
  viewBox: "0 0 24 24",
@@ -1719,16 +1904,16 @@ function Chevron({ className }) {
1719
1904
  strokeLinejoin: "round",
1720
1905
  className,
1721
1906
  "aria-hidden": "true",
1722
- children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" })
1907
+ children: /* @__PURE__ */ jsx13("path", { d: "m6 9 6 6 6-6" })
1723
1908
  }
1724
1909
  );
1725
1910
  }
1726
1911
 
1727
1912
  // src/components/HoldShutter.tsx
1728
1913
  import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef4, useState as useState7 } from "react";
1729
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1914
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1730
1915
  var HOLD_MS = 320;
1731
- var LOCK_AFTER_MS = 1200;
1916
+ var LOCK_DRAG_PX = 64;
1732
1917
  function HoldShutter({
1733
1918
  recording,
1734
1919
  elapsedSeconds,
@@ -1741,6 +1926,7 @@ function HoldShutter({
1741
1926
  }) {
1742
1927
  const holdTimer = useRef4(null);
1743
1928
  const startedRecording = useRef4(false);
1929
+ const pressOriginY = useRef4(0);
1744
1930
  const [pressed, setPressed] = useState7(false);
1745
1931
  const [locked, setLocked] = useState7(false);
1746
1932
  const clearHold = useCallback5(() => {
@@ -1750,17 +1936,14 @@ function HoldShutter({
1750
1936
  }
1751
1937
  }, []);
1752
1938
  useEffect6(() => {
1753
- if (!recording) {
1754
- setLocked(false);
1755
- return;
1756
- }
1757
- if (elapsedSeconds * 1e3 >= LOCK_AFTER_MS) setLocked(true);
1758
- }, [recording, elapsedSeconds]);
1939
+ if (!recording) setLocked(false);
1940
+ }, [recording]);
1759
1941
  useEffect6(() => clearHold, [clearHold]);
1760
1942
  const onPointerDown = useCallback5(
1761
1943
  (event) => {
1762
1944
  if (disabled) return;
1763
1945
  event.currentTarget.setPointerCapture?.(event.pointerId);
1946
+ pressOriginY.current = event.clientY;
1764
1947
  setPressed(true);
1765
1948
  onPressStart?.();
1766
1949
  if (recording && locked) return;
@@ -1773,6 +1956,16 @@ function HoldShutter({
1773
1956
  },
1774
1957
  [disabled, locked, onPressStart, onStartRecording, recording]
1775
1958
  );
1959
+ const onPointerMove = useCallback5(
1960
+ (event) => {
1961
+ if (!pressed || locked || !startedRecording.current) return;
1962
+ if (pressOriginY.current - event.clientY >= LOCK_DRAG_PX) {
1963
+ setLocked(true);
1964
+ navigator.vibrate?.(30);
1965
+ }
1966
+ },
1967
+ [pressed, locked]
1968
+ );
1776
1969
  const endPress = useCallback5(() => {
1777
1970
  if (!pressed) return;
1778
1971
  setPressed(false);
@@ -1792,15 +1985,15 @@ function HoldShutter({
1792
1985
  const progress = maxSeconds && maxSeconds > 0 ? Math.min(1, elapsedSeconds / maxSeconds) : 0;
1793
1986
  const R = 39;
1794
1987
  const C = 2 * Math.PI * R;
1795
- return /* @__PURE__ */ jsxs11("div", { className: "relative flex h-[86px] w-[86px] shrink-0 items-center justify-center", children: [
1796
- recording && maxSeconds ? /* @__PURE__ */ jsxs11(
1988
+ return /* @__PURE__ */ jsxs12("div", { className: "relative flex h-[86px] w-[86px] shrink-0 items-center justify-center", children: [
1989
+ recording && maxSeconds ? /* @__PURE__ */ jsxs12(
1797
1990
  "svg",
1798
1991
  {
1799
1992
  className: "pointer-events-none absolute inset-0 -rotate-90",
1800
1993
  viewBox: "0 0 86 86",
1801
1994
  "aria-hidden": "true",
1802
1995
  children: [
1803
- /* @__PURE__ */ jsx13(
1996
+ /* @__PURE__ */ jsx14(
1804
1997
  "circle",
1805
1998
  {
1806
1999
  cx: "43",
@@ -1811,7 +2004,7 @@ function HoldShutter({
1811
2004
  strokeWidth: "4"
1812
2005
  }
1813
2006
  ),
1814
- /* @__PURE__ */ jsx13(
2007
+ /* @__PURE__ */ jsx14(
1815
2008
  "circle",
1816
2009
  {
1817
2010
  cx: "43",
@@ -1828,12 +2021,34 @@ function HoldShutter({
1828
2021
  ]
1829
2022
  }
1830
2023
  ) : null,
1831
- /* @__PURE__ */ jsx13(
2024
+ recording && pressed && !locked && /* @__PURE__ */ jsxs12(
2025
+ "span",
2026
+ {
2027
+ className: "pointer-events-none absolute left-1/2 flex -translate-x-1/2 flex-col items-center gap-0.5",
2028
+ style: { top: -LOCK_DRAG_PX - 22 },
2029
+ "aria-hidden": true,
2030
+ children: [
2031
+ /* @__PURE__ */ jsx14("span", { className: "flex h-9 w-9 items-center justify-center rounded-full bg-black/60 ring-1 ring-white/30", children: /* @__PURE__ */ jsx14(LockIcon, { className: "h-4 w-4 text-white/90" }) }),
2032
+ /* @__PURE__ */ jsx14("span", { className: "text-[10px] font-medium text-white/80 drop-shadow", children: "Slide up to lock" })
2033
+ ]
2034
+ }
2035
+ ),
2036
+ recording && locked && /* @__PURE__ */ jsx14(
2037
+ "span",
2038
+ {
2039
+ className: "pointer-events-none absolute left-1/2 flex h-9 w-9 -translate-x-1/2 items-center justify-center rounded-full bg-[#FF3B30]",
2040
+ style: { top: -LOCK_DRAG_PX - 22 },
2041
+ "aria-hidden": true,
2042
+ children: /* @__PURE__ */ jsx14(LockIcon, { className: "h-4 w-4 text-white", fill: "currentColor" })
2043
+ }
2044
+ ),
2045
+ /* @__PURE__ */ jsx14(
1832
2046
  "button",
1833
2047
  {
1834
2048
  type: "button",
1835
2049
  disabled,
1836
2050
  onPointerDown,
2051
+ onPointerMove,
1837
2052
  onPointerUp: endPress,
1838
2053
  onPointerCancel: endPress,
1839
2054
  onLostPointerCapture: endPress,
@@ -1844,7 +2059,7 @@ function HoldShutter({
1844
2059
  "rounded-full border-[3.5px] border-white transition-opacity",
1845
2060
  disabled && "opacity-30"
1846
2061
  ),
1847
- children: /* @__PURE__ */ jsx13(
2062
+ children: /* @__PURE__ */ jsx14(
1848
2063
  "span",
1849
2064
  {
1850
2065
  className: cn(
@@ -1858,7 +2073,7 @@ function HoldShutter({
1858
2073
  )
1859
2074
  }
1860
2075
  ),
1861
- recording ? /* @__PURE__ */ jsxs11(
2076
+ recording ? /* @__PURE__ */ jsxs12(
1862
2077
  "span",
1863
2078
  {
1864
2079
  className: cn(
@@ -1880,7 +2095,7 @@ function formatElapsed2(totalSeconds) {
1880
2095
  }
1881
2096
 
1882
2097
  // src/components/CameraCaptureV3.tsx
1883
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2098
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1884
2099
  var ASPECT_CYCLE2 = ["full", "4:3", "1:1", "16:9"];
1885
2100
  function CameraCaptureV3({
1886
2101
  engine,
@@ -1947,7 +2162,7 @@ function CameraCaptureV3({
1947
2162
  {
1948
2163
  id: "flip",
1949
2164
  label: "Switch camera",
1950
- icon: /* @__PURE__ */ jsx14(RefreshCw2, { className: "h-[22px] w-[22px]" }),
2165
+ icon: /* @__PURE__ */ jsx15(RefreshCwIcon, { className: "h-[22px] w-[22px]" }),
1951
2166
  primary: true,
1952
2167
  onPress: engine.onFlipCamera
1953
2168
  }
@@ -1956,7 +2171,7 @@ function CameraCaptureV3({
1956
2171
  {
1957
2172
  id: "flash",
1958
2173
  label: "Flash",
1959
- icon: controls.torchOn ? /* @__PURE__ */ jsx14(Zap2, { className: "h-[22px] w-[22px]", fill: "currentColor" }) : /* @__PURE__ */ jsx14(ZapOff2, { className: "h-[22px] w-[22px]" }),
2174
+ icon: controls.torchOn ? /* @__PURE__ */ jsx15(ZapIcon, { className: "h-[22px] w-[22px]", fill: "currentColor" }) : /* @__PURE__ */ jsx15(ZapOffIcon, { className: "h-[22px] w-[22px]" }),
1960
2175
  active: controls.torchOn,
1961
2176
  primary: true,
1962
2177
  onPress: controls.toggleTorch
@@ -1965,7 +2180,7 @@ function CameraCaptureV3({
1965
2180
  {
1966
2181
  id: "timer",
1967
2182
  label: "Timer",
1968
- icon: /* @__PURE__ */ jsx14(Timer2, { className: "h-[22px] w-[22px]" }),
2183
+ icon: /* @__PURE__ */ jsx15(TimerIcon, { className: "h-[22px] w-[22px]" }),
1969
2184
  active: timerSetting !== 0,
1970
2185
  valueLabel: timerSetting === 0 ? void 0 : `${timerSetting}s`,
1971
2186
  onPress: () => setTimerSetting((t) => t === 0 ? 3 : t === 3 ? 10 : 0)
@@ -1973,14 +2188,14 @@ function CameraCaptureV3({
1973
2188
  {
1974
2189
  id: "grid",
1975
2190
  label: "Grid",
1976
- icon: /* @__PURE__ */ jsx14(Grid3x32, { className: "h-[22px] w-[22px]" }),
2191
+ icon: /* @__PURE__ */ jsx15(Grid3x3Icon, { className: "h-[22px] w-[22px]" }),
1977
2192
  active: gridOn,
1978
2193
  onPress: () => setGridOn((g) => !g)
1979
2194
  },
1980
2195
  {
1981
2196
  id: "aspect",
1982
2197
  label: "Aspect",
1983
- icon: /* @__PURE__ */ jsx14(Proportions2, { className: "h-[22px] w-[22px]" }),
2198
+ icon: /* @__PURE__ */ jsx15(ProportionsIcon, { className: "h-[22px] w-[22px]" }),
1984
2199
  active: aspect !== "full",
1985
2200
  valueLabel: aspect === "full" ? void 0 : aspect,
1986
2201
  onPress: () => setAspect(
@@ -1991,7 +2206,7 @@ function CameraCaptureV3({
1991
2206
  {
1992
2207
  id: "exposure",
1993
2208
  label: "Exposure",
1994
- icon: /* @__PURE__ */ jsx14(SunMedium2, { className: "h-[22px] w-[22px]" }),
2209
+ icon: /* @__PURE__ */ jsx15(SunMediumIcon, { className: "h-[22px] w-[22px]" }),
1995
2210
  active: controls.exposure !== 0,
1996
2211
  valueLabel: controls.exposure === 0 ? void 0 : `${controls.exposure > 0 ? "+" : ""}${controls.exposure}`,
1997
2212
  onPress: () => controls.setExposure(controls.exposure === 0 ? 1 : 0)
@@ -2002,15 +2217,15 @@ function CameraCaptureV3({
2002
2217
  ...coreRail.map((a) => blocked ? { ...a, disabled: true } : a),
2003
2218
  ...slots.railActions ?? []
2004
2219
  ];
2005
- return /* @__PURE__ */ jsxs12("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
2006
- /* @__PURE__ */ jsx14("div", { className: "absolute inset-0", children: preview }),
2007
- /* @__PURE__ */ jsx14(GridOverlay, { visible: gridOn && !blocked }),
2008
- aspect !== "full" && !blocked && !engine.recording && /* @__PURE__ */ jsx14(
2220
+ return /* @__PURE__ */ jsxs13("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
2221
+ /* @__PURE__ */ jsx15("div", { className: "absolute inset-0", children: preview }),
2222
+ /* @__PURE__ */ jsx15(GridOverlay, { visible: gridOn && !blocked }),
2223
+ aspect !== "full" && !blocked && !engine.recording && /* @__PURE__ */ jsx15(
2009
2224
  "div",
2010
2225
  {
2011
2226
  "aria-hidden": true,
2012
2227
  className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center",
2013
- children: /* @__PURE__ */ jsx14(
2228
+ children: /* @__PURE__ */ jsx15(
2014
2229
  "div",
2015
2230
  {
2016
2231
  className: "shadow-[0_0_0_9999px_rgba(0,0,0,0.45)]",
@@ -2025,32 +2240,32 @@ function CameraCaptureV3({
2025
2240
  )
2026
2241
  }
2027
2242
  ),
2028
- /* @__PURE__ */ jsx14(CountdownOverlay, { seconds: countdown }),
2029
- !controlsHidden && /* @__PURE__ */ jsxs12(
2243
+ /* @__PURE__ */ jsx15(CountdownOverlay, { seconds: countdown }),
2244
+ !controlsHidden && /* @__PURE__ */ jsxs13(
2030
2245
  "div",
2031
2246
  {
2032
2247
  className: "pointer-events-none absolute inset-x-0 top-0 z-20 px-2",
2033
2248
  style: safeTop,
2034
2249
  children: [
2035
- /* @__PURE__ */ jsxs12("div", { className: "flex min-h-[44px] items-center gap-2 py-1.5", children: [
2036
- onClose ? /* @__PURE__ */ jsx14(
2250
+ /* @__PURE__ */ jsxs13("div", { className: "flex min-h-[44px] items-center gap-2 py-1.5", children: [
2251
+ onClose ? /* @__PURE__ */ jsx15(
2037
2252
  "button",
2038
2253
  {
2039
2254
  type: "button",
2040
2255
  onClick: onClose,
2041
2256
  "aria-label": "Close camera",
2042
2257
  className: "pointer-events-auto flex h-10 w-10 shrink-0 touch-manipulation items-center justify-center rounded-full text-white drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)] transition-colors hover:bg-white/10",
2043
- children: /* @__PURE__ */ jsx14(X5, { className: "h-6 w-6" })
2258
+ children: /* @__PURE__ */ jsx15(XIcon, { className: "h-6 w-6" })
2044
2259
  }
2045
- ) : /* @__PURE__ */ jsx14("span", { className: "h-10 w-10 shrink-0" }),
2046
- /* @__PURE__ */ jsx14("div", { className: "pointer-events-auto flex min-w-0 flex-1 justify-center", children: slots.topEntry }),
2047
- /* @__PURE__ */ jsx14("span", { className: "h-10 w-10 shrink-0" })
2260
+ ) : /* @__PURE__ */ jsx15("span", { className: "h-10 w-10 shrink-0" }),
2261
+ /* @__PURE__ */ jsx15("div", { className: "pointer-events-auto flex min-w-0 flex-1 justify-center", children: slots.topEntry }),
2262
+ /* @__PURE__ */ jsx15("span", { className: "h-10 w-10 shrink-0" })
2048
2263
  ] }),
2049
- slots.topCenter ? /* @__PURE__ */ jsx14("div", { className: "pointer-events-none pb-1 text-center", children: slots.topCenter }) : null
2264
+ slots.topCenter ? /* @__PURE__ */ jsx15("div", { className: "pointer-events-none pb-1 text-center", children: slots.topCenter }) : null
2050
2265
  ]
2051
2266
  }
2052
2267
  ),
2053
- slots.statusChips ? /* @__PURE__ */ jsx14(
2268
+ slots.statusChips ? /* @__PURE__ */ jsx15(
2054
2269
  "div",
2055
2270
  {
2056
2271
  className: "pointer-events-none absolute inset-x-0 z-20 flex flex-col items-center gap-1.5 px-3",
@@ -2062,35 +2277,35 @@ function CameraCaptureV3({
2062
2277
  children: slots.statusChips
2063
2278
  }
2064
2279
  ) : null,
2065
- !controlsHidden && /* @__PURE__ */ jsx14(
2280
+ !controlsHidden && /* @__PURE__ */ jsx15(
2066
2281
  "div",
2067
2282
  {
2068
2283
  className: "pointer-events-none absolute right-1 z-20 flex justify-end",
2069
2284
  style: { top: `calc(env(safe-area-inset-top, 0px) + 64px)` },
2070
- children: /* @__PURE__ */ jsx14(CaptureRail, { actions: railActions })
2285
+ children: /* @__PURE__ */ jsx15(CaptureRail, { actions: railActions })
2071
2286
  }
2072
2287
  ),
2073
- !controlsHidden && /* @__PURE__ */ jsxs12("div", { className: "absolute inset-x-0 bottom-0 z-20", style: safeBottom, children: [
2074
- media && media.items.length > 0 ? /* @__PURE__ */ jsx14("div", { className: "px-2 pb-1.5", children: /* @__PURE__ */ jsx14(
2288
+ !controlsHidden && /* @__PURE__ */ jsxs13("div", { className: "absolute inset-x-0 bottom-0 z-20", style: safeBottom, children: [
2289
+ media && media.items.length > 0 ? /* @__PURE__ */ jsx15("div", { className: "px-2 pb-1.5", children: /* @__PURE__ */ jsx15(
2075
2290
  CaptureFilmstrip,
2076
2291
  {
2077
2292
  items: media.items,
2078
2293
  onOpen: (item) => setViewerKey(item.key)
2079
2294
  }
2080
2295
  ) }) : null,
2081
- slots.aboveShutter ? /* @__PURE__ */ jsx14("div", { className: "px-2 pb-1.5", children: slots.aboveShutter }) : null,
2082
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between px-3 pb-2", children: [
2083
- /* @__PURE__ */ jsx14("div", { className: "flex w-[86px] justify-start", children: /* @__PURE__ */ jsx14(
2296
+ slots.aboveShutter ? /* @__PURE__ */ jsx15("div", { className: "px-2 pb-1.5", children: slots.aboveShutter }) : null,
2297
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between px-3 pb-2", children: [
2298
+ /* @__PURE__ */ jsx15("div", { className: "flex w-[86px] justify-start", children: /* @__PURE__ */ jsx15(
2084
2299
  "button",
2085
2300
  {
2086
2301
  type: "button",
2087
2302
  onClick: cloud.onOpenLibrary,
2088
2303
  "aria-label": "Your media \u2014 library and upload",
2089
2304
  className: "relative h-12 w-12 touch-manipulation overflow-hidden rounded-xl bg-black/40 ring-1 ring-white/30 backdrop-blur-md transition-transform active:scale-95",
2090
- children: cloud.recentsThumb ?? /* @__PURE__ */ jsx14("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsx14(Images, { className: "h-5 w-5 text-white/80" }) })
2305
+ children: cloud.recentsThumb ?? /* @__PURE__ */ jsx15("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsx15(ImagesIcon, { className: "h-5 w-5 text-white/80" }) })
2091
2306
  }
2092
2307
  ) }),
2093
- /* @__PURE__ */ jsx14(
2308
+ /* @__PURE__ */ jsx15(
2094
2309
  HoldShutter,
2095
2310
  {
2096
2311
  recording: engine.recording,
@@ -2103,11 +2318,11 @@ function CameraCaptureV3({
2103
2318
  onStopRecording: engine.onStopRecording
2104
2319
  }
2105
2320
  ),
2106
- /* @__PURE__ */ jsx14("div", { className: "flex w-[86px] justify-end", children: slots.shutterTrailing })
2321
+ /* @__PURE__ */ jsx15("div", { className: "flex w-[86px] justify-end", children: slots.shutterTrailing })
2107
2322
  ] }),
2108
- !engine.recording && !blocked ? /* @__PURE__ */ jsx14("p", { className: "pb-1.5 text-center text-[11px] text-white/60 drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)]", children: "Tap for a photo \xB7 hold to record" }) : null
2323
+ !engine.recording && !blocked ? /* @__PURE__ */ jsx15("p", { className: "pb-1.5 text-center text-[11px] text-white/60 drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)]", children: "Tap for a photo \xB7 hold to record" }) : null
2109
2324
  ] }),
2110
- blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ jsx14(
2325
+ blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ jsx15(
2111
2326
  CaptureSheet,
2112
2327
  {
2113
2328
  open: true,
@@ -2117,7 +2332,7 @@ function CameraCaptureV3({
2117
2332
  actions: blockedSheet.actions
2118
2333
  }
2119
2334
  ),
2120
- media && viewerKey !== null && /* @__PURE__ */ jsx14(
2335
+ media && viewerKey !== null && /* @__PURE__ */ jsx15(
2121
2336
  MediaViewer,
2122
2337
  {
2123
2338
  items: media.items,
@@ -2134,7 +2349,7 @@ function CameraCaptureV3({
2134
2349
  } : void 0
2135
2350
  }
2136
2351
  ),
2137
- media?.onReplacePhoto && /* @__PURE__ */ jsx14(
2352
+ media?.onReplacePhoto && /* @__PURE__ */ jsx15(
2138
2353
  ImageEditSheet,
2139
2354
  {
2140
2355
  open: editTarget !== null,
@@ -2157,7 +2372,7 @@ function CameraCaptureV3({
2157
2372
 
2158
2373
  // src/components/CaptureExpandingField.tsx
2159
2374
  import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef6, useState as useState9 } from "react";
2160
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2375
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2161
2376
  function CaptureExpandingField({
2162
2377
  label,
2163
2378
  placeholder,
@@ -2195,7 +2410,7 @@ function CaptureExpandingField({
2195
2410
  setExpanded(false);
2196
2411
  }, [commit]);
2197
2412
  if (!expanded) {
2198
- return /* @__PURE__ */ jsxs13(
2413
+ return /* @__PURE__ */ jsxs14(
2199
2414
  "button",
2200
2415
  {
2201
2416
  type: "button",
@@ -2211,13 +2426,13 @@ function CaptureExpandingField({
2211
2426
  className
2212
2427
  ),
2213
2428
  children: [
2214
- icon ? /* @__PURE__ */ jsx15("span", { className: "shrink-0", children: icon }) : null,
2215
- /* @__PURE__ */ jsx15("span", { className: "truncate", children: currentValue?.trim() || label })
2429
+ icon ? /* @__PURE__ */ jsx16("span", { className: "shrink-0", children: icon }) : null,
2430
+ /* @__PURE__ */ jsx16("span", { className: "truncate", children: currentValue?.trim() || label })
2216
2431
  ]
2217
2432
  }
2218
2433
  );
2219
2434
  }
2220
- return /* @__PURE__ */ jsxs13(
2435
+ return /* @__PURE__ */ jsxs14(
2221
2436
  "div",
2222
2437
  {
2223
2438
  className: cn(
@@ -2226,8 +2441,8 @@ function CaptureExpandingField({
2226
2441
  className
2227
2442
  ),
2228
2443
  children: [
2229
- icon ? /* @__PURE__ */ jsx15("span", { className: "shrink-0 text-white/70", children: icon }) : null,
2230
- /* @__PURE__ */ jsx15(
2444
+ icon ? /* @__PURE__ */ jsx16("span", { className: "shrink-0 text-white/70", children: icon }) : null,
2445
+ /* @__PURE__ */ jsx16(
2231
2446
  "input",
2232
2447
  {
2233
2448
  ref: inputRef,
@@ -2256,7 +2471,7 @@ function CaptureExpandingField({
2256
2471
  )
2257
2472
  }
2258
2473
  ),
2259
- /* @__PURE__ */ jsx15(
2474
+ /* @__PURE__ */ jsx16(
2260
2475
  "button",
2261
2476
  {
2262
2477
  type: "button",
@@ -2267,7 +2482,7 @@ function CaptureExpandingField({
2267
2482
  },
2268
2483
  "aria-label": `Close ${label}`,
2269
2484
  className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-white/70 hover:bg-white/10 hover:text-white",
2270
- children: /* @__PURE__ */ jsx15(
2485
+ children: /* @__PURE__ */ jsx16(
2271
2486
  "svg",
2272
2487
  {
2273
2488
  viewBox: "0 0 24 24",
@@ -2277,7 +2492,7 @@ function CaptureExpandingField({
2277
2492
  strokeLinecap: "round",
2278
2493
  className: "h-3.5 w-3.5",
2279
2494
  "aria-hidden": "true",
2280
- children: /* @__PURE__ */ jsx15("path", { d: "M18 6 6 18M6 6l12 12" })
2495
+ children: /* @__PURE__ */ jsx16("path", { d: "M18 6 6 18M6 6l12 12" })
2281
2496
  }
2282
2497
  )
2283
2498
  }
@@ -2289,7 +2504,7 @@ function CaptureExpandingField({
2289
2504
 
2290
2505
  // src/components/CameraFeed.tsx
2291
2506
  import { useEffect as useEffect9 } from "react";
2292
- import { jsx as jsx16 } from "react/jsx-runtime";
2507
+ import { jsx as jsx17 } from "react/jsx-runtime";
2293
2508
  function CameraFeed({
2294
2509
  engine,
2295
2510
  mirror = false
@@ -2303,7 +2518,7 @@ function CameraFeed({
2303
2518
  video.srcObject = null;
2304
2519
  };
2305
2520
  }, [stream, videoRef]);
2306
- return /* @__PURE__ */ jsx16(
2521
+ return /* @__PURE__ */ jsx17(
2307
2522
  "video",
2308
2523
  {
2309
2524
  ref: videoRef,