@tastic/hud 0.17.0 → 0.19.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
@@ -38,22 +38,22 @@ __export(TriggerGauge_exports, {
38
38
  function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, dashWidth, startDeg = DEFAULT_START_DEG, endDeg = startDeg }) {
39
39
  const totalDurationMs = MOUNT_DURATION_MS + Math.max(0, segments - 1) * MOUNT_STAGGER_MS;
40
40
  const mountProgress = (0, import_react_native_reanimated.useSharedValue)(0);
41
- (0, import_react7.useLayoutEffect)(() => {
41
+ (0, import_react8.useLayoutEffect)(() => {
42
42
  mountProgress.value = (0, import_react_native_reanimated.withTiming)(1, { duration: totalDurationMs, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.cubic) });
43
43
  }, []);
44
44
  const rawSweepDeg = ((endDeg - startDeg) % 360 + 360) % 360;
45
45
  const totalSweepDeg = rawSweepDeg === 0 ? 360 : rawSweepDeg;
46
46
  const step = segments > 0 ? totalSweepDeg / segments : 0;
47
- const centerDeg = (0, import_react7.useCallback)((i) => startDeg + (i + 0.5) * step, [startDeg, step]);
47
+ const centerDeg = (0, import_react8.useCallback)((i) => startDeg + (i + 0.5) * step, [startDeg, step]);
48
48
  const singleSelect = litIndices.length === 1;
49
49
  const angleDeg = (0, import_react_native_reanimated.useSharedValue)(centerDeg(litIndices[0] ?? 0));
50
50
  const litIndicesKey = [...litIndices].sort((a, b) => a - b).join(",");
51
- const [transitionFrom, setTransitionFrom] = (0, import_react7.useState)(litIndices);
51
+ const [transitionFrom, setTransitionFrom] = (0, import_react8.useState)(litIndices);
52
52
  const transitionFromKey = [...transitionFrom].sort((a, b) => a - b).join(",");
53
- const lastKeyRef = (0, import_react7.useRef)(litIndicesKey);
54
- const lastIndicesRef = (0, import_react7.useRef)(litIndices);
53
+ const lastKeyRef = (0, import_react8.useRef)(litIndicesKey);
54
+ const lastIndicesRef = (0, import_react8.useRef)(litIndices);
55
55
  const selectionProgress = (0, import_react_native_reanimated.useSharedValue)(1);
56
- (0, import_react7.useLayoutEffect)(() => {
56
+ (0, import_react8.useLayoutEffect)(() => {
57
57
  if (litIndicesKey !== lastKeyRef.current) {
58
58
  if (singleSelect && lastIndicesRef.current.length === 1) {
59
59
  angleDeg.value = (0, import_react_native_reanimated.withTiming)(centerDeg(litIndices[0]), { duration: SELECTION_TRANSITION_DURATION_MS, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.cubic) });
@@ -75,27 +75,27 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
75
75
  const canvasSize = diameter + LIT_THICKNESS;
76
76
  const oval = import_react_native_skia.Skia.XYWHRect(LIT_THICKNESS / 2, LIT_THICKNESS / 2, diameter, diameter);
77
77
  const unlitPath = (0, import_react_native_reanimated.useDerivedValue)(() => {
78
- const path = import_react_native_skia.Skia.Path.Make();
78
+ const path = import_react_native_skia.Skia.PathBuilder.Make();
79
79
  for (let i = 0; i < segments; i++) {
80
80
  if (litIndices.includes(i)) continue;
81
81
  let local = 1;
82
82
  if (mountProgress.value < 1) {
83
83
  const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
84
84
  const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
85
- local = (0, import_core6.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
85
+ local = (0, import_core7.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
86
86
  }
87
87
  const sweep = dashAngleDeg * local;
88
88
  if (sweep <= 0) continue;
89
89
  const dashCenterDeg = startDeg + (i + 0.5) * step;
90
90
  path.addArc(oval, dashCenterDeg - 90 - sweep / 2, sweep);
91
91
  }
92
- return path;
92
+ return path.detach();
93
93
  }, [segments, litIndicesKey, step, startDeg, dashAngleDeg, totalDurationMs, oval.x, oval.y, oval.width, oval.height]);
94
94
  const litPath = (0, import_react_native_reanimated.useDerivedValue)(() => {
95
- const path = import_react_native_skia.Skia.Path.Make();
95
+ const path = import_react_native_skia.Skia.PathBuilder.Make();
96
96
  if (mountProgress.value >= 1 && singleSelect) {
97
97
  path.addArc(oval, angleDeg.value - 90 - dashAngleDeg / 2, dashAngleDeg);
98
- return path;
98
+ return path.detach();
99
99
  }
100
100
  for (let i = 0; i < segments; i++) {
101
101
  const isLitNow = litIndices.includes(i);
@@ -106,7 +106,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
106
106
  if (!isLitNow) continue;
107
107
  const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
108
108
  const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
109
- local = (0, import_core6.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
109
+ local = (0, import_core7.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
110
110
  } else if (isLitNow === wasLit) {
111
111
  local = 1;
112
112
  } else if (isLitNow) {
@@ -119,7 +119,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
119
119
  const dashCenterDeg = startDeg + (i + 0.5) * step;
120
120
  path.addArc(oval, dashCenterDeg - 90 - sweep / 2, sweep);
121
121
  }
122
- return path;
122
+ return path.detach();
123
123
  }, [segments, litIndicesKey, transitionFromKey, singleSelect, step, startDeg, dashAngleDeg, totalDurationMs, oval.x, oval.y, oval.width, oval.height]);
124
124
  if (segments < 2) return null;
125
125
  const gaugeSizeStyle = {
@@ -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_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 })
133
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native17.View, { style: [styles14.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
134
+ /* @__PURE__ */ (0, import_jsx_runtime16.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_runtime16.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_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;
138
+ var import_react_native_skia, import_core7, import_react8, import_react_native17, import_react_native_reanimated, import_jsx_runtime16, 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, styles14;
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
- import_core6 = require("@tastic/core");
144
- import_react7 = require("react");
145
- import_react_native15 = require("react-native");
143
+ import_core7 = require("@tastic/core");
144
+ import_react8 = require("react");
145
+ import_react_native17 = require("react-native");
146
146
  import_react_native_reanimated = require("react-native-reanimated");
147
- import_jsx_runtime15 = require("react/jsx-runtime");
147
+ import_jsx_runtime16 = 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
- styles13 = import_react_native15.StyleSheet.create({
157
+ styles14 = import_react_native17.StyleSheet.create({
158
158
  container: {
159
159
  alignItems: "center",
160
160
  justifyContent: "center",
@@ -173,11 +173,13 @@ __export(index_exports, {
173
173
  ActivityStatSection: () => ActivityStatSection,
174
174
  BaseSettingsDialog: () => BaseSettingsDialog,
175
175
  BaseStatsScreen: () => BaseStatsScreen,
176
+ COMPACT_DIALOG_HEIGHT: () => COMPACT_DIALOG_HEIGHT,
176
177
  ConfirmDialog: () => ConfirmDialog,
177
178
  ContentGutter: () => ContentGutter,
178
179
  ControlSchemePicker: () => ControlSchemePicker,
179
180
  CornerActionButtons: () => CornerActionButtons,
180
181
  CornerStatusBadges: () => CornerStatusBadges,
182
+ DialogHeader: () => DialogHeader,
181
183
  InlineColorPicker: () => InlineColorPicker,
182
184
  LABELED_DROPDOWN_POPOVER_WIDTH: () => LABELED_DROPDOWN_POPOVER_WIDTH,
183
185
  LOCKED_BADGE_COLOR: () => LOCKED_BADGE_COLOR,
@@ -202,12 +204,13 @@ __export(index_exports, {
202
204
  getCpuDifficultyPopoverId: () => getCpuDifficultyPopoverId,
203
205
  getInlineColorPickerContentSize: () => getInlineColorPickerContentSize,
204
206
  getLabeledDropdownContentHeight: () => getLabeledDropdownContentHeight,
205
- getOverlayCardColors: () => getOverlayCardColors,
206
207
  getStaggeredWordDuration: () => getStaggeredWordDuration,
208
+ isCompactDialogHeight: () => isCompactDialogHeight,
207
209
  loadSkiaWeb: () => loadSkiaWeb,
208
210
  overlayActionStyles: () => overlayActionStyles,
209
211
  overlayStyles: () => overlayStyles,
210
212
  useAutoAlign: () => useAutoAlign,
213
+ useCompactDialog: () => useCompactDialog,
211
214
  useOverlayCardColors: () => useOverlayCardColors,
212
215
  usePopoverHost: () => usePopoverHost,
213
216
  useQuitConfirmation: () => useQuitConfirmation,
@@ -420,39 +423,74 @@ function ActivityStatSection({ stats }) {
420
423
  }
421
424
 
422
425
  // src/BaseSettingsDialog.tsx
423
- var import_auto_paper8 = require("@rific/auto-paper");
426
+ var import_auto_paper9 = require("@rific/auto-paper");
424
427
  var import_feedback_press2 = require("@rific/feedback-press");
425
428
  var import_updater = require("@rific/updater");
426
- var import_core3 = require("@tastic/core");
427
- var import_react4 = require("react");
428
- var import_react_native11 = require("react-native");
429
- var import_react_native_paper8 = require("react-native-paper");
429
+ var import_core4 = require("@tastic/core");
430
+ var import_react5 = require("react");
431
+ var import_react_native13 = require("react-native");
432
+ var import_react_native_paper9 = require("react-native-paper");
433
+ var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
430
434
 
431
435
  // src/ConfirmDialog.tsx
432
- var import_auto_paper7 = require("@rific/auto-paper");
436
+ var import_auto_paper8 = require("@rific/auto-paper");
433
437
  var import_feedback_press = require("@rific/feedback-press");
434
- var import_core = require("@tastic/core");
435
- var import_react_native9 = require("react-native");
436
- var import_react_native_paper6 = require("react-native-paper");
438
+ var import_core2 = require("@tastic/core");
439
+ var import_react_native11 = require("react-native");
440
+ var import_react_native_paper7 = require("react-native-paper");
437
441
 
438
- // src/overlayCard.ts
442
+ // src/DialogHeader.tsx
443
+ var import_auto_paper6 = require("@rific/auto-paper");
439
444
  var import_react_native7 = require("react-native");
440
- function getOverlayCardColors(dark) {
441
- return {
442
- fg: dark ? "#FFFFFF" : "#000000",
443
- fgMuted: dark ? "rgba(255,255,255,0.4)" : "rgba(0,0,0,0.4)",
444
- cardBg: dark ? "#111111" : "#F2F2F2",
445
- cardBorder: dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)"
446
- };
445
+ var import_react_native_paper6 = require("react-native-paper");
446
+ var import_jsx_runtime7 = require("react/jsx-runtime");
447
+ var COMPACT_DIALOG_HEIGHT = 528;
448
+ function isCompactDialogHeight(height) {
449
+ return height < COMPACT_DIALOG_HEIGHT;
450
+ }
451
+ function DialogHeader({ icon, title, color, compact = false, style }) {
452
+ const { colors } = (0, import_auto_paper6.useAutoPaperTheme)();
453
+ const accent = color ?? colors.primary;
454
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native7.View, { style: [compact ? styles6.compact : styles6.full, style], children: [
455
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper6.Icon, { source: icon, size: compact ? COMPACT_ICON_SIZE : ICON_SIZE, color: accent }),
456
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper6.Text, { accessibilityRole: "header", variant: compact ? "headlineSmall" : "headlineLarge", style: [styles6.title, compact && styles6.titleCompact, { color: accent }], children: title })
457
+ ] });
447
458
  }
448
- var overlayStyles = import_react_native7.StyleSheet.create({
459
+ var ICON_SIZE = 64;
460
+ var COMPACT_ICON_SIZE = 32;
461
+ var styles6 = import_react_native7.StyleSheet.create({
462
+ compact: {
463
+ alignItems: "center",
464
+ alignSelf: "stretch",
465
+ flexDirection: "row",
466
+ gap: 12,
467
+ justifyContent: "center"
468
+ },
469
+ full: {
470
+ alignItems: "center",
471
+ alignSelf: "stretch",
472
+ gap: 16
473
+ },
474
+ // textAlign matters once a title wraps: the card centers the Text's block, but each wrapped line
475
+ // still defaults to left-aligned without it.
476
+ title: {
477
+ fontWeight: "bold",
478
+ textAlign: "center"
479
+ },
480
+ titleCompact: {
481
+ flexShrink: 1
482
+ }
483
+ });
484
+
485
+ // src/overlayCard.ts
486
+ var import_react_native8 = require("react-native");
487
+ var overlayStyles = import_react_native8.StyleSheet.create({
449
488
  card: {
450
489
  alignItems: "center",
451
- borderRadius: 20,
452
- borderWidth: 1,
490
+ borderRadius: 28,
453
491
  gap: 16,
454
492
  maxWidth: 360,
455
- padding: 32
493
+ padding: 24
456
494
  },
457
495
  overlay: {
458
496
  alignItems: "center",
@@ -465,7 +503,7 @@ var overlayStyles = import_react_native7.StyleSheet.create({
465
503
  top: 0
466
504
  }
467
505
  });
468
- var overlayActionStyles = import_react_native7.StyleSheet.create({
506
+ var overlayActionStyles = import_react_native8.StyleSheet.create({
469
507
  // minWidth (not flexBasis) is each button's real floor - whenever both fit side by side, flexGrow
470
508
  // still splits any leftover width evenly beyond that floor, same visual result as a plain flex: 1
471
509
  // on a roomy screen, but a button can never be squeezed narrower than 128, only wrap to its own
@@ -508,46 +546,63 @@ var overlayActionStyles = import_react_native7.StyleSheet.create({
508
546
  });
509
547
 
510
548
  // src/OverlaySurface.tsx
511
- var import_auto_paper6 = require("@rific/auto-paper");
512
- var import_react_native8 = require("react-native");
513
- var import_jsx_runtime7 = require("react/jsx-runtime");
549
+ var import_auto_paper7 = require("@rific/auto-paper");
550
+ var import_react_native9 = require("react-native");
551
+ var import_jsx_runtime8 = require("react/jsx-runtime");
514
552
  function useOverlayCardColors() {
515
- const { colors } = (0, import_auto_paper6.useAutoPaperTheme)();
553
+ const { colors } = (0, import_auto_paper7.useAutoPaperTheme)();
516
554
  return { fg: colors.onSurface, fgMuted: colors.onSurfaceVariant, cardBorder: colors.outlineVariant, backdrop: colors.backdrop };
517
555
  }
518
- function OverlayBackdrop({ children, style }) {
556
+ function OverlayBackdrop({ children, style, onLayout }) {
519
557
  const { backdrop } = useOverlayCardColors();
520
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.View, { style: [overlayStyles.overlay, { backgroundColor: backdrop }, style], children });
558
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, { onLayout, style: [overlayStyles.overlay, { backgroundColor: backdrop }, style], children });
521
559
  }
522
560
  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 });
561
+ const { isV3, roundness } = (0, import_auto_paper7.useAutoPaperTheme)();
562
+ const blur = (0, import_auto_paper7.useBlur)();
563
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_auto_paper7.BlurView, { blur, style: [overlayStyles.card, styles7.card, { borderRadius: (isV3 ? 7 : 1) * roundness }, style], ...rest, children });
526
564
  }
527
- var styles6 = import_react_native8.StyleSheet.create({
565
+ var styles7 = import_react_native9.StyleSheet.create({
528
566
  card: { overflow: "hidden" }
529
567
  });
530
568
 
569
+ // src/useCompactDialog.ts
570
+ var import_core = require("@tastic/core");
571
+ var import_react2 = require("react");
572
+ var import_react_native10 = require("react-native");
573
+ function useCompactDialog(rotation = 0) {
574
+ const window = (0, import_react_native10.useWindowDimensions)();
575
+ const framed = (0, import_core.useRotatedWindowDimensions)();
576
+ const [measured, setMeasured] = (0, import_react2.useState)(null);
577
+ const onLayout = (0, import_react2.useCallback)((e) => {
578
+ const { width, height } = e.nativeEvent.layout;
579
+ setMeasured((prev) => prev && prev.width === width && prev.height === height ? prev : { width, height });
580
+ }, []);
581
+ const box = measured ?? (rotation === 0 ? framed : window);
582
+ const turned = rotation === 90 || rotation === -90;
583
+ return { compact: isCompactDialogHeight(turned ? box.width : box.height), onLayout };
584
+ }
585
+
531
586
  // src/ConfirmDialog.tsx
532
- var import_jsx_runtime8 = require("react/jsx-runtime");
587
+ var import_jsx_runtime9 = require("react/jsx-runtime");
533
588
  function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
534
- const { colors } = (0, import_auto_paper7.useAutoPaperTheme)();
589
+ const { colors } = (0, import_auto_paper8.useAutoPaperTheme)();
535
590
  const { fg } = useOverlayCardColors();
591
+ const { compact, onLayout } = useCompactDialog(rotation);
536
592
  if (!visible) return null;
537
593
  const accent = destructive ? colors.danger : colors.primary;
538
594
  const onAccent = destructive ? colors.onDanger : colors.onPrimary;
539
595
  const showCancel = cancelLabel !== void 0 && onCancel !== void 0;
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 })
596
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper7.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(OverlayBackdrop, { style: styles8.overlay, onLayout, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(OverlayCard, { style: [styles8.card, (0, import_core2.toRotationStyle)(rotation)], children: [
597
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogHeader, { icon, title, color: accent, compact }),
598
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper7.Text, { variant: "bodyLarge", style: [styles8.body, { color: fg }], children: message }),
599
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native11.View, { style: overlayActionStyles.actions, children: [
600
+ showCancel && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press.Button, { mode: "outlined", onPress: onCancel, style: overlayActionStyles.actionButton, children: cancelLabel }),
601
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press.Button, { mode: "contained", onPress: onConfirm, style: showCancel ? overlayActionStyles.actionButton : overlayActionStyles.actionButtonSingle, buttonColor: accent, textColor: onAccent, children: confirmLabel })
547
602
  ] })
548
603
  ] }) }) });
549
604
  }
550
- var styles7 = import_react_native9.StyleSheet.create({
605
+ var styles8 = import_react_native11.StyleSheet.create({
551
606
  body: {
552
607
  textAlign: "center"
553
608
  },
@@ -565,35 +620,28 @@ var styles7 = import_react_native9.StyleSheet.create({
565
620
  // screen narrower than maxWidth's own 360.
566
621
  overlay: {
567
622
  paddingHorizontal: 24
568
- },
569
- // textAlign is load-bearing, not decorative, once `title` wraps to more than one line - centered
570
- // within card's own alignItems: 'center' only centers the Text's block as a whole; each wrapped
571
- // line inside that block still defaults to left-aligned without this.
572
- title: {
573
- fontWeight: "bold",
574
- textAlign: "center"
575
623
  }
576
624
  });
577
625
 
578
626
  // src/RotatedFrame.tsx
579
- var import_core2 = require("@tastic/core");
580
- var import_react2 = require("react");
581
- var import_react_native10 = require("react-native");
582
- var import_react_native_paper7 = require("react-native-paper");
627
+ var import_core3 = require("@tastic/core");
628
+ var import_react3 = require("react");
629
+ var import_react_native12 = require("react-native");
630
+ var import_react_native_paper8 = require("react-native-paper");
583
631
  var import_react_native_safe_area_context = require("react-native-safe-area-context");
584
- var import_jsx_runtime9 = require("react/jsx-runtime");
632
+ var import_jsx_runtime10 = require("react/jsx-runtime");
585
633
  function RotatedFrame({ children, rotation: rotationOverride, rotatedSafeArea = false, portalHost = false, passThrough = false, maxContentWidth }) {
586
- const ambientRotation = (0, import_core2.useRotation)();
634
+ const ambientRotation = (0, import_core3.useRotation)();
587
635
  const rotation = rotationOverride ?? ambientRotation;
588
- const window = (0, import_react_native10.useWindowDimensions)();
589
- const { width, height } = (0, import_core2.rotateDimensions)(window.width, window.height, rotation);
636
+ const window = (0, import_react_native12.useWindowDimensions)();
637
+ const { width, height } = (0, import_core3.rotateDimensions)(window.width, window.height, rotation);
590
638
  const rawInsets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
591
- const insets = (0, import_react2.useMemo)(() => rotatedSafeArea ? (0, import_core2.rotateInsets)(rawInsets, rotation) : rawInsets, [rotatedSafeArea, rawInsets, rotation]);
639
+ const insets = (0, import_react3.useMemo)(() => rotatedSafeArea ? (0, import_core3.rotateInsets)(rawInsets, rotation) : rawInsets, [rotatedSafeArea, rawInsets, rotation]);
592
640
  const cappedWidth = maxContentWidth !== void 0 && width > height ? maxContentWidth : void 0;
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 }) });
641
+ const column = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [styles9.column, cappedWidth !== void 0 && { maxWidth: cappedWidth }], pointerEvents: passThrough ? "box-none" : void 0, children });
642
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_core3.FakeLandscapeView, { rotation, passThrough, style: styles9.root, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_safe_area_context.SafeAreaInsetsContext.Provider, { value: insets, children: portalHost ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Portal.Host, { children: column }) : column }) });
595
643
  }
596
- var styles8 = import_react_native10.StyleSheet.create({
644
+ var styles9 = import_react_native12.StyleSheet.create({
597
645
  // A centred column: full width up to `maxWidth`, so a capped frame sits in the middle of a wider window.
598
646
  column: {
599
647
  alignSelf: "center",
@@ -606,18 +654,18 @@ var styles8 = import_react_native10.StyleSheet.create({
606
654
  });
607
655
 
608
656
  // src/useUpdateConfirmBridge.ts
609
- var import_react3 = require("react");
657
+ var import_react4 = require("react");
610
658
  function useUpdateConfirmBridge() {
611
- const [manifest, setManifest] = (0, import_react3.useState)(null);
612
- const resolveRef = (0, import_react3.useRef)(null);
613
- const onConfirm = (0, import_react3.useCallback)(
659
+ const [manifest, setManifest] = (0, import_react4.useState)(null);
660
+ const resolveRef = (0, import_react4.useRef)(null);
661
+ const onConfirm = (0, import_react4.useCallback)(
614
662
  (next) => new Promise((resolve) => {
615
663
  resolveRef.current = resolve;
616
664
  setManifest(next);
617
665
  }),
618
666
  []
619
667
  );
620
- const respond = (0, import_react3.useCallback)((confirmed) => {
668
+ const respond = (0, import_react4.useCallback)((confirmed) => {
621
669
  setManifest(null);
622
670
  resolveRef.current?.(confirmed);
623
671
  resolveRef.current = null;
@@ -626,22 +674,27 @@ function useUpdateConfirmBridge() {
626
674
  }
627
675
 
628
676
  // src/BaseSettingsDialog.tsx
629
- var import_jsx_runtime10 = require("react/jsx-runtime");
677
+ var import_jsx_runtime11 = require("react/jsx-runtime");
630
678
  function SettingIcon({ source, color, containerColor }) {
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 }) });
679
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: [styles10.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Icon, { source, size: 18, color }) });
632
680
  }
633
- function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, onShowHowToPlay, children }) {
634
- const { colors } = (0, import_auto_paper8.useAutoPaperTheme)();
635
- const ambientRotation = (0, import_core3.useRotation)();
681
+ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, keepAwake, onKeepAwakeChange, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, onShowHowToPlay, children }) {
682
+ const { colors } = (0, import_auto_paper9.useAutoPaperTheme)();
683
+ const ambientRotation = (0, import_core4.useRotation)();
636
684
  const rotation = rotationOverride ?? ambientRotation;
637
- const isTouchPrimary = (0, import_core3.useIsTouchPrimaryDevice)();
685
+ const window = (0, import_react_native13.useWindowDimensions)();
686
+ const turned = rotation === 90 || rotation === -90;
687
+ const compactHeader = isCompactDialogHeight(turned ? window.width : window.height);
688
+ const insets = (0, import_core4.rotateInsets)((0, import_react_native_safe_area_context2.useSafeAreaInsets)(), rotation);
689
+ const sheetWidth = Math.min(overlayStyles.card.maxWidth, (turned ? window.height : window.width) - 2 * Math.max(insets.left, insets.right, SHEET_GUTTER));
690
+ const isTouchPrimary = (0, import_core4.useIsTouchPrimaryDevice)();
638
691
  const { settings: hapticSettings, set: setHapticSettings } = (0, import_feedback_press2.useHapticSettings)();
639
692
  const { settings: soundSettings, set: setSoundSettings } = (0, import_feedback_press2.useSoundSettings)();
640
- const sound = (0, import_react4.useContext)(import_feedback_press2.SoundContext);
693
+ const sound = (0, import_react5.useContext)(import_feedback_press2.SoundContext);
641
694
  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)();
644
- const [infoMessage, setInfoMessage] = (0, import_react4.useState)(null);
695
+ const { settings: themeSettings, set: setThemeSettings } = (0, import_auto_paper9.useThemeSettings)();
696
+ const expoBlur = (0, import_auto_paper9.useBlurModule)();
697
+ const [infoMessage, setInfoMessage] = (0, import_react5.useState)(null);
645
698
  const { manifest: updateManifest, onConfirm: onUpdateConfirm, respond: respondToUpdateConfirm } = useUpdateConfirmBridge();
646
699
  const { check, checking, updateReady } = (0, import_updater.useUpdater)({
647
700
  autoCheck: false,
@@ -651,117 +704,132 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
651
704
  onInfo: (title, message) => setInfoMessage({ title, message })
652
705
  });
653
706
  const updateManifestDate = updateManifest ? new Date(updateManifest.createdAt) : null;
654
- const [opened, setOpened] = (0, import_react4.useState)(visible);
707
+ const [opened, setOpened] = (0, import_react5.useState)(visible);
655
708
  if (visible && !opened) setOpened(true);
656
709
  const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
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;
710
+ const showEdgeGuard = import_react_native13.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
711
+ const showKeepAwake = isTouchPrimary && keepAwake !== void 0 && onKeepAwakeChange !== void 0;
712
+ const showHaptics = import_react_native13.Platform.OS !== "web" && !hideHaptics;
659
713
  const showSound = !hideSound;
660
714
  const showAppearance = !hideAppearance;
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;
715
+ const showBlur = showAppearance && import_react_native13.Platform.OS !== "android" && expoBlur !== void 0 && expoBlur !== null;
716
+ const showUpdateCheck = import_react_native13.Platform.OS !== "web" && !hideUpdateCheck;
663
717
  if (!opened) return null;
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" })
674
- ] })
675
- ] }) }),
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" })
681
- ] })
682
- ] }) }),
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)(
685
- import_feedback_press2.TouchableRipple,
686
- {
687
- soundDisabled: true,
688
- onPress: () => {
689
- const enabled = !soundSettings.enabled;
690
- setSoundSettings({ enabled });
691
- if (enabled) sound.selection?.();
692
- },
693
- style: styles9.toggleButtonInRow,
694
- accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
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" })
698
- ] })
699
- }
700
- ),
701
- showHaptics && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
718
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
719
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_auto_paper9.Dialog, { visible, onDismiss, style: [styles10.dialog, { width: sheetWidth }], children: [
720
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_auto_paper9.Dialog.ScrollArea, { style: styles10.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_auto_paper9.FadingScrollView, { contentContainerStyle: styles10.scrollContent, showsVerticalScrollIndicator: false, children: [
721
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogHeader, { icon: "cog", title: "Settings", compact: compactHeader }),
722
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.content, children: [
723
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleGroup, children: [
724
+ showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles10.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
725
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.tertiary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant }),
726
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
727
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
728
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pin current layout" })
729
+ ] })
730
+ ] }) }),
731
+ showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles10.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
732
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant }),
733
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
734
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
735
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Require second swipe" })
736
+ ] })
737
+ ] }) }),
738
+ showKeepAwake && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onKeepAwakeChange(!keepAwake), style: styles10.toggleButton, accessibilityLabel: `Keep awake ${keepAwake ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
739
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: keepAwake ? "eye" : "eye-closed", color: keepAwake ? colors.tertiary : colors.onSurfaceVariant, containerColor: keepAwake ? colors.tertiaryContainer : colors.surfaceVariant }),
740
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
741
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Keep Awake" }),
742
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Stop auto-lock mid-match" })
743
+ ] })
744
+ ] }) }),
745
+ (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleRow, children: [
746
+ showSound && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
747
+ import_feedback_press2.TouchableRipple,
748
+ {
749
+ soundDisabled: true,
750
+ onPress: () => {
751
+ const enabled = !soundSettings.enabled;
752
+ setSoundSettings({ enabled });
753
+ if (enabled) sound.selection?.();
754
+ },
755
+ style: styles10.toggleButtonInRow,
756
+ accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
757
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
758
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
759
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
760
+ ] })
761
+ }
762
+ ),
763
+ showHaptics && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
764
+ import_feedback_press2.TouchableRipple,
765
+ {
766
+ hapticDisabled: true,
767
+ onPress: () => {
768
+ const vibrate = !hapticSettings.vibrate;
769
+ setHapticSettings({ vibrate });
770
+ if (vibrate) forceHapticFeedback();
771
+ },
772
+ style: styles10.toggleButtonInRow,
773
+ accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
774
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
775
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
776
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
777
+ ] })
778
+ }
779
+ )
780
+ ] }),
781
+ onShowHowToPlay && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
702
782
  import_feedback_press2.TouchableRipple,
703
783
  {
704
- hapticDisabled: true,
705
784
  onPress: () => {
706
- const vibrate = !hapticSettings.vibrate;
707
- setHapticSettings({ vibrate });
708
- if (vibrate) forceHapticFeedback();
785
+ onDismiss();
786
+ onShowHowToPlay();
709
787
  },
710
- style: styles9.toggleButtonInRow,
711
- accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
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" })
788
+ style: styles10.toggleButton,
789
+ accessibilityLabel: "How to Play",
790
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
791
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: "help-circle-outline", color: colors.secondary, containerColor: colors.secondaryContainer }),
792
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
793
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "How to Play" }),
794
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Replay quick intro" })
795
+ ] })
715
796
  ] })
716
797
  }
717
798
  )
718
799
  ] }),
719
- onShowHowToPlay && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
720
- import_feedback_press2.TouchableRipple,
721
- {
722
- onPress: () => {
723
- onDismiss();
724
- onShowHowToPlay();
725
- },
726
- style: styles9.toggleButton,
727
- accessibilityLabel: "How to Play",
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" })
733
- ] })
800
+ showAppearance && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.section, children: [
801
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles10.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
802
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_auto_paper9.AutoAppearancePicker, { showLabels: false }),
803
+ showBlur && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => setThemeSettings({ blur: !themeSettings.blur }), style: styles10.toggleButton, accessibilityLabel: `Blur ${themeSettings.blur ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
804
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: themeSettings.blur ? "blur" : "blur-off", color: themeSettings.blur ? colors.tertiary : colors.onSurfaceVariant, containerColor: themeSettings.blur ? colors.tertiaryContainer : colors.surfaceVariant }),
805
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
806
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Blur" }),
807
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Frost behind dialogs" })
734
808
  ] })
735
- }
736
- )
737
- ] }),
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
- ] }) })
745
- ] }),
746
- 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: [
749
- "VERSION ",
750
- version,
751
- updateReady ? " \xB7 UPDATE READY" : ""
809
+ ] }) })
752
810
  ] }),
753
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
811
+ children,
812
+ showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.section, children: [
813
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles10.sectionLabel, { color: colors.onSurfaceVariant }], children: [
814
+ "VERSION ",
815
+ version,
816
+ updateReady ? " \xB7 UPDATE READY" : ""
817
+ ] }),
818
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
819
+ ] })
754
820
  ] })
755
- ] }) })
821
+ ] }) }),
822
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: [overlayActionStyles.actions, styles10.footer], children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: onDismiss, style: overlayActionStyles.actionButtonSingle, buttonColor: colors.primary, textColor: colors.onPrimary, children: "Done" }) })
756
823
  ] }),
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) })
824
+ /* @__PURE__ */ (0, import_jsx_runtime11.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) }),
825
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ConfirmDialog, { visible: !!infoMessage, title: infoMessage?.title ?? "", message: infoMessage?.message ?? "", confirmLabel: "OK", icon: "information-outline", rotation: 0, onConfirm: () => setInfoMessage(null) })
759
826
  ] }) });
760
827
  }
761
- var styles9 = import_react_native11.StyleSheet.create({
828
+ var SHEET_GUTTER = 24;
829
+ var styles10 = import_react_native13.StyleSheet.create({
830
+ // The rows' sections, 24pt apart.
762
831
  content: {
763
- gap: 24,
764
- paddingVertical: 20
832
+ gap: 24
765
833
  },
766
834
  // Caps the card so it never grows past the screen - without this the dialog just keeps
767
835
  // growing to fit its content and the overflow gets clipped by the screen edge, which is
@@ -773,6 +841,11 @@ var styles9 = import_react_native11.StyleSheet.create({
773
841
  flexShrink: {
774
842
  flexShrink: 1
775
843
  },
844
+ // The overlay cards' 24pt padding, as the sheet's own insets (its scroll area pads 24 sideways).
845
+ footer: {
846
+ paddingBottom: 24,
847
+ paddingHorizontal: 24
848
+ },
776
849
  iconBadge: {
777
850
  alignItems: "center",
778
851
  borderRadius: 10,
@@ -780,9 +853,20 @@ var styles9 = import_react_native11.StyleSheet.create({
780
853
  justifyContent: "center",
781
854
  width: 36
782
855
  },
856
+ // No hairline dividers above and below the scroll area (Paper's MD2-era borders): none of the
857
+ // fleet's other dialogs draws one, so the sheet matches them (Jay, 2026-10-15).
783
858
  scrollArea: {
859
+ borderBottomWidth: 0,
860
+ borderTopWidth: 0,
784
861
  marginBottom: 0
785
862
  },
863
+ // The header and the rows scroll together: the card's 24pt inset above the header, the overlay
864
+ // cards' 16pt gap between it and the rows, and 16pt below the last row before the Done row.
865
+ scrollContent: {
866
+ gap: 16,
867
+ paddingBottom: 16,
868
+ paddingTop: 24
869
+ },
786
870
  section: {
787
871
  gap: 12
788
872
  },
@@ -826,31 +910,31 @@ var styles9 = import_react_native11.StyleSheet.create({
826
910
  });
827
911
 
828
912
  // src/BaseStatsScreen.tsx
829
- var import_auto_paper9 = require("@rific/auto-paper");
913
+ var import_auto_paper10 = require("@rific/auto-paper");
830
914
  var import_feedback_press3 = require("@rific/feedback-press");
831
- var import_core4 = require("@tastic/core");
832
- var import_react5 = require("react");
833
- var import_react_native12 = require("react-native");
834
- var import_react_native_paper9 = require("react-native-paper");
835
- var import_jsx_runtime11 = require("react/jsx-runtime");
915
+ var import_core5 = require("@tastic/core");
916
+ var import_react6 = require("react");
917
+ var import_react_native14 = require("react-native");
918
+ var import_react_native_paper10 = require("react-native-paper");
919
+ var import_jsx_runtime12 = require("react/jsx-runtime");
836
920
  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 }) {
837
- const { dark, colors } = (0, import_auto_paper9.useAutoPaperTheme)();
838
- const ambientRotation = (0, import_core4.useRotation)();
921
+ const { dark, colors } = (0, import_auto_paper10.useAutoPaperTheme)();
922
+ const ambientRotation = (0, import_core5.useRotation)();
839
923
  const rotation = rotationOverride ?? ambientRotation;
840
- const [confirmResetVisible, setConfirmResetVisible] = (0, import_react5.useState)(false);
924
+ const [confirmResetVisible, setConfirmResetVisible] = (0, import_react6.useState)(false);
841
925
  const showReset = !!onReset;
842
926
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
843
927
  const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
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 })
928
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: [styles11.container, { backgroundColor: bg }], children: [
929
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: [styles11.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
930
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
931
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper10.Text, { variant: titleVariant, style: [styles11.title, { color: fg }], children: title })
848
932
  ] }),
849
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native12.ScrollView, { style: styles10.scrollView, contentContainerStyle: [styles10.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
933
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.ScrollView, { style: styles11.scrollView, contentContainerStyle: [styles11.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
850
934
  children,
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 })
935
+ showReset && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles11.resetButton, children: resetLabel })
852
936
  ] }),
853
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
937
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
854
938
  ConfirmDialog,
855
939
  {
856
940
  visible: confirmResetVisible,
@@ -870,7 +954,7 @@ function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", t
870
954
  )
871
955
  ] });
872
956
  }
873
- var styles10 = import_react_native12.StyleSheet.create({
957
+ var styles11 = import_react_native14.StyleSheet.create({
874
958
  container: {
875
959
  flex: 1
876
960
  },
@@ -901,19 +985,19 @@ var styles10 = import_react_native12.StyleSheet.create({
901
985
  });
902
986
 
903
987
  // src/ContentGutter.tsx
904
- var import_core5 = require("@tastic/core");
905
- var import_react_native13 = require("react-native");
906
- var import_jsx_runtime12 = require("react/jsx-runtime");
988
+ var import_core6 = require("@tastic/core");
989
+ var import_react_native15 = require("react-native");
990
+ var import_jsx_runtime13 = require("react/jsx-runtime");
907
991
  function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
908
- const { width: windowWidth } = (0, import_core5.useRotatedWindowDimensions)();
909
- const { contentWidth, gutterWidth } = (0, import_core5.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
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 })
992
+ const { width: windowWidth } = (0, import_core6.useRotatedWindowDimensions)();
993
+ const { contentWidth, gutterWidth } = (0, import_core6.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
994
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native15.View, { style: [styles12.row, style], children: [
995
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: [styles12.gutter, { width: gutterWidth }], children: leftGutter }),
996
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: { width: contentWidth }, children }),
997
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: [styles12.gutter, { width: gutterWidth }], children: rightGutter })
914
998
  ] });
915
999
  }
916
- var styles11 = import_react_native13.StyleSheet.create({
1000
+ var styles12 = import_react_native15.StyleSheet.create({
917
1001
  // overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
918
1002
  // column instead of clipping cleanly at its own real width.
919
1003
  gutter: {
@@ -925,41 +1009,41 @@ var styles11 = import_react_native13.StyleSheet.create({
925
1009
  });
926
1010
 
927
1011
  // src/ControlSchemePicker.tsx
928
- var import_core8 = require("@tastic/core");
929
- var import_react_native18 = require("react-native");
1012
+ var import_core9 = require("@tastic/core");
1013
+ var import_react_native20 = require("react-native");
930
1014
 
931
1015
  // src/SectionedDropdown.tsx
932
- var import_auto_paper10 = require("@rific/auto-paper");
1016
+ var import_auto_paper11 = require("@rific/auto-paper");
933
1017
  var import_feedback_press4 = require("@rific/feedback-press");
934
- var import_core7 = require("@tastic/core");
935
- var import_react_native17 = require("react-native");
936
- var import_react_native_paper10 = require("react-native-paper");
1018
+ var import_core8 = require("@tastic/core");
1019
+ var import_react_native19 = require("react-native");
1020
+ var import_react_native_paper11 = require("react-native-paper");
937
1021
 
938
1022
  // src/PopoverBody.tsx
939
- var import_react_native14 = require("react-native");
940
- var import_jsx_runtime13 = require("react/jsx-runtime");
1023
+ var import_react_native16 = require("react-native");
1024
+ var import_jsx_runtime14 = require("react/jsx-runtime");
941
1025
  var CARET_SIZE = 7;
942
1026
  var CARET_RING_OFFSET = 2;
943
1027
  var CARET_DIP = 1;
944
1028
  function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
945
1029
  if (!visible) return null;
946
1030
  const above = verticalAlign === "above";
947
- const alignStyle = align === "left" ? styles12.contentLeft : align === "right" ? styles12.contentRight : styles12.contentCenter;
948
- const verticalStyle = above ? styles12.contentAbove : styles12.contentBelow;
1031
+ const alignStyle = align === "left" ? styles13.contentLeft : align === "right" ? styles13.contentRight : styles13.contentCenter;
1032
+ const verticalStyle = above ? styles13.contentAbove : styles13.contentBelow;
949
1033
  const ringSize = CARET_SIZE + caretBorderWidth;
950
1034
  const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
951
1035
  const caretFill = above ? "borderTopColor" : "borderBottomColor";
952
1036
  const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
953
1037
  const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
954
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: [styles12.content, alignStyle, verticalStyle], children: [
1038
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native16.View, { style: [styles13.content, alignStyle, verticalStyle], children: [
955
1039
  children,
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 }] })
1040
+ caretColor && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1041
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
1042
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
959
1043
  ] })
960
1044
  ] });
961
1045
  }
962
- var styles12 = import_react_native14.StyleSheet.create({
1046
+ var styles13 = import_react_native16.StyleSheet.create({
963
1047
  caret: {
964
1048
  borderLeftColor: "transparent",
965
1049
  borderRightColor: "transparent",
@@ -1002,11 +1086,11 @@ var styles12 = import_react_native14.StyleSheet.create({
1002
1086
  });
1003
1087
 
1004
1088
  // src/SkiaGate.tsx
1005
- var import_react6 = require("react");
1006
- var import_jsx_runtime14 = require("react/jsx-runtime");
1089
+ var import_react7 = require("react");
1090
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1007
1091
  function SkiaGate({ getComponent, componentProps, fallback = null }) {
1008
- const [Component, setComponent] = (0, import_react6.useState)(null);
1009
- (0, import_react6.useEffect)(() => {
1092
+ const [Component, setComponent] = (0, import_react7.useState)(null);
1093
+ (0, import_react7.useEffect)(() => {
1010
1094
  let cancelled = false;
1011
1095
  getComponent().then((mod) => {
1012
1096
  if (!cancelled) setComponent(() => mod.default);
@@ -1016,19 +1100,19 @@ function SkiaGate({ getComponent, componentProps, fallback = null }) {
1016
1100
  };
1017
1101
  }, [getComponent]);
1018
1102
  if (!Component) return fallback;
1019
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Component, { ...componentProps });
1103
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Component, { ...componentProps });
1020
1104
  }
1021
1105
 
1022
1106
  // src/TriggerGaugeHost.tsx
1023
- var import_jsx_runtime16 = require("react/jsx-runtime");
1107
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1024
1108
  var getTriggerGauge = () => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((mod) => ({ default: mod.TriggerGauge }));
1025
1109
  function TriggerGaugeHost(props) {
1026
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
1110
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
1027
1111
  }
1028
1112
 
1029
1113
  // src/useAutoAlign.ts
1030
- var import_react8 = require("react");
1031
- var import_react_native16 = require("react-native");
1114
+ var import_react9 = require("react");
1115
+ var import_react_native18 = require("react-native");
1032
1116
  var EDGE_MARGIN = 12;
1033
1117
  function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
1034
1118
  if (rotation === 0) return { x, y, width, height };
@@ -1040,18 +1124,18 @@ function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
1040
1124
  return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
1041
1125
  }
1042
1126
  function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
1043
- const triggerRef = (0, import_react8.useRef)(null);
1044
- const { width: windowWidth, height: windowHeight } = (0, import_react_native16.useWindowDimensions)();
1045
- const [align, setAlign] = (0, import_react8.useState)("center");
1046
- const [verticalAlign, setVerticalAlign] = (0, import_react8.useState)("below");
1047
- const [maxHeight, setMaxHeight] = (0, import_react8.useState)(contentHeight);
1048
- const [measured, setMeasured] = (0, import_react8.useState)(false);
1049
- const [prevOpen, setPrevOpen] = (0, import_react8.useState)(open);
1127
+ const triggerRef = (0, import_react9.useRef)(null);
1128
+ const { width: windowWidth, height: windowHeight } = (0, import_react_native18.useWindowDimensions)();
1129
+ const [align, setAlign] = (0, import_react9.useState)("center");
1130
+ const [verticalAlign, setVerticalAlign] = (0, import_react9.useState)("below");
1131
+ const [maxHeight, setMaxHeight] = (0, import_react9.useState)(contentHeight);
1132
+ const [measured, setMeasured] = (0, import_react9.useState)(false);
1133
+ const [prevOpen, setPrevOpen] = (0, import_react9.useState)(open);
1050
1134
  if (open !== prevOpen) {
1051
1135
  setPrevOpen(open);
1052
1136
  if (open) setMeasured(false);
1053
1137
  }
1054
- const measure = (0, import_react8.useCallback)(() => {
1138
+ const measure = (0, import_react9.useCallback)(() => {
1055
1139
  triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
1056
1140
  const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
1057
1141
  const centerX = x + triggerWidth / 2;
@@ -1068,14 +1152,14 @@ function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
1068
1152
  setMeasured(true);
1069
1153
  });
1070
1154
  }, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
1071
- (0, import_react8.useEffect)(() => {
1155
+ (0, import_react9.useEffect)(() => {
1072
1156
  if (open) measure();
1073
1157
  }, [open, measure]);
1074
1158
  return { align, maxHeight, measured, triggerRef, verticalAlign };
1075
1159
  }
1076
1160
 
1077
1161
  // src/SectionedDropdown.tsx
1078
- var import_jsx_runtime17 = require("react/jsx-runtime");
1162
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1079
1163
  var MENU_BORDER_WIDTH = 1;
1080
1164
  var TRIGGER_SIZE = 44;
1081
1165
  var MENU_MIN_WIDTH = 200;
@@ -1087,11 +1171,11 @@ var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
1087
1171
  var MENU_DIVIDER_HEIGHT = 9;
1088
1172
  var MENU_VERTICAL_PADDING = 12;
1089
1173
  function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
1090
- const ambientRotation = (0, import_core7.useRotation)();
1174
+ const ambientRotation = (0, import_core8.useRotation)();
1091
1175
  const rotation = rotationOverride ?? ambientRotation;
1092
1176
  const menuBg = dark ? "#000000" : "#FFFFFF";
1093
- const menuBorderColor = (0, import_auto_paper10.getBlendedColor)(mutedColor, menuBg, 0.5);
1094
- const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper10.getColorRoles)(accentColor, menuBg).onColor;
1177
+ const menuBorderColor = (0, import_auto_paper11.getBlendedColor)(mutedColor, menuBg, 0.5);
1178
+ const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper11.getColorRoles)(accentColor, menuBg).onColor;
1095
1179
  const fg = dark ? "#FFFFFF" : "#000000";
1096
1180
  const open = host.openId === id;
1097
1181
  const estimatedHeight = MENU_VERTICAL_PADDING + sections.reduce((sum, section, sectionIndex) => {
@@ -1125,17 +1209,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1125
1209
  }
1126
1210
  gaugeOffset += section.options.length;
1127
1211
  }
1128
- const anchorStyle = [styles14.anchor, open && styles14.anchorOpen];
1212
+ const anchorStyle = [styles15.anchor, open && styles15.anchorOpen];
1129
1213
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
1130
1214
  const dividerStyle = { backgroundColor: menuBorderColor };
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) })
1215
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: anchorStyle, children: [
1216
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { ref: triggerRef, collapsable: false, style: styles15.triggerBox, children: [
1217
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1218
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
1135
1219
  ] }),
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)(
1220
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native19.ScrollView, { style: [styles15.menu, menuStyle], contentContainerStyle: styles15.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { children: [
1221
+ sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native19.View, { style: [styles15.divider, dividerStyle] }),
1222
+ section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1139
1223
  SingleSection,
1140
1224
  {
1141
1225
  section,
@@ -1148,7 +1232,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1148
1232
  if (autoDismiss) host.close();
1149
1233
  }
1150
1234
  }
1151
- ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1235
+ ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1152
1236
  ] }, section.id)) }) })
1153
1237
  ] });
1154
1238
  }
@@ -1160,18 +1244,18 @@ function SingleSection({
1160
1244
  labelFontFamily,
1161
1245
  onSelect
1162
1246
  }) {
1163
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: section.options.map((option) => {
1247
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: section.options.map((option) => {
1164
1248
  const selected = option.value === section.value;
1165
1249
  const taken = !selected && option.value === section.takenValue;
1166
1250
  const rowColor = selected ? onAccentColor : mutedColor;
1167
- const itemStyle = [styles14.item, selected && { backgroundColor: accentColor }, taken && styles14.itemTaken];
1251
+ const itemStyle = [styles15.item, selected && { backgroundColor: accentColor }, taken && styles15.itemTaken];
1168
1252
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1169
1253
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
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 })
1254
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles15.itemRow, children: [
1255
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1256
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles15.itemLabelColumn, children: [
1257
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1258
+ option.description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
1175
1259
  ] })
1176
1260
  ] }) }, option.value);
1177
1261
  }) });
@@ -1185,23 +1269,23 @@ function MultiSection({
1185
1269
  allClearLabels
1186
1270
  }) {
1187
1271
  const allSelected = section.value.length === section.options.length;
1188
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1272
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
1189
1273
  section.options.map((option, i) => {
1190
1274
  const selected = section.value.includes(option.value);
1191
1275
  const rowColor = selected ? onAccentColor : mutedColor;
1192
1276
  const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
1193
1277
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
1194
- const itemStyle = [styles14.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
1278
+ const itemStyle = [styles15.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
1195
1279
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
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 })
1280
+ return /* @__PURE__ */ (0, import_jsx_runtime18.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_runtime18.jsxs)(import_react_native19.View, { style: styles15.itemRow, children: [
1281
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1282
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: [styles15.itemLabelFlex, labelStyle], children: option.label })
1199
1283
  ] }) }, option.value);
1200
1284
  }),
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 }) })
1285
+ section.allClear && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles15.item, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: [styles15.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
1202
1286
  ] });
1203
1287
  }
1204
- var styles14 = import_react_native17.StyleSheet.create({
1288
+ var styles15 = import_react_native19.StyleSheet.create({
1205
1289
  allClearLabel: {
1206
1290
  fontWeight: "bold",
1207
1291
  textAlign: "center"
@@ -1218,7 +1302,7 @@ var styles14 = import_react_native17.StyleSheet.create({
1218
1302
  zIndex: 100
1219
1303
  },
1220
1304
  divider: {
1221
- height: import_react_native17.StyleSheet.hairlineWidth,
1305
+ height: import_react_native19.StyleSheet.hairlineWidth,
1222
1306
  marginVertical: 4
1223
1307
  },
1224
1308
  item: {
@@ -1271,24 +1355,24 @@ var styles14 = import_react_native17.StyleSheet.create({
1271
1355
  });
1272
1356
 
1273
1357
  // src/ControlSchemePicker.tsx
1274
- var import_jsx_runtime18 = require("react/jsx-runtime");
1358
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1275
1359
  function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily }) {
1276
- const isTouchPrimary = (0, import_core8.useIsTouchPrimaryDevice)();
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 });
1360
+ const isTouchPrimary = (0, import_core9.useIsTouchPrimaryDevice)();
1361
+ if (import_react_native20.Platform.OS !== "web" || isTouchPrimary) return null;
1362
+ return /* @__PURE__ */ (0, import_jsx_runtime19.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 });
1279
1363
  }
1280
1364
 
1281
1365
  // src/CornerActionButtons.tsx
1282
1366
  var import_feedback_press5 = require("@rific/feedback-press");
1283
- var import_react_native19 = require("react-native");
1284
- var import_jsx_runtime19 = require("react/jsx-runtime");
1367
+ var import_react_native21 = require("react-native");
1368
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1285
1369
  function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back", hitSlop }) {
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" })
1370
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
1371
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_feedback_press5.IconButton, { icon: backIcon, iconColor: fg, size: 24, style: [styles16.back, { top: 8 + insets.top, left: 8 + insets.left }], hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
1372
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_feedback_press5.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles16.topRight, { top: 8 + insets.top, right: 8 + insets.right }], hitSlop, onPress: onSettings, accessibilityLabel: "Settings" })
1289
1373
  ] });
1290
1374
  }
1291
- var styles15 = import_react_native19.StyleSheet.create({
1375
+ var styles16 = import_react_native21.StyleSheet.create({
1292
1376
  back: {
1293
1377
  position: "absolute"
1294
1378
  },
@@ -1298,22 +1382,22 @@ var styles15 = import_react_native19.StyleSheet.create({
1298
1382
  });
1299
1383
 
1300
1384
  // src/CornerStatusBadges.tsx
1301
- var import_react_native20 = require("react-native");
1302
- var import_react_native_paper11 = require("react-native-paper");
1303
- var import_jsx_runtime20 = require("react/jsx-runtime");
1385
+ var import_react_native22 = require("react-native");
1386
+ var import_react_native_paper12 = require("react-native-paper");
1387
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1304
1388
  var BADGE_SIZE = 30;
1305
1389
  function StatusBadge({ icon }) {
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)" }) });
1390
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native22.View, { style: styles17.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper12.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
1307
1391
  }
1308
1392
  function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
1309
1393
  const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
1310
1394
  const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
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 }) })
1395
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
1396
+ p1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native22.View, { pointerEvents: "none", style: p1OnRightSide ? styles17.bottomRight : styles17.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { icon: p1.icon }) }),
1397
+ p2 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native22.View, { pointerEvents: "none", style: p2OnLeftSide ? styles17.topLeft : styles17.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { icon: p2.icon }) })
1314
1398
  ] });
1315
1399
  }
1316
- var styles16 = import_react_native20.StyleSheet.create({
1400
+ var styles17 = import_react_native22.StyleSheet.create({
1317
1401
  badge: {
1318
1402
  alignItems: "center",
1319
1403
  backgroundColor: "rgba(0,0,0,0.28)",
@@ -1332,12 +1416,12 @@ var styles16 = import_react_native20.StyleSheet.create({
1332
1416
  });
1333
1417
 
1334
1418
  // src/InlineColorPicker.tsx
1335
- var import_auto_paper11 = require("@rific/auto-paper");
1419
+ var import_auto_paper12 = require("@rific/auto-paper");
1336
1420
  var import_feedback_press6 = require("@rific/feedback-press");
1337
- var import_core9 = require("@tastic/core");
1338
- var import_react_native21 = require("react-native");
1339
- var import_react_native_paper12 = require("react-native-paper");
1340
- var import_jsx_runtime21 = require("react/jsx-runtime");
1421
+ var import_core10 = require("@tastic/core");
1422
+ var import_react_native23 = require("react-native");
1423
+ var import_react_native_paper13 = require("react-native-paper");
1424
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1341
1425
  var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
1342
1426
  var DEFAULT_SIZE = 48;
1343
1427
  var SWATCH_SIZE = 28;
@@ -1351,18 +1435,18 @@ function widthForColumns(columns) {
1351
1435
  return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
1352
1436
  }
1353
1437
  function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
1354
- const autoColumns = (0, import_core9.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
1438
+ const autoColumns = (0, import_core10.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
1355
1439
  const resolvedColumns = columns ?? autoColumns;
1356
1440
  const width = widthForColumns(resolvedColumns);
1357
1441
  const rows = Math.ceil(swatchCount / resolvedColumns);
1358
1442
  const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
1359
1443
  return { width, height };
1360
1444
  }
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 }) {
1362
- const ambientRotation = (0, import_core9.useRotation)();
1445
+ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper12.defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
1446
+ const ambientRotation = (0, import_core10.useRotation)();
1363
1447
  const rotation = rotationOverride ?? ambientRotation;
1364
1448
  const menuBg = dark ? "#000000" : "#FFFFFF";
1365
- const { width: windowWidth } = (0, import_react_native21.useWindowDimensions)();
1449
+ const { width: windowWidth } = (0, import_react_native23.useWindowDimensions)();
1366
1450
  const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
1367
1451
  const open = host.openId === id;
1368
1452
  const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
@@ -1371,16 +1455,16 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1371
1455
  const align = forcedAlign ?? placement.align;
1372
1456
  const displayFor = previewValue ?? ((hex) => hex);
1373
1457
  const displayValue = displayFor(value);
1374
- const contrastColor = (0, import_auto_paper11.getContrastColor)(displayValue);
1458
+ const contrastColor = (0, import_auto_paper12.getContrastColor)(displayValue);
1375
1459
  const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
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) => {
1460
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native23.View, { style: [styles18.anchor, open && styles18.anchorOpen], children: [
1461
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles18.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native23.View, { ref: triggerRef, collapsable: false, style: styles18.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Text, { style: [styles18.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
1462
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native23.ScrollView, { style: [styles18.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles18.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
1379
1463
  const selected = swatch.value.toLowerCase() === value.toLowerCase();
1380
1464
  const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
1381
1465
  const swappable = taken && allowSwapTaken;
1382
1466
  const swatchDisplay = displayFor(swatch.value);
1383
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1467
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1384
1468
  import_feedback_press6.TouchableRipple,
1385
1469
  {
1386
1470
  disabled: taken && !swappable,
@@ -1389,15 +1473,15 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1389
1473
  if (autoDismiss) host.close();
1390
1474
  },
1391
1475
  borderless: true,
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, {})
1476
+ style: [styles18.swatch, { backgroundColor: swatchDisplay }, selected && styles18.swatchSelected, taken && !swappable && styles18.swatchTaken],
1477
+ children: selected ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: "check", size: 16, color: (0, import_auto_paper12.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper12.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: "close", size: 16, color: (0, import_auto_paper12.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native23.View, {})
1394
1478
  },
1395
1479
  swatch.value
1396
1480
  );
1397
1481
  }) }) })
1398
1482
  ] });
1399
1483
  }
1400
- var styles17 = import_react_native21.StyleSheet.create({
1484
+ var styles18 = import_react_native23.StyleSheet.create({
1401
1485
  anchor: {
1402
1486
  position: "relative"
1403
1487
  },
@@ -1469,11 +1553,11 @@ var styles17 = import_react_native21.StyleSheet.create({
1469
1553
  });
1470
1554
 
1471
1555
  // src/LabeledDropdown.tsx
1472
- var import_auto_paper12 = require("@rific/auto-paper");
1556
+ var import_auto_paper13 = require("@rific/auto-paper");
1473
1557
  var import_feedback_press7 = require("@rific/feedback-press");
1474
- var import_react_native22 = require("react-native");
1475
- var import_react_native_paper13 = require("react-native-paper");
1476
- var import_jsx_runtime22 = require("react/jsx-runtime");
1558
+ var import_react_native24 = require("react-native");
1559
+ var import_react_native_paper14 = require("react-native-paper");
1560
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1477
1561
  var TRIGGER_HEIGHT = 28;
1478
1562
  var POPOVER_WIDTH = 180;
1479
1563
  var ROW_HEIGHT = 36;
@@ -1496,22 +1580,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
1496
1580
  onChange(option.value);
1497
1581
  host.close();
1498
1582
  };
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 })
1583
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native24.View, { style: [styles19.anchor, open && styles19.anchorOpen], children: [
1584
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles19.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native24.View, { ref: triggerRef, collapsable: false, style: styles19.triggerInner, children: [
1585
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Text, { style: [styles19.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
1586
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Icon, { source: "menu-down", size: 16, color })
1503
1587
  ] }) }),
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) => {
1588
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native24.ScrollView, { style: [styles19.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles19.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
1505
1589
  const isSelected = option.value === value;
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 })
1590
+ const onColor = (0, import_auto_paper13.getContrastColor)(color);
1591
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles19.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native24.View, { style: styles19.rowInner, children: [
1592
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
1593
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Text, { style: [styles19.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
1510
1594
  ] }) }, option.value);
1511
1595
  }) }) })
1512
1596
  ] });
1513
1597
  }
1514
- var styles18 = import_react_native22.StyleSheet.create({
1598
+ var styles19 = import_react_native24.StyleSheet.create({
1515
1599
  anchor: {
1516
1600
  position: "relative"
1517
1601
  },
@@ -1570,21 +1654,21 @@ function loadSkiaWeb() {
1570
1654
 
1571
1655
  // src/PlayerSetupPanel.tsx
1572
1656
  var import_profile2 = require("@tastic/profile");
1573
- var import_react_native24 = require("react-native");
1574
- var import_react_native_paper15 = require("react-native-paper");
1657
+ var import_react_native26 = require("react-native");
1658
+ var import_react_native_paper16 = require("react-native-paper");
1575
1659
 
1576
1660
  // src/ReadyButton.tsx
1577
1661
  var import_feedback_press8 = require("@rific/feedback-press");
1578
- var import_react_native23 = require("react-native");
1579
- var import_react_native_paper14 = require("react-native-paper");
1580
- var import_jsx_runtime23 = require("react/jsx-runtime");
1662
+ var import_react_native25 = require("react-native");
1663
+ var import_react_native_paper15 = require("react-native-paper");
1664
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1581
1665
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
1582
- const readyButtonStyle = [styles19.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
1666
+ const readyButtonStyle = [styles20.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
1583
1667
  const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
1584
1668
  const labelColorStyle = { color: ready ? "#000000" : color };
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?" }) });
1669
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_feedback_press8.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_paper15.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
1586
1670
  }
1587
- var styles19 = import_react_native23.StyleSheet.create({
1671
+ var styles20 = import_react_native25.StyleSheet.create({
1588
1672
  readyButton: {
1589
1673
  alignItems: "center",
1590
1674
  borderRadius: 12,
@@ -1597,18 +1681,18 @@ var styles19 = import_react_native23.StyleSheet.create({
1597
1681
  });
1598
1682
 
1599
1683
  // src/usePopoverHost.ts
1600
- var import_react9 = require("react");
1684
+ var import_react10 = require("react");
1601
1685
  function usePopoverHost() {
1602
- const [openId, setOpenId] = (0, import_react9.useState)(null);
1603
- const toggle = (0, import_react9.useCallback)((id) => {
1686
+ const [openId, setOpenId] = (0, import_react10.useState)(null);
1687
+ const toggle = (0, import_react10.useCallback)((id) => {
1604
1688
  setOpenId((prev) => prev === id ? null : id);
1605
1689
  }, []);
1606
- const close = (0, import_react9.useCallback)(() => setOpenId(null), []);
1690
+ const close = (0, import_react10.useCallback)(() => setOpenId(null), []);
1607
1691
  return { openId, toggle, close };
1608
1692
  }
1609
1693
 
1610
1694
  // src/PlayerSetupPanel.tsx
1611
- var import_jsx_runtime24 = require("react/jsx-runtime");
1695
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1612
1696
  function getColorPopoverId(idPrefix) {
1613
1697
  return `${idPrefix}-color`;
1614
1698
  }
@@ -1623,16 +1707,16 @@ function PlayerSetupPanel({ idPrefix, host, label, labelFontFamily, color, onCol
1623
1707
  const showProfilePicker = isHuman && profiles !== void 0 && !!onProfileSelect;
1624
1708
  const showCpuDifficulty = !isHuman && cpuDifficulty !== void 0 && cpuDifficultyOptions !== void 0 && !!onCpuDifficultyChange;
1625
1709
  const selectedProfile = profiles?.find((p) => p.id === selectedProfileId) ?? null;
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 }),
1710
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native26.View, { style: [styles21.panel, ownPopoverOpen && styles21.panelOpen], children: [
1711
+ showProfilePicker ? /* @__PURE__ */ (0, import_jsx_runtime25.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_runtime25.jsx)(LabeledDropdown, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, alignOverride: cpuDifficultyAlignOverride }) : label && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native_paper16.Text, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
1712
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native26.View, { style: [styles21.pickerRow, pickerRowPopoverOpen && styles21.pickerRowOpen], children: [
1713
+ /* @__PURE__ */ (0, import_jsx_runtime25.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 }),
1630
1714
  secondPicker
1631
1715
  ] }),
1632
- isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ReadyButton, { color, ready: ready ?? false, onToggleReady })
1716
+ isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReadyButton, { color, ready: ready ?? false, onToggleReady })
1633
1717
  ] });
1634
1718
  }
1635
- var styles20 = import_react_native24.StyleSheet.create({
1719
+ var styles21 = import_react_native26.StyleSheet.create({
1636
1720
  panel: {
1637
1721
  alignItems: "center",
1638
1722
  gap: 12
@@ -1664,29 +1748,29 @@ var styles20 = import_react_native24.StyleSheet.create({
1664
1748
  });
1665
1749
 
1666
1750
  // src/PressAwayOverlay.tsx
1667
- var import_react_native25 = require("react-native");
1668
- var import_jsx_runtime25 = require("react/jsx-runtime");
1751
+ var import_react_native27 = require("react-native");
1752
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1669
1753
  function PressAwayOverlay({ active, onPress, style }) {
1670
1754
  if (!active) return null;
1671
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native25.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native25.StyleSheet.absoluteFill, style] });
1755
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native27.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native27.StyleSheet.absoluteFill, style] });
1672
1756
  }
1673
1757
 
1674
1758
  // src/SharedActionBand.tsx
1675
1759
  var import_feedback_press9 = require("@rific/feedback-press");
1676
- var import_react_native26 = require("react-native");
1677
- var import_jsx_runtime26 = require("react/jsx-runtime");
1760
+ var import_react_native28 = require("react-native");
1761
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1678
1762
  function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
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" })
1763
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_native28.View, { style: [styles22.column, popoverOpen && styles22.columnOpen], children: [
1764
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_native28.View, { style: styles22.actionsRow, children: [
1765
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press9.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1766
+ onRandomize && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press9.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1767
+ onReset && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press9.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
1768
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press9.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
1685
1769
  ] }),
1686
1770
  children
1687
1771
  ] });
1688
1772
  }
1689
- var styles21 = import_react_native26.StyleSheet.create({
1773
+ var styles22 = import_react_native28.StyleSheet.create({
1690
1774
  actionsRow: {
1691
1775
  alignItems: "center",
1692
1776
  flexDirection: "row",
@@ -1702,10 +1786,10 @@ var styles21 = import_react_native26.StyleSheet.create({
1702
1786
  });
1703
1787
 
1704
1788
  // src/StaggeredWord.tsx
1705
- var import_react10 = require("react");
1706
- var import_react_native27 = require("react-native");
1789
+ var import_react11 = require("react");
1790
+ var import_react_native29 = require("react-native");
1707
1791
  var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
1708
- var import_jsx_runtime27 = require("react/jsx-runtime");
1792
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1709
1793
  var STAGGER_MS = 45;
1710
1794
  var LETTER_DURATION_MS = 320;
1711
1795
  function getStaggeredWordDuration(letterCount) {
@@ -1713,7 +1797,7 @@ function getStaggeredWordDuration(letterCount) {
1713
1797
  }
1714
1798
  function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }) {
1715
1799
  const progress = (0, import_react_native_reanimated2.useSharedValue)(reducedMotion ? 1 : 0);
1716
- (0, import_react10.useEffect)(() => {
1800
+ (0, import_react11.useEffect)(() => {
1717
1801
  if (reducedMotion) return;
1718
1802
  progress.value = (0, import_react_native_reanimated2.withDelay)(index * STAGGER_MS, (0, import_react_native_reanimated2.withTiming)(1, { duration: LETTER_DURATION_MS, easing: import_react_native_reanimated2.Easing.out(import_react_native_reanimated2.Easing.back(1.5)) }));
1719
1803
  }, [reducedMotion]);
@@ -1721,12 +1805,12 @@ function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSiz
1721
1805
  opacity: progress.value,
1722
1806
  transform: [{ translateY: (1 - progress.value) * 12 }, { scale: 0.85 + progress.value * 0.15 }]
1723
1807
  }));
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 });
1808
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native_reanimated2.default.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
1725
1809
  }
1726
1810
  function StaggeredWord({ word, color, fontFamily, fontSize, lineHeight, reducedMotion, startIndex = 0, fontWeight = "bold", letterSpacing, style, onLayout }) {
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)) });
1811
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.View, { style: [styles23.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
1728
1812
  }
1729
- var styles22 = import_react_native27.StyleSheet.create({
1813
+ var styles23 = import_react_native29.StyleSheet.create({
1730
1814
  row: {
1731
1815
  flexDirection: "row"
1732
1816
  }
@@ -1734,53 +1818,53 @@ var styles22 = import_react_native27.StyleSheet.create({
1734
1818
 
1735
1819
  // src/UpdateDialog.tsx
1736
1820
  var import_updater2 = require("@rific/updater");
1737
- var import_jsx_runtime28 = require("react/jsx-runtime");
1821
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1738
1822
  function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onError }) {
1739
1823
  const { manifest, onConfirm, respond } = useUpdateConfirmBridge();
1740
1824
  (0, import_updater2.useUpdater)({ autoCheck, autoPrompt, onConfirm, onError });
1741
1825
  const date = manifest ? new Date(manifest.createdAt) : null;
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) });
1826
+ return /* @__PURE__ */ (0, import_jsx_runtime29.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) });
1743
1827
  }
1744
1828
 
1745
1829
  // src/useQuitConfirmation.ts
1746
- var import_react11 = require("react");
1830
+ var import_react12 = require("react");
1747
1831
  function useQuitConfirmation(hasProgress, onConfirmedBack) {
1748
- const [confirmVisible, setConfirmVisible] = (0, import_react11.useState)(false);
1749
- const hasProgressRef = (0, import_react11.useRef)(hasProgress);
1750
- (0, import_react11.useEffect)(() => {
1832
+ const [confirmVisible, setConfirmVisible] = (0, import_react12.useState)(false);
1833
+ const hasProgressRef = (0, import_react12.useRef)(hasProgress);
1834
+ (0, import_react12.useEffect)(() => {
1751
1835
  hasProgressRef.current = hasProgress;
1752
1836
  });
1753
- const onConfirmedBackRef = (0, import_react11.useRef)(onConfirmedBack);
1754
- (0, import_react11.useEffect)(() => {
1837
+ const onConfirmedBackRef = (0, import_react12.useRef)(onConfirmedBack);
1838
+ (0, import_react12.useEffect)(() => {
1755
1839
  onConfirmedBackRef.current = onConfirmedBack;
1756
1840
  });
1757
- const requestBack = (0, import_react11.useCallback)(() => {
1841
+ const requestBack = (0, import_react12.useCallback)(() => {
1758
1842
  if (hasProgressRef.current()) setConfirmVisible(true);
1759
1843
  else onConfirmedBackRef.current();
1760
1844
  }, []);
1761
- const cancelBack = (0, import_react11.useCallback)(() => setConfirmVisible(false), []);
1845
+ const cancelBack = (0, import_react12.useCallback)(() => setConfirmVisible(false), []);
1762
1846
  return { confirmVisible, requestBack, cancelBack };
1763
1847
  }
1764
1848
 
1765
1849
  // src/useZoneClampedAlign.ts
1766
1850
  var import_split_screen = require("@tastic/split-screen");
1767
- var import_react12 = require("react");
1768
- var import_react_native28 = require("react-native");
1769
- var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
1851
+ var import_react13 = require("react");
1852
+ var import_react_native30 = require("react-native");
1853
+ var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
1770
1854
  var EDGE_MARGIN2 = 12;
1771
1855
  function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
1772
1856
  const auto = useAutoAlign(open, contentWidth, contentHeight, rotation);
1773
1857
  const zone = (0, import_split_screen.useZoneBounds)();
1774
- const { height: windowHeight } = (0, import_react_native28.useWindowDimensions)();
1775
- const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
1858
+ const { height: windowHeight } = (0, import_react_native30.useWindowDimensions)();
1859
+ const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
1776
1860
  const shouldMeasure = open && auto.measured && zone !== null;
1777
- const [ownBounds, setOwnBounds] = (0, import_react12.useState)(null);
1778
- const [prevShouldMeasure, setPrevShouldMeasure] = (0, import_react12.useState)(shouldMeasure);
1861
+ const [ownBounds, setOwnBounds] = (0, import_react13.useState)(null);
1862
+ const [prevShouldMeasure, setPrevShouldMeasure] = (0, import_react13.useState)(shouldMeasure);
1779
1863
  if (shouldMeasure !== prevShouldMeasure) {
1780
1864
  setPrevShouldMeasure(shouldMeasure);
1781
1865
  setOwnBounds(null);
1782
1866
  }
1783
- (0, import_react12.useEffect)(() => {
1867
+ (0, import_react13.useEffect)(() => {
1784
1868
  if (!shouldMeasure) return;
1785
1869
  auto.triggerRef.current?.measureInWindow((_x, y, _width, height) => {
1786
1870
  const belowShared = zone.zoneSide === "belowShared";
@@ -1808,11 +1892,13 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
1808
1892
  ActivityStatSection,
1809
1893
  BaseSettingsDialog,
1810
1894
  BaseStatsScreen,
1895
+ COMPACT_DIALOG_HEIGHT,
1811
1896
  ConfirmDialog,
1812
1897
  ContentGutter,
1813
1898
  ControlSchemePicker,
1814
1899
  CornerActionButtons,
1815
1900
  CornerStatusBadges,
1901
+ DialogHeader,
1816
1902
  InlineColorPicker,
1817
1903
  LABELED_DROPDOWN_POPOVER_WIDTH,
1818
1904
  LOCKED_BADGE_COLOR,
@@ -1837,12 +1923,13 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
1837
1923
  getCpuDifficultyPopoverId,
1838
1924
  getInlineColorPickerContentSize,
1839
1925
  getLabeledDropdownContentHeight,
1840
- getOverlayCardColors,
1841
1926
  getStaggeredWordDuration,
1927
+ isCompactDialogHeight,
1842
1928
  loadSkiaWeb,
1843
1929
  overlayActionStyles,
1844
1930
  overlayStyles,
1845
1931
  useAutoAlign,
1932
+ useCompactDialog,
1846
1933
  useOverlayCardColors,
1847
1934
  usePopoverHost,
1848
1935
  useQuitConfirmation,