@buoy-gg/debug-borders 7.0.40 → 7.0.42

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.
Files changed (39) hide show
  1. package/README.md +9 -63
  2. package/lib/commonjs/debug-borders/components/DebugBordersModal.js +1 -236
  3. package/lib/commonjs/debug-borders/components/DebugBordersStandaloneOverlay.js +1 -469
  4. package/lib/commonjs/debug-borders/index.js +1 -51
  5. package/lib/commonjs/debug-borders/types.js +1 -1
  6. package/lib/commonjs/debug-borders/utils/DebugBordersManager.js +1 -119
  7. package/lib/commonjs/debug-borders/utils/ViewTypeMapper.js +1 -264
  8. package/lib/commonjs/debug-borders/utils/colorGeneration.js +1 -76
  9. package/lib/commonjs/debug-borders/utils/componentInfo.js +1 -183
  10. package/lib/commonjs/debug-borders/utils/componentMeasurement.js +1 -111
  11. package/lib/commonjs/debug-borders/utils/fiberTreeTraversal.js +1 -309
  12. package/lib/commonjs/debug-borders/utils/labelPositioning.js +1 -202
  13. package/lib/commonjs/index.js +1 -42
  14. package/lib/commonjs/preset.js +1 -178
  15. package/lib/commonjs/sync/debugBordersSyncAdapter.js +1 -34
  16. package/lib/module/debug-borders/components/DebugBordersModal.js +1 -231
  17. package/lib/module/debug-borders/components/DebugBordersStandaloneOverlay.js +1 -464
  18. package/lib/module/debug-borders/index.js +1 -15
  19. package/lib/module/debug-borders/types.js +1 -1
  20. package/lib/module/debug-borders/utils/DebugBordersManager.js +1 -119
  21. package/lib/module/debug-borders/utils/ViewTypeMapper.js +1 -255
  22. package/lib/module/debug-borders/utils/colorGeneration.js +1 -76
  23. package/lib/module/debug-borders/utils/componentInfo.js +1 -183
  24. package/lib/module/debug-borders/utils/componentMeasurement.js +1 -111
  25. package/lib/module/debug-borders/utils/fiberTreeTraversal.js +1 -309
  26. package/lib/module/debug-borders/utils/labelPositioning.js +1 -202
  27. package/lib/module/index.js +1 -10
  28. package/lib/module/preset.js +1 -166
  29. package/lib/module/sync/debugBordersSyncAdapter.js +1 -30
  30. package/lib/web/index.mjs +1 -0
  31. package/package.json +34 -12
  32. package/lib/typescript/debug-borders/components/DebugBordersModal.d.ts.map +0 -1
  33. package/lib/typescript/debug-borders/components/DebugBordersStandaloneOverlay.d.ts.map +0 -1
  34. package/lib/typescript/debug-borders/index.d.ts.map +0 -1
  35. package/lib/typescript/debug-borders/types.d.ts.map +0 -1
  36. package/lib/typescript/debug-borders/utils/ViewTypeMapper.d.ts.map +0 -1
  37. package/lib/typescript/index.d.ts.map +0 -1
  38. package/lib/typescript/preset.d.ts.map +0 -1
  39. package/lib/typescript/sync/debugBordersSyncAdapter.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,12 +1,14 @@
1
+ <div align="center">
2
+
1
3
  # @buoy-gg/debug-borders
2
4
 
3
- [![npm version](https://img.shields.io/npm/v/@buoy-gg/debug-borders?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/debug-borders) [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/debug-borders?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/debug-borders)
5
+ Show layout borders and component labels over your React Native app. Tap a label to inspect the component's available properties.
4
6
 
5
- Show layout borders and component labels over your React Native app. Tap a label to inspect the component’s available properties.
7
+ <a href="https://buoy.gg/buoy/latest/docs/tools/debug-borders"><b>Debug Borders guide</b></a> &nbsp;·&nbsp; <a href="https://buoy.gg">buoy.gg</a> &nbsp;·&nbsp; <a href="https://github.com/Buoy-gg/buoy">All tools</a>
6
8
 
7
- Part of [Buoy](https://github.com/Buoy-gg/buoy). Install the package, complete account setup, and follow the integration steps below.
9
+ [![npm version](https://img.shields.io/npm/v/@buoy-gg/debug-borders?style=flat-square&labelColor=10302a&color=2a9d78)](https://www.npmjs.com/package/@buoy-gg/debug-borders) [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/debug-borders?style=flat-square&labelColor=10302a&color=2a9d78&label=downloads%2Fmonth)](https://www.npmjs.com/package/@buoy-gg/debug-borders)
8
10
 
9
- ![Debug Borders demo](https://github.com/user-attachments/assets/945fdb5d-2546-442d-98e7-ef73231abbba)
11
+ </div>
10
12
 
11
13
  ## Install
12
14
 
@@ -14,66 +16,10 @@ Part of [Buoy](https://github.com/Buoy-gg/buoy). Install the package, complete a
14
16
  npm install @buoy-gg/core @buoy-gg/debug-borders
15
17
  ```
16
18
 
17
- ## Before you start
18
-
19
- Use a development build with `@buoy-gg/core` and a Free or Pro Buoy account key. From your app’s directory, sign in:
20
-
21
- ```bash
22
- npx --package=@buoy-gg/core buoy login
23
- ```
24
-
25
- For Expo, initialize Buoy before rendering the menu:
26
-
27
- ```tsx
28
- import { Buoy } from "@buoy-gg/core";
29
-
30
- Buoy.init({ licenseKey: process.env.EXPO_PUBLIC_BUOY_KEY });
31
- ```
32
-
33
- The login command writes the Expo key to `.env.local`. For React Native CLI, pass the key from your app’s environment configuration; React Native does not load `.env.local` automatically. Mount `FloatingDevTools` inside the same providers as your screens and restart the development server after installation. The [Quick Start](https://buoy.gg/buoy/latest/docs/quick-start) shows the complete root component setup.
34
-
35
- ## Quick start
36
-
37
- ```tsx
38
- import { FloatingDevTools } from "@buoy-gg/core";
39
-
40
- export default function App() {
41
- return (
42
- <>
43
- <YourApp />
44
- <FloatingDevTools />
45
- </>
46
- );
47
- }
48
- ```
49
-
50
- Tap the BORDERS icon in the floating menu to cycle Off → Borders → Labels.
51
-
52
- Want your own naming or colors? Build the tool with `createDebugBordersTool({ name: "LAYOUT", bordersColor: "#ec4899", ... })` and pass it to `FloatingDevTools` via the `apps` array.
53
-
54
- ## Check the integration
55
-
56
- Enable borders on a known screen, then tap a component label and inspect its properties. Border drawing and label interaction differ: the labels are intentionally tappable.
19
+ Tap the Borders icon in the menu to cycle through off, borders and labels.
57
20
 
58
- ## What you get
59
-
60
- - **Depth-colored borders** — rainbow borders on every component, colored by depth in the tree, fully touch-through so they never block interaction.
61
- - **Labels mode** — filters down to components with a `testID` or `accessibilityLabel`: green = testID, pink = accessibilityLabel. Labels sit above their boxes and stack automatically when they overlap.
62
- - **Tap to inspect** — tap any label for the component's `testID`, `accessibilityLabel`, `nativeID`, key, accessibility props, full computed styles, and exact position and size.
63
- - **Answers real questions on-device** — "what testID does QA need for this button?" or "which component owns this padding?" without leaving the phone.
64
- - **Stays out of the way** — borders auto-hide on inactive screens in stack navigators and whenever a DevTools modal is open, and they track layout changes automatically.
65
- - **Works everywhere** — Expo and React Native CLI, Fabric (New Architecture) and Paper.
66
-
67
- ## Desktop & AI
68
-
69
- To connect a React Native app to [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop) or MCP, install `@buoy-gg/external-sync` and follow the [Desktop connection guide](https://buoy.gg/buoy/latest/docs/desktop). Sign in to Desktop separately. [MCP setup](https://buoy.gg/buoy/latest/docs/mcp) also requires a process account and Pro access. Available remote actions depend on the tool and app integration.
70
-
71
- ## Account and plan requirements
72
-
73
- Use a Free or Pro Buoy account. History limits and paid features vary by tool; see [pricing](https://buoy.gg/pricing). Production access requires Pro where supported. Development-only hooks and actions remain unavailable in release builds.
21
+ The [Debug Borders guide](https://buoy.gg/buoy/latest/docs/tools/debug-borders) covers setup, what it captures and its limits. New to Buoy? Start with the [Quick start](https://buoy.gg/buoy/latest/docs/quick-start).
74
22
 
75
23
  ---
76
24
 
77
- 📚 [Full docs](https://buoy.gg/buoy/latest/docs/tools/debug-borders) · [All Buoy tools](https://github.com/Buoy-gg/buoy)
78
-
79
- Proprietary software. © Buoy LLC. [Terms](https://buoy.gg/terms)
25
+ <sub>Part of <a href="https://buoy.gg">Buoy</a>, developer tools that live inside your app. Proprietary software. © Buoy LLC. <a href="https://buoy.gg/terms">Terms</a></sub>
@@ -1,236 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.DebugBordersModal = DebugBordersModal;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _jsxRuntime = require("react/jsx-runtime");
11
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
- const DebugBordersManager = require("../utils/DebugBordersManager");
13
-
14
- /**
15
- * Modal component for controlling debug borders.
16
- * This allows developers to toggle visual layout debugging borders on/off.
17
- */
18
- function DebugBordersModal({
19
- visible,
20
- onClose
21
- }) {
22
- const [enabled, setEnabled] = (0, _react.useState)(false);
23
- const [componentCount, setComponentCount] = (0, _react.useState)(0);
24
-
25
- // Subscribe to manager state
26
- (0, _react.useEffect)(() => {
27
- const unsubscribe = DebugBordersManager.subscribe(setEnabled);
28
- setEnabled(DebugBordersManager.isEnabled());
29
- return unsubscribe;
30
- }, []);
31
-
32
- // Track component count when enabled
33
- (0, _react.useEffect)(() => {
34
- if (!enabled) {
35
- setComponentCount(0);
36
- return;
37
- }
38
-
39
- // Update component count periodically
40
- const updateCount = () => {
41
- try {
42
- const {
43
- getAllHostComponentInstances
44
- } = require("../utils/fiberTreeTraversal");
45
- const instances = getAllHostComponentInstances();
46
- setComponentCount(instances.length);
47
- } catch (error) {
48
- console.error("[DebugBorders] Error getting component count:", error);
49
- }
50
- };
51
-
52
- // Initial count
53
- setTimeout(updateCount, 600);
54
-
55
- // Update every 2 seconds
56
- const interval = setInterval(updateCount, 2000);
57
- return () => clearInterval(interval);
58
- }, [enabled]);
59
- const handleToggle = () => {
60
- DebugBordersManager.toggle();
61
- };
62
- if (!visible) return null;
63
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
64
- style: styles.container,
65
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
66
- style: styles.content,
67
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
68
- style: styles.title,
69
- children: "Debug Borders"
70
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
71
- style: styles.description,
72
- children: "Visualize component layout structure with colored borders"
73
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
74
- style: styles.statusRow,
75
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
76
- style: styles.statusLabel,
77
- children: "Status:"
78
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.StatusBadge, {
79
- status: enabled ? "active" : "inactive"
80
- })]
81
- }), enabled && componentCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
82
- style: styles.statsRow,
83
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
84
- style: styles.statsLabel,
85
- children: "Components Tracked:"
86
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
87
- style: styles.statsValue,
88
- children: componentCount
89
- })]
90
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
91
- style: styles.toggleContainer,
92
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
93
- style: [styles.button, enabled && styles.buttonActive],
94
- onPress: handleToggle,
95
- accessibilityRole: "button",
96
- accessibilityLabel: `Debug borders ${enabled ? "enabled" : "disabled"}`,
97
- accessibilityHint: "Tap to toggle debug borders",
98
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Layers, {
99
- size: 40,
100
- color: enabled ? _sharedUi.night.color.accent : _sharedUi.night.color.textSecondary
101
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
102
- style: [styles.buttonText, enabled && styles.buttonTextActive],
103
- children: enabled ? "Disable Borders" : "Enable Borders"
104
- })]
105
- })
106
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
107
- style: styles.infoBox,
108
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.StatusIndicator, {
109
- status: enabled ? "success" : "info",
110
- size: "small"
111
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
112
- style: styles.infoText,
113
- children: enabled ? "Borders update every 2 seconds. Tap button to disable." : "Tap button to show colored borders around all components."
114
- })]
115
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
116
- style: styles.closeButton,
117
- onPress: onClose,
118
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
119
- style: styles.closeButtonText,
120
- children: "Close"
121
- })
122
- })]
123
- })
124
- });
125
- }
126
- const styles = _reactNative.StyleSheet.create({
127
- container: {
128
- flex: 1,
129
- justifyContent: "center",
130
- alignItems: "center",
131
- backgroundColor: "rgba(0, 0, 0, 0.5)"
132
- },
133
- content: {
134
- backgroundColor: _sharedUi.night.color.surface,
135
- borderWidth: 1,
136
- borderColor: _sharedUi.night.color.border,
137
- borderRadius: 16,
138
- padding: 32,
139
- width: "85%",
140
- maxWidth: 420,
141
- alignItems: "center"
142
- },
143
- title: {
144
- fontSize: 24,
145
- fontWeight: "700",
146
- color: _sharedUi.night.color.text,
147
- marginBottom: 8
148
- },
149
- description: {
150
- fontSize: 14,
151
- color: _sharedUi.night.color.textSecondary,
152
- textAlign: "center",
153
- marginBottom: 24
154
- },
155
- statusRow: {
156
- flexDirection: "row",
157
- alignItems: "center",
158
- marginBottom: 16,
159
- gap: 8
160
- },
161
- statusLabel: {
162
- fontSize: 14,
163
- color: _sharedUi.night.color.textSecondary,
164
- fontWeight: "600"
165
- },
166
- statsRow: {
167
- flexDirection: "row",
168
- alignItems: "center",
169
- marginBottom: 16,
170
- gap: 8
171
- },
172
- statsLabel: {
173
- fontSize: 14,
174
- color: _sharedUi.night.color.textSecondary,
175
- fontWeight: "600"
176
- },
177
- statsValue: {
178
- fontSize: 16,
179
- color: _sharedUi.night.color.text,
180
- fontWeight: "700"
181
- },
182
- toggleContainer: {
183
- alignItems: "center",
184
- justifyContent: "center",
185
- marginBottom: 24
186
- },
187
- button: {
188
- alignItems: "center",
189
- justifyContent: "center",
190
- padding: 24,
191
- borderRadius: 16,
192
- backgroundColor: _sharedUi.night.color.surfaceElevated,
193
- borderWidth: 2,
194
- borderColor: _sharedUi.night.color.border,
195
- minWidth: 200
196
- },
197
- buttonActive: {
198
- borderColor: _sharedUi.night.color.accentBorderStrong,
199
- backgroundColor: _sharedUi.night.color.accentSoft
200
- },
201
- buttonText: {
202
- marginTop: 12,
203
- fontSize: 16,
204
- fontWeight: "600",
205
- color: _sharedUi.night.color.textSecondary
206
- },
207
- buttonTextActive: {
208
- color: _sharedUi.night.color.accent
209
- },
210
- infoBox: {
211
- flexDirection: "row",
212
- alignItems: "flex-start",
213
- backgroundColor: _sharedUi.night.color.surfaceElevated,
214
- padding: 12,
215
- borderRadius: 8,
216
- marginBottom: 24,
217
- gap: 8
218
- },
219
- infoText: {
220
- flex: 1,
221
- fontSize: 12,
222
- color: _sharedUi.night.color.textSecondary,
223
- lineHeight: 16
224
- },
225
- closeButton: {
226
- paddingVertical: 12,
227
- paddingHorizontal: 32,
228
- backgroundColor: _sharedUi.night.color.accent,
229
- borderRadius: 8
230
- },
231
- closeButtonText: {
232
- color: _sharedUi.night.color.onAccent,
233
- fontSize: 16,
234
- fontWeight: "600"
235
- }
236
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.DebugBordersModal=DebugBordersModal;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(l,a){if("function"==typeof WeakMap)var e=new WeakMap,c=new WeakMap;return(_interopRequireWildcard=function(t,s){if(!s&&t&&t.__esModule)return t;var n,r,i={__proto__:null,default:t};if(null===t||"object"!=typeof t&&"function"!=typeof t)return i;if(n=s?c:e){if(n.has(t))return n.get(t);n.set(t,i)}for(const o in t)"default"!==o&&{}.hasOwnProperty.call(t,o)&&((r=(n=Object.defineProperty)&&Object.getOwnPropertyDescriptor(t,o))&&(r.get||r.set)?n(i,o,r):i[o]=t[o]);return i})(l,a)}const DebugBordersManager=require("../utils/DebugBordersManager");function DebugBordersModal({visible:l,onClose:a}){const[e,c]=(0,_react.useState)(false);const[t,s]=(0,_react.useState)(0);(0,_react.useEffect)(()=>{const r=DebugBordersManager.subscribe(c);c(DebugBordersManager.isEnabled());return r},[]);(0,_react.useEffect)(()=>{if(!e){s(0);return}const r=()=>{try{const{getAllHostComponentInstances:o}=require("../utils/fiberTreeTraversal");const u=o();s(u.length)}catch(o){console.error("[DebugBorders] Error getting component count:",o)}};setTimeout(r,600);const i=setInterval(r,2e3);return()=>clearInterval(i)},[e]);const n=()=>{DebugBordersManager.toggle()};if(!l)return null;return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.content,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.title,children:"Debug Borders"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.description,children:"Visualize component layout structure with colored borders"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statusRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statusLabel,children:"Status:"}),(0,_jsxRuntime.jsx)(_sharedUi.StatusBadge,{status:e?"active":"inactive"})]}),e&&t>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statsRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statsLabel,children:"Components Tracked:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statsValue,children:t})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.toggleContainer,children:(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:[styles.button,e&&styles.buttonActive],onPress:n,accessibilityRole:"button",accessibilityLabel:`Debug borders ${e?"enabled":"disabled"}`,accessibilityHint:"Tap to toggle debug borders",children:[(0,_jsxRuntime.jsx)(_sharedUi.Layers,{size:40,color:e?_sharedUi.night.color.accent:_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.buttonText,e&&styles.buttonTextActive],children:e?"Disable Borders":"Enable Borders"})]})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoBox,children:[(0,_jsxRuntime.jsx)(_sharedUi.StatusIndicator,{status:e?"success":"info",size:"small"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoText,children:e?"Borders update every 2 seconds. Tap button to disable.":"Tap button to show colored borders around all components."})]}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.closeButton,onPress:a,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.closeButtonText,children:"Close"})})]})})}const styles=_reactNative.StyleSheet.create({container:{flex:1,justifyContent:"center",alignItems:"center",backgroundColor:"rgba(0, 0, 0, 0.5)"},content:{backgroundColor:_sharedUi.night.color.surface,borderWidth:1,borderColor:_sharedUi.night.color.border,borderRadius:16,padding:32,width:"85%",maxWidth:420,alignItems:"center"},title:{fontSize:24,fontWeight:"700",color:_sharedUi.night.color.text,marginBottom:8},description:{fontSize:14,color:_sharedUi.night.color.textSecondary,textAlign:"center",marginBottom:24},statusRow:{flexDirection:"row",alignItems:"center",marginBottom:16,gap:8},statusLabel:{fontSize:14,color:_sharedUi.night.color.textSecondary,fontWeight:"600"},statsRow:{flexDirection:"row",alignItems:"center",marginBottom:16,gap:8},statsLabel:{fontSize:14,color:_sharedUi.night.color.textSecondary,fontWeight:"600"},statsValue:{fontSize:16,color:_sharedUi.night.color.text,fontWeight:"700"},toggleContainer:{alignItems:"center",justifyContent:"center",marginBottom:24},button:{alignItems:"center",justifyContent:"center",padding:24,borderRadius:16,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:2,borderColor:_sharedUi.night.color.border,minWidth:200},buttonActive:{borderColor:_sharedUi.night.color.accentBorderStrong,backgroundColor:_sharedUi.night.color.accentSoft},buttonText:{marginTop:12,fontSize:16,fontWeight:"600",color:_sharedUi.night.color.textSecondary},buttonTextActive:{color:_sharedUi.night.color.accent},infoBox:{flexDirection:"row",alignItems:"flex-start",backgroundColor:_sharedUi.night.color.surfaceElevated,padding:12,borderRadius:8,marginBottom:24,gap:8},infoText:{flex:1,fontSize:12,color:_sharedUi.night.color.textSecondary,lineHeight:16},closeButton:{paddingVertical:12,paddingHorizontal:32,backgroundColor:_sharedUi.night.color.accent,borderRadius:8},closeButtonText:{color:_sharedUi.night.color.onAccent,fontSize:16,fontWeight:"600"}});