@tastic/hud 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -130,21 +130,21 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
130
130
  height: canvasSize,
131
131
  width: canvasSize
132
132
  };
133
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native14.View, { style: [styles12.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
134
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
135
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
133
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native15.View, { style: [styles13.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
134
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
135
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
136
136
  ] }) });
137
137
  }
138
- var import_react_native_skia, import_core6, import_react7, import_react_native14, import_react_native_reanimated, import_jsx_runtime14, 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, styles12;
138
+ var import_react_native_skia, import_core6, import_react7, import_react_native15, import_react_native_reanimated, import_jsx_runtime15, 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, styles13;
139
139
  var init_TriggerGauge = __esm({
140
140
  "src/TriggerGauge.tsx"() {
141
141
  "use strict";
142
142
  import_react_native_skia = require("@shopify/react-native-skia");
143
143
  import_core6 = require("@tastic/core");
144
144
  import_react7 = require("react");
145
- import_react_native14 = require("react-native");
145
+ import_react_native15 = require("react-native");
146
146
  import_react_native_reanimated = require("react-native-reanimated");
147
- import_jsx_runtime14 = require("react/jsx-runtime");
147
+ import_jsx_runtime15 = require("react/jsx-runtime");
148
148
  UNLIT_THICKNESS = 3;
149
149
  LIT_THICKNESS = 7;
150
150
  DASH_GAP_PX = 9;
@@ -154,7 +154,7 @@ var init_TriggerGauge = __esm({
154
154
  MOUNT_DURATION_MS = 450;
155
155
  MOUNT_STAGGER_MS = 40;
156
156
  SELECTION_TRANSITION_DURATION_MS = 260;
157
- styles12 = import_react_native14.StyleSheet.create({
157
+ styles13 = import_react_native15.StyleSheet.create({
158
158
  container: {
159
159
  alignItems: "center",
160
160
  justifyContent: "center",
@@ -183,6 +183,8 @@ __export(index_exports, {
183
183
  LOCKED_BADGE_COLOR: () => LOCKED_BADGE_COLOR,
184
184
  LabeledDropdown: () => LabeledDropdown,
185
185
  MONO_FONT: () => MONO_FONT,
186
+ OverlayBackdrop: () => OverlayBackdrop,
187
+ OverlayCard: () => OverlayCard,
186
188
  PlayerSetupPanel: () => PlayerSetupPanel,
187
189
  PopoverBody: () => PopoverBody,
188
190
  PressAwayOverlay: () => PressAwayOverlay,
@@ -206,6 +208,7 @@ __export(index_exports, {
206
208
  overlayActionStyles: () => overlayActionStyles,
207
209
  overlayStyles: () => overlayStyles,
208
210
  useAutoAlign: () => useAutoAlign,
211
+ useOverlayCardColors: () => useOverlayCardColors,
209
212
  usePopoverHost: () => usePopoverHost,
210
213
  useQuitConfirmation: () => useQuitConfirmation,
211
214
  useZoneClampedAlign: () => useZoneClampedAlign
@@ -417,19 +420,19 @@ function ActivityStatSection({ stats }) {
417
420
  }
418
421
 
419
422
  // src/BaseSettingsDialog.tsx
420
- var import_auto_paper7 = require("@rific/auto-paper");
423
+ var import_auto_paper8 = require("@rific/auto-paper");
421
424
  var import_feedback_press2 = require("@rific/feedback-press");
422
425
  var import_updater = require("@rific/updater");
423
426
  var import_core3 = require("@tastic/core");
424
427
  var import_react4 = require("react");
425
- var import_react_native10 = require("react-native");
428
+ var import_react_native11 = require("react-native");
426
429
  var import_react_native_paper8 = require("react-native-paper");
427
430
 
428
431
  // src/ConfirmDialog.tsx
429
- var import_auto_paper6 = require("@rific/auto-paper");
432
+ var import_auto_paper7 = require("@rific/auto-paper");
430
433
  var import_feedback_press = require("@rific/feedback-press");
431
434
  var import_core = require("@tastic/core");
432
- var import_react_native8 = require("react-native");
435
+ var import_react_native9 = require("react-native");
433
436
  var import_react_native_paper6 = require("react-native-paper");
434
437
 
435
438
  // src/overlayCard.ts
@@ -504,26 +507,47 @@ var overlayActionStyles = import_react_native7.StyleSheet.create({
504
507
  }
505
508
  });
506
509
 
507
- // src/ConfirmDialog.tsx
510
+ // src/OverlaySurface.tsx
511
+ var import_auto_paper6 = require("@rific/auto-paper");
512
+ var import_react_native8 = require("react-native");
508
513
  var import_jsx_runtime7 = require("react/jsx-runtime");
514
+ function useOverlayCardColors() {
515
+ const { colors } = (0, import_auto_paper6.useAutoPaperTheme)();
516
+ return { fg: colors.onSurface, fgMuted: colors.onSurfaceVariant, cardBorder: colors.outlineVariant, backdrop: colors.backdrop };
517
+ }
518
+ function OverlayBackdrop({ children, style }) {
519
+ const { backdrop } = useOverlayCardColors();
520
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.View, { style: [overlayStyles.overlay, { backgroundColor: backdrop }, style], children });
521
+ }
522
+ function OverlayCard({ children, style, ...rest }) {
523
+ const { cardBorder } = useOverlayCardColors();
524
+ const blur = (0, import_auto_paper6.useBlur)();
525
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_auto_paper6.BlurView, { blur, elevation: 3, style: [overlayStyles.card, styles6.card, { borderColor: cardBorder }, style], ...rest, children });
526
+ }
527
+ var styles6 = import_react_native8.StyleSheet.create({
528
+ card: { overflow: "hidden" }
529
+ });
530
+
531
+ // src/ConfirmDialog.tsx
532
+ var import_jsx_runtime8 = require("react/jsx-runtime");
509
533
  function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
510
- const { dark, colors } = (0, import_auto_paper6.useAutoPaperTheme)();
534
+ const { colors } = (0, import_auto_paper7.useAutoPaperTheme)();
535
+ const { fg } = useOverlayCardColors();
511
536
  if (!visible) return null;
512
- const { fg, cardBg, cardBorder } = getOverlayCardColors(dark);
513
537
  const accent = destructive ? colors.danger : colors.primary;
514
538
  const onAccent = destructive ? colors.onDanger : colors.onPrimary;
515
539
  const showCancel = cancelLabel !== void 0 && onCancel !== void 0;
516
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper6.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.View, { style: [overlayStyles.overlay, styles6.overlay], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: [overlayStyles.card, styles6.card, { backgroundColor: cardBg, borderColor: cardBorder }, (0, import_core.toRotationStyle)(rotation)], children: [
517
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper6.Icon, { source: icon, size: 64, color: accent }),
518
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper6.Text, { variant: "headlineLarge", style: [styles6.title, { color: accent }], children: title }),
519
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper6.Text, { variant: "bodyLarge", style: [styles6.body, { color: fg }], children: message }),
520
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: overlayActionStyles.actions, children: [
521
- showCancel && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press.Button, { mode: "outlined", onPress: onCancel, style: overlayActionStyles.actionButton, children: cancelLabel }),
522
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press.Button, { mode: "contained", onPress: onConfirm, style: showCancel ? overlayActionStyles.actionButton : overlayActionStyles.actionButtonSingle, buttonColor: accent, textColor: onAccent, children: confirmLabel })
540
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper6.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(OverlayBackdrop, { style: styles7.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(OverlayCard, { style: [styles7.card, (0, import_core.toRotationStyle)(rotation)], children: [
541
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper6.Icon, { source: icon, size: 64, color: accent }),
542
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper6.Text, { variant: "headlineLarge", style: [styles7.title, { color: accent }], children: title }),
543
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper6.Text, { variant: "bodyLarge", style: [styles7.body, { color: fg }], children: message }),
544
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native9.View, { style: overlayActionStyles.actions, children: [
545
+ showCancel && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_feedback_press.Button, { mode: "outlined", onPress: onCancel, style: overlayActionStyles.actionButton, children: cancelLabel }),
546
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_feedback_press.Button, { mode: "contained", onPress: onConfirm, style: showCancel ? overlayActionStyles.actionButton : overlayActionStyles.actionButtonSingle, buttonColor: accent, textColor: onAccent, children: confirmLabel })
523
547
  ] })
524
548
  ] }) }) });
525
549
  }
526
- var styles6 = import_react_native8.StyleSheet.create({
550
+ var styles7 = import_react_native9.StyleSheet.create({
527
551
  body: {
528
552
  textAlign: "center"
529
553
  },
@@ -554,22 +578,22 @@ var styles6 = import_react_native8.StyleSheet.create({
554
578
  // src/RotatedFrame.tsx
555
579
  var import_core2 = require("@tastic/core");
556
580
  var import_react2 = require("react");
557
- var import_react_native9 = require("react-native");
581
+ var import_react_native10 = require("react-native");
558
582
  var import_react_native_paper7 = require("react-native-paper");
559
583
  var import_react_native_safe_area_context = require("react-native-safe-area-context");
560
- var import_jsx_runtime8 = require("react/jsx-runtime");
584
+ var import_jsx_runtime9 = require("react/jsx-runtime");
561
585
  function RotatedFrame({ children, rotation: rotationOverride, rotatedSafeArea = false, portalHost = false, passThrough = false, maxContentWidth }) {
562
586
  const ambientRotation = (0, import_core2.useRotation)();
563
587
  const rotation = rotationOverride ?? ambientRotation;
564
- const window = (0, import_react_native9.useWindowDimensions)();
588
+ const window = (0, import_react_native10.useWindowDimensions)();
565
589
  const { width, height } = (0, import_core2.rotateDimensions)(window.width, window.height, rotation);
566
590
  const rawInsets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
567
591
  const insets = (0, import_react2.useMemo)(() => rotatedSafeArea ? (0, import_core2.rotateInsets)(rawInsets, rotation) : rawInsets, [rotatedSafeArea, rawInsets, rotation]);
568
592
  const cappedWidth = maxContentWidth !== void 0 && width > height ? maxContentWidth : void 0;
569
- const column = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, { style: [styles7.column, cappedWidth !== void 0 && { maxWidth: cappedWidth }], pointerEvents: passThrough ? "box-none" : void 0, children });
570
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_core2.FakeLandscapeView, { rotation, passThrough, style: styles7.root, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_safe_area_context.SafeAreaInsetsContext.Provider, { value: insets, children: portalHost ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper7.Portal.Host, { children: column }) : column }) });
593
+ const column = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [styles8.column, cappedWidth !== void 0 && { maxWidth: cappedWidth }], pointerEvents: passThrough ? "box-none" : void 0, children });
594
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_core2.FakeLandscapeView, { rotation, passThrough, style: styles8.root, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_safe_area_context.SafeAreaInsetsContext.Provider, { value: insets, children: portalHost ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper7.Portal.Host, { children: column }) : column }) });
571
595
  }
572
- var styles7 = import_react_native9.StyleSheet.create({
596
+ var styles8 = import_react_native10.StyleSheet.create({
573
597
  // A centred column: full width up to `maxWidth`, so a capped frame sits in the middle of a wider window.
574
598
  column: {
575
599
  alignSelf: "center",
@@ -602,12 +626,12 @@ function useUpdateConfirmBridge() {
602
626
  }
603
627
 
604
628
  // src/BaseSettingsDialog.tsx
605
- var import_jsx_runtime9 = require("react/jsx-runtime");
629
+ var import_jsx_runtime10 = require("react/jsx-runtime");
606
630
  function SettingIcon({ source, color, containerColor }) {
607
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [styles8.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Icon, { source, size: 18, color }) });
631
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native11.View, { style: [styles9.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Icon, { source, size: 18, color }) });
608
632
  }
609
633
  function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, onShowHowToPlay, children }) {
610
- const { colors } = (0, import_auto_paper7.useAutoPaperTheme)();
634
+ const { colors } = (0, import_auto_paper8.useAutoPaperTheme)();
611
635
  const ambientRotation = (0, import_core3.useRotation)();
612
636
  const rotation = rotationOverride ?? ambientRotation;
613
637
  const isTouchPrimary = (0, import_core3.useIsTouchPrimaryDevice)();
@@ -615,6 +639,8 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
615
639
  const { settings: soundSettings, set: setSoundSettings } = (0, import_feedback_press2.useSoundSettings)();
616
640
  const sound = (0, import_react4.useContext)(import_feedback_press2.SoundContext);
617
641
  const { forceShort: forceHapticFeedback } = (0, import_feedback_press2.useVibration)();
642
+ const { settings: themeSettings, set: setThemeSettings } = (0, import_auto_paper8.useThemeSettings)();
643
+ const expoBlur = (0, import_auto_paper8.useBlurModule)();
618
644
  const [infoMessage, setInfoMessage] = (0, import_react4.useState)(null);
619
645
  const { manifest: updateManifest, onConfirm: onUpdateConfirm, respond: respondToUpdateConfirm } = useUpdateConfirmBridge();
620
646
  const { check, checking, updateReady } = (0, import_updater.useUpdater)({
@@ -628,33 +654,34 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
628
654
  const [opened, setOpened] = (0, import_react4.useState)(visible);
629
655
  if (visible && !opened) setOpened(true);
630
656
  const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
631
- const showEdgeGuard = import_react_native10.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
632
- const showHaptics = import_react_native10.Platform.OS !== "web" && !hideHaptics;
657
+ const showEdgeGuard = import_react_native11.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
658
+ const showHaptics = import_react_native11.Platform.OS !== "web" && !hideHaptics;
633
659
  const showSound = !hideSound;
634
660
  const showAppearance = !hideAppearance;
635
- const showUpdateCheck = import_react_native10.Platform.OS !== "web" && !hideUpdateCheck;
661
+ const showBlur = showAppearance && import_react_native11.Platform.OS !== "android" && expoBlur !== void 0 && expoBlur !== null;
662
+ const showUpdateCheck = import_react_native11.Platform.OS !== "web" && !hideUpdateCheck;
636
663
  if (!opened) return null;
637
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
638
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_auto_paper7.Dialog, { visible, onDismiss, style: styles8.dialog, children: [
639
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper7.Dialog.Title, { children: "Settings" }),
640
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper7.Dialog.ScrollArea, { style: styles8.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.ScrollView, { contentContainerStyle: styles8.content, showsVerticalScrollIndicator: false, children: [
641
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleGroup, children: [
642
- showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles8.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleContent, children: [
643
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.tertiary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant }),
644
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.flexShrink, children: [
645
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
646
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
664
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
665
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_auto_paper8.Dialog, { visible, onDismiss, style: styles9.dialog, children: [
666
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_auto_paper8.Dialog.Title, { children: "Settings" }),
667
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_auto_paper8.Dialog.ScrollArea, { style: styles9.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.ScrollView, { contentContainerStyle: styles9.content, showsVerticalScrollIndicator: false, children: [
668
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleGroup, children: [
669
+ showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles9.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleContent, children: [
670
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.tertiary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant }),
671
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.flexShrink, children: [
672
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
673
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
647
674
  ] })
648
675
  ] }) }),
649
- showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles8.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleContent, children: [
650
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant }),
651
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.flexShrink, children: [
652
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
653
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
676
+ showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles9.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleContent, children: [
677
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant }),
678
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.flexShrink, children: [
679
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
680
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
654
681
  ] })
655
682
  ] }) }),
656
- (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleRow, children: [
657
- showSound && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
683
+ (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleRow, children: [
684
+ showSound && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
658
685
  import_feedback_press2.TouchableRipple,
659
686
  {
660
687
  soundDisabled: true,
@@ -663,15 +690,15 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
663
690
  setSoundSettings({ enabled });
664
691
  if (enabled) sound.selection?.();
665
692
  },
666
- style: styles8.toggleButtonInRow,
693
+ style: styles9.toggleButtonInRow,
667
694
  accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
668
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleContent, children: [
669
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
670
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
695
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleContent, children: [
696
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
697
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
671
698
  ] })
672
699
  }
673
700
  ),
674
- showHaptics && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
701
+ showHaptics && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
675
702
  import_feedback_press2.TouchableRipple,
676
703
  {
677
704
  hapticDisabled: true,
@@ -680,54 +707,58 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
680
707
  setHapticSettings({ vibrate });
681
708
  if (vibrate) forceHapticFeedback();
682
709
  },
683
- style: styles8.toggleButtonInRow,
710
+ style: styles9.toggleButtonInRow,
684
711
  accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
685
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleContent, children: [
686
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
687
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
712
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleContent, children: [
713
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
714
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
688
715
  ] })
689
716
  }
690
717
  )
691
718
  ] }),
692
- onShowHowToPlay && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
719
+ onShowHowToPlay && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
693
720
  import_feedback_press2.TouchableRipple,
694
721
  {
695
722
  onPress: () => {
696
723
  onDismiss();
697
724
  onShowHowToPlay();
698
725
  },
699
- style: styles8.toggleButton,
726
+ style: styles9.toggleButton,
700
727
  accessibilityLabel: "How to Play",
701
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleContent, children: [
702
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: "help-circle-outline", color: colors.secondary, containerColor: colors.secondaryContainer }),
703
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.flexShrink, children: [
704
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "How to Play" }),
705
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Replay the quick intro" })
728
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleContent, children: [
729
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: "help-circle-outline", color: colors.secondary, containerColor: colors.secondaryContainer }),
730
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.flexShrink, children: [
731
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "How to Play" }),
732
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Replay the quick intro" })
706
733
  ] })
707
734
  ] })
708
735
  }
709
736
  )
710
737
  ] }),
711
- showAppearance && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.section, children: [
712
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "labelMedium", style: [styles8.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
713
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper7.AutoAppearancePicker, { showLabels: false })
738
+ showAppearance && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.section, children: [
739
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "labelMedium", style: [styles9.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
740
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_auto_paper8.AutoAppearancePicker, { showLabels: false }),
741
+ showBlur && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => setThemeSettings({ blur: !themeSettings.blur }), style: styles9.toggleButton, accessibilityLabel: `Blur ${themeSettings.blur ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.toggleContent, children: [
742
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: themeSettings.blur ? "blur" : "blur-off", color: themeSettings.blur ? colors.tertiary : colors.onSurfaceVariant, containerColor: themeSettings.blur ? colors.tertiaryContainer : colors.surfaceVariant }),
743
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Blur" })
744
+ ] }) })
714
745
  ] }),
715
746
  children,
716
- showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.section, children: [
717
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_paper8.Text, { variant: "labelSmall", style: [styles8.sectionLabel, { color: colors.onSurfaceVariant }], children: [
747
+ showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles9.section, children: [
748
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native_paper8.Text, { variant: "labelSmall", style: [styles9.sectionLabel, { color: colors.onSurfaceVariant }], children: [
718
749
  "VERSION ",
719
750
  version,
720
751
  updateReady ? " \xB7 UPDATE READY" : ""
721
752
  ] }),
722
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
753
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
723
754
  ] })
724
755
  ] }) })
725
756
  ] }),
726
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ConfirmDialog, { visible: !!updateManifest, title: "Update Available", message: updateManifestDate ? `Released ${updateManifestDate.toLocaleDateString()} at ${updateManifestDate.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation: 0, onConfirm: () => respondToUpdateConfirm(true), onCancel: () => respondToUpdateConfirm(false) }),
727
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ConfirmDialog, { visible: !!infoMessage, title: infoMessage?.title ?? "", message: infoMessage?.message ?? "", confirmLabel: "OK", icon: "information-outline", rotation: 0, onConfirm: () => setInfoMessage(null) })
757
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ConfirmDialog, { visible: !!updateManifest, title: "Update Available", message: updateManifestDate ? `Released ${updateManifestDate.toLocaleDateString()} at ${updateManifestDate.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation: 0, onConfirm: () => respondToUpdateConfirm(true), onCancel: () => respondToUpdateConfirm(false) }),
758
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ConfirmDialog, { visible: !!infoMessage, title: infoMessage?.title ?? "", message: infoMessage?.message ?? "", confirmLabel: "OK", icon: "information-outline", rotation: 0, onConfirm: () => setInfoMessage(null) })
728
759
  ] }) });
729
760
  }
730
- var styles8 = import_react_native10.StyleSheet.create({
761
+ var styles9 = import_react_native11.StyleSheet.create({
731
762
  content: {
732
763
  gap: 24,
733
764
  paddingVertical: 20
@@ -795,31 +826,31 @@ var styles8 = import_react_native10.StyleSheet.create({
795
826
  });
796
827
 
797
828
  // src/BaseStatsScreen.tsx
798
- var import_auto_paper8 = require("@rific/auto-paper");
829
+ var import_auto_paper9 = require("@rific/auto-paper");
799
830
  var import_feedback_press3 = require("@rific/feedback-press");
800
831
  var import_core4 = require("@tastic/core");
801
832
  var import_react5 = require("react");
802
- var import_react_native11 = require("react-native");
833
+ var import_react_native12 = require("react-native");
803
834
  var import_react_native_paper9 = require("react-native-paper");
804
- var import_jsx_runtime10 = require("react/jsx-runtime");
835
+ var import_jsx_runtime11 = require("react/jsx-runtime");
805
836
  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 }) {
806
- const { dark, colors } = (0, import_auto_paper8.useAutoPaperTheme)();
837
+ const { dark, colors } = (0, import_auto_paper9.useAutoPaperTheme)();
807
838
  const ambientRotation = (0, import_core4.useRotation)();
808
839
  const rotation = rotationOverride ?? ambientRotation;
809
840
  const [confirmResetVisible, setConfirmResetVisible] = (0, import_react5.useState)(false);
810
841
  const showReset = !!onReset;
811
842
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
812
843
  const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
813
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: [styles9.container, { backgroundColor: bg }], children: [
814
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: [styles9.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
815
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
816
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper9.Text, { variant: titleVariant, style: [styles9.title, { color: fg }], children: title })
844
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native12.View, { style: [styles10.container, { backgroundColor: bg }], children: [
845
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native12.View, { style: [styles10.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
846
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
847
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: titleVariant, style: [styles10.title, { color: fg }], children: title })
817
848
  ] }),
818
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.ScrollView, { style: styles9.scrollView, contentContainerStyle: [styles9.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
849
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native12.ScrollView, { style: styles10.scrollView, contentContainerStyle: [styles10.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
819
850
  children,
820
- showReset && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles9.resetButton, children: resetLabel })
851
+ showReset && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles10.resetButton, children: resetLabel })
821
852
  ] }),
822
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
853
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
823
854
  ConfirmDialog,
824
855
  {
825
856
  visible: confirmResetVisible,
@@ -839,7 +870,7 @@ function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", t
839
870
  )
840
871
  ] });
841
872
  }
842
- var styles9 = import_react_native11.StyleSheet.create({
873
+ var styles10 = import_react_native12.StyleSheet.create({
843
874
  container: {
844
875
  flex: 1
845
876
  },
@@ -871,18 +902,18 @@ var styles9 = import_react_native11.StyleSheet.create({
871
902
 
872
903
  // src/ContentGutter.tsx
873
904
  var import_core5 = require("@tastic/core");
874
- var import_react_native12 = require("react-native");
875
- var import_jsx_runtime11 = require("react/jsx-runtime");
905
+ var import_react_native13 = require("react-native");
906
+ var import_jsx_runtime12 = require("react/jsx-runtime");
876
907
  function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
877
908
  const { width: windowWidth } = (0, import_core5.useRotatedWindowDimensions)();
878
909
  const { contentWidth, gutterWidth } = (0, import_core5.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
879
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native12.View, { style: [styles10.row, style], children: [
880
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native12.View, { style: [styles10.gutter, { width: gutterWidth }], children: leftGutter }),
881
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native12.View, { style: { width: contentWidth }, children }),
882
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native12.View, { style: [styles10.gutter, { width: gutterWidth }], children: rightGutter })
910
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: [styles11.row, style], children: [
911
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [styles11.gutter, { width: gutterWidth }], children: leftGutter }),
912
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: { width: contentWidth }, children }),
913
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [styles11.gutter, { width: gutterWidth }], children: rightGutter })
883
914
  ] });
884
915
  }
885
- var styles10 = import_react_native12.StyleSheet.create({
916
+ var styles11 = import_react_native13.StyleSheet.create({
886
917
  // overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
887
918
  // column instead of clipping cleanly at its own real width.
888
919
  gutter: {
@@ -895,40 +926,40 @@ var styles10 = import_react_native12.StyleSheet.create({
895
926
 
896
927
  // src/ControlSchemePicker.tsx
897
928
  var import_core8 = require("@tastic/core");
898
- var import_react_native17 = require("react-native");
929
+ var import_react_native18 = require("react-native");
899
930
 
900
931
  // src/SectionedDropdown.tsx
901
- var import_auto_paper9 = require("@rific/auto-paper");
932
+ var import_auto_paper10 = require("@rific/auto-paper");
902
933
  var import_feedback_press4 = require("@rific/feedback-press");
903
934
  var import_core7 = require("@tastic/core");
904
- var import_react_native16 = require("react-native");
935
+ var import_react_native17 = require("react-native");
905
936
  var import_react_native_paper10 = require("react-native-paper");
906
937
 
907
938
  // src/PopoverBody.tsx
908
- var import_react_native13 = require("react-native");
909
- var import_jsx_runtime12 = require("react/jsx-runtime");
939
+ var import_react_native14 = require("react-native");
940
+ var import_jsx_runtime13 = require("react/jsx-runtime");
910
941
  var CARET_SIZE = 7;
911
942
  var CARET_RING_OFFSET = 2;
912
943
  var CARET_DIP = 1;
913
944
  function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
914
945
  if (!visible) return null;
915
946
  const above = verticalAlign === "above";
916
- const alignStyle = align === "left" ? styles11.contentLeft : align === "right" ? styles11.contentRight : styles11.contentCenter;
917
- const verticalStyle = above ? styles11.contentAbove : styles11.contentBelow;
947
+ const alignStyle = align === "left" ? styles12.contentLeft : align === "right" ? styles12.contentRight : styles12.contentCenter;
948
+ const verticalStyle = above ? styles12.contentAbove : styles12.contentBelow;
918
949
  const ringSize = CARET_SIZE + caretBorderWidth;
919
950
  const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
920
951
  const caretFill = above ? "borderTopColor" : "borderBottomColor";
921
952
  const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
922
953
  const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
923
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: [styles11.content, alignStyle, verticalStyle], children: [
954
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: [styles12.content, alignStyle, verticalStyle], children: [
924
955
  children,
925
- caretColor && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
926
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [styles11.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
927
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [styles11.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
956
+ caretColor && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
957
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { style: [styles12.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
958
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { style: [styles12.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
928
959
  ] })
929
960
  ] });
930
961
  }
931
- var styles11 = import_react_native13.StyleSheet.create({
962
+ var styles12 = import_react_native14.StyleSheet.create({
932
963
  caret: {
933
964
  borderLeftColor: "transparent",
934
965
  borderRightColor: "transparent",
@@ -972,7 +1003,7 @@ var styles11 = import_react_native13.StyleSheet.create({
972
1003
 
973
1004
  // src/SkiaGate.tsx
974
1005
  var import_react6 = require("react");
975
- var import_jsx_runtime13 = require("react/jsx-runtime");
1006
+ var import_jsx_runtime14 = require("react/jsx-runtime");
976
1007
  function SkiaGate({ getComponent, componentProps, fallback = null }) {
977
1008
  const [Component, setComponent] = (0, import_react6.useState)(null);
978
1009
  (0, import_react6.useEffect)(() => {
@@ -985,19 +1016,19 @@ function SkiaGate({ getComponent, componentProps, fallback = null }) {
985
1016
  };
986
1017
  }, [getComponent]);
987
1018
  if (!Component) return fallback;
988
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Component, { ...componentProps });
1019
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Component, { ...componentProps });
989
1020
  }
990
1021
 
991
1022
  // src/TriggerGaugeHost.tsx
992
- var import_jsx_runtime15 = require("react/jsx-runtime");
1023
+ var import_jsx_runtime16 = require("react/jsx-runtime");
993
1024
  var getTriggerGauge = () => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((mod) => ({ default: mod.TriggerGauge }));
994
1025
  function TriggerGaugeHost(props) {
995
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
1026
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
996
1027
  }
997
1028
 
998
1029
  // src/useAutoAlign.ts
999
1030
  var import_react8 = require("react");
1000
- var import_react_native15 = require("react-native");
1031
+ var import_react_native16 = require("react-native");
1001
1032
  var EDGE_MARGIN = 12;
1002
1033
  function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
1003
1034
  if (rotation === 0) return { x, y, width, height };
@@ -1010,7 +1041,7 @@ function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
1010
1041
  }
1011
1042
  function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
1012
1043
  const triggerRef = (0, import_react8.useRef)(null);
1013
- const { width: windowWidth, height: windowHeight } = (0, import_react_native15.useWindowDimensions)();
1044
+ const { width: windowWidth, height: windowHeight } = (0, import_react_native16.useWindowDimensions)();
1014
1045
  const [align, setAlign] = (0, import_react8.useState)("center");
1015
1046
  const [verticalAlign, setVerticalAlign] = (0, import_react8.useState)("below");
1016
1047
  const [maxHeight, setMaxHeight] = (0, import_react8.useState)(contentHeight);
@@ -1044,7 +1075,7 @@ function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
1044
1075
  }
1045
1076
 
1046
1077
  // src/SectionedDropdown.tsx
1047
- var import_jsx_runtime16 = require("react/jsx-runtime");
1078
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1048
1079
  var MENU_BORDER_WIDTH = 1;
1049
1080
  var TRIGGER_SIZE = 44;
1050
1081
  var MENU_MIN_WIDTH = 200;
@@ -1059,8 +1090,8 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1059
1090
  const ambientRotation = (0, import_core7.useRotation)();
1060
1091
  const rotation = rotationOverride ?? ambientRotation;
1061
1092
  const menuBg = dark ? "#000000" : "#FFFFFF";
1062
- const menuBorderColor = (0, import_auto_paper9.getBlendedColor)(mutedColor, menuBg, 0.5);
1063
- const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper9.getColorRoles)(accentColor, menuBg).onColor;
1093
+ const menuBorderColor = (0, import_auto_paper10.getBlendedColor)(mutedColor, menuBg, 0.5);
1094
+ const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper10.getColorRoles)(accentColor, menuBg).onColor;
1064
1095
  const fg = dark ? "#FFFFFF" : "#000000";
1065
1096
  const open = host.openId === id;
1066
1097
  const estimatedHeight = MENU_VERTICAL_PADDING + sections.reduce((sum, section, sectionIndex) => {
@@ -1094,17 +1125,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1094
1125
  }
1095
1126
  gaugeOffset += section.options.length;
1096
1127
  }
1097
- const anchorStyle = [styles13.anchor, open && styles13.anchorOpen];
1128
+ const anchorStyle = [styles14.anchor, open && styles14.anchorOpen];
1098
1129
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
1099
1130
  const dividerStyle = { backgroundColor: menuBorderColor };
1100
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native16.View, { style: anchorStyle, children: [
1101
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native16.View, { ref: triggerRef, collapsable: false, style: styles13.triggerBox, children: [
1102
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1103
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
1131
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native17.View, { style: anchorStyle, children: [
1132
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native17.View, { ref: triggerRef, collapsable: false, style: styles14.triggerBox, children: [
1133
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1134
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
1104
1135
  ] }),
1105
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native16.ScrollView, { style: [styles13.menu, menuStyle], contentContainerStyle: styles13.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native16.View, { children: [
1106
- sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native16.View, { style: [styles13.divider, dividerStyle] }),
1107
- section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1136
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native17.ScrollView, { style: [styles14.menu, menuStyle], contentContainerStyle: styles14.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native17.View, { children: [
1137
+ sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native17.View, { style: [styles14.divider, dividerStyle] }),
1138
+ section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1108
1139
  SingleSection,
1109
1140
  {
1110
1141
  section,
@@ -1117,7 +1148,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1117
1148
  if (autoDismiss) host.close();
1118
1149
  }
1119
1150
  }
1120
- ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1151
+ ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1121
1152
  ] }, section.id)) }) })
1122
1153
  ] });
1123
1154
  }
@@ -1129,18 +1160,18 @@ function SingleSection({
1129
1160
  labelFontFamily,
1130
1161
  onSelect
1131
1162
  }) {
1132
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: section.options.map((option) => {
1163
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: section.options.map((option) => {
1133
1164
  const selected = option.value === section.value;
1134
1165
  const taken = !selected && option.value === section.takenValue;
1135
1166
  const rowColor = selected ? onAccentColor : mutedColor;
1136
- const itemStyle = [styles13.item, selected && { backgroundColor: accentColor }, taken && styles13.itemTaken];
1167
+ const itemStyle = [styles14.item, selected && { backgroundColor: accentColor }, taken && styles14.itemTaken];
1137
1168
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1138
1169
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
1139
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native16.View, { style: styles13.itemRow, children: [
1140
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper10.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1141
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native16.View, { style: styles13.itemLabelColumn, children: [
1142
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper10.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1143
- option.description && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper10.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
1170
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native17.View, { style: styles14.itemRow, children: [
1171
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper10.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1172
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native17.View, { style: styles14.itemLabelColumn, children: [
1173
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper10.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1174
+ option.description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper10.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
1144
1175
  ] })
1145
1176
  ] }) }, option.value);
1146
1177
  }) });
@@ -1154,23 +1185,23 @@ function MultiSection({
1154
1185
  allClearLabels
1155
1186
  }) {
1156
1187
  const allSelected = section.value.length === section.options.length;
1157
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1188
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1158
1189
  section.options.map((option, i) => {
1159
1190
  const selected = section.value.includes(option.value);
1160
1191
  const rowColor = selected ? onAccentColor : mutedColor;
1161
1192
  const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
1162
1193
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
1163
- const itemStyle = [styles13.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
1194
+ const itemStyle = [styles14.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
1164
1195
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1165
- return /* @__PURE__ */ (0, import_jsx_runtime16.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_runtime16.jsxs)(import_react_native16.View, { style: styles13.itemRow, children: [
1166
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper10.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1167
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper10.Text, { variant: "labelLarge", style: [styles13.itemLabelFlex, labelStyle], children: option.label })
1196
+ return /* @__PURE__ */ (0, import_jsx_runtime17.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_runtime17.jsxs)(import_react_native17.View, { style: styles14.itemRow, children: [
1197
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper10.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1198
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper10.Text, { variant: "labelLarge", style: [styles14.itemLabelFlex, labelStyle], children: option.label })
1168
1199
  ] }) }, option.value);
1169
1200
  }),
1170
- section.allClear && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles13.item, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper10.Text, { variant: "labelLarge", style: [styles13.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
1201
+ section.allClear && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles14.item, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper10.Text, { variant: "labelLarge", style: [styles14.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
1171
1202
  ] });
1172
1203
  }
1173
- var styles13 = import_react_native16.StyleSheet.create({
1204
+ var styles14 = import_react_native17.StyleSheet.create({
1174
1205
  allClearLabel: {
1175
1206
  fontWeight: "bold",
1176
1207
  textAlign: "center"
@@ -1187,7 +1218,7 @@ var styles13 = import_react_native16.StyleSheet.create({
1187
1218
  zIndex: 100
1188
1219
  },
1189
1220
  divider: {
1190
- height: import_react_native16.StyleSheet.hairlineWidth,
1221
+ height: import_react_native17.StyleSheet.hairlineWidth,
1191
1222
  marginVertical: 4
1192
1223
  },
1193
1224
  item: {
@@ -1240,24 +1271,24 @@ var styles13 = import_react_native16.StyleSheet.create({
1240
1271
  });
1241
1272
 
1242
1273
  // src/ControlSchemePicker.tsx
1243
- var import_jsx_runtime17 = require("react/jsx-runtime");
1274
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1244
1275
  function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily }) {
1245
1276
  const isTouchPrimary = (0, import_core8.useIsTouchPrimaryDevice)();
1246
- if (import_react_native17.Platform.OS !== "web" || isTouchPrimary) return null;
1247
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily });
1277
+ if (import_react_native18.Platform.OS !== "web" || isTouchPrimary) return null;
1278
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily });
1248
1279
  }
1249
1280
 
1250
1281
  // src/CornerActionButtons.tsx
1251
1282
  var import_feedback_press5 = require("@rific/feedback-press");
1252
- var import_react_native18 = require("react-native");
1253
- var import_jsx_runtime18 = require("react/jsx-runtime");
1283
+ var import_react_native19 = require("react-native");
1284
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1254
1285
  function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back", hitSlop }) {
1255
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
1256
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press5.IconButton, { icon: backIcon, iconColor: fg, size: 24, style: [styles14.back, { top: 8 + insets.top, left: 8 + insets.left }], hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
1257
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press5.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles14.topRight, { top: 8 + insets.top, right: 8 + insets.right }], hitSlop, onPress: onSettings, accessibilityLabel: "Settings" })
1286
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1287
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_feedback_press5.IconButton, { icon: backIcon, iconColor: fg, size: 24, style: [styles15.back, { top: 8 + insets.top, left: 8 + insets.left }], hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
1288
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_feedback_press5.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles15.topRight, { top: 8 + insets.top, right: 8 + insets.right }], hitSlop, onPress: onSettings, accessibilityLabel: "Settings" })
1258
1289
  ] });
1259
1290
  }
1260
- var styles14 = import_react_native18.StyleSheet.create({
1291
+ var styles15 = import_react_native19.StyleSheet.create({
1261
1292
  back: {
1262
1293
  position: "absolute"
1263
1294
  },
@@ -1267,22 +1298,22 @@ var styles14 = import_react_native18.StyleSheet.create({
1267
1298
  });
1268
1299
 
1269
1300
  // src/CornerStatusBadges.tsx
1270
- var import_react_native19 = require("react-native");
1301
+ var import_react_native20 = require("react-native");
1271
1302
  var import_react_native_paper11 = require("react-native-paper");
1272
- var import_jsx_runtime19 = require("react/jsx-runtime");
1303
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1273
1304
  var BADGE_SIZE = 30;
1274
1305
  function StatusBadge({ icon }) {
1275
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native19.View, { style: styles15.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native_paper11.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
1306
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, { style: styles16.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper11.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
1276
1307
  }
1277
1308
  function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
1278
1309
  const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
1279
1310
  const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
1280
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1281
- p1 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native19.View, { pointerEvents: "none", style: p1OnRightSide ? styles15.bottomRight : styles15.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatusBadge, { icon: p1.icon }) }),
1282
- p2 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native19.View, { pointerEvents: "none", style: p2OnLeftSide ? styles15.topLeft : styles15.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatusBadge, { icon: p2.icon }) })
1311
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
1312
+ p1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, { pointerEvents: "none", style: p1OnRightSide ? styles16.bottomRight : styles16.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StatusBadge, { icon: p1.icon }) }),
1313
+ p2 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, { pointerEvents: "none", style: p2OnLeftSide ? styles16.topLeft : styles16.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StatusBadge, { icon: p2.icon }) })
1283
1314
  ] });
1284
1315
  }
1285
- var styles15 = import_react_native19.StyleSheet.create({
1316
+ var styles16 = import_react_native20.StyleSheet.create({
1286
1317
  badge: {
1287
1318
  alignItems: "center",
1288
1319
  backgroundColor: "rgba(0,0,0,0.28)",
@@ -1301,12 +1332,12 @@ var styles15 = import_react_native19.StyleSheet.create({
1301
1332
  });
1302
1333
 
1303
1334
  // src/InlineColorPicker.tsx
1304
- var import_auto_paper10 = require("@rific/auto-paper");
1335
+ var import_auto_paper11 = require("@rific/auto-paper");
1305
1336
  var import_feedback_press6 = require("@rific/feedback-press");
1306
1337
  var import_core9 = require("@tastic/core");
1307
- var import_react_native20 = require("react-native");
1338
+ var import_react_native21 = require("react-native");
1308
1339
  var import_react_native_paper12 = require("react-native-paper");
1309
- var import_jsx_runtime20 = require("react/jsx-runtime");
1340
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1310
1341
  var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
1311
1342
  var DEFAULT_SIZE = 48;
1312
1343
  var SWATCH_SIZE = 28;
@@ -1327,11 +1358,11 @@ function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
1327
1358
  const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
1328
1359
  return { width, height };
1329
1360
  }
1330
- function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper10.defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
1361
+ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper11.defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
1331
1362
  const ambientRotation = (0, import_core9.useRotation)();
1332
1363
  const rotation = rotationOverride ?? ambientRotation;
1333
1364
  const menuBg = dark ? "#000000" : "#FFFFFF";
1334
- const { width: windowWidth } = (0, import_react_native20.useWindowDimensions)();
1365
+ const { width: windowWidth } = (0, import_react_native21.useWindowDimensions)();
1335
1366
  const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
1336
1367
  const open = host.openId === id;
1337
1368
  const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
@@ -1340,16 +1371,16 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1340
1371
  const align = forcedAlign ?? placement.align;
1341
1372
  const displayFor = previewValue ?? ((hex) => hex);
1342
1373
  const displayValue = displayFor(value);
1343
- const contrastColor = (0, import_auto_paper10.getContrastColor)(displayValue);
1374
+ const contrastColor = (0, import_auto_paper11.getContrastColor)(displayValue);
1344
1375
  const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
1345
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native20.View, { style: [styles16.anchor, open && styles16.anchorOpen], children: [
1346
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles16.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, { ref: triggerRef, collapsable: false, style: styles16.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper12.Text, { style: [styles16.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper12.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
1347
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.ScrollView, { style: [styles16.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles16.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
1376
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native21.View, { style: [styles17.anchor, open && styles17.anchorOpen], children: [
1377
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles17.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.View, { ref: triggerRef, collapsable: false, style: styles17.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper12.Text, { style: [styles17.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper12.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
1378
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.ScrollView, { style: [styles17.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles17.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
1348
1379
  const selected = swatch.value.toLowerCase() === value.toLowerCase();
1349
1380
  const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
1350
1381
  const swappable = taken && allowSwapTaken;
1351
1382
  const swatchDisplay = displayFor(swatch.value);
1352
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1383
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1353
1384
  import_feedback_press6.TouchableRipple,
1354
1385
  {
1355
1386
  disabled: taken && !swappable,
@@ -1358,15 +1389,15 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1358
1389
  if (autoDismiss) host.close();
1359
1390
  },
1360
1391
  borderless: true,
1361
- style: [styles16.swatch, { backgroundColor: swatchDisplay }, selected && styles16.swatchSelected, taken && !swappable && styles16.swatchTaken],
1362
- children: selected ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper12.Icon, { source: "check", size: 16, color: (0, import_auto_paper10.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper12.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper10.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper12.Icon, { source: "close", size: 16, color: (0, import_auto_paper10.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native20.View, {})
1392
+ style: [styles17.swatch, { backgroundColor: swatchDisplay }, selected && styles17.swatchSelected, taken && !swappable && styles17.swatchTaken],
1393
+ children: selected ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper12.Icon, { source: "check", size: 16, color: (0, import_auto_paper11.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper12.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper11.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper12.Icon, { source: "close", size: 16, color: (0, import_auto_paper11.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.View, {})
1363
1394
  },
1364
1395
  swatch.value
1365
1396
  );
1366
1397
  }) }) })
1367
1398
  ] });
1368
1399
  }
1369
- var styles16 = import_react_native20.StyleSheet.create({
1400
+ var styles17 = import_react_native21.StyleSheet.create({
1370
1401
  anchor: {
1371
1402
  position: "relative"
1372
1403
  },
@@ -1438,11 +1469,11 @@ var styles16 = import_react_native20.StyleSheet.create({
1438
1469
  });
1439
1470
 
1440
1471
  // src/LabeledDropdown.tsx
1441
- var import_auto_paper11 = require("@rific/auto-paper");
1472
+ var import_auto_paper12 = require("@rific/auto-paper");
1442
1473
  var import_feedback_press7 = require("@rific/feedback-press");
1443
- var import_react_native21 = require("react-native");
1474
+ var import_react_native22 = require("react-native");
1444
1475
  var import_react_native_paper13 = require("react-native-paper");
1445
- var import_jsx_runtime21 = require("react/jsx-runtime");
1476
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1446
1477
  var TRIGGER_HEIGHT = 28;
1447
1478
  var POPOVER_WIDTH = 180;
1448
1479
  var ROW_HEIGHT = 36;
@@ -1465,22 +1496,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
1465
1496
  onChange(option.value);
1466
1497
  host.close();
1467
1498
  };
1468
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native21.View, { style: [styles17.anchor, open && styles17.anchorOpen], children: [
1469
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles17.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native21.View, { ref: triggerRef, collapsable: false, style: styles17.triggerInner, children: [
1470
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Text, { style: [styles17.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
1471
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Icon, { source: "menu-down", size: 16, color })
1499
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native22.View, { style: [styles18.anchor, open && styles18.anchorOpen], children: [
1500
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles18.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native22.View, { ref: triggerRef, collapsable: false, style: styles18.triggerInner, children: [
1501
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Text, { style: [styles18.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
1502
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: "menu-down", size: 16, color })
1472
1503
  ] }) }),
1473
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native21.ScrollView, { style: [styles17.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles17.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
1504
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native22.ScrollView, { style: [styles18.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles18.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
1474
1505
  const isSelected = option.value === value;
1475
- const onColor = (0, import_auto_paper11.getContrastColor)(color);
1476
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles17.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native21.View, { style: styles17.rowInner, children: [
1477
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
1478
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Text, { style: [styles17.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
1506
+ const onColor = (0, import_auto_paper12.getContrastColor)(color);
1507
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles18.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native22.View, { style: styles18.rowInner, children: [
1508
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
1509
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Text, { style: [styles18.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
1479
1510
  ] }) }, option.value);
1480
1511
  }) }) })
1481
1512
  ] });
1482
1513
  }
1483
- var styles17 = import_react_native21.StyleSheet.create({
1514
+ var styles18 = import_react_native22.StyleSheet.create({
1484
1515
  anchor: {
1485
1516
  position: "relative"
1486
1517
  },
@@ -1539,21 +1570,21 @@ function loadSkiaWeb() {
1539
1570
 
1540
1571
  // src/PlayerSetupPanel.tsx
1541
1572
  var import_profile2 = require("@tastic/profile");
1542
- var import_react_native23 = require("react-native");
1573
+ var import_react_native24 = require("react-native");
1543
1574
  var import_react_native_paper15 = require("react-native-paper");
1544
1575
 
1545
1576
  // src/ReadyButton.tsx
1546
1577
  var import_feedback_press8 = require("@rific/feedback-press");
1547
- var import_react_native22 = require("react-native");
1578
+ var import_react_native23 = require("react-native");
1548
1579
  var import_react_native_paper14 = require("react-native-paper");
1549
- var import_jsx_runtime22 = require("react/jsx-runtime");
1580
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1550
1581
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
1551
- const readyButtonStyle = [styles18.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
1582
+ const readyButtonStyle = [styles19.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
1552
1583
  const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
1553
1584
  const labelColorStyle = { color: ready ? "#000000" : color };
1554
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_feedback_press8.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper14.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
1585
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_feedback_press8.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
1555
1586
  }
1556
- var styles18 = import_react_native22.StyleSheet.create({
1587
+ var styles19 = import_react_native23.StyleSheet.create({
1557
1588
  readyButton: {
1558
1589
  alignItems: "center",
1559
1590
  borderRadius: 12,
@@ -1577,7 +1608,7 @@ function usePopoverHost() {
1577
1608
  }
1578
1609
 
1579
1610
  // src/PlayerSetupPanel.tsx
1580
- var import_jsx_runtime23 = require("react/jsx-runtime");
1611
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1581
1612
  function getColorPopoverId(idPrefix) {
1582
1613
  return `${idPrefix}-color`;
1583
1614
  }
@@ -1592,16 +1623,16 @@ function PlayerSetupPanel({ idPrefix, host, label, labelFontFamily, color, onCol
1592
1623
  const showProfilePicker = isHuman && profiles !== void 0 && !!onProfileSelect;
1593
1624
  const showCpuDifficulty = !isHuman && cpuDifficulty !== void 0 && cpuDifficultyOptions !== void 0 && !!onCpuDifficultyChange;
1594
1625
  const selectedProfile = profiles?.find((p) => p.id === selectedProfileId) ?? null;
1595
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native23.View, { style: [styles19.panel, ownPopoverOpen && styles19.panelOpen], children: [
1596
- showProfilePicker ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_profile2.ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles }) : showCpuDifficulty ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LabeledDropdown, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, alignOverride: cpuDifficultyAlignOverride }) : label && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper15.Text, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
1597
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native23.View, { style: [styles19.pickerRow, pickerRowPopoverOpen && styles19.pickerRowOpen], children: [
1598
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InlineColorPicker, { id: getColorPopoverId(idPrefix), host: popover, value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, alignOverride: colorAlignOverride, rotation: colorRotation, dark, tag: isHuman ? selectedProfile?.tag : void 0, icon: isHuman ? humanIcon : cpuIcon }),
1626
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native24.View, { style: [styles20.panel, ownPopoverOpen && styles20.panelOpen], children: [
1627
+ showProfilePicker ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_profile2.ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles }) : showCpuDifficulty ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LabeledDropdown, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, alignOverride: cpuDifficultyAlignOverride }) : label && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_paper15.Text, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
1628
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native24.View, { style: [styles20.pickerRow, pickerRowPopoverOpen && styles20.pickerRowOpen], children: [
1629
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(InlineColorPicker, { id: getColorPopoverId(idPrefix), host: popover, value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, alignOverride: colorAlignOverride, rotation: colorRotation, dark, tag: isHuman ? selectedProfile?.tag : void 0, icon: isHuman ? humanIcon : cpuIcon }),
1599
1630
  secondPicker
1600
1631
  ] }),
1601
- isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReadyButton, { color, ready: ready ?? false, onToggleReady })
1632
+ isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ReadyButton, { color, ready: ready ?? false, onToggleReady })
1602
1633
  ] });
1603
1634
  }
1604
- var styles19 = import_react_native23.StyleSheet.create({
1635
+ var styles20 = import_react_native24.StyleSheet.create({
1605
1636
  panel: {
1606
1637
  alignItems: "center",
1607
1638
  gap: 12
@@ -1633,29 +1664,29 @@ var styles19 = import_react_native23.StyleSheet.create({
1633
1664
  });
1634
1665
 
1635
1666
  // src/PressAwayOverlay.tsx
1636
- var import_react_native24 = require("react-native");
1637
- var import_jsx_runtime24 = require("react/jsx-runtime");
1667
+ var import_react_native25 = require("react-native");
1668
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1638
1669
  function PressAwayOverlay({ active, onPress, style }) {
1639
1670
  if (!active) return null;
1640
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native24.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native24.StyleSheet.absoluteFill, style] });
1671
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native25.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native25.StyleSheet.absoluteFill, style] });
1641
1672
  }
1642
1673
 
1643
1674
  // src/SharedActionBand.tsx
1644
1675
  var import_feedback_press9 = require("@rific/feedback-press");
1645
- var import_react_native25 = require("react-native");
1646
- var import_jsx_runtime25 = require("react/jsx-runtime");
1676
+ var import_react_native26 = require("react-native");
1677
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1647
1678
  function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
1648
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native25.View, { style: [styles20.column, popoverOpen && styles20.columnOpen], children: [
1649
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native25.View, { style: styles20.actionsRow, children: [
1650
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_feedback_press9.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1651
- onRandomize && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_feedback_press9.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1652
- onReset && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_feedback_press9.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
1653
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_feedback_press9.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
1679
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native26.View, { style: [styles21.column, popoverOpen && styles21.columnOpen], children: [
1680
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native26.View, { style: styles21.actionsRow, children: [
1681
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1682
+ onRandomize && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1683
+ onReset && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
1684
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
1654
1685
  ] }),
1655
1686
  children
1656
1687
  ] });
1657
1688
  }
1658
- var styles20 = import_react_native25.StyleSheet.create({
1689
+ var styles21 = import_react_native26.StyleSheet.create({
1659
1690
  actionsRow: {
1660
1691
  alignItems: "center",
1661
1692
  flexDirection: "row",
@@ -1672,9 +1703,9 @@ var styles20 = import_react_native25.StyleSheet.create({
1672
1703
 
1673
1704
  // src/StaggeredWord.tsx
1674
1705
  var import_react10 = require("react");
1675
- var import_react_native26 = require("react-native");
1706
+ var import_react_native27 = require("react-native");
1676
1707
  var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
1677
- var import_jsx_runtime26 = require("react/jsx-runtime");
1708
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1678
1709
  var STAGGER_MS = 45;
1679
1710
  var LETTER_DURATION_MS = 320;
1680
1711
  function getStaggeredWordDuration(letterCount) {
@@ -1690,12 +1721,12 @@ function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSiz
1690
1721
  opacity: progress.value,
1691
1722
  transform: [{ translateY: (1 - progress.value) * 12 }, { scale: 0.85 + progress.value * 0.15 }]
1692
1723
  }));
1693
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native_reanimated2.default.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
1724
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native_reanimated2.default.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
1694
1725
  }
1695
1726
  function StaggeredWord({ word, color, fontFamily, fontSize, lineHeight, reducedMotion, startIndex = 0, fontWeight = "bold", letterSpacing, style, onLayout }) {
1696
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native26.View, { style: [styles21.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
1727
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native27.View, { style: [styles22.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
1697
1728
  }
1698
- var styles21 = import_react_native26.StyleSheet.create({
1729
+ var styles22 = import_react_native27.StyleSheet.create({
1699
1730
  row: {
1700
1731
  flexDirection: "row"
1701
1732
  }
@@ -1703,12 +1734,12 @@ var styles21 = import_react_native26.StyleSheet.create({
1703
1734
 
1704
1735
  // src/UpdateDialog.tsx
1705
1736
  var import_updater2 = require("@rific/updater");
1706
- var import_jsx_runtime27 = require("react/jsx-runtime");
1737
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1707
1738
  function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onError }) {
1708
1739
  const { manifest, onConfirm, respond } = useUpdateConfirmBridge();
1709
1740
  (0, import_updater2.useUpdater)({ autoCheck, autoPrompt, onConfirm, onError });
1710
1741
  const date = manifest ? new Date(manifest.createdAt) : null;
1711
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ConfirmDialog, { visible: !!manifest, title: "Update Available", message: date ? `Released ${date.toLocaleDateString()} at ${date.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation, onConfirm: () => respond(true), onCancel: () => respond(false) });
1742
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ConfirmDialog, { visible: !!manifest, title: "Update Available", message: date ? `Released ${date.toLocaleDateString()} at ${date.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation, onConfirm: () => respond(true), onCancel: () => respond(false) });
1712
1743
  }
1713
1744
 
1714
1745
  // src/useQuitConfirmation.ts
@@ -1734,13 +1765,13 @@ function useQuitConfirmation(hasProgress, onConfirmedBack) {
1734
1765
  // src/useZoneClampedAlign.ts
1735
1766
  var import_split_screen = require("@tastic/split-screen");
1736
1767
  var import_react12 = require("react");
1737
- var import_react_native27 = require("react-native");
1768
+ var import_react_native28 = require("react-native");
1738
1769
  var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
1739
1770
  var EDGE_MARGIN2 = 12;
1740
1771
  function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
1741
1772
  const auto = useAutoAlign(open, contentWidth, contentHeight, rotation);
1742
1773
  const zone = (0, import_split_screen.useZoneBounds)();
1743
- const { height: windowHeight } = (0, import_react_native27.useWindowDimensions)();
1774
+ const { height: windowHeight } = (0, import_react_native28.useWindowDimensions)();
1744
1775
  const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
1745
1776
  const shouldMeasure = open && auto.measured && zone !== null;
1746
1777
  const [ownBounds, setOwnBounds] = (0, import_react12.useState)(null);
@@ -1787,6 +1818,8 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
1787
1818
  LOCKED_BADGE_COLOR,
1788
1819
  LabeledDropdown,
1789
1820
  MONO_FONT,
1821
+ OverlayBackdrop,
1822
+ OverlayCard,
1790
1823
  PlayerSetupPanel,
1791
1824
  PopoverBody,
1792
1825
  PressAwayOverlay,
@@ -1810,6 +1843,7 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
1810
1843
  overlayActionStyles,
1811
1844
  overlayStyles,
1812
1845
  useAutoAlign,
1846
+ useOverlayCardColors,
1813
1847
  usePopoverHost,
1814
1848
  useQuitConfirmation,
1815
1849
  useZoneClampedAlign