@tastic/hud 0.8.1 → 0.8.3

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/index.js CHANGED
@@ -72,7 +72,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
72
72
  if (mountProgress.value < 1) {
73
73
  const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
74
74
  const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
75
- local = (0, import_core4.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
75
+ local = (0, import_core5.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
76
76
  }
77
77
  const sweep = dashAngleDeg * local;
78
78
  if (sweep <= 0) continue;
@@ -96,7 +96,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
96
96
  if (!isLitNow) continue;
97
97
  const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
98
98
  const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
99
- local = (0, import_core4.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
99
+ local = (0, import_core5.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
100
100
  } else if (isLitNow === wasLit) {
101
101
  local = 1;
102
102
  } else if (isLitNow) {
@@ -120,19 +120,19 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
120
120
  height: canvasSize,
121
121
  width: canvasSize
122
122
  };
123
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native8.View, { style: [styles7.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
123
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, { style: [styles7.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
124
124
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
125
125
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
126
126
  ] }) });
127
127
  }
128
- var import_react_native_skia, import_core4, import_react4, import_react_native8, import_react_native_reanimated, import_jsx_runtime8, UNLIT_THICKNESS, LIT_THICKNESS, DASH_GAP_PX, ARC_GAP, DEFAULT_START_DEG, MIN_DASH_ANGLE_DEG, MOUNT_DURATION_MS, MOUNT_STAGGER_MS, SELECTION_TRANSITION_DURATION_MS, styles7;
128
+ var import_react_native_skia, import_core5, import_react4, import_react_native9, import_react_native_reanimated, import_jsx_runtime8, UNLIT_THICKNESS, LIT_THICKNESS, DASH_GAP_PX, ARC_GAP, DEFAULT_START_DEG, MIN_DASH_ANGLE_DEG, MOUNT_DURATION_MS, MOUNT_STAGGER_MS, SELECTION_TRANSITION_DURATION_MS, styles7;
129
129
  var init_TriggerGauge = __esm({
130
130
  "src/TriggerGauge.tsx"() {
131
131
  "use strict";
132
132
  import_react_native_skia = require("@shopify/react-native-skia");
133
- import_core4 = require("@tastic/core");
133
+ import_core5 = require("@tastic/core");
134
134
  import_react4 = require("react");
135
- import_react_native8 = require("react-native");
135
+ import_react_native9 = require("react-native");
136
136
  import_react_native_reanimated = require("react-native-reanimated");
137
137
  import_jsx_runtime8 = require("react/jsx-runtime");
138
138
  UNLIT_THICKNESS = 3;
@@ -144,7 +144,7 @@ var init_TriggerGauge = __esm({
144
144
  MOUNT_DURATION_MS = 450;
145
145
  MOUNT_STAGGER_MS = 40;
146
146
  SELECTION_TRANSITION_DURATION_MS = 260;
147
- styles7 = import_react_native8.StyleSheet.create({
147
+ styles7 = import_react_native9.StyleSheet.create({
148
148
  container: {
149
149
  alignItems: "center",
150
150
  justifyContent: "center",
@@ -180,7 +180,9 @@ __export(index_exports, {
180
180
  StatSection: () => StatSection,
181
181
  TriggerGaugeHost: () => TriggerGaugeHost,
182
182
  getLabeledDropdownContentHeight: () => getLabeledDropdownContentHeight,
183
+ getOverlayCardColors: () => getOverlayCardColors,
183
184
  loadSkiaWeb: () => loadSkiaWeb,
185
+ overlayStyles: () => overlayStyles,
184
186
  useAutoAlign: () => useAutoAlign,
185
187
  usePopoverHost: () => usePopoverHost
186
188
  });
@@ -260,11 +262,44 @@ var import_feedback_press = require("@rific/feedback-press");
260
262
  var import_updater = require("@rific/updater");
261
263
  var import_core = require("@tastic/core");
262
264
  var import_react = require("react");
263
- var import_react_native2 = require("react-native");
265
+ var import_react_native3 = require("react-native");
264
266
  var import_react_native_paper2 = require("react-native-paper");
267
+
268
+ // src/overlayCard.ts
269
+ var import_react_native2 = require("react-native");
270
+ function getOverlayCardColors(dark) {
271
+ return {
272
+ fg: dark ? "#FFFFFF" : "#000000",
273
+ fgMuted: dark ? "rgba(255,255,255,0.4)" : "rgba(0,0,0,0.4)",
274
+ cardBg: dark ? "#111111" : "#F2F2F2",
275
+ cardBorder: dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)"
276
+ };
277
+ }
278
+ var overlayStyles = import_react_native2.StyleSheet.create({
279
+ card: {
280
+ alignItems: "center",
281
+ borderRadius: 20,
282
+ borderWidth: 1,
283
+ gap: 16,
284
+ maxWidth: 360,
285
+ padding: 32
286
+ },
287
+ overlay: {
288
+ alignItems: "center",
289
+ backgroundColor: "rgba(0,0,0,0.72)",
290
+ bottom: 0,
291
+ justifyContent: "center",
292
+ left: 0,
293
+ position: "absolute",
294
+ right: 0,
295
+ top: 0
296
+ }
297
+ });
298
+
299
+ // src/BaseSettingsDialog.tsx
265
300
  var import_jsx_runtime2 = require("react/jsx-runtime");
266
301
  function SettingIcon({ source, color, containerColor }) {
267
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [styles2.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Icon, { source, size: 18, color }) });
302
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: [styles2.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Icon, { source, size: 18, color }) });
268
303
  }
269
304
  function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, children }) {
270
305
  const { dark, colors } = (0, import_auto_paper2.useAutoPaperTheme)();
@@ -283,34 +318,32 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
283
318
  onInfo: (title, message) => setInfoMessage({ title, message })
284
319
  });
285
320
  const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
286
- const showEdgeGuard = import_react_native2.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
287
- const showHaptics = import_react_native2.Platform.OS !== "web" && !hideHaptics;
321
+ const showEdgeGuard = import_react_native3.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
322
+ const showHaptics = import_react_native3.Platform.OS !== "web" && !hideHaptics;
288
323
  const showSound = !hideSound;
289
324
  const showAppearance = !hideAppearance;
290
- const showUpdateCheck = import_react_native2.Platform.OS !== "web" && !hideUpdateCheck;
291
- const fg = dark ? "#FFFFFF" : "#000000";
292
- const cardBg = dark ? "#111111" : "#F2F2F2";
293
- const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
325
+ const showUpdateCheck = import_react_native3.Platform.OS !== "web" && !hideUpdateCheck;
326
+ const { fg, cardBg, cardBorder } = getOverlayCardColors(dark);
294
327
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
295
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_auto_paper2.Dialog, { visible, onDismiss, style: [styles2.dialog, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
328
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_auto_paper2.Dialog, { visible, onDismiss, style: [styles2.dialog, (0, import_core.toRotationStyle)(rotation)], children: [
296
329
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_auto_paper2.Dialog.Title, { children: "Settings" }),
297
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_auto_paper2.Dialog.ScrollArea, { style: styles2.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.ScrollView, { contentContainerStyle: styles2.content, showsVerticalScrollIndicator: false, children: [
298
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.toggleGroup, children: [
299
- showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles2.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.toggleContent, children: [
330
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_auto_paper2.Dialog.ScrollArea, { style: styles2.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.ScrollView, { contentContainerStyle: styles2.content, showsVerticalScrollIndicator: false, children: [
331
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.toggleGroup, children: [
332
+ showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles2.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.toggleContent, children: [
300
333
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.secondary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.secondaryContainer : colors.surfaceVariant }),
301
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.flexShrink, children: [
334
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.flexShrink, children: [
302
335
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
303
336
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
304
337
  ] })
305
338
  ] }) }),
306
- showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles2.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.toggleContent, children: [
339
+ showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles2.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.toggleContent, children: [
307
340
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.secondary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.secondaryContainer : colors.surfaceVariant }),
308
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.flexShrink, children: [
341
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.flexShrink, children: [
309
342
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
310
343
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
311
344
  ] })
312
345
  ] }) }),
313
- (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.toggleRow, children: [
346
+ (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.toggleRow, children: [
314
347
  showSound && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
315
348
  import_feedback_press.TouchableRipple,
316
349
  {
@@ -322,7 +355,7 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
322
355
  },
323
356
  style: styles2.toggleButtonInRow,
324
357
  accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
325
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.toggleContent, children: [
358
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.toggleContent, children: [
326
359
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
327
360
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
328
361
  ] })
@@ -339,7 +372,7 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
339
372
  },
340
373
  style: styles2.toggleButtonInRow,
341
374
  accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
342
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.toggleContent, children: [
375
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.toggleContent, children: [
343
376
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
344
377
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
345
378
  ] })
@@ -347,12 +380,12 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
347
380
  )
348
381
  ] })
349
382
  ] }),
350
- showAppearance && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.section, children: [
383
+ showAppearance && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.section, children: [
351
384
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "labelMedium", style: [styles2.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
352
385
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_auto_paper2.AutoAppearancePicker, { showLabels: false })
353
386
  ] }),
354
387
  children,
355
- showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.section, children: [
388
+ showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.section, children: [
356
389
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native_paper2.Text, { variant: "labelSmall", style: [styles2.sectionLabel, { color: colors.onSurfaceVariant }], children: [
357
390
  "VERSION ",
358
391
  version,
@@ -362,7 +395,7 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
362
395
  ] })
363
396
  ] }) })
364
397
  ] }),
365
- infoMessage && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: styles2.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [styles2.overlayCard, { backgroundColor: cardBg, borderColor: cardBorder }, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
398
+ infoMessage && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: overlayStyles.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: [overlayStyles.card, { backgroundColor: cardBg, borderColor: cardBorder }, (0, import_core.toRotationStyle)(rotation)], children: [
366
399
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Icon, { source: "information-outline", size: 64, color: colors.secondary }),
367
400
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "headlineLarge", style: [styles2.overlayTitle, { color: colors.secondary }], children: infoMessage.title }),
368
401
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: [styles2.overlayBody, { color: fg }], children: infoMessage.message }),
@@ -370,7 +403,7 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
370
403
  ] }) }) })
371
404
  ] });
372
405
  }
373
- var styles2 = import_react_native2.StyleSheet.create({
406
+ var styles2 = import_react_native3.StyleSheet.create({
374
407
  content: {
375
408
  gap: 24,
376
409
  paddingVertical: 20
@@ -392,26 +425,8 @@ var styles2 = import_react_native2.StyleSheet.create({
392
425
  justifyContent: "center",
393
426
  width: 36
394
427
  },
395
- overlay: {
396
- alignItems: "center",
397
- backgroundColor: "rgba(0,0,0,0.72)",
398
- bottom: 0,
399
- justifyContent: "center",
400
- left: 0,
401
- position: "absolute",
402
- right: 0,
403
- top: 0
404
- },
405
428
  overlayBody: { textAlign: "center" },
406
429
  overlayButton: { width: 160 },
407
- overlayCard: {
408
- alignItems: "center",
409
- borderRadius: 20,
410
- borderWidth: 1,
411
- gap: 16,
412
- maxWidth: 360,
413
- padding: 32
414
- },
415
430
  overlayTitle: { fontWeight: "bold" },
416
431
  scrollArea: {
417
432
  marginBottom: 0
@@ -459,56 +474,125 @@ var styles2 = import_react_native2.StyleSheet.create({
459
474
  });
460
475
 
461
476
  // src/BaseStatsScreen.tsx
477
+ var import_auto_paper4 = require("@rific/auto-paper");
478
+ var import_feedback_press3 = require("@rific/feedback-press");
479
+ var import_core3 = require("@tastic/core");
480
+ var import_react2 = require("react");
481
+ var import_react_native5 = require("react-native");
482
+ var import_react_native_paper4 = require("react-native-paper");
483
+
484
+ // src/ConfirmDialog.tsx
462
485
  var import_auto_paper3 = require("@rific/auto-paper");
463
486
  var import_feedback_press2 = require("@rific/feedback-press");
464
487
  var import_core2 = require("@tastic/core");
465
- var import_react2 = require("react");
466
- var import_react_native3 = require("react-native");
488
+ var import_react_native4 = require("react-native");
467
489
  var import_react_native_paper3 = require("react-native-paper");
468
490
  var import_jsx_runtime3 = require("react/jsx-runtime");
469
- function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", titleVariant = "headlineSmall", onBack, insets, onReset, resetLabel = "Reset All Stats", resetConfirmTitle = "Reset Everything?", resetConfirmBody = "This permanently erases all stats and achievements. This cannot be undone.", fg: fgOverride, bg: bgOverride, cardBg: cardBgOverride, accentColor: accentColorOverride, children }) {
491
+ function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
470
492
  const { dark, colors } = (0, import_auto_paper3.useAutoPaperTheme)();
471
- const ambientRotation = (0, import_core2.useRotation)();
493
+ if (!visible) return null;
494
+ const { fg, cardBg, cardBorder } = getOverlayCardColors(dark);
495
+ const accent = destructive ? colors.danger : colors.primary;
496
+ const onAccent = destructive ? colors.onDanger : colors.onPrimary;
497
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native4.View, { style: [overlayStyles.overlay, styles3.overlay], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: [overlayStyles.card, styles3.card, { backgroundColor: cardBg, borderColor: cardBorder }, (0, import_core2.toRotationStyle)(rotation)], children: [
498
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source: icon, size: 64, color: accent }),
499
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "headlineLarge", style: [styles3.title, { color: accent }], children: title }),
500
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: [styles3.body, { color: fg }], children: message }),
501
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.actions, children: [
502
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: onCancel, style: styles3.actionButton, children: cancelLabel }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: onConfirm, style: styles3.actionButton, buttonColor: accent, textColor: onAccent, children: confirmLabel })
504
+ ] })
505
+ ] }) }) });
506
+ }
507
+ var styles3 = import_react_native4.StyleSheet.create({
508
+ // flexBasis (not flex: 1's own 0%) is each button's real floor: whenever both fit side by side,
509
+ // flexGrow still splits any leftover width evenly beyond that floor, same visual result as the
510
+ // old flex: 1 on a roomy screen - but a button can never be squeezed narrower than 128, only
511
+ // wrap to its own row instead (see actions' flexWrap below). react-native-paper's Button
512
+ // hardcodes numberOfLines={1} on its label with no override, so a button squeezed under its
513
+ // label's natural width silently ellipsizes ("Cancel" -> "Can...") instead of wrapping - assumed
514
+ // fixable by just giving the row more width, until confirmed live that these two-word labels
515
+ // (Cancel/Reset/New Game) can still lose the truncation fight even with the extra room card's own
516
+ // width fix below provides, on a narrow enough screen. flexBasis is the real fix: past a certain
517
+ // width there's no side-by-side arrangement that fits both buttons at their natural label size,
518
+ // so the layout has to give (stack) rather than the label (truncate).
519
+ actionButton: {
520
+ flexBasis: 128,
521
+ flexGrow: 1
522
+ },
523
+ actions: {
524
+ flexDirection: "row",
525
+ flexWrap: "wrap",
526
+ gap: 12,
527
+ width: "100%"
528
+ },
529
+ body: {
530
+ textAlign: "center"
531
+ },
532
+ // Additive on top of overlayCard's own shared `card` shape (borderRadius/borderWidth/gap/maxWidth/
533
+ // padding) — claims its full allowance instead of just maxWidth alone, which only caps how wide the
534
+ // card is allowed to get - without an explicit width, a flex-centered child sizes to its own content
535
+ // instead of stretching, so the card (and therefore actions below) can end up narrower than the
536
+ // screen actually has room for, needlessly forcing the action row to wrap sooner than it has to.
537
+ card: {
538
+ width: "100%"
539
+ },
540
+ // Additive on top of overlayCard's own shared `overlay` backdrop — gives the card room to breathe
541
+ // from the screen edges now that it reliably stretches to fill its full width allowance (see
542
+ // card's own width comment) - without this, width: '100%' would run the card edge-to-edge on a
543
+ // screen narrower than maxWidth's own 360.
544
+ overlay: {
545
+ paddingHorizontal: 24
546
+ },
547
+ // textAlign is load-bearing, not decorative, once `title` wraps to more than one line - centered
548
+ // within card's own alignItems: 'center' only centers the Text's block as a whole; each wrapped
549
+ // line inside that block still defaults to left-aligned without this.
550
+ title: {
551
+ fontWeight: "bold",
552
+ textAlign: "center"
553
+ }
554
+ });
555
+
556
+ // src/BaseStatsScreen.tsx
557
+ var import_jsx_runtime4 = require("react/jsx-runtime");
558
+ function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", titleVariant = "headlineSmall", onBack, insets, onReset, resetLabel = "Reset All Stats", resetConfirmTitle = "Reset Everything?", resetConfirmBody = "This permanently erases all stats and achievements. This cannot be undone.", fg: fgOverride, bg: bgOverride, children }) {
559
+ const { dark, colors } = (0, import_auto_paper4.useAutoPaperTheme)();
560
+ const ambientRotation = (0, import_core3.useRotation)();
472
561
  const rotation = rotationOverride ?? ambientRotation;
473
562
  const [confirmResetVisible, setConfirmResetVisible] = (0, import_react2.useState)(false);
474
563
  const showReset = !!onReset;
475
564
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
476
565
  const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
477
- const cardBg = cardBgOverride ?? (dark ? "#111111" : "#F2F2F2");
478
- const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
479
- const accentColor = accentColorOverride ?? colors.secondary;
480
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles3.container, { backgroundColor: bg }], children: [
481
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles3.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
482
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
483
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: titleVariant, style: [styles3.title, { color: fg }], children: title })
566
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: [styles4.container, { backgroundColor: bg }], children: [
567
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: [styles4.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
568
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
569
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Text, { variant: titleVariant, style: [styles4.title, { color: fg }], children: title })
484
570
  ] }),
485
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.ScrollView, { style: styles3.scrollView, contentContainerStyle: [styles3.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
571
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.ScrollView, { style: styles4.scrollView, contentContainerStyle: [styles4.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
486
572
  children,
487
- showReset && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.secondary, textColor: colors.onSecondary, style: styles3.resetButton, children: resetLabel })
573
+ showReset && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles4.resetButton, children: resetLabel })
488
574
  ] }),
489
- confirmResetVisible && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles3.overlay, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles3.overlayCard, { backgroundColor: cardBg, borderColor: cardBorder }], children: [
490
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source: "alert-outline", size: 64, color: accentColor }),
491
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "headlineLarge", style: [styles3.overlayTitle, { color: accentColor }], children: resetConfirmTitle }),
492
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: [styles3.overlayBody, { color: fg }], children: resetConfirmBody }),
493
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: () => setConfirmResetVisible(false), style: styles3.overlayButton, children: "Cancel" }),
494
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
495
- import_feedback_press2.Button,
496
- {
497
- mode: "contained",
498
- onPress: () => {
499
- onReset?.();
500
- setConfirmResetVisible(false);
501
- },
502
- style: styles3.overlayButton,
503
- buttonColor: colors.secondary,
504
- textColor: colors.onSecondary,
505
- children: "Reset"
575
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
576
+ ConfirmDialog,
577
+ {
578
+ visible: confirmResetVisible,
579
+ title: resetConfirmTitle,
580
+ message: resetConfirmBody,
581
+ confirmLabel: "Reset",
582
+ cancelLabel: "Cancel",
583
+ icon: "alert-outline",
584
+ destructive: true,
585
+ rotation,
586
+ onCancel: () => setConfirmResetVisible(false),
587
+ onConfirm: () => {
588
+ onReset?.();
589
+ setConfirmResetVisible(false);
506
590
  }
507
- )
508
- ] }) }) })
591
+ }
592
+ )
509
593
  ] });
510
594
  }
511
- var styles3 = import_react_native3.StyleSheet.create({
595
+ var styles4 = import_react_native5.StyleSheet.create({
512
596
  container: {
513
597
  flex: 1
514
598
  },
@@ -522,30 +606,6 @@ var styles3 = import_react_native3.StyleSheet.create({
522
606
  gap: 4,
523
607
  paddingBottom: 8
524
608
  },
525
- // Same overlay shape BaseSettingsDialog's own info overlay uses (backdrop + centered card),
526
- // rotated in place the same way rather than via Portal-root transform for the same reason — see
527
- // that component's own identical styles for the full rationale.
528
- overlay: {
529
- alignItems: "center",
530
- backgroundColor: "rgba(0,0,0,0.72)",
531
- bottom: 0,
532
- justifyContent: "center",
533
- left: 0,
534
- position: "absolute",
535
- right: 0,
536
- top: 0
537
- },
538
- overlayBody: { textAlign: "center" },
539
- overlayButton: { width: 160 },
540
- overlayCard: {
541
- alignItems: "center",
542
- borderRadius: 20,
543
- borderWidth: 1,
544
- gap: 16,
545
- maxWidth: 360,
546
- padding: 32
547
- },
548
- overlayTitle: { fontWeight: "bold", marginBottom: -8 },
549
609
  resetButton: {
550
610
  marginTop: 16
551
611
  },
@@ -562,79 +622,20 @@ var styles3 = import_react_native3.StyleSheet.create({
562
622
  }
563
623
  });
564
624
 
565
- // src/ConfirmDialog.tsx
566
- var import_auto_paper4 = require("@rific/auto-paper");
567
- var import_feedback_press3 = require("@rific/feedback-press");
568
- var import_react_native4 = require("react-native");
569
- var import_react_native_paper4 = require("react-native-paper");
570
- var import_jsx_runtime4 = require("react/jsx-runtime");
571
- function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
572
- const { dark, colors } = (0, import_auto_paper4.useAutoPaperTheme)();
573
- if (!visible) return null;
574
- const fg = dark ? "#FFFFFF" : "#000000";
575
- const cardBg = dark ? "#111111" : "#F2F2F2";
576
- const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
577
- const accent = destructive ? colors.danger : colors.primary;
578
- const onAccent = destructive ? colors.onDanger : colors.onPrimary;
579
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: styles4.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: [styles4.card, { backgroundColor: cardBg, borderColor: cardBorder }, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
580
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Icon, { source: icon, size: 64, color: accent }),
581
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Text, { variant: "headlineLarge", style: [styles4.title, { color: accent }], children: title }),
582
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Text, { variant: "bodyLarge", style: [styles4.body, { color: fg }], children: message }),
583
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: styles4.actions, children: [
584
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.Button, { mode: "outlined", onPress: onCancel, style: styles4.actionButton, children: cancelLabel }),
585
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: onConfirm, style: styles4.actionButton, buttonColor: accent, textColor: onAccent, children: confirmLabel })
586
- ] })
587
- ] }) }) });
588
- }
589
- var styles4 = import_react_native4.StyleSheet.create({
590
- actionButton: {
591
- flex: 1
592
- },
593
- actions: {
594
- flexDirection: "row",
595
- gap: 12,
596
- width: "100%"
597
- },
598
- body: {
599
- textAlign: "center"
600
- },
601
- card: {
602
- alignItems: "center",
603
- borderRadius: 20,
604
- borderWidth: 1,
605
- gap: 16,
606
- maxWidth: 360,
607
- padding: 32
608
- },
609
- overlay: {
610
- alignItems: "center",
611
- backgroundColor: "rgba(0,0,0,0.72)",
612
- bottom: 0,
613
- justifyContent: "center",
614
- left: 0,
615
- position: "absolute",
616
- right: 0,
617
- top: 0
618
- },
619
- title: {
620
- fontWeight: "bold"
621
- }
622
- });
623
-
624
625
  // src/ContentGutter.tsx
625
- var import_core3 = require("@tastic/core");
626
- var import_react_native5 = require("react-native");
626
+ var import_core4 = require("@tastic/core");
627
+ var import_react_native6 = require("react-native");
627
628
  var import_jsx_runtime5 = require("react/jsx-runtime");
628
629
  function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
629
- const { width: windowWidth } = (0, import_react_native5.useWindowDimensions)();
630
- const { contentWidth, gutterWidth } = (0, import_core3.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
631
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [styles5.row, style], children: [
632
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: [styles5.gutter, { width: gutterWidth }], children: leftGutter }),
633
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: { width: contentWidth }, children }),
634
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: [styles5.gutter, { width: gutterWidth }], children: rightGutter })
630
+ const { width: windowWidth } = (0, import_react_native6.useWindowDimensions)();
631
+ const { contentWidth, gutterWidth } = (0, import_core4.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
632
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native6.View, { style: [styles5.row, style], children: [
633
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: [styles5.gutter, { width: gutterWidth }], children: leftGutter }),
634
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: { width: contentWidth }, children }),
635
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: [styles5.gutter, { width: gutterWidth }], children: rightGutter })
635
636
  ] });
636
637
  }
637
- var styles5 = import_react_native5.StyleSheet.create({
638
+ var styles5 = import_react_native6.StyleSheet.create({
638
639
  // overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
639
640
  // column instead of clipping cleanly at its own real width.
640
641
  gutter: {
@@ -646,22 +647,22 @@ var styles5 = import_react_native5.StyleSheet.create({
646
647
  });
647
648
 
648
649
  // src/ControlSchemePicker.tsx
649
- var import_core6 = require("@tastic/core");
650
- var import_react_native11 = require("react-native");
650
+ var import_core7 = require("@tastic/core");
651
+ var import_react_native12 = require("react-native");
651
652
 
652
653
  // src/SectionedDropdown.tsx
653
654
  var import_auto_paper5 = require("@rific/auto-paper");
654
655
  var import_feedback_press4 = require("@rific/feedback-press");
655
- var import_core5 = require("@tastic/core");
656
- var import_react_native10 = require("react-native");
656
+ var import_core6 = require("@tastic/core");
657
+ var import_react_native11 = require("react-native");
657
658
  var import_react_native_paper5 = require("react-native-paper");
658
659
 
659
660
  // src/fonts.ts
660
- var import_react_native6 = require("react-native");
661
- var MONO_FONT = import_react_native6.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
661
+ var import_react_native7 = require("react-native");
662
+ var MONO_FONT = import_react_native7.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
662
663
 
663
664
  // src/PopoverBody.tsx
664
- var import_react_native7 = require("react-native");
665
+ var import_react_native8 = require("react-native");
665
666
  var import_jsx_runtime6 = require("react/jsx-runtime");
666
667
  var CARET_SIZE = 7;
667
668
  var CARET_RING_OFFSET = 2;
@@ -676,15 +677,15 @@ function PopoverBody({ visible, children, align = "center", verticalAlign = "bel
676
677
  const caretFill = above ? "borderTopColor" : "borderBottomColor";
677
678
  const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
678
679
  const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
679
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native7.View, { style: [styles6.content, alignStyle, verticalStyle], children: [
680
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native8.View, { style: [styles6.content, alignStyle, verticalStyle], children: [
680
681
  children,
681
682
  caretColor && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
682
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native7.View, { style: [styles6.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
683
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native7.View, { style: [styles6.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
683
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.View, { style: [styles6.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
684
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.View, { style: [styles6.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
684
685
  ] })
685
686
  ] });
686
687
  }
687
- var styles6 = import_react_native7.StyleSheet.create({
688
+ var styles6 = import_react_native8.StyleSheet.create({
688
689
  caret: {
689
690
  borderLeftColor: "transparent",
690
691
  borderRightColor: "transparent",
@@ -753,7 +754,7 @@ function TriggerGaugeHost(props) {
753
754
 
754
755
  // src/useAutoAlign.ts
755
756
  var import_react5 = require("react");
756
- var import_react_native9 = require("react-native");
757
+ var import_react_native10 = require("react-native");
757
758
  var EDGE_MARGIN = 12;
758
759
  function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
759
760
  if (rotation === 0) return { x, y, width, height };
@@ -766,7 +767,7 @@ function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
766
767
  }
767
768
  function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
768
769
  const triggerRef = (0, import_react5.useRef)(null);
769
- const { width: windowWidth, height: windowHeight } = (0, import_react_native9.useWindowDimensions)();
770
+ const { width: windowWidth, height: windowHeight } = (0, import_react_native10.useWindowDimensions)();
770
771
  const [align, setAlign] = (0, import_react5.useState)("center");
771
772
  const [verticalAlign, setVerticalAlign] = (0, import_react5.useState)("below");
772
773
  const [maxHeight, setMaxHeight] = (0, import_react5.useState)(contentHeight);
@@ -812,7 +813,7 @@ var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
812
813
  var MENU_DIVIDER_HEIGHT = 9;
813
814
  var MENU_VERTICAL_PADDING = 12;
814
815
  function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: alignOverride, rotation: rotationOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
815
- const ambientRotation = (0, import_core5.useRotation)();
816
+ const ambientRotation = (0, import_core6.useRotation)();
816
817
  const rotation = rotationOverride ?? ambientRotation;
817
818
  const menuBg = dark ? "#000000" : "#FFFFFF";
818
819
  const menuBorderColor = (0, import_auto_paper5.getBlendedColor)(mutedColor, menuBg, 0.5);
@@ -851,13 +852,13 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
851
852
  const anchorStyle = [styles8.anchor, open && styles8.anchorOpen];
852
853
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
853
854
  const dividerStyle = { backgroundColor: menuBorderColor };
854
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native10.View, { style: anchorStyle, children: [
855
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native10.View, { ref: triggerRef, collapsable: false, style: styles8.triggerBox, children: [
855
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: anchorStyle, children: [
856
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { ref: triggerRef, collapsable: false, style: styles8.triggerBox, children: [
856
857
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
857
858
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
858
859
  ] }),
859
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native10.ScrollView, { style: [styles8.menu, menuStyle], contentContainerStyle: styles8.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native10.View, { children: [
860
- sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native10.View, { style: [styles8.divider, dividerStyle] }),
860
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native11.ScrollView, { style: [styles8.menu, menuStyle], contentContainerStyle: styles8.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { children: [
861
+ sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native11.View, { style: [styles8.divider, dividerStyle] }),
861
862
  section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
862
863
  SingleSection,
863
864
  {
@@ -890,9 +891,9 @@ function SingleSection({
890
891
  const itemStyle = [styles8.item, selected && { backgroundColor: accentColor }, taken && styles8.itemTaken];
891
892
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
892
893
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
893
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native10.View, { style: styles8.itemRow, children: [
894
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles8.itemRow, children: [
894
895
  option.icon && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
895
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native10.View, { style: styles8.itemLabelColumn, children: [
896
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles8.itemLabelColumn, children: [
896
897
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
897
898
  option.description && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
898
899
  ] })
@@ -916,7 +917,7 @@ function MultiSection({
916
917
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
917
918
  const itemStyle = [styles8.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
918
919
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
919
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native10.View, { style: styles8.itemRow, children: [
920
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles8.itemRow, children: [
920
921
  option.icon && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
921
922
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: [styles8.itemLabelFlex, labelStyle], children: option.label })
922
923
  ] }) }, option.value);
@@ -924,7 +925,7 @@ function MultiSection({
924
925
  section.allClear && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles8.item, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: [styles8.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
925
926
  ] });
926
927
  }
927
- var styles8 = import_react_native10.StyleSheet.create({
928
+ var styles8 = import_react_native11.StyleSheet.create({
928
929
  allClearLabel: {
929
930
  fontWeight: "bold",
930
931
  textAlign: "center"
@@ -941,7 +942,7 @@ var styles8 = import_react_native10.StyleSheet.create({
941
942
  zIndex: 100
942
943
  },
943
944
  divider: {
944
- height: import_react_native10.StyleSheet.hairlineWidth,
945
+ height: import_react_native11.StyleSheet.hairlineWidth,
945
946
  marginVertical: 4
946
947
  },
947
948
  item: {
@@ -996,14 +997,14 @@ var styles8 = import_react_native10.StyleSheet.create({
996
997
  // src/ControlSchemePicker.tsx
997
998
  var import_jsx_runtime11 = require("react/jsx-runtime");
998
999
  function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily }) {
999
- const isTouchPrimary = (0, import_core6.useIsTouchPrimaryDevice)();
1000
- if (import_react_native11.Platform.OS !== "web" || isTouchPrimary) return null;
1000
+ const isTouchPrimary = (0, import_core7.useIsTouchPrimaryDevice)();
1001
+ if (import_react_native12.Platform.OS !== "web" || isTouchPrimary) return null;
1001
1002
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily });
1002
1003
  }
1003
1004
 
1004
1005
  // src/CornerActionButtons.tsx
1005
1006
  var import_feedback_press5 = require("@rific/feedback-press");
1006
- var import_react_native12 = require("react-native");
1007
+ var import_react_native13 = require("react-native");
1007
1008
  var import_jsx_runtime12 = require("react/jsx-runtime");
1008
1009
  function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back" }) {
1009
1010
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
@@ -1011,7 +1012,7 @@ function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow
1011
1012
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press5.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles9.topRight, { top: 8 + insets.top, right: 8 + insets.right }], onPress: onSettings, accessibilityLabel: "Settings" })
1012
1013
  ] });
1013
1014
  }
1014
- var styles9 = import_react_native12.StyleSheet.create({
1015
+ var styles9 = import_react_native13.StyleSheet.create({
1015
1016
  back: {
1016
1017
  position: "absolute"
1017
1018
  },
@@ -1021,22 +1022,22 @@ var styles9 = import_react_native12.StyleSheet.create({
1021
1022
  });
1022
1023
 
1023
1024
  // src/CornerStatusBadges.tsx
1024
- var import_react_native13 = require("react-native");
1025
+ var import_react_native14 = require("react-native");
1025
1026
  var import_react_native_paper6 = require("react-native-paper");
1026
1027
  var import_jsx_runtime13 = require("react/jsx-runtime");
1027
1028
  var BADGE_SIZE = 30;
1028
1029
  function StatusBadge({ icon }) {
1029
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native13.View, { style: styles10.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper6.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
1030
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { style: styles10.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper6.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
1030
1031
  }
1031
1032
  function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
1032
1033
  const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
1033
1034
  const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
1034
1035
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1035
- p1 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native13.View, { pointerEvents: "none", style: p1OnRightSide ? styles10.bottomRight : styles10.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatusBadge, { icon: p1.icon }) }),
1036
- p2 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native13.View, { pointerEvents: "none", style: p2OnLeftSide ? styles10.topLeft : styles10.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatusBadge, { icon: p2.icon }) })
1036
+ p1 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { pointerEvents: "none", style: p1OnRightSide ? styles10.bottomRight : styles10.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatusBadge, { icon: p1.icon }) }),
1037
+ p2 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { pointerEvents: "none", style: p2OnLeftSide ? styles10.topLeft : styles10.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatusBadge, { icon: p2.icon }) })
1037
1038
  ] });
1038
1039
  }
1039
- var styles10 = import_react_native13.StyleSheet.create({
1040
+ var styles10 = import_react_native14.StyleSheet.create({
1040
1041
  badge: {
1041
1042
  alignItems: "center",
1042
1043
  backgroundColor: "rgba(0,0,0,0.28)",
@@ -1057,8 +1058,8 @@ var styles10 = import_react_native13.StyleSheet.create({
1057
1058
  // src/InlineColorPicker.tsx
1058
1059
  var import_auto_paper6 = require("@rific/auto-paper");
1059
1060
  var import_feedback_press6 = require("@rific/feedback-press");
1060
- var import_core7 = require("@tastic/core");
1061
- var import_react_native14 = require("react-native");
1061
+ var import_core8 = require("@tastic/core");
1062
+ var import_react_native15 = require("react-native");
1062
1063
  var import_react_native_paper7 = require("react-native-paper");
1063
1064
  var import_jsx_runtime14 = require("react/jsx-runtime");
1064
1065
  var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
@@ -1074,11 +1075,11 @@ function widthForColumns(columns) {
1074
1075
  return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
1075
1076
  }
1076
1077
  function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper6.defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
1077
- const ambientRotation = (0, import_core7.useRotation)();
1078
+ const ambientRotation = (0, import_core8.useRotation)();
1078
1079
  const rotation = rotationOverride ?? ambientRotation;
1079
1080
  const menuBg = dark ? "#000000" : "#FFFFFF";
1080
- const { width: windowWidth } = (0, import_react_native14.useWindowDimensions)();
1081
- const autoColumns = (0, import_core7.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
1081
+ const { width: windowWidth } = (0, import_react_native15.useWindowDimensions)();
1082
+ const autoColumns = (0, import_core8.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
1082
1083
  const resolvedColumns = columns ?? autoColumns;
1083
1084
  const swatchesWidth = widthForColumns(resolvedColumns);
1084
1085
  const swatchRows = Math.ceil(swatches.length / resolvedColumns);
@@ -1090,9 +1091,9 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1090
1091
  const displayValue = displayFor(value);
1091
1092
  const contrastColor = (0, import_auto_paper6.getContrastColor)(displayValue);
1092
1093
  const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
1093
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native14.View, { style: [styles11.anchor, open && styles11.anchorOpen], children: [
1094
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles11.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native14.View, { ref: triggerRef, collapsable: false, style: styles11.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Text, { style: [styles11.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
1095
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native14.ScrollView, { style: [styles11.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles11.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
1094
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: [styles11.anchor, open && styles11.anchorOpen], children: [
1095
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles11.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, { ref: triggerRef, collapsable: false, style: styles11.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Text, { style: [styles11.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
1096
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.ScrollView, { style: [styles11.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles11.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
1096
1097
  const selected = swatch.value.toLowerCase() === value.toLowerCase();
1097
1098
  const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
1098
1099
  const swappable = taken && allowSwapTaken;
@@ -1107,14 +1108,14 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1107
1108
  },
1108
1109
  borderless: true,
1109
1110
  style: [styles11.swatch, { backgroundColor: swatchDisplay }, selected && styles11.swatchSelected, taken && !swappable && styles11.swatchTaken],
1110
- children: selected ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "check", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "close", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native14.View, {})
1111
+ children: selected ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "check", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "close", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, {})
1111
1112
  },
1112
1113
  swatch.value
1113
1114
  );
1114
1115
  }) }) })
1115
1116
  ] });
1116
1117
  }
1117
- var styles11 = import_react_native14.StyleSheet.create({
1118
+ var styles11 = import_react_native15.StyleSheet.create({
1118
1119
  anchor: {
1119
1120
  position: "relative"
1120
1121
  },
@@ -1188,7 +1189,7 @@ var styles11 = import_react_native14.StyleSheet.create({
1188
1189
  // src/LabeledDropdown.tsx
1189
1190
  var import_auto_paper7 = require("@rific/auto-paper");
1190
1191
  var import_feedback_press7 = require("@rific/feedback-press");
1191
- var import_react_native15 = require("react-native");
1192
+ var import_react_native16 = require("react-native");
1192
1193
  var import_react_native_paper8 = require("react-native-paper");
1193
1194
  var import_jsx_runtime15 = require("react/jsx-runtime");
1194
1195
  var TRIGGER_HEIGHT = 28;
@@ -1213,22 +1214,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
1213
1214
  onChange(option.value);
1214
1215
  host.close();
1215
1216
  };
1216
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native15.View, { style: [styles12.anchor, open && styles12.anchorOpen], children: [
1217
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles12.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native15.View, { ref: triggerRef, collapsable: false, style: styles12.triggerInner, children: [
1217
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: [styles12.anchor, open && styles12.anchorOpen], children: [
1218
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles12.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { ref: triggerRef, collapsable: false, style: styles12.triggerInner, children: [
1218
1219
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Text, { style: [styles12.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
1219
1220
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Icon, { source: "menu-down", size: 16, color })
1220
1221
  ] }) }),
1221
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native15.ScrollView, { style: [styles12.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles12.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
1222
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.ScrollView, { style: [styles12.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles12.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
1222
1223
  const isSelected = option.value === value;
1223
1224
  const onColor = (0, import_auto_paper7.getContrastColor)(color);
1224
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles12.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native15.View, { style: styles12.rowInner, children: [
1225
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles12.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: styles12.rowInner, children: [
1225
1226
  option.icon && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
1226
1227
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Text, { style: [styles12.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
1227
1228
  ] }) }, option.value);
1228
1229
  }) }) })
1229
1230
  ] });
1230
1231
  }
1231
- var styles12 = import_react_native15.StyleSheet.create({
1232
+ var styles12 = import_react_native16.StyleSheet.create({
1232
1233
  anchor: {
1233
1234
  position: "relative"
1234
1235
  },
@@ -1286,16 +1287,16 @@ function loadSkiaWeb() {
1286
1287
  }
1287
1288
 
1288
1289
  // src/PressAwayOverlay.tsx
1289
- var import_react_native16 = require("react-native");
1290
+ var import_react_native17 = require("react-native");
1290
1291
  var import_jsx_runtime16 = require("react/jsx-runtime");
1291
1292
  function PressAwayOverlay({ active, onPress, style }) {
1292
1293
  if (!active) return null;
1293
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native16.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native16.StyleSheet.absoluteFill, style] });
1294
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native17.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native17.StyleSheet.absoluteFill, style] });
1294
1295
  }
1295
1296
 
1296
1297
  // src/ReadyButton.tsx
1297
1298
  var import_feedback_press8 = require("@rific/feedback-press");
1298
- var import_react_native17 = require("react-native");
1299
+ var import_react_native18 = require("react-native");
1299
1300
  var import_react_native_paper9 = require("react-native-paper");
1300
1301
  var import_jsx_runtime17 = require("react/jsx-runtime");
1301
1302
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
@@ -1304,7 +1305,7 @@ function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MON
1304
1305
  const labelColorStyle = { color: ready ? "#000000" : color };
1305
1306
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press8.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper9.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
1306
1307
  }
1307
- var styles13 = import_react_native17.StyleSheet.create({
1308
+ var styles13 = import_react_native18.StyleSheet.create({
1308
1309
  readyButton: {
1309
1310
  alignItems: "center",
1310
1311
  borderRadius: 12,
@@ -1318,11 +1319,11 @@ var styles13 = import_react_native17.StyleSheet.create({
1318
1319
 
1319
1320
  // src/SharedActionBand.tsx
1320
1321
  var import_feedback_press9 = require("@rific/feedback-press");
1321
- var import_react_native18 = require("react-native");
1322
+ var import_react_native19 = require("react-native");
1322
1323
  var import_jsx_runtime18 = require("react/jsx-runtime");
1323
1324
  function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
1324
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native18.View, { style: [styles14.column, popoverOpen && styles14.columnOpen], children: [
1325
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native18.View, { style: styles14.actionsRow, children: [
1325
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: [styles14.column, popoverOpen && styles14.columnOpen], children: [
1326
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles14.actionsRow, children: [
1326
1327
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press9.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1327
1328
  onRandomize && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press9.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1328
1329
  onReset && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press9.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
@@ -1331,7 +1332,7 @@ function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popove
1331
1332
  children
1332
1333
  ] });
1333
1334
  }
1334
- var styles14 = import_react_native18.StyleSheet.create({
1335
+ var styles14 = import_react_native19.StyleSheet.create({
1335
1336
  actionsRow: {
1336
1337
  alignItems: "center",
1337
1338
  flexDirection: "row",
@@ -1348,19 +1349,19 @@ var styles14 = import_react_native18.StyleSheet.create({
1348
1349
 
1349
1350
  // src/StatRow.tsx
1350
1351
  var import_auto_paper8 = require("@rific/auto-paper");
1351
- var import_react_native19 = require("react-native");
1352
+ var import_react_native20 = require("react-native");
1352
1353
  var import_react_native_paper10 = require("react-native-paper");
1353
1354
  var import_jsx_runtime19 = require("react/jsx-runtime");
1354
1355
  function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
1355
1356
  const { dark } = (0, import_auto_paper8.useAutoPaperTheme)();
1356
1357
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
1357
1358
  const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
1358
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native19.View, { style: styles15.row, children: [
1359
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native20.View, { style: styles15.row, children: [
1359
1360
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native_paper10.Text, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
1360
1361
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native_paper10.Text, { variant: "bodyMedium", style: [styles15.value, { color: fg }], children: value })
1361
1362
  ] });
1362
1363
  }
1363
- var styles15 = import_react_native19.StyleSheet.create({
1364
+ var styles15 = import_react_native20.StyleSheet.create({
1364
1365
  row: {
1365
1366
  alignItems: "center",
1366
1367
  flexDirection: "row",
@@ -1373,19 +1374,19 @@ var styles15 = import_react_native19.StyleSheet.create({
1373
1374
 
1374
1375
  // src/StatSection.tsx
1375
1376
  var import_auto_paper9 = require("@rific/auto-paper");
1376
- var import_react_native20 = require("react-native");
1377
+ var import_react_native21 = require("react-native");
1377
1378
  var import_react_native_paper11 = require("react-native-paper");
1378
1379
  var import_jsx_runtime20 = require("react/jsx-runtime");
1379
1380
  function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
1380
1381
  const { dark } = (0, import_auto_paper9.useAutoPaperTheme)();
1381
1382
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
1382
1383
  const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
1383
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native20.View, { style: [styles16.section, { backgroundColor: sectionBg }], children: [
1384
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native21.View, { style: [styles16.section, { backgroundColor: sectionBg }], children: [
1384
1385
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper11.Text, { variant: "labelMedium", style: [styles16.label, { color: fg }], children: label }),
1385
1386
  children
1386
1387
  ] });
1387
1388
  }
1388
- var styles16 = import_react_native20.StyleSheet.create({
1389
+ var styles16 = import_react_native21.StyleSheet.create({
1389
1390
  // Bold and full-contrast (fg), not the original fontless/fgMuted treatment — that read at the
1390
1391
  // same visual weight as StatRow's own row labels below it (both used the identical muted color;
1391
1392
  // letterSpacing/variant alone didn't separate them enough to read as "this is the group header"
@@ -1436,7 +1437,9 @@ function usePopoverHost() {
1436
1437
  StatSection,
1437
1438
  TriggerGaugeHost,
1438
1439
  getLabeledDropdownContentHeight,
1440
+ getOverlayCardColors,
1439
1441
  loadSkiaWeb,
1442
+ overlayStyles,
1440
1443
  useAutoAlign,
1441
1444
  usePopoverHost
1442
1445
  });