@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.cjs CHANGED
@@ -48,7 +48,158 @@ module.exports = __toCommonJS(react_exports);
48
48
 
49
49
  // src/components/CameraCapture.tsx
50
50
  var import_react5 = require("react");
51
- var import_lucide_react4 = require("lucide-react");
51
+
52
+ // src/components/icons.tsx
53
+ var import_jsx_runtime = require("react/jsx-runtime");
54
+ function svgProps(props) {
55
+ return {
56
+ xmlns: "http://www.w3.org/2000/svg",
57
+ viewBox: "0 0 24 24",
58
+ width: 24,
59
+ height: 24,
60
+ fill: "none",
61
+ stroke: "currentColor",
62
+ strokeWidth: 2,
63
+ strokeLinecap: "round",
64
+ strokeLinejoin: "round",
65
+ "aria-hidden": true,
66
+ ...props
67
+ };
68
+ }
69
+ function CheckIcon(props) {
70
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...svgProps(props), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 6 9 17l-5-5" }) });
71
+ }
72
+ function ChevronLeftIcon(props) {
73
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...svgProps(props), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m15 18-6-6 6-6" }) });
74
+ }
75
+ function ChevronRightIcon(props) {
76
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...svgProps(props), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m9 18 6-6-6-6" }) });
77
+ }
78
+ function FlipHorizontal2Icon(props) {
79
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
80
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m3 7 5 5-5 5V7" }),
81
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21 7-5 5 5 5V7" }),
82
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 20v2" }),
83
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 14v2" }),
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 8v2" }),
85
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2v2" })
86
+ ] });
87
+ }
88
+ function Grid3x3Icon(props) {
89
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
90
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
91
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 9h18" }),
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 15h18" }),
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 3v18" }),
94
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 3v18" })
95
+ ] });
96
+ }
97
+ function GripIcon(props) {
98
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
99
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "5", r: "1" }),
100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "19", cy: "5", r: "1" }),
101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "5", cy: "5", r: "1" }),
102
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "1" }),
103
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "19", cy: "12", r: "1" }),
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "5", cy: "12", r: "1" }),
105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "19", r: "1" }),
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "19", cy: "19", r: "1" }),
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "5", cy: "19", r: "1" })
108
+ ] });
109
+ }
110
+ function ImagesIcon(props) {
111
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m22 11-1.296-1.296a2.4 2.4 0 0 0-3.408 0L11 16" }),
113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 8a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2" }),
114
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "13", cy: "7", r: "1", fill: "currentColor" }),
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "8", y: "2", width: "14", height: "14", rx: "2" })
116
+ ] });
117
+ }
118
+ function Loader2Icon(props) {
119
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...svgProps(props), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
120
+ }
121
+ function LockIcon(props) {
122
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2" }),
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
125
+ ] });
126
+ }
127
+ function PencilIcon(props) {
128
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
129
+ /* @__PURE__ */ (0, import_jsx_runtime.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" }),
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m15 5 4 4" })
131
+ ] });
132
+ }
133
+ function PlayIcon(props) {
134
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...svgProps(props), children: /* @__PURE__ */ (0, import_jsx_runtime.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" }) });
135
+ }
136
+ function ProportionsIcon(props) {
137
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" }),
139
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 9v11" }),
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 9h13a2 2 0 0 1 2 2v9" })
141
+ ] });
142
+ }
143
+ function RefreshCwIcon(props) {
144
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
145
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
146
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 3v5h-5" }),
147
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
148
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 16H3v5" })
149
+ ] });
150
+ }
151
+ function RotateCcwIcon(props) {
152
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
154
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 3v5h5" })
155
+ ] });
156
+ }
157
+ function SunMediumIcon(props) {
158
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
160
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 3v1" }),
161
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 20v1" }),
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12h1" }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 12h1" }),
164
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m18.364 5.636-.707.707" }),
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m6.343 17.657-.707.707" }),
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m5.636 5.636.707.707" }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m17.657 17.657.707.707" })
168
+ ] });
169
+ }
170
+ function TimerIcon(props) {
171
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "10", x2: "14", y1: "2", y2: "2" }),
173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", x2: "15", y1: "14", y2: "11" }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "14", r: "8" })
175
+ ] });
176
+ }
177
+ function Trash2Icon(props) {
178
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
179
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 11v6" }),
180
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 11v6" }),
181
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }),
182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 6h18" }),
183
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
184
+ ] });
185
+ }
186
+ function XIcon(props) {
187
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
188
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6 6 18" }),
189
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m6 6 12 12" })
190
+ ] });
191
+ }
192
+ function ZapIcon(props) {
193
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...svgProps(props), children: /* @__PURE__ */ (0, import_jsx_runtime.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" }) });
194
+ }
195
+ function ZapOffIcon(props) {
196
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10.513 4.856 13.12 2.17a.5.5 0 0 1 .86.46l-1.377 4.317" }),
198
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15.656 10H20a1 1 0 0 1 .78 1.63l-1.72 1.773" }),
199
+ /* @__PURE__ */ (0, import_jsx_runtime.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" }),
200
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m2 2 20 20" })
201
+ ] });
202
+ }
52
203
 
53
204
  // src/cn.ts
54
205
  var import_tailwind_merge = require("tailwind-merge");
@@ -181,14 +332,14 @@ function useTrackControls(stream) {
181
332
  }
182
333
 
183
334
  // src/components/ShutterButton.tsx
184
- var import_jsx_runtime = require("react/jsx-runtime");
335
+ var import_jsx_runtime2 = require("react/jsx-runtime");
185
336
  function ShutterButton({
186
337
  mode,
187
338
  recording,
188
339
  disabled = false,
189
340
  onPress
190
341
  }) {
191
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
342
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
192
343
  "button",
193
344
  {
194
345
  type: "button",
@@ -200,7 +351,7 @@ function ShutterButton({
200
351
  "border-[3.5px] border-white transition-opacity",
201
352
  disabled && "opacity-30"
202
353
  ),
203
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
354
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
204
355
  "span",
205
356
  {
206
357
  className: cn(
@@ -214,7 +365,7 @@ function ShutterButton({
214
365
  }
215
366
 
216
367
  // src/components/ModeSelector.tsx
217
- var import_jsx_runtime2 = require("react/jsx-runtime");
368
+ var import_jsx_runtime3 = require("react/jsx-runtime");
218
369
  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)";
219
370
  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";
220
371
  function ModeSelector({
@@ -227,7 +378,7 @@ function ModeSelector({
227
378
  }) {
228
379
  const segments = 3 + extraModes.length;
229
380
  const activeIndex = mode === "video" ? 0 : 1;
230
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
381
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
231
382
  "div",
232
383
  {
233
384
  role: "tablist",
@@ -235,7 +386,7 @@ function ModeSelector({
235
386
  className: "relative inline-grid rounded-full bg-white/10 p-1",
236
387
  style: { gridTemplateColumns: `repeat(${segments}, minmax(0, 1fr))` },
237
388
  children: [
238
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
389
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
239
390
  "div",
240
391
  {
241
392
  "aria-hidden": true,
@@ -247,7 +398,7 @@ function ModeSelector({
247
398
  }
248
399
  }
249
400
  ),
250
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
401
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
251
402
  "button",
252
403
  {
253
404
  type: "button",
@@ -262,7 +413,7 @@ function ModeSelector({
262
413
  children: "Video"
263
414
  }
264
415
  ),
265
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
416
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
266
417
  "button",
267
418
  {
268
419
  type: "button",
@@ -277,7 +428,7 @@ function ModeSelector({
277
428
  children: "Photo"
278
429
  }
279
430
  ),
280
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
431
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
281
432
  "button",
282
433
  {
283
434
  type: "button",
@@ -288,7 +439,7 @@ function ModeSelector({
288
439
  children: "Upload"
289
440
  }
290
441
  ),
291
- extraModes.map((extra) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
442
+ extraModes.map((extra) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
292
443
  "button",
293
444
  {
294
445
  type: "button",
@@ -306,7 +457,7 @@ function ModeSelector({
306
457
  }
307
458
 
308
459
  // src/components/ZoomRow.tsx
309
- var import_jsx_runtime3 = require("react/jsx-runtime");
460
+ var import_jsx_runtime4 = require("react/jsx-runtime");
310
461
  function formatFactor(factor) {
311
462
  return factor < 1 ? `.${String(Math.round(factor * 10))}` : String(Math.round(factor * 10) / 10);
312
463
  }
@@ -315,9 +466,9 @@ function ZoomRow({ options, value, onSelect }) {
315
466
  const active = options.reduce(
316
467
  (best, opt) => Math.abs(opt - value) < Math.abs(best - value) ? opt : best
317
468
  );
318
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center justify-center gap-3", children: options.map((opt) => {
469
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center justify-center gap-3", children: options.map((opt) => {
319
470
  const isActive = opt === active;
320
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
471
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
321
472
  "button",
322
473
  {
323
474
  type: "button",
@@ -330,7 +481,7 @@ function ZoomRow({ options, value, onSelect }) {
330
481
  ),
331
482
  children: [
332
483
  formatFactor(opt),
333
- isActive && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[10px]", children: "\xD7" })
484
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[10px]", children: "\xD7" })
334
485
  ]
335
486
  },
336
487
  opt
@@ -339,15 +490,15 @@ function ZoomRow({ options, value, onSelect }) {
339
490
  }
340
491
 
341
492
  // src/components/OptionsGridPanel.tsx
342
- var import_jsx_runtime4 = require("react/jsx-runtime");
493
+ var import_jsx_runtime5 = require("react/jsx-runtime");
343
494
  function OptionsGridPanel({
344
495
  open,
345
496
  onClose,
346
497
  tiles
347
498
  }) {
348
499
  if (!open) return null;
349
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "absolute inset-0 z-40", children: [
350
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
500
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "absolute inset-0 z-40", children: [
501
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
351
502
  "button",
352
503
  {
353
504
  type: "button",
@@ -356,13 +507,13 @@ function OptionsGridPanel({
356
507
  className: "absolute inset-0 bg-black/70"
357
508
  }
358
509
  ),
359
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
510
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
360
511
  "div",
361
512
  {
362
513
  className: "absolute inset-x-3 bottom-3 rounded-[2.5rem] bg-[#3a3a3c]/95 px-6 py-8 shadow-2xl",
363
514
  style: { marginBottom: "env(safe-area-inset-bottom, 0px)" },
364
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "grid grid-cols-3 gap-x-4 gap-y-7", children: tiles.map((tile) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col items-center gap-2.5", children: [
365
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
515
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "grid grid-cols-3 gap-x-4 gap-y-7", children: tiles.map((tile) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col items-center gap-2.5", children: [
516
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
366
517
  "button",
367
518
  {
368
519
  type: "button",
@@ -378,7 +529,7 @@ function OptionsGridPanel({
378
529
  children: tile.icon
379
530
  }
380
531
  ),
381
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[13px] font-semibold uppercase tracking-[0.14em] text-white", children: tile.valueLabel ? `${tile.label} ${tile.valueLabel}` : tile.label })
532
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[13px] font-semibold uppercase tracking-[0.14em] text-white", children: tile.valueLabel ? `${tile.label} ${tile.valueLabel}` : tile.label })
382
533
  ] }, tile.id)) })
383
534
  }
384
535
  )
@@ -386,8 +537,7 @@ function OptionsGridPanel({
386
537
  }
387
538
 
388
539
  // src/components/CaptureSheet.tsx
389
- var import_lucide_react = require("lucide-react");
390
- var import_jsx_runtime5 = require("react/jsx-runtime");
540
+ var import_jsx_runtime6 = require("react/jsx-runtime");
391
541
  function CaptureSheet({
392
542
  open,
393
543
  onClose,
@@ -399,8 +549,8 @@ function CaptureSheet({
399
549
  busyLabel = "Working\u2026"
400
550
  }) {
401
551
  if (!open) return null;
402
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "absolute inset-0 z-50 flex flex-col justify-end", children: [
403
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
552
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "absolute inset-0 z-50 flex flex-col justify-end", children: [
553
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
404
554
  "button",
405
555
  {
406
556
  type: "button",
@@ -409,30 +559,30 @@ function CaptureSheet({
409
559
  className: "absolute inset-0 bg-black/30"
410
560
  }
411
561
  ),
412
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
562
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
413
563
  "div",
414
564
  {
415
565
  className: "relative mx-2 mb-2 rounded-[2rem] bg-[#f2f2f7] px-6 pb-6 pt-5 text-black shadow-2xl",
416
566
  style: { marginBottom: "calc(0.5rem + env(safe-area-inset-bottom, 0px))" },
417
567
  children: [
418
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
568
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
419
569
  "button",
420
570
  {
421
571
  type: "button",
422
572
  onClick: onClose,
423
573
  "aria-label": "Close",
424
574
  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",
425
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.X, { className: "h-5 w-5", strokeWidth: 2.5 })
575
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(XIcon, { className: "h-5 w-5", strokeWidth: 2.5 })
426
576
  }
427
577
  ),
428
- variant === "busy" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex min-h-[220px] items-center justify-center gap-2.5", children: [
429
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.Loader2, { className: "h-5 w-5 animate-spin text-black/50" }),
430
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[17px] font-medium text-black/80", children: busyLabel })
431
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pt-4", children: [
432
- icon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mb-5 text-[#0a84ff]", children: icon }),
433
- title && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: "mb-2 text-[26px] font-bold leading-tight", children: title }),
434
- body && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-[17px] leading-snug text-black/85", children: body }),
435
- actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mt-7 flex flex-col gap-3", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
578
+ variant === "busy" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex min-h-[220px] items-center justify-center gap-2.5", children: [
579
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Loader2Icon, { className: "h-5 w-5 animate-spin text-black/50" }),
580
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[17px] font-medium text-black/80", children: busyLabel })
581
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "pt-4", children: [
582
+ icon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mb-5 text-[#0a84ff]", children: icon }),
583
+ title && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { className: "mb-2 text-[26px] font-bold leading-tight", children: title }),
584
+ body && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-[17px] leading-snug text-black/85", children: body }),
585
+ actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mt-7 flex flex-col gap-3", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
436
586
  "button",
437
587
  {
438
588
  type: "button",
@@ -453,22 +603,22 @@ function CaptureSheet({
453
603
  }
454
604
 
455
605
  // src/components/GridOverlay.tsx
456
- var import_jsx_runtime6 = require("react/jsx-runtime");
606
+ var import_jsx_runtime7 = require("react/jsx-runtime");
457
607
  function GridOverlay({ visible }) {
458
608
  if (!visible) return null;
459
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-0 z-10", children: [
460
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute inset-y-0 left-1/3 w-px bg-white/40" }),
461
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute inset-y-0 left-2/3 w-px bg-white/40" }),
462
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute inset-x-0 top-1/3 h-px bg-white/40" }),
463
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute inset-x-0 top-2/3 h-px bg-white/40" })
609
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-0 z-10", children: [
610
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-y-0 left-1/3 w-px bg-white/40" }),
611
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-y-0 left-2/3 w-px bg-white/40" }),
612
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-x-0 top-1/3 h-px bg-white/40" }),
613
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-x-0 top-2/3 h-px bg-white/40" })
464
614
  ] });
465
615
  }
466
616
 
467
617
  // src/components/CountdownOverlay.tsx
468
- var import_jsx_runtime7 = require("react/jsx-runtime");
618
+ var import_jsx_runtime8 = require("react/jsx-runtime");
469
619
  function CountdownOverlay({ seconds }) {
470
620
  if (seconds === null || seconds <= 0) return null;
471
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "pointer-events-none absolute inset-0 z-30 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
621
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "pointer-events-none absolute inset-0 z-30 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
472
622
  "span",
473
623
  {
474
624
  className: "text-[120px] font-light text-white drop-shadow-lg [@starting-style]:scale-125 [@starting-style]:opacity-0 transition-all duration-300",
@@ -481,35 +631,43 @@ function CountdownOverlay({ seconds }) {
481
631
  // src/media/media-cache.ts
482
632
  var import_react2 = require("react");
483
633
  var MAX_ENTRIES = 80;
484
- var cache = /* @__PURE__ */ new Map();
485
- var listeners = /* @__PURE__ */ new Map();
634
+ var STATE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.capture.media-cache-state");
635
+ function getState() {
636
+ const holder = globalThis;
637
+ let state = holder[STATE_SLOT];
638
+ if (!state) {
639
+ state = { cache: /* @__PURE__ */ new Map(), listeners: /* @__PURE__ */ new Map() };
640
+ holder[STATE_SLOT] = state;
641
+ }
642
+ return state;
643
+ }
486
644
  function notify(key) {
487
- listeners.get(key)?.forEach((fn) => fn());
645
+ getState().listeners.get(key)?.forEach((fn) => fn());
488
646
  }
489
647
  function evictIfNeeded() {
490
- while (cache.size > MAX_ENTRIES) {
491
- const oldest = cache.keys().next().value;
648
+ while (getState().cache.size > MAX_ENTRIES) {
649
+ const oldest = getState().cache.keys().next().value;
492
650
  if (oldest === void 0) return;
493
- const entry = cache.get(oldest);
494
- cache.delete(oldest);
651
+ const entry = getState().cache.get(oldest);
652
+ getState().cache.delete(oldest);
495
653
  if (entry?.revoke && entry.url) URL.revokeObjectURL(entry.url);
496
654
  }
497
655
  }
498
656
  function touch(key, entry) {
499
- cache.delete(key);
500
- cache.set(key, entry);
657
+ getState().cache.delete(key);
658
+ getState().cache.set(key, entry);
501
659
  }
502
660
  function getMediaUrl(item) {
503
661
  if (item.src) return item.src;
504
662
  if (!item.resolve) return null;
505
- const existing = cache.get(item.key);
663
+ const existing = getState().cache.get(item.key);
506
664
  if (existing) {
507
665
  touch(item.key, existing);
508
666
  if (existing.url || existing.error) return existing.url;
509
667
  return null;
510
668
  }
511
669
  const entry = { url: null, revoke: false, promise: null, error: false };
512
- cache.set(item.key, entry);
670
+ getState().cache.set(item.key, entry);
513
671
  evictIfNeeded();
514
672
  entry.promise = item.resolve().then((resolved) => {
515
673
  const url = typeof resolved === "string" ? resolved : resolved.url;
@@ -527,8 +685,8 @@ function getMediaUrl(item) {
527
685
  return null;
528
686
  }
529
687
  function invalidateMedia(key) {
530
- const entry = cache.get(key);
531
- cache.delete(key);
688
+ const entry = getState().cache.get(key);
689
+ getState().cache.delete(key);
532
690
  if (entry?.revoke && entry.url) URL.revokeObjectURL(entry.url);
533
691
  notify(key);
534
692
  }
@@ -537,13 +695,13 @@ function useMediaUrl(item) {
537
695
  const key = item?.key ?? null;
538
696
  (0, import_react2.useEffect)(() => {
539
697
  if (!key) return;
540
- const set = listeners.get(key) ?? /* @__PURE__ */ new Set();
698
+ const set = getState().listeners.get(key) ?? /* @__PURE__ */ new Set();
541
699
  const fn = () => bump((n) => n + 1);
542
700
  set.add(fn);
543
- listeners.set(key, set);
701
+ getState().listeners.set(key, set);
544
702
  return () => {
545
703
  set.delete(fn);
546
- if (set.size === 0) listeners.delete(key);
704
+ if (set.size === 0) getState().listeners.delete(key);
547
705
  };
548
706
  }, [key]);
549
707
  if (!item) return null;
@@ -556,14 +714,14 @@ function primeMedia(items) {
556
714
  }
557
715
 
558
716
  // src/components/CaptureFilmstrip.tsx
559
- var import_jsx_runtime8 = require("react/jsx-runtime");
717
+ var import_jsx_runtime9 = require("react/jsx-runtime");
560
718
  function CaptureFilmstrip({
561
719
  items,
562
720
  onOpen,
563
721
  limit = 12
564
722
  }) {
565
723
  if (items.length === 0) return null;
566
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex items-center gap-1.5 overflow-x-auto py-1", children: items.slice(-limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
724
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center gap-1.5 overflow-x-auto py-1", children: items.slice(-limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
567
725
  "button",
568
726
  {
569
727
  type: "button",
@@ -574,9 +732,9 @@ function CaptureFilmstrip({
574
732
  item.accent && "ring-2 ring-inset ring-amber-400"
575
733
  ),
576
734
  children: [
577
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FilmstripThumb, { item }),
578
- item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "absolute inset-0 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/40 border-t-white" }) }),
579
- item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "absolute inset-0 rounded ring-2 ring-inset ring-red-500" })
735
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilmstripThumb, { item }),
736
+ item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "absolute inset-0 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "h-3.5 w-3.5 animate-spin rounded-full border-2 border-white/40 border-t-white" }) }),
737
+ item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "absolute inset-0 rounded ring-2 ring-inset ring-red-500" })
580
738
  ]
581
739
  },
582
740
  item.key
@@ -585,7 +743,7 @@ function CaptureFilmstrip({
585
743
  function FilmstripThumb({ item }) {
586
744
  const url = useMediaUrl(item);
587
745
  if (item.kind === "audio") {
588
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
746
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
589
747
  "svg",
590
748
  {
591
749
  viewBox: "0 0 24 24",
@@ -595,17 +753,17 @@ function FilmstripThumb({ item }) {
595
753
  strokeLinecap: "round",
596
754
  "aria-hidden": true,
597
755
  children: [
598
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 3v10" }),
599
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M8 7v4M16 7v4M4 9v1M20 9v1" }),
600
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "17", r: "3" })
756
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M12 3v10" }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M8 7v4M16 7v4M4 9v1M20 9v1" }),
758
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "17", r: "3" })
601
759
  ]
602
760
  }
603
761
  ) });
604
762
  }
605
- if (!url) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "block h-full w-full bg-white/5" });
763
+ if (!url) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "block h-full w-full bg-white/5" });
606
764
  if (item.kind === "video") {
607
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "relative block h-full w-full", children: [
608
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
765
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "relative block h-full w-full", children: [
766
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
609
767
  "video",
610
768
  {
611
769
  src: url,
@@ -615,24 +773,23 @@ function FilmstripThumb({ item }) {
615
773
  className: "h-full w-full object-cover"
616
774
  }
617
775
  ),
618
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
776
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
619
777
  "svg",
620
778
  {
621
779
  viewBox: "0 0 24 24",
622
780
  className: "absolute inset-0 m-auto h-4 w-4 fill-white drop-shadow",
623
781
  "aria-hidden": true,
624
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M8 5v14l11-7z" })
782
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M8 5v14l11-7z" })
625
783
  }
626
784
  )
627
785
  ] });
628
786
  }
629
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: url, alt: "", className: "h-full w-full object-cover" });
787
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: url, alt: "", className: "h-full w-full object-cover" });
630
788
  }
631
789
 
632
790
  // src/components/MediaViewer.tsx
633
791
  var import_react3 = require("react");
634
- var import_lucide_react2 = require("lucide-react");
635
- var import_jsx_runtime9 = require("react/jsx-runtime");
792
+ var import_jsx_runtime10 = require("react/jsx-runtime");
636
793
  var SWIPE_TRIGGER_PX = 40;
637
794
  var SWIPE_TRIGGER_VELOCITY = 0.25;
638
795
  var DISMISS_TRIGGER_PX = 110;
@@ -654,6 +811,7 @@ function MediaViewer({
654
811
  const clamped = Math.min(index, count - 1);
655
812
  const current = count > 0 ? items[clamped] : void 0;
656
813
  const [confirmingDelete, setConfirmingDelete] = (0, import_react3.useState)(false);
814
+ const activeVideoRef = (0, import_react3.useRef)(null);
657
815
  const dragRef = (0, import_react3.useRef)(null);
658
816
  const [drag, setDrag] = (0, import_react3.useState)(null);
659
817
  const [settling, setSettling] = (0, import_react3.useState)(false);
@@ -694,7 +852,7 @@ function MediaViewer({
694
852
  return () => window.removeEventListener("keydown", onKey);
695
853
  }, [go, onClose, keysDisabled]);
696
854
  const onPointerDown = (0, import_react3.useCallback)((e) => {
697
- if (e.target.closest("video, audio")) return;
855
+ if (e.target.closest("audio")) return;
698
856
  dragRef.current = {
699
857
  x0: e.clientX,
700
858
  y0: e.clientY,
@@ -741,6 +899,14 @@ function MediaViewer({
741
899
  return;
742
900
  }
743
901
  }
902
+ if (d.axis === null) {
903
+ const video = activeVideoRef.current;
904
+ if (video) {
905
+ if (video.paused) void video.play().catch(() => {
906
+ });
907
+ else video.pause();
908
+ }
909
+ }
744
910
  setDrag(null);
745
911
  setSettling(true);
746
912
  },
@@ -756,55 +922,55 @@ function MediaViewer({
756
922
  }, [items, clamped]);
757
923
  if (!current) return null;
758
924
  const canEdit = onEdit && current.kind === "photo";
759
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "absolute inset-0 z-40 flex flex-col bg-black", children: [
760
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
925
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "absolute inset-0 z-40 flex flex-col bg-black", children: [
926
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
761
927
  "div",
762
928
  {
763
929
  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",
764
930
  style: safeTop,
765
931
  children: [
766
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
932
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
767
933
  "button",
768
934
  {
769
935
  type: "button",
770
936
  onClick: onClose,
771
937
  "aria-label": "Close viewer",
772
938
  className: "flex h-10 w-10 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
773
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.X, { className: "h-5 w-5" })
939
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(XIcon, { className: "h-5 w-5" })
774
940
  }
775
941
  ),
776
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "rounded-full bg-black/50 px-3 py-1 text-sm tabular-nums text-white/90", children: [
942
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "rounded-full bg-black/50 px-3 py-1 text-sm tabular-nums text-white/90", children: [
777
943
  clamped + 1,
778
944
  " / ",
779
945
  count
780
946
  ] }),
781
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex items-center gap-1", children: [
782
- canEdit ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
947
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex items-center gap-1", children: [
948
+ canEdit ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
783
949
  "button",
784
950
  {
785
951
  type: "button",
786
952
  onClick: () => onEdit(current),
787
953
  "aria-label": "Edit this photo",
788
954
  className: "flex h-10 w-10 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
789
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Pencil, { className: "h-5 w-5" })
955
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PencilIcon, { className: "h-5 w-5" })
790
956
  }
791
957
  ) : null,
792
- onDelete ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
958
+ onDelete ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
793
959
  "button",
794
960
  {
795
961
  type: "button",
796
962
  onClick: () => setConfirmingDelete(true),
797
963
  "aria-label": "Delete this file",
798
964
  className: "flex h-10 w-10 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
799
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Trash2, { className: "h-5 w-5" })
965
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Trash2Icon, { className: "h-5 w-5" })
800
966
  }
801
- ) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "h-10 w-10", "aria-hidden": true })
967
+ ) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "h-10 w-10", "aria-hidden": true })
802
968
  ] })
803
969
  ]
804
970
  }
805
971
  ),
806
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [
807
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
972
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [
973
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
808
974
  "div",
809
975
  {
810
976
  className: "absolute inset-0 touch-none",
@@ -817,39 +983,47 @@ function MediaViewer({
817
983
  onPointerMove,
818
984
  onPointerUp: endDrag,
819
985
  onPointerCancel: endDrag,
820
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ViewerSlide, { item: current, active: true }, current.key)
986
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
987
+ ViewerSlide,
988
+ {
989
+ item: current,
990
+ active: true,
991
+ videoRef: activeVideoRef
992
+ },
993
+ current.key
994
+ )
821
995
  }
822
996
  ),
823
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
997
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
824
998
  "div",
825
999
  {
826
1000
  "aria-hidden": true,
827
1001
  className: "pointer-events-none absolute inset-0 opacity-0",
828
- children: neighborKeys.map((m) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ViewerSlide, { item: m, active: false }) }, m.key))
1002
+ children: neighborKeys.map((m) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ViewerSlide, { item: m, active: false }) }, m.key))
829
1003
  }
830
1004
  ),
831
- clamped > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1005
+ clamped > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
832
1006
  "button",
833
1007
  {
834
1008
  type: "button",
835
1009
  onClick: () => go(-1),
836
1010
  "aria-label": "Previous file",
837
1011
  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",
838
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.ChevronLeft, { className: "h-6 w-6" })
1012
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChevronLeftIcon, { className: "h-6 w-6" })
839
1013
  }
840
1014
  ),
841
- clamped < count - 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1015
+ clamped < count - 1 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
842
1016
  "button",
843
1017
  {
844
1018
  type: "button",
845
1019
  onClick: () => go(1),
846
1020
  "aria-label": "Next file",
847
1021
  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",
848
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.ChevronRight, { className: "h-6 w-6" })
1022
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChevronRightIcon, { className: "h-6 w-6" })
849
1023
  }
850
1024
  )
851
1025
  ] }),
852
- confirmingDelete && onDelete && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1026
+ confirmingDelete && onDelete && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
853
1027
  "div",
854
1028
  {
855
1029
  className: "absolute inset-x-0 bottom-0 z-30 bg-black/85 px-4 pt-4 backdrop-blur-sm",
@@ -857,14 +1031,14 @@ function MediaViewer({
857
1031
  paddingBottom: "calc(1rem + env(safe-area-inset-bottom, 0px))"
858
1032
  },
859
1033
  children: [
860
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { className: "pb-3 text-center text-sm text-white/85", children: [
1034
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "pb-3 text-center text-sm text-white/85", children: [
861
1035
  "Delete this ",
862
1036
  current.kind === "video" ? "video" : current.kind === "audio" ? "voice note" : "photo",
863
1037
  "? ",
864
1038
  deleteConsequence
865
1039
  ] }),
866
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-center gap-3", children: [
867
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1040
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-center gap-3", children: [
1041
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
868
1042
  "button",
869
1043
  {
870
1044
  type: "button",
@@ -873,7 +1047,7 @@ function MediaViewer({
873
1047
  children: "Keep it"
874
1048
  }
875
1049
  ),
876
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1050
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
877
1051
  "button",
878
1052
  {
879
1053
  type: "button",
@@ -889,12 +1063,12 @@ function MediaViewer({
889
1063
  ]
890
1064
  }
891
1065
  ),
892
- count > 1 && count <= 12 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1066
+ count > 1 && count <= 12 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
893
1067
  "div",
894
1068
  {
895
1069
  className: "pointer-events-none absolute inset-x-0 bottom-4 z-20 flex justify-center gap-1.5",
896
1070
  style: safeMarginBottom,
897
- children: items.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1071
+ children: items.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
898
1072
  "span",
899
1073
  {
900
1074
  className: cn(
@@ -910,16 +1084,17 @@ function MediaViewer({
910
1084
  }
911
1085
  function ViewerSlide({
912
1086
  item,
913
- active
1087
+ active,
1088
+ videoRef
914
1089
  }) {
915
1090
  const url = useMediaUrl(item);
916
1091
  if (!url) {
917
- return active ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "h-8 w-8 animate-spin rounded-full border-2 border-white/30 border-t-white" }) }) : null;
1092
+ return active ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "h-8 w-8 animate-spin rounded-full border-2 border-white/30 border-t-white" }) }) : null;
918
1093
  }
919
1094
  if (item.kind === "audio") {
920
1095
  if (!active) return null;
921
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-6 px-8", children: [
922
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1096
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-6 px-8", children: [
1097
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
923
1098
  "svg",
924
1099
  {
925
1100
  viewBox: "0 0 24 24",
@@ -929,32 +1104,19 @@ function ViewerSlide({
929
1104
  strokeLinecap: "round",
930
1105
  "aria-hidden": true,
931
1106
  children: [
932
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M12 2v12" }),
933
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M7 6v6M17 6v6M2 9v2M22 9v2" }),
934
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "19", r: "3" })
1107
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 2v12" }),
1108
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M7 6v6M17 6v6M2 9v2M22 9v2" }),
1109
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "19", r: "3" })
935
1110
  ]
936
1111
  }
937
1112
  ),
938
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("audio", { src: url, controls: true, className: "w-full max-w-sm" })
1113
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("audio", { src: url, controls: true, className: "w-full max-w-sm" })
939
1114
  ] });
940
1115
  }
941
1116
  if (item.kind === "video") {
942
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
943
- "video",
944
- {
945
- src: url,
946
- controls: active,
947
- playsInline: true,
948
- preload: active ? "auto" : "metadata",
949
- muted: !active,
950
- className: cn(
951
- "absolute inset-0 h-full w-full object-contain",
952
- active ? "pointer-events-auto" : "pointer-events-none"
953
- )
954
- }
955
- );
1117
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(VideoSlide, { url, active, videoRef });
956
1118
  }
957
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1119
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
958
1120
  "img",
959
1121
  {
960
1122
  src: url,
@@ -965,11 +1127,55 @@ function ViewerSlide({
965
1127
  }
966
1128
  );
967
1129
  }
1130
+ function VideoSlide({
1131
+ url,
1132
+ active,
1133
+ videoRef
1134
+ }) {
1135
+ const [paused, setPaused] = (0, import_react3.useState)(true);
1136
+ const [progress, setProgress] = (0, import_react3.useState)(0);
1137
+ const localRef = (0, import_react3.useRef)(null);
1138
+ (0, import_react3.useEffect)(() => {
1139
+ if (!active || !videoRef) return;
1140
+ videoRef.current = localRef.current;
1141
+ return () => {
1142
+ if (videoRef.current === localRef.current) videoRef.current = null;
1143
+ };
1144
+ }, [active, videoRef]);
1145
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "pointer-events-none absolute inset-0", children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1147
+ "video",
1148
+ {
1149
+ ref: localRef,
1150
+ src: url,
1151
+ playsInline: true,
1152
+ preload: active ? "auto" : "metadata",
1153
+ muted: !active,
1154
+ loop: false,
1155
+ onPlay: () => setPaused(false),
1156
+ onPause: () => setPaused(true),
1157
+ onEnded: () => setPaused(true),
1158
+ onTimeUpdate: (e) => {
1159
+ const v = e.currentTarget;
1160
+ setProgress(v.duration > 0 ? v.currentTime / v.duration : 0);
1161
+ },
1162
+ className: "absolute inset-0 h-full w-full object-contain"
1163
+ }
1164
+ ),
1165
+ active && paused && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-black/45", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PlayIcon, { className: "ml-1 h-8 w-8 fill-white text-white" }) }) }),
1166
+ active && !paused && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "absolute inset-x-4 bottom-2 h-0.5 overflow-hidden rounded-full bg-white/25", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1167
+ "span",
1168
+ {
1169
+ className: "block h-full rounded-full bg-white",
1170
+ style: { width: `${Math.round(progress * 100)}%` }
1171
+ }
1172
+ ) })
1173
+ ] });
1174
+ }
968
1175
 
969
1176
  // src/components/ImageEditSheet.tsx
970
1177
  var import_react4 = require("react");
971
- var import_lucide_react3 = require("lucide-react");
972
- var import_jsx_runtime10 = require("react/jsx-runtime");
1178
+ var import_jsx_runtime11 = require("react/jsx-runtime");
973
1179
  var ASPECTS = [
974
1180
  { id: "free", label: "Free", ratio: null },
975
1181
  { id: "1:1", label: "Square", ratio: 1 },
@@ -1149,14 +1355,14 @@ function ImageEditSheet({
1149
1355
  }
1150
1356
  }, [crop, onSave, onClose]);
1151
1357
  if (!open || !src) return null;
1152
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "absolute inset-0 z-50 flex flex-col bg-black", children: [
1153
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1358
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "absolute inset-0 z-50 flex flex-col bg-black", children: [
1359
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1154
1360
  "div",
1155
1361
  {
1156
1362
  className: "flex shrink-0 items-center justify-between px-4",
1157
1363
  style: { paddingTop: "env(safe-area-inset-top, 0px)" },
1158
1364
  children: [
1159
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1365
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1160
1366
  "button",
1161
1367
  {
1162
1368
  type: "button",
@@ -1164,13 +1370,13 @@ function ImageEditSheet({
1164
1370
  "aria-label": "Cancel editing",
1165
1371
  className: "flex h-11 items-center gap-1.5 rounded-full px-3 text-[15px] font-medium text-white",
1166
1372
  children: [
1167
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.X, { className: "h-5 w-5" }),
1373
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(XIcon, { className: "h-5 w-5" }),
1168
1374
  "Cancel"
1169
1375
  ]
1170
1376
  }
1171
1377
  ),
1172
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[15px] font-semibold text-white/90", children: "Edit" }),
1173
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1378
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-[15px] font-semibold text-white/90", children: "Edit" }),
1379
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1174
1380
  "button",
1175
1381
  {
1176
1382
  type: "button",
@@ -1179,7 +1385,7 @@ function ImageEditSheet({
1179
1385
  "aria-label": "Save edited image",
1180
1386
  className: "flex h-11 items-center gap-1.5 rounded-full px-3 text-[15px] font-semibold text-[#FFCC00] disabled:opacity-50",
1181
1387
  children: [
1182
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Check, { className: "h-5 w-5" }),
1388
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CheckIcon, { className: "h-5 w-5" }),
1183
1389
  "Save"
1184
1390
  ]
1185
1391
  }
@@ -1187,7 +1393,7 @@ function ImageEditSheet({
1187
1393
  ]
1188
1394
  }
1189
1395
  ),
1190
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1396
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1191
1397
  "div",
1192
1398
  {
1193
1399
  ref: stageRef,
@@ -1195,8 +1401,8 @@ function ImageEditSheet({
1195
1401
  onPointerMove,
1196
1402
  onPointerUp,
1197
1403
  onPointerCancel: onPointerUp,
1198
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative max-h-full max-w-full", children: [
1199
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1404
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "relative max-h-full max-w-full", children: [
1405
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1200
1406
  "img",
1201
1407
  {
1202
1408
  ref: imgRef,
@@ -1206,7 +1412,7 @@ function ImageEditSheet({
1206
1412
  className: "max-h-[62dvh] max-w-full select-none object-contain"
1207
1413
  }
1208
1414
  ),
1209
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1415
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1210
1416
  "div",
1211
1417
  {
1212
1418
  role: "presentation",
@@ -1218,7 +1424,7 @@ function ImageEditSheet({
1218
1424
  width: `${crop.w * 100}%`,
1219
1425
  height: `${crop.h * 100}%`
1220
1426
  },
1221
- children: ["nw", "ne", "sw", "se"].map((corner) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1427
+ children: ["nw", "ne", "sw", "se"].map((corner) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1222
1428
  "span",
1223
1429
  {
1224
1430
  role: "presentation",
@@ -1239,9 +1445,9 @@ function ImageEditSheet({
1239
1445
  ] })
1240
1446
  }
1241
1447
  ),
1242
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "shrink-0", style: { paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
1243
- editError && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "px-6 pb-2 text-center text-sm text-[#FF6961]", children: editError }),
1244
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center justify-center gap-2 pb-2", children: ASPECTS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1448
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "shrink-0", style: { paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
1449
+ editError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "px-6 pb-2 text-center text-sm text-[#FF6961]", children: editError }),
1450
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex items-center justify-center gap-2 pb-2", children: ASPECTS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1245
1451
  "button",
1246
1452
  {
1247
1453
  type: "button",
@@ -1255,25 +1461,25 @@ function ImageEditSheet({
1255
1461
  },
1256
1462
  a.id
1257
1463
  )) }),
1258
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-center gap-6 pb-4", children: [
1259
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1464
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-center gap-6 pb-4", children: [
1465
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1260
1466
  "button",
1261
1467
  {
1262
1468
  type: "button",
1263
1469
  onClick: () => bake("rotate-left"),
1264
1470
  "aria-label": "Rotate left",
1265
1471
  className: "flex h-12 w-12 touch-manipulation items-center justify-center rounded-full bg-white/10 text-white",
1266
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.RotateCcw, { className: "h-5 w-5" })
1472
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RotateCcwIcon, { className: "h-5 w-5" })
1267
1473
  }
1268
1474
  ),
1269
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1475
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1270
1476
  "button",
1271
1477
  {
1272
1478
  type: "button",
1273
1479
  onClick: () => bake("flip"),
1274
1480
  "aria-label": "Flip horizontally",
1275
1481
  className: "flex h-12 w-12 touch-manipulation items-center justify-center rounded-full bg-white/10 text-white",
1276
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.FlipHorizontal2, { className: "h-5 w-5" })
1482
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FlipHorizontal2Icon, { className: "h-5 w-5" })
1277
1483
  }
1278
1484
  )
1279
1485
  ] })
@@ -1282,7 +1488,7 @@ function ImageEditSheet({
1282
1488
  }
1283
1489
 
1284
1490
  // src/components/CameraCapture.tsx
1285
- var import_jsx_runtime11 = require("react/jsx-runtime");
1491
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1286
1492
  function formatElapsed(totalSeconds) {
1287
1493
  const m = Math.floor(totalSeconds / 60);
1288
1494
  const s = String(totalSeconds % 60).padStart(2, "0");
@@ -1361,7 +1567,7 @@ function CameraCapture({
1361
1567
  {
1362
1568
  id: "flash",
1363
1569
  label: "Flash",
1364
- icon: controls.torchOn ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Zap, { className: "h-6 w-6", fill: "currentColor" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.ZapOff, { className: "h-6 w-6" }),
1570
+ icon: controls.torchOn ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ZapIcon, { className: "h-6 w-6", fill: "currentColor" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ZapOffIcon, { className: "h-6 w-6" }),
1365
1571
  active: controls.torchOn,
1366
1572
  onPress: controls.toggleTorch
1367
1573
  }
@@ -1369,7 +1575,7 @@ function CameraCapture({
1369
1575
  {
1370
1576
  id: "timer",
1371
1577
  label: "Timer",
1372
- icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Timer, { className: "h-6 w-6" }),
1578
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TimerIcon, { className: "h-6 w-6" }),
1373
1579
  active: timerSetting !== 0,
1374
1580
  valueLabel: timerSetting === 0 ? void 0 : `${timerSetting}s`,
1375
1581
  onPress: cycleTimer
@@ -1377,7 +1583,7 @@ function CameraCapture({
1377
1583
  {
1378
1584
  id: "grid",
1379
1585
  label: "Grid",
1380
- icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Grid3x3, { className: "h-6 w-6" }),
1586
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Grid3x3Icon, { className: "h-6 w-6" }),
1381
1587
  active: gridOn,
1382
1588
  onPress: () => setGridOn((g) => !g)
1383
1589
  },
@@ -1385,7 +1591,7 @@ function CameraCapture({
1385
1591
  {
1386
1592
  id: "aspect",
1387
1593
  label: "Aspect",
1388
- icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Proportions, { className: "h-6 w-6" }),
1594
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ProportionsIcon, { className: "h-6 w-6" }),
1389
1595
  active: aspect !== "full",
1390
1596
  valueLabel: aspect === "full" ? void 0 : aspect,
1391
1597
  onPress: () => setAspect(
@@ -1396,7 +1602,7 @@ function CameraCapture({
1396
1602
  {
1397
1603
  id: "exposure",
1398
1604
  label: "Exposure",
1399
- icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.SunMedium, { className: "h-6 w-6" }),
1605
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SunMediumIcon, { className: "h-6 w-6" }),
1400
1606
  active: controls.exposure !== 0 || exposureOpen,
1401
1607
  valueLabel: controls.exposure === 0 ? void 0 : `${controls.exposure > 0 ? "+" : ""}${controls.exposure}`,
1402
1608
  onPress: () => setExposureOpen((o) => !o)
@@ -1405,15 +1611,15 @@ function CameraCapture({
1405
1611
  ];
1406
1612
  const tiles = [...coreTiles, ...slots.optionTiles ?? []];
1407
1613
  const blocked = engine.blocked !== null;
1408
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
1409
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "absolute inset-0", children: preview }),
1410
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(GridOverlay, { visible: gridOn && !blocked }),
1411
- mode === "photo" && aspect !== "full" && !blocked && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1614
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
1615
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "absolute inset-0", children: preview }),
1616
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(GridOverlay, { visible: gridOn && !blocked }),
1617
+ mode === "photo" && aspect !== "full" && !blocked && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1412
1618
  "div",
1413
1619
  {
1414
1620
  "aria-hidden": true,
1415
1621
  className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center",
1416
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1622
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1417
1623
  "div",
1418
1624
  {
1419
1625
  className: "shadow-[0_0_0_9999px_rgba(0,0,0,0.45)]",
@@ -1428,25 +1634,25 @@ function CameraCapture({
1428
1634
  )
1429
1635
  }
1430
1636
  ),
1431
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CountdownOverlay, { seconds: countdown }),
1432
- !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1637
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CountdownOverlay, { seconds: countdown }),
1638
+ !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1433
1639
  "div",
1434
1640
  {
1435
1641
  className: "absolute inset-x-0 top-0 z-20 bg-black/65 backdrop-blur-[2px]",
1436
1642
  style: safeTop,
1437
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex h-11 items-center gap-0.5 px-1.5", children: [
1438
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1643
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex h-11 items-center gap-0.5 px-1.5", children: [
1644
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1439
1645
  "button",
1440
1646
  {
1441
1647
  type: "button",
1442
1648
  onClick: onClose,
1443
1649
  "aria-label": "Close camera",
1444
1650
  className: "flex h-10 w-10 shrink-0 touch-manipulation items-center justify-center rounded-full text-white transition-colors hover:bg-white/10",
1445
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.X, { className: "h-5 w-5" })
1651
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(XIcon, { className: "h-5 w-5" })
1446
1652
  }
1447
- ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "w-10 shrink-0" }),
1448
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "min-w-0 flex-1", children: slots.topBarCenter }),
1449
- controls.torchSupported && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1653
+ ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-10 shrink-0" }),
1654
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-w-0 flex-1", children: slots.topBarCenter }),
1655
+ controls.torchSupported && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1450
1656
  "button",
1451
1657
  {
1452
1658
  type: "button",
@@ -1457,8 +1663,8 @@ function CameraCapture({
1457
1663
  "flex h-10 w-10 shrink-0 touch-manipulation items-center justify-center rounded-full transition-colors",
1458
1664
  controls.torchOn ? "text-[#FFCC00]" : "text-white hover:bg-white/10"
1459
1665
  ),
1460
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1461
- import_lucide_react4.Zap,
1666
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1667
+ ZapIcon,
1462
1668
  {
1463
1669
  className: "h-5 w-5",
1464
1670
  fill: controls.torchOn ? "currentColor" : "none"
@@ -1467,7 +1673,7 @@ function CameraCapture({
1467
1673
  }
1468
1674
  ),
1469
1675
  slots.topBarTrailing,
1470
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1676
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1471
1677
  "button",
1472
1678
  {
1473
1679
  type: "button",
@@ -1478,28 +1684,28 @@ function CameraCapture({
1478
1684
  "flex h-10 w-10 shrink-0 touch-manipulation items-center justify-center rounded-full transition-colors",
1479
1685
  optionsOpen ? "bg-white/20 text-white" : "text-white hover:bg-white/10"
1480
1686
  ),
1481
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Grip, { className: "h-5 w-5" })
1687
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(GripIcon, { className: "h-5 w-5" })
1482
1688
  }
1483
1689
  )
1484
1690
  ] })
1485
1691
  }
1486
1692
  ),
1487
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1693
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1488
1694
  "div",
1489
1695
  {
1490
1696
  className: "pointer-events-none absolute inset-x-0 top-[50px] z-20 flex flex-col items-center gap-1.5",
1491
1697
  style: safeMarginTop,
1492
1698
  children: [
1493
- engine.recording && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "flex items-center gap-2 rounded-full bg-black/60 px-3 py-1.5 text-sm font-medium text-white", children: [
1494
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "h-2.5 w-2.5 animate-pulse rounded-full bg-[#FF3B30]" }),
1699
+ engine.recording && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex items-center gap-2 rounded-full bg-black/60 px-3 py-1.5 text-sm font-medium text-white", children: [
1700
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "h-2.5 w-2.5 animate-pulse rounded-full bg-[#FF3B30]" }),
1495
1701
  formatElapsed(engine.recordElapsedSeconds)
1496
1702
  ] }),
1497
1703
  slots.statusChips
1498
1704
  ]
1499
1705
  }
1500
1706
  ),
1501
- !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "absolute inset-x-0 bottom-0 z-20", children: [
1502
- !blocked && controls.zoomOptions.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1707
+ !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "absolute inset-x-0 bottom-0 z-20", children: [
1708
+ !blocked && controls.zoomOptions.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1503
1709
  ZoomRow,
1504
1710
  {
1505
1711
  options: controls.zoomOptions,
@@ -1507,17 +1713,17 @@ function CameraCapture({
1507
1713
  onSelect: controls.setZoom
1508
1714
  }
1509
1715
  ) }),
1510
- media && media.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-1.5 px-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1716
+ media && media.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mb-1.5 px-2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1511
1717
  CaptureFilmstrip,
1512
1718
  {
1513
1719
  items: media.items,
1514
1720
  onOpen: (item) => setViewerKey(item.key)
1515
1721
  }
1516
1722
  ) }),
1517
- slots.aboveBar && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-1.5 px-2", children: slots.aboveBar }),
1518
- exposureOpen && controls.exposureSupported && controls.exposureRange && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mx-auto mb-3 flex w-64 items-center gap-3 rounded-full bg-black/55 px-4 py-2", children: [
1519
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.SunMedium, { className: "h-4 w-4 shrink-0 text-[#FFCC00]" }),
1520
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1723
+ slots.aboveBar && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mb-1.5 px-2", children: slots.aboveBar }),
1724
+ exposureOpen && controls.exposureSupported && controls.exposureRange && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mx-auto mb-3 flex w-64 items-center gap-3 rounded-full bg-black/55 px-4 py-2", children: [
1725
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SunMediumIcon, { className: "h-4 w-4 shrink-0 text-[#FFCC00]" }),
1726
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1521
1727
  "input",
1522
1728
  {
1523
1729
  type: "range",
@@ -1530,20 +1736,20 @@ function CameraCapture({
1530
1736
  className: "w-full accent-[#FFCC00]"
1531
1737
  }
1532
1738
  ),
1533
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "w-8 shrink-0 text-right text-xs tabular-nums text-white", children: [
1739
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "w-8 shrink-0 text-right text-xs tabular-nums text-white", children: [
1534
1740
  controls.exposure > 0 ? "+" : "",
1535
1741
  controls.exposure
1536
1742
  ] })
1537
1743
  ] }),
1538
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1744
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1539
1745
  "div",
1540
1746
  {
1541
1747
  className: "bg-black/65 px-3 backdrop-blur-[2px]",
1542
1748
  style: safeBottom,
1543
1749
  children: [
1544
1750
  slots.aboveModeSelector,
1545
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-center gap-2 py-1.5", children: [
1546
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1751
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-center gap-2 py-1.5", children: [
1752
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1547
1753
  ModeSelector,
1548
1754
  {
1549
1755
  mode,
@@ -1554,20 +1760,20 @@ function CameraCapture({
1554
1760
  extraModes: slots.extraModes
1555
1761
  }
1556
1762
  ),
1557
- slots.modeRowTrailing && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "shrink-0", children: slots.modeRowTrailing })
1763
+ slots.modeRowTrailing && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "shrink-0", children: slots.modeRowTrailing })
1558
1764
  ] }),
1559
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between px-2 pb-1.5 pt-0.5", children: [
1560
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex w-14 justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1765
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between px-2 pb-1.5 pt-0.5", children: [
1766
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex w-14 justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1561
1767
  "button",
1562
1768
  {
1563
1769
  type: "button",
1564
1770
  onClick: cloud.onOpenLibrary,
1565
1771
  "aria-label": "Open your media library",
1566
1772
  className: "h-11 w-11 touch-manipulation overflow-hidden rounded-xl bg-white/10 ring-1 ring-white/25 transition-transform active:scale-95",
1567
- children: cloud.recentsThumb ?? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "block h-full w-full bg-white/5" })
1773
+ children: cloud.recentsThumb ?? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "block h-full w-full bg-white/5" })
1568
1774
  }
1569
1775
  ) }),
1570
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1776
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1571
1777
  ShutterButton,
1572
1778
  {
1573
1779
  mode,
@@ -1576,22 +1782,22 @@ function CameraCapture({
1576
1782
  onPress: onShutter
1577
1783
  }
1578
1784
  ),
1579
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex w-14 justify-end", children: engine.onFlipCamera ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1785
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex w-14 justify-end", children: engine.onFlipCamera ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1580
1786
  "button",
1581
1787
  {
1582
1788
  type: "button",
1583
1789
  onClick: engine.onFlipCamera,
1584
1790
  "aria-label": "Switch camera",
1585
1791
  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",
1586
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.RefreshCw, { className: "h-5 w-5" })
1792
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefreshCwIcon, { className: "h-5 w-5" })
1587
1793
  }
1588
- ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "h-11 w-11" }) })
1794
+ ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "h-11 w-11" }) })
1589
1795
  ] })
1590
1796
  ]
1591
1797
  }
1592
1798
  )
1593
1799
  ] }),
1594
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1800
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1595
1801
  OptionsGridPanel,
1596
1802
  {
1597
1803
  open: optionsOpen && !controlsHidden,
@@ -1599,7 +1805,7 @@ function CameraCapture({
1599
1805
  tiles
1600
1806
  }
1601
1807
  ),
1602
- blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1808
+ blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1603
1809
  CaptureSheet,
1604
1810
  {
1605
1811
  open: true,
@@ -1609,7 +1815,7 @@ function CameraCapture({
1609
1815
  actions: blockedSheet.actions
1610
1816
  }
1611
1817
  ),
1612
- media && viewerKey !== null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1818
+ media && viewerKey !== null && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1613
1819
  MediaViewer,
1614
1820
  {
1615
1821
  items: media.items,
@@ -1626,7 +1832,7 @@ function CameraCapture({
1626
1832
  } : void 0
1627
1833
  }
1628
1834
  ),
1629
- media?.onReplacePhoto && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1835
+ media?.onReplacePhoto && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1630
1836
  ImageEditSheet,
1631
1837
  {
1632
1838
  open: editTarget !== null,
@@ -1649,11 +1855,10 @@ function CameraCapture({
1649
1855
 
1650
1856
  // src/components/CameraCaptureV3.tsx
1651
1857
  var import_react8 = require("react");
1652
- var import_lucide_react5 = require("lucide-react");
1653
1858
 
1654
1859
  // src/components/CaptureRail.tsx
1655
1860
  var import_react6 = require("react");
1656
- var import_jsx_runtime12 = require("react/jsx-runtime");
1861
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1657
1862
  function CaptureRail({
1658
1863
  actions,
1659
1864
  defaultExpanded = false,
@@ -1665,7 +1870,7 @@ function CaptureRail({
1665
1870
  const shown = primary.length === 0 ? actions : expanded ? actions : primary;
1666
1871
  const collapsible = primary.length > 0 && extra.length > 0;
1667
1872
  if (actions.length === 0) return null;
1668
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1873
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1669
1874
  "div",
1670
1875
  {
1671
1876
  className: cn(
@@ -1673,8 +1878,8 @@ function CaptureRail({
1673
1878
  className
1674
1879
  ),
1675
1880
  children: [
1676
- shown.map((action) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RailButton, { action }, action.id)),
1677
- collapsible ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1881
+ shown.map((action) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RailButton, { action }, action.id)),
1882
+ collapsible ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1678
1883
  "button",
1679
1884
  {
1680
1885
  type: "button",
@@ -1685,7 +1890,7 @@ function CaptureRail({
1685
1890
  "mt-0.5 flex h-9 w-9 touch-manipulation items-center justify-center",
1686
1891
  "rounded-full text-white/90 transition-colors hover:bg-white/10"
1687
1892
  ),
1688
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1893
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1689
1894
  Chevron,
1690
1895
  {
1691
1896
  className: cn(
@@ -1701,7 +1906,7 @@ function CaptureRail({
1701
1906
  );
1702
1907
  }
1703
1908
  function RailButton({ action }) {
1704
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1909
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1705
1910
  "button",
1706
1911
  {
1707
1912
  type: "button",
@@ -1716,14 +1921,14 @@ function RailButton({ action }) {
1716
1921
  action.disabled ? "opacity-40" : "hover:bg-white/10 active:bg-white/15"
1717
1922
  ),
1718
1923
  children: [
1719
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", children: action.icon }),
1720
- action.valueLabel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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
1924
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", children: action.icon }),
1925
+ action.valueLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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
1721
1926
  ]
1722
1927
  }
1723
1928
  );
1724
1929
  }
1725
1930
  function Chevron({ className }) {
1726
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1931
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1727
1932
  "svg",
1728
1933
  {
1729
1934
  viewBox: "0 0 24 24",
@@ -1734,16 +1939,16 @@ function Chevron({ className }) {
1734
1939
  strokeLinejoin: "round",
1735
1940
  className,
1736
1941
  "aria-hidden": "true",
1737
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m6 9 6 6 6-6" })
1942
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m6 9 6 6 6-6" })
1738
1943
  }
1739
1944
  );
1740
1945
  }
1741
1946
 
1742
1947
  // src/components/HoldShutter.tsx
1743
1948
  var import_react7 = require("react");
1744
- var import_jsx_runtime13 = require("react/jsx-runtime");
1949
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1745
1950
  var HOLD_MS = 320;
1746
- var LOCK_AFTER_MS = 1200;
1951
+ var LOCK_DRAG_PX = 64;
1747
1952
  function HoldShutter({
1748
1953
  recording,
1749
1954
  elapsedSeconds,
@@ -1756,6 +1961,7 @@ function HoldShutter({
1756
1961
  }) {
1757
1962
  const holdTimer = (0, import_react7.useRef)(null);
1758
1963
  const startedRecording = (0, import_react7.useRef)(false);
1964
+ const pressOriginY = (0, import_react7.useRef)(0);
1759
1965
  const [pressed, setPressed] = (0, import_react7.useState)(false);
1760
1966
  const [locked, setLocked] = (0, import_react7.useState)(false);
1761
1967
  const clearHold = (0, import_react7.useCallback)(() => {
@@ -1765,17 +1971,14 @@ function HoldShutter({
1765
1971
  }
1766
1972
  }, []);
1767
1973
  (0, import_react7.useEffect)(() => {
1768
- if (!recording) {
1769
- setLocked(false);
1770
- return;
1771
- }
1772
- if (elapsedSeconds * 1e3 >= LOCK_AFTER_MS) setLocked(true);
1773
- }, [recording, elapsedSeconds]);
1974
+ if (!recording) setLocked(false);
1975
+ }, [recording]);
1774
1976
  (0, import_react7.useEffect)(() => clearHold, [clearHold]);
1775
1977
  const onPointerDown = (0, import_react7.useCallback)(
1776
1978
  (event) => {
1777
1979
  if (disabled) return;
1778
1980
  event.currentTarget.setPointerCapture?.(event.pointerId);
1981
+ pressOriginY.current = event.clientY;
1779
1982
  setPressed(true);
1780
1983
  onPressStart?.();
1781
1984
  if (recording && locked) return;
@@ -1788,6 +1991,16 @@ function HoldShutter({
1788
1991
  },
1789
1992
  [disabled, locked, onPressStart, onStartRecording, recording]
1790
1993
  );
1994
+ const onPointerMove = (0, import_react7.useCallback)(
1995
+ (event) => {
1996
+ if (!pressed || locked || !startedRecording.current) return;
1997
+ if (pressOriginY.current - event.clientY >= LOCK_DRAG_PX) {
1998
+ setLocked(true);
1999
+ navigator.vibrate?.(30);
2000
+ }
2001
+ },
2002
+ [pressed, locked]
2003
+ );
1791
2004
  const endPress = (0, import_react7.useCallback)(() => {
1792
2005
  if (!pressed) return;
1793
2006
  setPressed(false);
@@ -1807,15 +2020,15 @@ function HoldShutter({
1807
2020
  const progress = maxSeconds && maxSeconds > 0 ? Math.min(1, elapsedSeconds / maxSeconds) : 0;
1808
2021
  const R = 39;
1809
2022
  const C = 2 * Math.PI * R;
1810
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative flex h-[86px] w-[86px] shrink-0 items-center justify-center", children: [
1811
- recording && maxSeconds ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2023
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "relative flex h-[86px] w-[86px] shrink-0 items-center justify-center", children: [
2024
+ recording && maxSeconds ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1812
2025
  "svg",
1813
2026
  {
1814
2027
  className: "pointer-events-none absolute inset-0 -rotate-90",
1815
2028
  viewBox: "0 0 86 86",
1816
2029
  "aria-hidden": "true",
1817
2030
  children: [
1818
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2031
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1819
2032
  "circle",
1820
2033
  {
1821
2034
  cx: "43",
@@ -1826,7 +2039,7 @@ function HoldShutter({
1826
2039
  strokeWidth: "4"
1827
2040
  }
1828
2041
  ),
1829
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2042
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1830
2043
  "circle",
1831
2044
  {
1832
2045
  cx: "43",
@@ -1843,12 +2056,34 @@ function HoldShutter({
1843
2056
  ]
1844
2057
  }
1845
2058
  ) : null,
1846
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2059
+ recording && pressed && !locked && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2060
+ "span",
2061
+ {
2062
+ className: "pointer-events-none absolute left-1/2 flex -translate-x-1/2 flex-col items-center gap-0.5",
2063
+ style: { top: -LOCK_DRAG_PX - 22 },
2064
+ "aria-hidden": true,
2065
+ children: [
2066
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "flex h-9 w-9 items-center justify-center rounded-full bg-black/60 ring-1 ring-white/30", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LockIcon, { className: "h-4 w-4 text-white/90" }) }),
2067
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-[10px] font-medium text-white/80 drop-shadow", children: "Slide up to lock" })
2068
+ ]
2069
+ }
2070
+ ),
2071
+ recording && locked && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2072
+ "span",
2073
+ {
2074
+ 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]",
2075
+ style: { top: -LOCK_DRAG_PX - 22 },
2076
+ "aria-hidden": true,
2077
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LockIcon, { className: "h-4 w-4 text-white", fill: "currentColor" })
2078
+ }
2079
+ ),
2080
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1847
2081
  "button",
1848
2082
  {
1849
2083
  type: "button",
1850
2084
  disabled,
1851
2085
  onPointerDown,
2086
+ onPointerMove,
1852
2087
  onPointerUp: endPress,
1853
2088
  onPointerCancel: endPress,
1854
2089
  onLostPointerCapture: endPress,
@@ -1859,7 +2094,7 @@ function HoldShutter({
1859
2094
  "rounded-full border-[3.5px] border-white transition-opacity",
1860
2095
  disabled && "opacity-30"
1861
2096
  ),
1862
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2097
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1863
2098
  "span",
1864
2099
  {
1865
2100
  className: cn(
@@ -1873,7 +2108,7 @@ function HoldShutter({
1873
2108
  )
1874
2109
  }
1875
2110
  ),
1876
- recording ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2111
+ recording ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1877
2112
  "span",
1878
2113
  {
1879
2114
  className: cn(
@@ -1895,7 +2130,7 @@ function formatElapsed2(totalSeconds) {
1895
2130
  }
1896
2131
 
1897
2132
  // src/components/CameraCaptureV3.tsx
1898
- var import_jsx_runtime14 = require("react/jsx-runtime");
2133
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1899
2134
  var ASPECT_CYCLE2 = ["full", "4:3", "1:1", "16:9"];
1900
2135
  function CameraCaptureV3({
1901
2136
  engine,
@@ -1962,7 +2197,7 @@ function CameraCaptureV3({
1962
2197
  {
1963
2198
  id: "flip",
1964
2199
  label: "Switch camera",
1965
- icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.RefreshCw, { className: "h-[22px] w-[22px]" }),
2200
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RefreshCwIcon, { className: "h-[22px] w-[22px]" }),
1966
2201
  primary: true,
1967
2202
  onPress: engine.onFlipCamera
1968
2203
  }
@@ -1971,7 +2206,7 @@ function CameraCaptureV3({
1971
2206
  {
1972
2207
  id: "flash",
1973
2208
  label: "Flash",
1974
- icon: controls.torchOn ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Zap, { className: "h-[22px] w-[22px]", fill: "currentColor" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.ZapOff, { className: "h-[22px] w-[22px]" }),
2209
+ icon: controls.torchOn ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ZapIcon, { className: "h-[22px] w-[22px]", fill: "currentColor" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ZapOffIcon, { className: "h-[22px] w-[22px]" }),
1975
2210
  active: controls.torchOn,
1976
2211
  primary: true,
1977
2212
  onPress: controls.toggleTorch
@@ -1980,7 +2215,7 @@ function CameraCaptureV3({
1980
2215
  {
1981
2216
  id: "timer",
1982
2217
  label: "Timer",
1983
- icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Timer, { className: "h-[22px] w-[22px]" }),
2218
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TimerIcon, { className: "h-[22px] w-[22px]" }),
1984
2219
  active: timerSetting !== 0,
1985
2220
  valueLabel: timerSetting === 0 ? void 0 : `${timerSetting}s`,
1986
2221
  onPress: () => setTimerSetting((t) => t === 0 ? 3 : t === 3 ? 10 : 0)
@@ -1988,14 +2223,14 @@ function CameraCaptureV3({
1988
2223
  {
1989
2224
  id: "grid",
1990
2225
  label: "Grid",
1991
- icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Grid3x3, { className: "h-[22px] w-[22px]" }),
2226
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Grid3x3Icon, { className: "h-[22px] w-[22px]" }),
1992
2227
  active: gridOn,
1993
2228
  onPress: () => setGridOn((g) => !g)
1994
2229
  },
1995
2230
  {
1996
2231
  id: "aspect",
1997
2232
  label: "Aspect",
1998
- icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Proportions, { className: "h-[22px] w-[22px]" }),
2233
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ProportionsIcon, { className: "h-[22px] w-[22px]" }),
1999
2234
  active: aspect !== "full",
2000
2235
  valueLabel: aspect === "full" ? void 0 : aspect,
2001
2236
  onPress: () => setAspect(
@@ -2006,7 +2241,7 @@ function CameraCaptureV3({
2006
2241
  {
2007
2242
  id: "exposure",
2008
2243
  label: "Exposure",
2009
- icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.SunMedium, { className: "h-[22px] w-[22px]" }),
2244
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SunMediumIcon, { className: "h-[22px] w-[22px]" }),
2010
2245
  active: controls.exposure !== 0,
2011
2246
  valueLabel: controls.exposure === 0 ? void 0 : `${controls.exposure > 0 ? "+" : ""}${controls.exposure}`,
2012
2247
  onPress: () => controls.setExposure(controls.exposure === 0 ? 1 : 0)
@@ -2017,15 +2252,15 @@ function CameraCaptureV3({
2017
2252
  ...coreRail.map((a) => blocked ? { ...a, disabled: true } : a),
2018
2253
  ...slots.railActions ?? []
2019
2254
  ];
2020
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
2021
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "absolute inset-0", children: preview }),
2022
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GridOverlay, { visible: gridOn && !blocked }),
2023
- aspect !== "full" && !blocked && !engine.recording && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2255
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "absolute inset-0 select-none overflow-hidden bg-black", children: [
2256
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "absolute inset-0", children: preview }),
2257
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(GridOverlay, { visible: gridOn && !blocked }),
2258
+ aspect !== "full" && !blocked && !engine.recording && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2024
2259
  "div",
2025
2260
  {
2026
2261
  "aria-hidden": true,
2027
2262
  className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center",
2028
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2263
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2029
2264
  "div",
2030
2265
  {
2031
2266
  className: "shadow-[0_0_0_9999px_rgba(0,0,0,0.45)]",
@@ -2040,32 +2275,32 @@ function CameraCaptureV3({
2040
2275
  )
2041
2276
  }
2042
2277
  ),
2043
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CountdownOverlay, { seconds: countdown }),
2044
- !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2278
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CountdownOverlay, { seconds: countdown }),
2279
+ !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2045
2280
  "div",
2046
2281
  {
2047
2282
  className: "pointer-events-none absolute inset-x-0 top-0 z-20 px-2",
2048
2283
  style: safeTop,
2049
2284
  children: [
2050
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-h-[44px] items-center gap-2 py-1.5", children: [
2051
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2285
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex min-h-[44px] items-center gap-2 py-1.5", children: [
2286
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2052
2287
  "button",
2053
2288
  {
2054
2289
  type: "button",
2055
2290
  onClick: onClose,
2056
2291
  "aria-label": "Close camera",
2057
2292
  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",
2058
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.X, { className: "h-6 w-6" })
2293
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(XIcon, { className: "h-6 w-6" })
2059
2294
  }
2060
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "h-10 w-10 shrink-0" }),
2061
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "pointer-events-auto flex min-w-0 flex-1 justify-center", children: slots.topEntry }),
2062
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "h-10 w-10 shrink-0" })
2295
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "h-10 w-10 shrink-0" }),
2296
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "pointer-events-auto flex min-w-0 flex-1 justify-center", children: slots.topEntry }),
2297
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "h-10 w-10 shrink-0" })
2063
2298
  ] }),
2064
- slots.topCenter ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "pointer-events-none pb-1 text-center", children: slots.topCenter }) : null
2299
+ slots.topCenter ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "pointer-events-none pb-1 text-center", children: slots.topCenter }) : null
2065
2300
  ]
2066
2301
  }
2067
2302
  ),
2068
- slots.statusChips ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2303
+ slots.statusChips ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2069
2304
  "div",
2070
2305
  {
2071
2306
  className: "pointer-events-none absolute inset-x-0 z-20 flex flex-col items-center gap-1.5 px-3",
@@ -2077,35 +2312,35 @@ function CameraCaptureV3({
2077
2312
  children: slots.statusChips
2078
2313
  }
2079
2314
  ) : null,
2080
- !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2315
+ !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2081
2316
  "div",
2082
2317
  {
2083
2318
  className: "pointer-events-none absolute right-1 z-20 flex justify-end",
2084
2319
  style: { top: `calc(env(safe-area-inset-top, 0px) + 64px)` },
2085
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CaptureRail, { actions: railActions })
2320
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CaptureRail, { actions: railActions })
2086
2321
  }
2087
2322
  ),
2088
- !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "absolute inset-x-0 bottom-0 z-20", style: safeBottom, children: [
2089
- media && media.items.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "px-2 pb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2323
+ !controlsHidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "absolute inset-x-0 bottom-0 z-20", style: safeBottom, children: [
2324
+ media && media.items.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "px-2 pb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2090
2325
  CaptureFilmstrip,
2091
2326
  {
2092
2327
  items: media.items,
2093
2328
  onOpen: (item) => setViewerKey(item.key)
2094
2329
  }
2095
2330
  ) }) : null,
2096
- slots.aboveShutter ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "px-2 pb-1.5", children: slots.aboveShutter }) : null,
2097
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between px-3 pb-2", children: [
2098
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex w-[86px] justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2331
+ slots.aboveShutter ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "px-2 pb-1.5", children: slots.aboveShutter }) : null,
2332
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center justify-between px-3 pb-2", children: [
2333
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex w-[86px] justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2099
2334
  "button",
2100
2335
  {
2101
2336
  type: "button",
2102
2337
  onClick: cloud.onOpenLibrary,
2103
2338
  "aria-label": "Your media \u2014 library and upload",
2104
2339
  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",
2105
- children: cloud.recentsThumb ?? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Images, { className: "h-5 w-5 text-white/80" }) })
2340
+ children: cloud.recentsThumb ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ImagesIcon, { className: "h-5 w-5 text-white/80" }) })
2106
2341
  }
2107
2342
  ) }),
2108
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2343
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2109
2344
  HoldShutter,
2110
2345
  {
2111
2346
  recording: engine.recording,
@@ -2118,11 +2353,11 @@ function CameraCaptureV3({
2118
2353
  onStopRecording: engine.onStopRecording
2119
2354
  }
2120
2355
  ),
2121
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex w-[86px] justify-end", children: slots.shutterTrailing })
2356
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex w-[86px] justify-end", children: slots.shutterTrailing })
2122
2357
  ] }),
2123
- !engine.recording && !blocked ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("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
2358
+ !engine.recording && !blocked ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("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
2124
2359
  ] }),
2125
- blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2360
+ blocked && blockedSheet && !blockedDismissed && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2126
2361
  CaptureSheet,
2127
2362
  {
2128
2363
  open: true,
@@ -2132,7 +2367,7 @@ function CameraCaptureV3({
2132
2367
  actions: blockedSheet.actions
2133
2368
  }
2134
2369
  ),
2135
- media && viewerKey !== null && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2370
+ media && viewerKey !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2136
2371
  MediaViewer,
2137
2372
  {
2138
2373
  items: media.items,
@@ -2149,7 +2384,7 @@ function CameraCaptureV3({
2149
2384
  } : void 0
2150
2385
  }
2151
2386
  ),
2152
- media?.onReplacePhoto && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2387
+ media?.onReplacePhoto && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2153
2388
  ImageEditSheet,
2154
2389
  {
2155
2390
  open: editTarget !== null,
@@ -2172,7 +2407,7 @@ function CameraCaptureV3({
2172
2407
 
2173
2408
  // src/components/CaptureExpandingField.tsx
2174
2409
  var import_react9 = require("react");
2175
- var import_jsx_runtime15 = require("react/jsx-runtime");
2410
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2176
2411
  function CaptureExpandingField({
2177
2412
  label,
2178
2413
  placeholder,
@@ -2210,7 +2445,7 @@ function CaptureExpandingField({
2210
2445
  setExpanded(false);
2211
2446
  }, [commit]);
2212
2447
  if (!expanded) {
2213
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2448
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2214
2449
  "button",
2215
2450
  {
2216
2451
  type: "button",
@@ -2226,13 +2461,13 @@ function CaptureExpandingField({
2226
2461
  className
2227
2462
  ),
2228
2463
  children: [
2229
- icon ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "shrink-0", children: icon }) : null,
2230
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate", children: currentValue?.trim() || label })
2464
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "shrink-0", children: icon }) : null,
2465
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate", children: currentValue?.trim() || label })
2231
2466
  ]
2232
2467
  }
2233
2468
  );
2234
2469
  }
2235
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2470
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2236
2471
  "div",
2237
2472
  {
2238
2473
  className: cn(
@@ -2241,8 +2476,8 @@ function CaptureExpandingField({
2241
2476
  className
2242
2477
  ),
2243
2478
  children: [
2244
- icon ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "shrink-0 text-white/70", children: icon }) : null,
2245
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2479
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "shrink-0 text-white/70", children: icon }) : null,
2480
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2246
2481
  "input",
2247
2482
  {
2248
2483
  ref: inputRef,
@@ -2271,7 +2506,7 @@ function CaptureExpandingField({
2271
2506
  )
2272
2507
  }
2273
2508
  ),
2274
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2509
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2275
2510
  "button",
2276
2511
  {
2277
2512
  type: "button",
@@ -2282,7 +2517,7 @@ function CaptureExpandingField({
2282
2517
  },
2283
2518
  "aria-label": `Close ${label}`,
2284
2519
  className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-white/70 hover:bg-white/10 hover:text-white",
2285
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2520
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2286
2521
  "svg",
2287
2522
  {
2288
2523
  viewBox: "0 0 24 24",
@@ -2292,7 +2527,7 @@ function CaptureExpandingField({
2292
2527
  strokeLinecap: "round",
2293
2528
  className: "h-3.5 w-3.5",
2294
2529
  "aria-hidden": "true",
2295
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M18 6 6 18M6 6l12 12" })
2530
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M18 6 6 18M6 6l12 12" })
2296
2531
  }
2297
2532
  )
2298
2533
  }
@@ -2304,7 +2539,7 @@ function CaptureExpandingField({
2304
2539
 
2305
2540
  // src/components/CameraFeed.tsx
2306
2541
  var import_react10 = require("react");
2307
- var import_jsx_runtime16 = require("react/jsx-runtime");
2542
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2308
2543
  function CameraFeed({
2309
2544
  engine,
2310
2545
  mirror = false
@@ -2318,7 +2553,7 @@ function CameraFeed({
2318
2553
  video.srcObject = null;
2319
2554
  };
2320
2555
  }, [stream, videoRef]);
2321
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2556
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2322
2557
  "video",
2323
2558
  {
2324
2559
  ref: videoRef,