@tastic/hud 0.5.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,
@@ -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
 
@@ -552,17 +553,41 @@ var styles3 = import_react_native3.StyleSheet.create({
552
553
  }
553
554
  });
554
555
 
555
- // src/CornerActionButtons.tsx
556
- var import_feedback_press3 = require("@rific/feedback-press");
556
+ // src/ContentGutter.tsx
557
+ var import_core2 = require("@tastic/core");
557
558
  var import_react_native4 = require("react-native");
558
559
  var import_jsx_runtime4 = require("react/jsx-runtime");
559
- function CornerActionButtons({ onBack, onSettings, fg, insets }) {
560
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
561
- /* @__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" }),
562
- /* @__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 })
563
567
  ] });
564
568
  }
565
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({
566
591
  back: {
567
592
  position: "absolute"
568
593
  },
@@ -572,41 +597,41 @@ var styles4 = import_react_native4.StyleSheet.create({
572
597
  });
573
598
 
574
599
  // src/fonts.ts
575
- var import_react_native5 = require("react-native");
576
- 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" });
577
602
 
578
603
  // src/InlineColorPicker.tsx
579
604
  var import_auto_paper4 = require("@rific/auto-paper");
580
605
  var import_feedback_press4 = require("@rific/feedback-press");
581
- var import_core2 = require("@tastic/core");
582
- var import_react_native8 = require("react-native");
606
+ var import_core3 = require("@tastic/core");
607
+ var import_react_native9 = require("react-native");
583
608
  var import_react_native_paper4 = require("react-native-paper");
584
609
 
585
610
  // src/PopoverBody.tsx
586
- var import_react_native6 = require("react-native");
587
- 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");
588
613
  var CARET_SIZE = 7;
589
614
  var CARET_RING_OFFSET = 2;
590
615
  var CARET_DIP = 1;
591
616
  function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
592
617
  if (!visible) return null;
593
618
  const above = verticalAlign === "above";
594
- const alignStyle = align === "left" ? styles5.contentLeft : align === "right" ? styles5.contentRight : styles5.contentCenter;
595
- 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;
596
621
  const ringSize = CARET_SIZE + caretBorderWidth;
597
622
  const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
598
623
  const caretFill = above ? "borderTopColor" : "borderBottomColor";
599
624
  const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
600
625
  const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
601
- 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: [
602
627
  children,
603
- caretColor && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
604
- /* @__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 }] }),
605
- /* @__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 }] })
606
631
  ] })
607
632
  ] });
608
633
  }
609
- var styles5 = import_react_native6.StyleSheet.create({
634
+ var styles6 = import_react_native7.StyleSheet.create({
610
635
  caret: {
611
636
  borderLeftColor: "transparent",
612
637
  borderRightColor: "transparent",
@@ -650,11 +675,11 @@ var styles5 = import_react_native6.StyleSheet.create({
650
675
 
651
676
  // src/useAutoAlign.ts
652
677
  var import_react3 = require("react");
653
- var import_react_native7 = require("react-native");
678
+ var import_react_native8 = require("react-native");
654
679
  var EDGE_MARGIN = 12;
655
680
  function useAutoAlign(open, contentWidth, contentHeight) {
656
681
  const triggerRef = (0, import_react3.useRef)(null);
657
- const { width: windowWidth, height: windowHeight } = (0, import_react_native7.useWindowDimensions)();
682
+ const { width: windowWidth, height: windowHeight } = (0, import_react_native8.useWindowDimensions)();
658
683
  const [align, setAlign] = (0, import_react3.useState)("center");
659
684
  const [verticalAlign, setVerticalAlign] = (0, import_react3.useState)("below");
660
685
  const [maxHeight, setMaxHeight] = (0, import_react3.useState)(contentHeight);
@@ -687,7 +712,7 @@ function useAutoAlign(open, contentWidth, contentHeight) {
687
712
  }
688
713
 
689
714
  // src/InlineColorPicker.tsx
690
- var import_jsx_runtime6 = require("react/jsx-runtime");
715
+ var import_jsx_runtime7 = require("react/jsx-runtime");
691
716
  var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
692
717
  var DEFAULT_SIZE = 48;
693
718
  var SWATCH_SIZE = 28;
@@ -700,10 +725,10 @@ var SCREEN_MARGIN = 40;
700
725
  function widthForColumns(columns) {
701
726
  return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
702
727
  }
703
- 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 }) {
704
729
  const menuBg = dark ? "#000000" : "#FFFFFF";
705
- const { width: windowWidth } = (0, import_react_native8.useWindowDimensions)();
706
- 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);
707
732
  const resolvedColumns = columns ?? autoColumns;
708
733
  const swatchesWidth = widthForColumns(resolvedColumns);
709
734
  const swatchRows = Math.ceil(swatches.length / resolvedColumns);
@@ -711,15 +736,18 @@ function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_p
711
736
  const open = host.openId === id;
712
737
  const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, swatchesWidth, swatchesHeight);
713
738
  const align = alignOverride ?? autoAlign;
714
- 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);
715
742
  const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
716
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native8.View, { style: [styles6.anchor, open && styles6.anchorOpen], children: [
717
- /* @__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 }) }) }),
718
- /* @__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) => {
719
746
  const selected = swatch.value.toLowerCase() === value.toLowerCase();
720
747
  const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
721
748
  const swappable = taken && allowSwapTaken;
722
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
749
+ const swatchDisplay = displayFor(swatch.value);
750
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
723
751
  import_feedback_press4.TouchableRipple,
724
752
  {
725
753
  disabled: taken && !swappable,
@@ -728,15 +756,15 @@ function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_p
728
756
  if (autoDismiss) host.close();
729
757
  },
730
758
  borderless: true,
731
- style: [styles6.swatch, { backgroundColor: swatch.value }, selected && styles6.swatchSelected, taken && !swappable && styles6.swatchTaken],
732
- 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, {})
733
761
  },
734
762
  swatch.value
735
763
  );
736
764
  }) }) })
737
765
  ] });
738
766
  }
739
- var styles6 = import_react_native8.StyleSheet.create({
767
+ var styles7 = import_react_native9.StyleSheet.create({
740
768
  anchor: {
741
769
  position: "relative"
742
770
  },
@@ -782,6 +810,10 @@ var styles6 = import_react_native8.StyleSheet.create({
782
810
  gap: SWATCHES_GAP,
783
811
  padding: SWATCHES_PADDING
784
812
  },
813
+ tagLabel: {
814
+ fontWeight: "700",
815
+ letterSpacing: 0.5
816
+ },
785
817
  // borderRadius/height/width come from the `size` prop instead (see render-site override) — no
786
818
  // fixed default here, since this style object is shared by every caller regardless of size.
787
819
  trigger: {
@@ -800,19 +832,15 @@ var styles6 = import_react_native8.StyleSheet.create({
800
832
  justifyContent: "center",
801
833
  paddingHorizontal: 4,
802
834
  width: "100%"
803
- },
804
- tagLabel: {
805
- fontWeight: "700",
806
- letterSpacing: 0.5
807
835
  }
808
836
  });
809
837
 
810
838
  // src/LabeledDropdown.tsx
811
839
  var import_auto_paper5 = require("@rific/auto-paper");
812
840
  var import_feedback_press5 = require("@rific/feedback-press");
813
- var import_react_native9 = require("react-native");
841
+ var import_react_native10 = require("react-native");
814
842
  var import_react_native_paper5 = require("react-native-paper");
815
- var import_jsx_runtime7 = require("react/jsx-runtime");
843
+ var import_jsx_runtime8 = require("react/jsx-runtime");
816
844
  var TRIGGER_HEIGHT = 28;
817
845
  var POPOVER_WIDTH = 180;
818
846
  var ROW_HEIGHT = 36;
@@ -835,22 +863,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
835
863
  onChange(option.value);
836
864
  host.close();
837
865
  };
838
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: [styles7.anchor, open && styles7.anchorOpen], children: [
839
- /* @__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: [
840
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper5.Text, { style: [styles7.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
841
- /* @__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 })
842
870
  ] }) }),
843
- /* @__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) => {
844
872
  const isSelected = option.value === value;
845
873
  const onColor = (0, import_auto_paper5.getContrastColor)(color);
846
- 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: [
847
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
848
- /* @__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 })
849
877
  ] }) }, option.value);
850
878
  }) }) })
851
879
  ] });
852
880
  }
853
- var styles7 = import_react_native9.StyleSheet.create({
881
+ var styles8 = import_react_native10.StyleSheet.create({
854
882
  anchor: {
855
883
  position: "relative"
856
884
  },
@@ -908,25 +936,25 @@ function loadSkiaWeb() {
908
936
  }
909
937
 
910
938
  // src/PressAwayOverlay.tsx
911
- var import_react_native10 = require("react-native");
912
- 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");
913
941
  function PressAwayOverlay({ active, onPress, style }) {
914
942
  if (!active) return null;
915
- 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] });
916
944
  }
917
945
 
918
946
  // src/ReadyButton.tsx
919
947
  var import_feedback_press6 = require("@rific/feedback-press");
920
- var import_react_native11 = require("react-native");
948
+ var import_react_native12 = require("react-native");
921
949
  var import_react_native_paper6 = require("react-native-paper");
922
- var import_jsx_runtime9 = require("react/jsx-runtime");
950
+ var import_jsx_runtime10 = require("react/jsx-runtime");
923
951
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
924
- const readyButtonStyle = [styles8.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
952
+ const readyButtonStyle = [styles9.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
925
953
  const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
926
954
  const labelColorStyle = { color: ready ? "#000000" : color };
927
- 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?" }) });
928
956
  }
929
- var styles8 = import_react_native11.StyleSheet.create({
957
+ var styles9 = import_react_native12.StyleSheet.create({
930
958
  readyButton: {
931
959
  alignItems: "center",
932
960
  borderRadius: 12,
@@ -941,19 +969,19 @@ var styles8 = import_react_native11.StyleSheet.create({
941
969
  // src/SectionedDropdown.tsx
942
970
  var import_auto_paper6 = require("@rific/auto-paper");
943
971
  var import_feedback_press7 = require("@rific/feedback-press");
944
- var import_react_native13 = require("react-native");
972
+ var import_react_native14 = require("react-native");
945
973
  var import_react_native_paper7 = require("react-native-paper");
946
974
 
947
975
  // src/TriggerGaugeHost.tsx
948
976
  var import_react5 = require("react");
949
- var import_jsx_runtime11 = require("react/jsx-runtime");
977
+ var import_jsx_runtime12 = require("react/jsx-runtime");
950
978
  var LazyTriggerGauge = (0, import_react5.lazy)(() => loadSkiaWeb().then(() => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((m) => ({ default: m.TriggerGauge }))));
951
979
  function TriggerGaugeHost(props) {
952
- 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 }) });
953
981
  }
954
982
 
955
983
  // src/SectionedDropdown.tsx
956
- var import_jsx_runtime12 = require("react/jsx-runtime");
984
+ var import_jsx_runtime13 = require("react/jsx-runtime");
957
985
  var MENU_BORDER_WIDTH = 1;
958
986
  var TRIGGER_SIZE = 44;
959
987
  var MENU_MIN_WIDTH = 200;
@@ -999,17 +1027,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
999
1027
  }
1000
1028
  gaugeOffset += section.options.length;
1001
1029
  }
1002
- const anchorStyle = [styles10.anchor, open && styles10.anchorOpen];
1030
+ const anchorStyle = [styles11.anchor, open && styles11.anchorOpen];
1003
1031
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
1004
1032
  const dividerStyle = { backgroundColor: menuBorderColor };
1005
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: anchorStyle, children: [
1006
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { ref: triggerRef, collapsable: false, style: styles10.triggerBox, children: [
1007
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1008
- /* @__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) })
1009
1037
  ] }),
1010
- /* @__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: [
1011
- sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [styles10.divider, dividerStyle] }),
1012
- 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)(
1013
1041
  SingleSection,
1014
1042
  {
1015
1043
  section,
@@ -1022,7 +1050,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1022
1050
  if (autoDismiss) host.close();
1023
1051
  }
1024
1052
  }
1025
- ) : /* @__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 })
1026
1054
  ] }, section.id)) }) })
1027
1055
  ] });
1028
1056
  }
@@ -1034,17 +1062,18 @@ function SingleSection({
1034
1062
  labelFontFamily,
1035
1063
  onSelect
1036
1064
  }) {
1037
- 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) => {
1038
1066
  const selected = option.value === section.value;
1067
+ const taken = !selected && option.value === section.takenValue;
1039
1068
  const rowColor = selected ? onAccentColor : mutedColor;
1040
- const itemStyle = [styles10.item, selected && { backgroundColor: accentColor }];
1069
+ const itemStyle = [styles11.item, selected && { backgroundColor: accentColor }, taken && styles11.itemTaken];
1041
1070
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1042
1071
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
1043
- 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: [
1044
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1045
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.itemLabelColumn, children: [
1046
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1047
- 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 })
1048
1077
  ] })
1049
1078
  ] }) }, option.value);
1050
1079
  }) });
@@ -1058,23 +1087,23 @@ function MultiSection({
1058
1087
  allClearLabels
1059
1088
  }) {
1060
1089
  const allSelected = section.value.length === section.options.length;
1061
- 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: [
1062
1091
  section.options.map((option, i) => {
1063
1092
  const selected = section.value.includes(option.value);
1064
1093
  const rowColor = selected ? onAccentColor : mutedColor;
1065
1094
  const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
1066
1095
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
1067
- 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 }];
1068
1097
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1069
- 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: [
1070
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1071
- /* @__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 })
1072
1101
  ] }) }, option.value);
1073
1102
  }),
1074
- 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 }) })
1075
1104
  ] });
1076
1105
  }
1077
- var styles10 = import_react_native13.StyleSheet.create({
1106
+ var styles11 = import_react_native14.StyleSheet.create({
1078
1107
  allClearLabel: {
1079
1108
  fontWeight: "bold",
1080
1109
  textAlign: "center"
@@ -1091,7 +1120,7 @@ var styles10 = import_react_native13.StyleSheet.create({
1091
1120
  zIndex: 100
1092
1121
  },
1093
1122
  divider: {
1094
- height: import_react_native13.StyleSheet.hairlineWidth,
1123
+ height: import_react_native14.StyleSheet.hairlineWidth,
1095
1124
  marginVertical: 4
1096
1125
  },
1097
1126
  item: {
@@ -1110,6 +1139,11 @@ var styles10 = import_react_native13.StyleSheet.create({
1110
1139
  flexDirection: "row",
1111
1140
  gap: 8
1112
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
+ },
1113
1147
  menu: {
1114
1148
  borderRadius: 12,
1115
1149
  borderWidth: MENU_BORDER_WIDTH,
@@ -1140,20 +1174,20 @@ var styles10 = import_react_native13.StyleSheet.create({
1140
1174
 
1141
1175
  // src/SharedActionBand.tsx
1142
1176
  var import_feedback_press8 = require("@rific/feedback-press");
1143
- var import_react_native14 = require("react-native");
1144
- 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");
1145
1179
  function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
1146
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: [styles11.column, popoverOpen && styles11.columnOpen], children: [
1147
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.actionsRow, children: [
1148
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press8.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1149
- onRandomize && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press8.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1150
- 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" }),
1151
- /* @__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" })
1152
1186
  ] }),
1153
1187
  children
1154
1188
  ] });
1155
1189
  }
1156
- var styles11 = import_react_native14.StyleSheet.create({
1190
+ var styles12 = import_react_native15.StyleSheet.create({
1157
1191
  actionsRow: {
1158
1192
  alignItems: "center",
1159
1193
  flexDirection: "row",
@@ -1170,19 +1204,19 @@ var styles11 = import_react_native14.StyleSheet.create({
1170
1204
 
1171
1205
  // src/StatRow.tsx
1172
1206
  var import_auto_paper7 = require("@rific/auto-paper");
1173
- var import_react_native15 = require("react-native");
1207
+ var import_react_native16 = require("react-native");
1174
1208
  var import_react_native_paper8 = require("react-native-paper");
1175
- var import_jsx_runtime14 = require("react/jsx-runtime");
1209
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1176
1210
  function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
1177
1211
  const { dark } = (0, import_auto_paper7.useAutoPaperTheme)();
1178
1212
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
1179
1213
  const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
1180
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: styles12.row, children: [
1181
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Text, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
1182
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Text, { variant: "bodyMedium", style: [styles12.value, { color: fg }], children: value })
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 })
1183
1217
  ] });
1184
1218
  }
1185
- var styles12 = import_react_native15.StyleSheet.create({
1219
+ var styles13 = import_react_native16.StyleSheet.create({
1186
1220
  row: {
1187
1221
  alignItems: "center",
1188
1222
  flexDirection: "row",
@@ -1195,19 +1229,19 @@ var styles12 = import_react_native15.StyleSheet.create({
1195
1229
 
1196
1230
  // src/StatSection.tsx
1197
1231
  var import_auto_paper8 = require("@rific/auto-paper");
1198
- var import_react_native16 = require("react-native");
1232
+ var import_react_native17 = require("react-native");
1199
1233
  var import_react_native_paper9 = require("react-native-paper");
1200
- var import_jsx_runtime15 = require("react/jsx-runtime");
1234
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1201
1235
  function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
1202
1236
  const { dark } = (0, import_auto_paper8.useAutoPaperTheme)();
1203
1237
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
1204
1238
  const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
1205
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: [styles13.section, { backgroundColor: sectionBg }], children: [
1206
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles13.label, { color: fg }], children: label }),
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 }),
1207
1241
  children
1208
1242
  ] });
1209
1243
  }
1210
- var styles13 = import_react_native16.StyleSheet.create({
1244
+ var styles14 = import_react_native17.StyleSheet.create({
1211
1245
  // Bold and full-contrast (fg), not the original fontless/fgMuted treatment — that read at the
1212
1246
  // same visual weight as StatRow's own row labels below it (both used the identical muted color;
1213
1247
  // letterSpacing/variant alone didn't separate them enough to read as "this is the group header"
@@ -1238,6 +1272,7 @@ function usePopoverHost() {
1238
1272
  AchievementRow,
1239
1273
  BaseSettingsDialog,
1240
1274
  BaseStatsScreen,
1275
+ ContentGutter,
1241
1276
  CornerActionButtons,
1242
1277
  InlineColorPicker,
1243
1278
  LABELED_DROPDOWN_POPOVER_WIDTH,