@tastic/hud 0.4.0 → 0.6.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
@@ -72,7 +72,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
72
72
  if (mountProgress.value < 1) {
73
73
  const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
74
74
  const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
75
- local = (0, import_core3.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
75
+ local = (0, import_core4.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
76
76
  }
77
77
  const sweep = dashAngleDeg * local;
78
78
  if (sweep <= 0) continue;
@@ -96,7 +96,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
96
96
  if (!isLitNow) continue;
97
97
  const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
98
98
  const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
99
- local = (0, import_core3.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
99
+ local = (0, import_core4.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
100
100
  } else if (isLitNow === wasLit) {
101
101
  local = 1;
102
102
  } else if (isLitNow) {
@@ -120,21 +120,21 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
120
120
  height: canvasSize,
121
121
  width: canvasSize
122
122
  };
123
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [styles9.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
124
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
125
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
123
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: [styles10.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
124
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
125
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
126
126
  ] }) });
127
127
  }
128
- var import_react_native_skia, import_core3, import_react4, import_react_native12, import_react_native_reanimated, import_jsx_runtime10, 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, styles9;
128
+ var import_react_native_skia, import_core4, import_react4, import_react_native13, import_react_native_reanimated, import_jsx_runtime11, 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, styles10;
129
129
  var init_TriggerGauge = __esm({
130
130
  "src/TriggerGauge.tsx"() {
131
131
  "use strict";
132
132
  import_react_native_skia = require("@shopify/react-native-skia");
133
- import_core3 = require("@tastic/core");
133
+ import_core4 = require("@tastic/core");
134
134
  import_react4 = require("react");
135
- import_react_native12 = require("react-native");
135
+ import_react_native13 = require("react-native");
136
136
  import_react_native_reanimated = require("react-native-reanimated");
137
- import_jsx_runtime10 = require("react/jsx-runtime");
137
+ import_jsx_runtime11 = require("react/jsx-runtime");
138
138
  UNLIT_THICKNESS = 3;
139
139
  LIT_THICKNESS = 7;
140
140
  DASH_GAP_PX = 9;
@@ -144,7 +144,7 @@ var init_TriggerGauge = __esm({
144
144
  MOUNT_DURATION_MS = 450;
145
145
  MOUNT_STAGGER_MS = 40;
146
146
  SELECTION_TRANSITION_DURATION_MS = 260;
147
- styles9 = import_react_native12.StyleSheet.create({
147
+ styles10 = import_react_native13.StyleSheet.create({
148
148
  container: {
149
149
  alignItems: "center",
150
150
  justifyContent: "center",
@@ -160,6 +160,7 @@ __export(index_exports, {
160
160
  AchievementRow: () => AchievementRow,
161
161
  BaseSettingsDialog: () => BaseSettingsDialog,
162
162
  BaseStatsScreen: () => BaseStatsScreen,
163
+ ContentGutter: () => ContentGutter,
163
164
  CornerActionButtons: () => CornerActionButtons,
164
165
  InlineColorPicker: () => InlineColorPicker,
165
166
  LABELED_DROPDOWN_POPOVER_WIDTH: () => LABELED_DROPDOWN_POPOVER_WIDTH,
@@ -187,11 +188,11 @@ var import_react_native = require("react-native");
187
188
  var import_react_native_paper = require("react-native-paper");
188
189
  var import_jsx_runtime = require("react/jsx-runtime");
189
190
  var LOCKED_BADGE_COLOR = "rgba(128,128,128,0.3)";
190
- function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker }) {
191
+ function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker, fg: fgOverride, fgMuted: fgMutedOverride, sectionBg: sectionBgOverride }) {
191
192
  const { dark } = (0, import_auto_paper.useAutoPaperTheme)();
192
- const fg = dark ? "#FFFFFF" : "#000000";
193
- const fgMuted = dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)";
194
- const sectionBg = dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)";
193
+ const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
194
+ const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
195
+ const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
195
196
  const unlocked = unlockedLabel !== void 0;
196
197
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: [styles.row, { backgroundColor: sectionBg }], children: [
197
198
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.badge, { backgroundColor: badgeColor }], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Icon, { source: icon, size: 20, color: unlocked ? "#000000" : fgMuted }) }),
@@ -415,25 +416,25 @@ var styles2 = import_react_native2.StyleSheet.create({
415
416
  sectionLabel: {
416
417
  letterSpacing: 2
417
418
  },
418
- // Negative margin cancels the padding so the icon still lines up with APPEARANCE/SOUND &
419
- // HAPTICS below, while the ripple/hover highlight itself gets room to breathe on both sides
420
- // instead of a flush edge-to-edge slab. overflow: 'hidden' makes sure that highlight actually
421
- // clips to borderRadius instead of drawing as a plain rectangle.
419
+ // Used to carry marginHorizontal: -12 + paddingHorizontal: 12 (netting to the same inset as
420
+ // APPEARANCE/SOUND & HAPTICS below, while giving the ripple/hover highlight room to breathe
421
+ // into the dialog's own gutter beyond that). Removed: this dialog scrolls (Dialog.ScrollArea +
422
+ // ScrollView above), and on web a ScrollView's own content wrapper clips to its own bounds
423
+ // regardless of a child's negative margin - confirmed live, the icon's own rounded-square badge
424
+ // was getting its left edge sliced off by exactly that overhang. No horizontal inset of its own
425
+ // now - it relies purely on the same dialog padding APPEARANCE/every other row already does,
426
+ // which can never overflow because it's never negative.
422
427
  toggleButton: {
423
428
  borderRadius: 12,
424
- marginHorizontal: -12,
425
429
  overflow: "hidden",
426
- paddingHorizontal: 12,
427
430
  paddingVertical: 10
428
431
  },
429
- // Same shape as toggleButton but `flex: 1` instead of its own `marginHorizontal: -12` two of
430
- // these side by side in toggleRow would otherwise both pull inward and collide in the middle.
431
- // toggleRow carries that edge-alignment margin once, for the row as a whole, instead.
432
+ // Same shape as toggleButton, `flex: 1` instead of its own width - two of these side by side in
433
+ // toggleRow share the row's own edge alignment instead of each carrying their own.
432
434
  toggleButtonInRow: {
433
435
  borderRadius: 12,
434
436
  flex: 1,
435
437
  overflow: "hidden",
436
- paddingHorizontal: 12,
437
438
  paddingVertical: 10
438
439
  },
439
440
  toggleContent: {
@@ -444,10 +445,10 @@ var styles2 = import_react_native2.StyleSheet.create({
444
445
  toggleGroup: {
445
446
  gap: 4
446
447
  },
448
+ // No horizontal margin of its own now either - see toggleButton's identical note.
447
449
  toggleRow: {
448
450
  flexDirection: "row",
449
- gap: 4,
450
- marginHorizontal: -12
451
+ gap: 4
451
452
  }
452
453
  });
453
454
 
@@ -458,26 +459,27 @@ var import_react2 = require("react");
458
459
  var import_react_native3 = require("react-native");
459
460
  var import_react_native_paper3 = require("react-native-paper");
460
461
  var import_jsx_runtime3 = require("react/jsx-runtime");
461
- function BaseStatsScreen({ rotation = 0, title = "Achievements", onBack, insets, onReset, resetLabel = "Reset All Stats", resetConfirmTitle = "Reset Everything?", resetConfirmBody = "This permanently erases all stats and achievements. This cannot be undone.", children }) {
462
+ function BaseStatsScreen({ rotation = 0, title = "Achievements", titleVariant = "headlineSmall", onBack, insets, onReset, resetLabel = "Reset All Stats", resetConfirmTitle = "Reset Everything?", resetConfirmBody = "This permanently erases all stats and achievements. This cannot be undone.", fg: fgOverride, bg: bgOverride, cardBg: cardBgOverride, accentColor: accentColorOverride, children }) {
462
463
  const { dark, colors } = (0, import_auto_paper3.useAutoPaperTheme)();
463
464
  const [confirmResetVisible, setConfirmResetVisible] = (0, import_react2.useState)(false);
464
465
  const showReset = !!onReset;
465
- const fg = dark ? "#FFFFFF" : "#000000";
466
- const bg = dark ? "#000000" : "#FFFFFF";
467
- const cardBg = dark ? "#111111" : "#F2F2F2";
466
+ const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
467
+ const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
468
+ const cardBg = cardBgOverride ?? (dark ? "#111111" : "#F2F2F2");
468
469
  const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
470
+ const accentColor = accentColorOverride ?? colors.secondary;
469
471
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles3.container, { backgroundColor: bg }], children: [
470
472
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles3.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
471
473
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
472
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "displaySmall", style: [styles3.title, { color: fg }], children: title })
474
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: titleVariant, style: [styles3.title, { color: fg }], children: title })
473
475
  ] }),
474
476
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.ScrollView, { style: styles3.scrollView, contentContainerStyle: [styles3.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
475
477
  children,
476
- showReset && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: () => setConfirmResetVisible(true), textColor: colors.secondary, style: styles3.resetButton, children: resetLabel })
478
+ showReset && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.secondary, textColor: colors.onSecondary, style: styles3.resetButton, children: resetLabel })
477
479
  ] }),
478
480
  confirmResetVisible && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles3.overlay, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles3.overlayCard, { backgroundColor: cardBg, borderColor: cardBorder }], children: [
479
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source: "alert-outline", size: 64, color: colors.secondary }),
480
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "headlineLarge", style: [styles3.overlayTitle, { color: colors.secondary }], children: resetConfirmTitle }),
481
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source: "alert-outline", size: 64, color: accentColor }),
482
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "headlineLarge", style: [styles3.overlayTitle, { color: accentColor }], children: resetConfirmTitle }),
481
483
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: [styles3.overlayBody, { color: fg }], children: resetConfirmBody }),
482
484
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: () => setConfirmResetVisible(false), style: styles3.overlayButton, children: "Cancel" }),
483
485
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -551,17 +553,41 @@ var styles3 = import_react_native3.StyleSheet.create({
551
553
  }
552
554
  });
553
555
 
554
- // src/CornerActionButtons.tsx
555
- var import_feedback_press3 = require("@rific/feedback-press");
556
+ // src/ContentGutter.tsx
557
+ var import_core2 = require("@tastic/core");
556
558
  var import_react_native4 = require("react-native");
557
559
  var import_jsx_runtime4 = require("react/jsx-runtime");
558
- function CornerActionButtons({ onBack, onSettings, fg, insets }) {
559
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
560
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, style: [styles4.back, { top: 8 + insets.top, left: 8 + insets.left }], onPress: onBack, accessibilityLabel: "Back" }),
561
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles4.topRight, { top: 8 + insets.top, right: 8 + insets.right }], onPress: onSettings, accessibilityLabel: "Settings" })
560
+ function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
561
+ const { width: windowWidth } = (0, import_react_native4.useWindowDimensions)();
562
+ const { contentWidth, gutterWidth } = (0, import_core2.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
563
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: [styles4.row, style], children: [
564
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: [styles4.gutter, { width: gutterWidth }], children: leftGutter }),
565
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: { width: contentWidth }, children }),
566
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: [styles4.gutter, { width: gutterWidth }], children: rightGutter })
562
567
  ] });
563
568
  }
564
569
  var styles4 = import_react_native4.StyleSheet.create({
570
+ // overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
571
+ // column instead of clipping cleanly at its own real width.
572
+ gutter: {
573
+ overflow: "hidden"
574
+ },
575
+ row: {
576
+ flexDirection: "row"
577
+ }
578
+ });
579
+
580
+ // src/CornerActionButtons.tsx
581
+ var import_feedback_press3 = require("@rific/feedback-press");
582
+ var import_react_native5 = require("react-native");
583
+ var import_jsx_runtime5 = require("react/jsx-runtime");
584
+ function CornerActionButtons({ onBack, onSettings, fg, insets }) {
585
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
586
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, style: [styles5.back, { top: 8 + insets.top, left: 8 + insets.left }], onPress: onBack, accessibilityLabel: "Back" }),
587
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_feedback_press3.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles5.topRight, { top: 8 + insets.top, right: 8 + insets.right }], onPress: onSettings, accessibilityLabel: "Settings" })
588
+ ] });
589
+ }
590
+ var styles5 = import_react_native5.StyleSheet.create({
565
591
  back: {
566
592
  position: "absolute"
567
593
  },
@@ -571,41 +597,41 @@ var styles4 = import_react_native4.StyleSheet.create({
571
597
  });
572
598
 
573
599
  // src/fonts.ts
574
- var import_react_native5 = require("react-native");
575
- var MONO_FONT = import_react_native5.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
600
+ var import_react_native6 = require("react-native");
601
+ var MONO_FONT = import_react_native6.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
576
602
 
577
603
  // src/InlineColorPicker.tsx
578
604
  var import_auto_paper4 = require("@rific/auto-paper");
579
605
  var import_feedback_press4 = require("@rific/feedback-press");
580
- var import_core2 = require("@tastic/core");
581
- var import_react_native8 = require("react-native");
606
+ var import_core3 = require("@tastic/core");
607
+ var import_react_native9 = require("react-native");
582
608
  var import_react_native_paper4 = require("react-native-paper");
583
609
 
584
610
  // src/PopoverBody.tsx
585
- var import_react_native6 = require("react-native");
586
- var import_jsx_runtime5 = require("react/jsx-runtime");
611
+ var import_react_native7 = require("react-native");
612
+ var import_jsx_runtime6 = require("react/jsx-runtime");
587
613
  var CARET_SIZE = 7;
588
614
  var CARET_RING_OFFSET = 2;
589
615
  var CARET_DIP = 1;
590
616
  function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
591
617
  if (!visible) return null;
592
618
  const above = verticalAlign === "above";
593
- const alignStyle = align === "left" ? styles5.contentLeft : align === "right" ? styles5.contentRight : styles5.contentCenter;
594
- const verticalStyle = above ? styles5.contentAbove : styles5.contentBelow;
619
+ const alignStyle = align === "left" ? styles6.contentLeft : align === "right" ? styles6.contentRight : styles6.contentCenter;
620
+ const verticalStyle = above ? styles6.contentAbove : styles6.contentBelow;
595
621
  const ringSize = CARET_SIZE + caretBorderWidth;
596
622
  const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
597
623
  const caretFill = above ? "borderTopColor" : "borderBottomColor";
598
624
  const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
599
625
  const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
600
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native6.View, { style: [styles5.content, alignStyle, verticalStyle], children: [
626
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native7.View, { style: [styles6.content, alignStyle, verticalStyle], children: [
601
627
  children,
602
- caretColor && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
603
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: [styles5.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
604
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: [styles5.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
628
+ caretColor && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
629
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native7.View, { style: [styles6.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
630
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native7.View, { style: [styles6.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
605
631
  ] })
606
632
  ] });
607
633
  }
608
- var styles5 = import_react_native6.StyleSheet.create({
634
+ var styles6 = import_react_native7.StyleSheet.create({
609
635
  caret: {
610
636
  borderLeftColor: "transparent",
611
637
  borderRightColor: "transparent",
@@ -649,11 +675,11 @@ var styles5 = import_react_native6.StyleSheet.create({
649
675
 
650
676
  // src/useAutoAlign.ts
651
677
  var import_react3 = require("react");
652
- var import_react_native7 = require("react-native");
678
+ var import_react_native8 = require("react-native");
653
679
  var EDGE_MARGIN = 12;
654
680
  function useAutoAlign(open, contentWidth, contentHeight) {
655
681
  const triggerRef = (0, import_react3.useRef)(null);
656
- const { width: windowWidth, height: windowHeight } = (0, import_react_native7.useWindowDimensions)();
682
+ const { width: windowWidth, height: windowHeight } = (0, import_react_native8.useWindowDimensions)();
657
683
  const [align, setAlign] = (0, import_react3.useState)("center");
658
684
  const [verticalAlign, setVerticalAlign] = (0, import_react3.useState)("below");
659
685
  const [maxHeight, setMaxHeight] = (0, import_react3.useState)(contentHeight);
@@ -686,7 +712,7 @@ function useAutoAlign(open, contentWidth, contentHeight) {
686
712
  }
687
713
 
688
714
  // src/InlineColorPicker.tsx
689
- var import_jsx_runtime6 = require("react/jsx-runtime");
715
+ var import_jsx_runtime7 = require("react/jsx-runtime");
690
716
  var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
691
717
  var DEFAULT_SIZE = 48;
692
718
  var SWATCH_SIZE = 28;
@@ -699,10 +725,10 @@ var SCREEN_MARGIN = 40;
699
725
  function widthForColumns(columns) {
700
726
  return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
701
727
  }
702
- function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_paper4.defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
728
+ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper4.defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
703
729
  const menuBg = dark ? "#000000" : "#FFFFFF";
704
- const { width: windowWidth } = (0, import_react_native8.useWindowDimensions)();
705
- const autoColumns = (0, import_core2.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
730
+ const { width: windowWidth } = (0, import_react_native9.useWindowDimensions)();
731
+ const autoColumns = (0, import_core3.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
706
732
  const resolvedColumns = columns ?? autoColumns;
707
733
  const swatchesWidth = widthForColumns(resolvedColumns);
708
734
  const swatchRows = Math.ceil(swatches.length / resolvedColumns);
@@ -710,15 +736,18 @@ function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_p
710
736
  const open = host.openId === id;
711
737
  const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, swatchesWidth, swatchesHeight);
712
738
  const align = alignOverride ?? autoAlign;
713
- const contrastColor = (0, import_auto_paper4.getContrastColor)(value);
739
+ const displayFor = previewValue ?? ((hex) => hex);
740
+ const displayValue = displayFor(value);
741
+ const contrastColor = (0, import_auto_paper4.getContrastColor)(displayValue);
714
742
  const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
715
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native8.View, { style: [styles6.anchor, open && styles6.anchorOpen], children: [
716
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles6.trigger, { backgroundColor: value, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.View, { ref: triggerRef, collapsable: false, style: styles6.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper4.Text, { style: [styles6.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper4.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
717
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: value, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.ScrollView, { style: [styles6.swatches, { backgroundColor: menuBg, borderColor: value, width: swatchesWidth, maxHeight }], contentContainerStyle: styles6.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
743
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: [styles7.anchor, open && styles7.anchorOpen], children: [
744
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles7.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, { ref: triggerRef, collapsable: false, style: styles7.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper4.Text, { style: [styles7.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper4.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
745
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.ScrollView, { style: [styles7.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles7.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
718
746
  const selected = swatch.value.toLowerCase() === value.toLowerCase();
719
747
  const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
720
748
  const swappable = taken && allowSwapTaken;
721
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
749
+ const swatchDisplay = displayFor(swatch.value);
750
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
722
751
  import_feedback_press4.TouchableRipple,
723
752
  {
724
753
  disabled: taken && !swappable,
@@ -727,15 +756,15 @@ function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_p
727
756
  if (autoDismiss) host.close();
728
757
  },
729
758
  borderless: true,
730
- style: [styles6.swatch, { backgroundColor: swatch.value }, selected && styles6.swatchSelected, taken && !swappable && styles6.swatchTaken],
731
- children: selected ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper4.Icon, { source: "check", size: 16, color: (0, import_auto_paper4.getContrastColor)(swatch.value) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper4.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper4.getContrastColor)(swatch.value) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper4.Icon, { source: "close", size: 16, color: (0, import_auto_paper4.getContrastColor)(swatch.value) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.View, {})
759
+ style: [styles7.swatch, { backgroundColor: swatchDisplay }, selected && styles7.swatchSelected, taken && !swappable && styles7.swatchTaken],
760
+ children: selected ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper4.Icon, { source: "check", size: 16, color: (0, import_auto_paper4.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper4.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper4.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper4.Icon, { source: "close", size: 16, color: (0, import_auto_paper4.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, {})
732
761
  },
733
762
  swatch.value
734
763
  );
735
764
  }) }) })
736
765
  ] });
737
766
  }
738
- var styles6 = import_react_native8.StyleSheet.create({
767
+ var styles7 = import_react_native9.StyleSheet.create({
739
768
  anchor: {
740
769
  position: "relative"
741
770
  },
@@ -781,6 +810,10 @@ var styles6 = import_react_native8.StyleSheet.create({
781
810
  gap: SWATCHES_GAP,
782
811
  padding: SWATCHES_PADDING
783
812
  },
813
+ tagLabel: {
814
+ fontWeight: "700",
815
+ letterSpacing: 0.5
816
+ },
784
817
  // borderRadius/height/width come from the `size` prop instead (see render-site override) — no
785
818
  // fixed default here, since this style object is shared by every caller regardless of size.
786
819
  trigger: {
@@ -799,19 +832,15 @@ var styles6 = import_react_native8.StyleSheet.create({
799
832
  justifyContent: "center",
800
833
  paddingHorizontal: 4,
801
834
  width: "100%"
802
- },
803
- tagLabel: {
804
- fontWeight: "700",
805
- letterSpacing: 0.5
806
835
  }
807
836
  });
808
837
 
809
838
  // src/LabeledDropdown.tsx
810
839
  var import_auto_paper5 = require("@rific/auto-paper");
811
840
  var import_feedback_press5 = require("@rific/feedback-press");
812
- var import_react_native9 = require("react-native");
841
+ var import_react_native10 = require("react-native");
813
842
  var import_react_native_paper5 = require("react-native-paper");
814
- var import_jsx_runtime7 = require("react/jsx-runtime");
843
+ var import_jsx_runtime8 = require("react/jsx-runtime");
815
844
  var TRIGGER_HEIGHT = 28;
816
845
  var POPOVER_WIDTH = 180;
817
846
  var ROW_HEIGHT = 36;
@@ -834,22 +863,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
834
863
  onChange(option.value);
835
864
  host.close();
836
865
  };
837
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: [styles7.anchor, open && styles7.anchorOpen], children: [
838
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press5.TouchableRipple, { onPress: () => host.toggle(id), style: styles7.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { ref: triggerRef, collapsable: false, style: styles7.triggerInner, children: [
839
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper5.Text, { style: [styles7.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
840
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper5.Icon, { source: "menu-down", size: 16, color })
866
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native10.View, { style: [styles8.anchor, open && styles8.anchorOpen], children: [
867
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_feedback_press5.TouchableRipple, { onPress: () => host.toggle(id), style: styles8.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native10.View, { ref: triggerRef, collapsable: false, style: styles8.triggerInner, children: [
868
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper5.Text, { style: [styles8.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
869
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper5.Icon, { source: "menu-down", size: 16, color })
841
870
  ] }) }),
842
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.ScrollView, { style: [styles7.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles7.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
871
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native10.ScrollView, { style: [styles8.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles8.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
843
872
  const isSelected = option.value === value;
844
873
  const onColor = (0, import_auto_paper5.getContrastColor)(color);
845
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press5.TouchableRipple, { onPress: () => handleSelect(option), style: [styles7.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: styles7.rowInner, children: [
846
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
847
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper5.Text, { style: [styles7.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
874
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_feedback_press5.TouchableRipple, { onPress: () => handleSelect(option), style: [styles8.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native10.View, { style: styles8.rowInner, children: [
875
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
876
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper5.Text, { style: [styles8.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
848
877
  ] }) }, option.value);
849
878
  }) }) })
850
879
  ] });
851
880
  }
852
- var styles7 = import_react_native9.StyleSheet.create({
881
+ var styles8 = import_react_native10.StyleSheet.create({
853
882
  anchor: {
854
883
  position: "relative"
855
884
  },
@@ -907,25 +936,25 @@ function loadSkiaWeb() {
907
936
  }
908
937
 
909
938
  // src/PressAwayOverlay.tsx
910
- var import_react_native10 = require("react-native");
911
- var import_jsx_runtime8 = require("react/jsx-runtime");
939
+ var import_react_native11 = require("react-native");
940
+ var import_jsx_runtime9 = require("react/jsx-runtime");
912
941
  function PressAwayOverlay({ active, onPress, style }) {
913
942
  if (!active) return null;
914
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native10.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native10.StyleSheet.absoluteFill, style] });
943
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native11.StyleSheet.absoluteFill, style] });
915
944
  }
916
945
 
917
946
  // src/ReadyButton.tsx
918
947
  var import_feedback_press6 = require("@rific/feedback-press");
919
- var import_react_native11 = require("react-native");
948
+ var import_react_native12 = require("react-native");
920
949
  var import_react_native_paper6 = require("react-native-paper");
921
- var import_jsx_runtime9 = require("react/jsx-runtime");
950
+ var import_jsx_runtime10 = require("react/jsx-runtime");
922
951
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
923
- const readyButtonStyle = [styles8.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
952
+ const readyButtonStyle = [styles9.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
924
953
  const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
925
954
  const labelColorStyle = { color: ready ? "#000000" : color };
926
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press6.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper6.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
955
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press6.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper6.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
927
956
  }
928
- var styles8 = import_react_native11.StyleSheet.create({
957
+ var styles9 = import_react_native12.StyleSheet.create({
929
958
  readyButton: {
930
959
  alignItems: "center",
931
960
  borderRadius: 12,
@@ -940,19 +969,19 @@ var styles8 = import_react_native11.StyleSheet.create({
940
969
  // src/SectionedDropdown.tsx
941
970
  var import_auto_paper6 = require("@rific/auto-paper");
942
971
  var import_feedback_press7 = require("@rific/feedback-press");
943
- var import_react_native13 = require("react-native");
972
+ var import_react_native14 = require("react-native");
944
973
  var import_react_native_paper7 = require("react-native-paper");
945
974
 
946
975
  // src/TriggerGaugeHost.tsx
947
976
  var import_react5 = require("react");
948
- var import_jsx_runtime11 = require("react/jsx-runtime");
977
+ var import_jsx_runtime12 = require("react/jsx-runtime");
949
978
  var LazyTriggerGauge = (0, import_react5.lazy)(() => loadSkiaWeb().then(() => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((m) => ({ default: m.TriggerGauge }))));
950
979
  function TriggerGaugeHost(props) {
951
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react5.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LazyTriggerGauge, { ...props }) });
980
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react5.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LazyTriggerGauge, { ...props }) });
952
981
  }
953
982
 
954
983
  // src/SectionedDropdown.tsx
955
- var import_jsx_runtime12 = require("react/jsx-runtime");
984
+ var import_jsx_runtime13 = require("react/jsx-runtime");
956
985
  var MENU_BORDER_WIDTH = 1;
957
986
  var TRIGGER_SIZE = 44;
958
987
  var MENU_MIN_WIDTH = 200;
@@ -998,17 +1027,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
998
1027
  }
999
1028
  gaugeOffset += section.options.length;
1000
1029
  }
1001
- const anchorStyle = [styles10.anchor, open && styles10.anchorOpen];
1030
+ const anchorStyle = [styles11.anchor, open && styles11.anchorOpen];
1002
1031
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
1003
1032
  const dividerStyle = { backgroundColor: menuBorderColor };
1004
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: anchorStyle, children: [
1005
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { ref: triggerRef, collapsable: false, style: styles10.triggerBox, children: [
1006
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1007
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press7.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
1033
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: anchorStyle, children: [
1034
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { ref: triggerRef, collapsable: false, style: styles11.triggerBox, children: [
1035
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1036
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
1008
1037
  ] }),
1009
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.ScrollView, { style: [styles10.menu, menuStyle], contentContainerStyle: styles10.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { children: [
1010
- sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [styles10.divider, dividerStyle] }),
1011
- section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1038
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.ScrollView, { style: [styles11.menu, menuStyle], contentContainerStyle: styles11.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { children: [
1039
+ sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { style: [styles11.divider, dividerStyle] }),
1040
+ section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1012
1041
  SingleSection,
1013
1042
  {
1014
1043
  section,
@@ -1021,7 +1050,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1021
1050
  if (autoDismiss) host.close();
1022
1051
  }
1023
1052
  }
1024
- ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1053
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1025
1054
  ] }, section.id)) }) })
1026
1055
  ] });
1027
1056
  }
@@ -1033,17 +1062,18 @@ function SingleSection({
1033
1062
  labelFontFamily,
1034
1063
  onSelect
1035
1064
  }) {
1036
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: section.options.map((option) => {
1065
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: section.options.map((option) => {
1037
1066
  const selected = option.value === section.value;
1067
+ const taken = !selected && option.value === section.takenValue;
1038
1068
  const rowColor = selected ? onAccentColor : mutedColor;
1039
- const itemStyle = [styles10.item, selected && { backgroundColor: accentColor }];
1069
+ const itemStyle = [styles11.item, selected && { backgroundColor: accentColor }, taken && styles11.itemTaken];
1040
1070
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1041
1071
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
1042
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.itemRow, children: [
1043
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1044
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.itemLabelColumn, children: [
1045
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1046
- option.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
1072
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.itemRow, children: [
1073
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1074
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.itemLabelColumn, children: [
1075
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1076
+ option.description && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
1047
1077
  ] })
1048
1078
  ] }) }, option.value);
1049
1079
  }) });
@@ -1057,23 +1087,23 @@ function MultiSection({
1057
1087
  allClearLabels
1058
1088
  }) {
1059
1089
  const allSelected = section.value.length === section.options.length;
1060
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1090
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1061
1091
  section.options.map((option, i) => {
1062
1092
  const selected = section.value.includes(option.value);
1063
1093
  const rowColor = selected ? onAccentColor : mutedColor;
1064
1094
  const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
1065
1095
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
1066
- const itemStyle = [styles10.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
1096
+ const itemStyle = [styles11.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
1067
1097
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1068
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.itemRow, children: [
1069
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1070
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: [styles10.itemLabelFlex, labelStyle], children: option.label })
1098
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.itemRow, children: [
1099
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1100
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: [styles11.itemLabelFlex, labelStyle], children: option.label })
1071
1101
  ] }) }, option.value);
1072
1102
  }),
1073
- section.allClear && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles10.item, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: [styles10.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
1103
+ section.allClear && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles11.item, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: [styles11.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
1074
1104
  ] });
1075
1105
  }
1076
- var styles10 = import_react_native13.StyleSheet.create({
1106
+ var styles11 = import_react_native14.StyleSheet.create({
1077
1107
  allClearLabel: {
1078
1108
  fontWeight: "bold",
1079
1109
  textAlign: "center"
@@ -1090,7 +1120,7 @@ var styles10 = import_react_native13.StyleSheet.create({
1090
1120
  zIndex: 100
1091
1121
  },
1092
1122
  divider: {
1093
- height: import_react_native13.StyleSheet.hairlineWidth,
1123
+ height: import_react_native14.StyleSheet.hairlineWidth,
1094
1124
  marginVertical: 4
1095
1125
  },
1096
1126
  item: {
@@ -1109,6 +1139,11 @@ var styles10 = import_react_native13.StyleSheet.create({
1109
1139
  flexDirection: "row",
1110
1140
  gap: 8
1111
1141
  },
1142
+ // Same opacity as ProfilePicker's rowDisabled / InlineColorPicker's swatchTaken — the fleet's
1143
+ // established "shown, not removed" treatment for another seat's own current pick.
1144
+ itemTaken: {
1145
+ opacity: 0.35
1146
+ },
1112
1147
  menu: {
1113
1148
  borderRadius: 12,
1114
1149
  borderWidth: MENU_BORDER_WIDTH,
@@ -1139,20 +1174,20 @@ var styles10 = import_react_native13.StyleSheet.create({
1139
1174
 
1140
1175
  // src/SharedActionBand.tsx
1141
1176
  var import_feedback_press8 = require("@rific/feedback-press");
1142
- var import_react_native14 = require("react-native");
1143
- var import_jsx_runtime13 = require("react/jsx-runtime");
1177
+ var import_react_native15 = require("react-native");
1178
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1144
1179
  function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
1145
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: [styles11.column, popoverOpen && styles11.columnOpen], children: [
1146
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.actionsRow, children: [
1147
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press8.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1148
- onRandomize && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press8.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1149
- onReset && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press8.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
1150
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press8.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
1180
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: [styles12.column, popoverOpen && styles12.columnOpen], children: [
1181
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: styles12.actionsRow, children: [
1182
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press8.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1183
+ onRandomize && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press8.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1184
+ onReset && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press8.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
1185
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press8.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
1151
1186
  ] }),
1152
1187
  children
1153
1188
  ] });
1154
1189
  }
1155
- var styles11 = import_react_native14.StyleSheet.create({
1190
+ var styles12 = import_react_native15.StyleSheet.create({
1156
1191
  actionsRow: {
1157
1192
  alignItems: "center",
1158
1193
  flexDirection: "row",
@@ -1169,19 +1204,19 @@ var styles11 = import_react_native14.StyleSheet.create({
1169
1204
 
1170
1205
  // src/StatRow.tsx
1171
1206
  var import_auto_paper7 = require("@rific/auto-paper");
1172
- var import_react_native15 = require("react-native");
1207
+ var import_react_native16 = require("react-native");
1173
1208
  var import_react_native_paper8 = require("react-native-paper");
1174
- var import_jsx_runtime14 = require("react/jsx-runtime");
1175
- function StatRow({ label, value }) {
1209
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1210
+ function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
1176
1211
  const { dark } = (0, import_auto_paper7.useAutoPaperTheme)();
1177
- const fg = dark ? "#FFFFFF" : "#000000";
1178
- const fgMuted = dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)";
1179
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: styles12.row, children: [
1180
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Text, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
1181
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Text, { variant: "bodyMedium", style: [styles12.value, { color: fg }], children: value })
1212
+ const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
1213
+ const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
1214
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: styles13.row, children: [
1215
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Text, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
1216
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Text, { variant: "bodyMedium", style: [styles13.value, { color: fg }], children: value })
1182
1217
  ] });
1183
1218
  }
1184
- var styles12 = import_react_native15.StyleSheet.create({
1219
+ var styles13 = import_react_native16.StyleSheet.create({
1185
1220
  row: {
1186
1221
  alignItems: "center",
1187
1222
  flexDirection: "row",
@@ -1194,20 +1229,25 @@ var styles12 = import_react_native15.StyleSheet.create({
1194
1229
 
1195
1230
  // src/StatSection.tsx
1196
1231
  var import_auto_paper8 = require("@rific/auto-paper");
1197
- var import_react_native16 = require("react-native");
1232
+ var import_react_native17 = require("react-native");
1198
1233
  var import_react_native_paper9 = require("react-native-paper");
1199
- var import_jsx_runtime15 = require("react/jsx-runtime");
1200
- function StatSection({ label, children }) {
1234
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1235
+ function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
1201
1236
  const { dark } = (0, import_auto_paper8.useAutoPaperTheme)();
1202
- const fgMuted = dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)";
1203
- const sectionBg = dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)";
1204
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: [styles13.section, { backgroundColor: sectionBg }], children: [
1205
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles13.label, { color: fgMuted }], children: label }),
1237
+ const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
1238
+ const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
1239
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native17.View, { style: [styles14.section, { backgroundColor: sectionBg }], children: [
1240
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles14.label, { color: fg }], children: label }),
1206
1241
  children
1207
1242
  ] });
1208
1243
  }
1209
- var styles13 = import_react_native16.StyleSheet.create({
1244
+ var styles14 = import_react_native17.StyleSheet.create({
1245
+ // Bold and full-contrast (fg), not the original fontless/fgMuted treatment — that read at the
1246
+ // same visual weight as StatRow's own row labels below it (both used the identical muted color;
1247
+ // letterSpacing/variant alone didn't separate them enough to read as "this is the group header"
1248
+ // at a glance). Matches AchievementRow's own title styling (bold + fg) below it in the same list.
1210
1249
  label: {
1250
+ fontWeight: "bold",
1211
1251
  letterSpacing: 2
1212
1252
  },
1213
1253
  section: {
@@ -1232,6 +1272,7 @@ function usePopoverHost() {
1232
1272
  AchievementRow,
1233
1273
  BaseSettingsDialog,
1234
1274
  BaseStatsScreen,
1275
+ ContentGutter,
1235
1276
  CornerActionButtons,
1236
1277
  InlineColorPicker,
1237
1278
  LABELED_DROPDOWN_POPOVER_WIDTH,