cicy-desktop 2.1.69 → 2.1.71

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 (61) hide show
  1. package/package.json +7 -7
  2. package/src/backends/homepage-react/assets/index-BpljolQs.js +365 -0
  3. package/src/backends/homepage-react/assets/{index-BniEbx_j.css → index-C9AZlTew.css} +1 -1
  4. package/src/backends/homepage-react/index.html +2 -2
  5. package/src/backends/local-teams.js +42 -4
  6. package/src/backends/sidecar-ipc.js +23 -1
  7. package/src/i18n/locales/en.json +9 -7
  8. package/src/i18n/locales/zh-CN.json +9 -7
  9. package/src/sidecar/cicy-code.js +54 -111
  10. package/src/sidecar/localbin.js +133 -0
  11. package/src/sidecar/native.js +4 -2
  12. package/src/sidecar/runtime.js +7 -3
  13. package/workers/render/src/App.css +156 -10
  14. package/workers/render/src/App.jsx +254 -39
  15. package/.env.dev +0 -7
  16. package/src/backends/homepage-react/assets/index-B8gGhz8B.js +0 -365
  17. package/workers/render.bak.20260528-2338/DESIGN_v2.md +0 -254
  18. package/workers/render.bak.20260528-2338/index.html +0 -12
  19. package/workers/render.bak.20260528-2338/package-lock.json +0 -827
  20. package/workers/render.bak.20260528-2338/package.json +0 -19
  21. package/workers/render.bak.20260528-2338/public/_headers +0 -5
  22. package/workers/render.bak.20260528-2338/public/manifest.json +0 -6
  23. package/workers/render.bak.20260528-2338/src/App.css +0 -224
  24. package/workers/render.bak.20260528-2338/src/App.jsx +0 -1028
  25. package/workers/render.bak.20260528-2338/src/api.js +0 -285
  26. package/workers/render.bak.20260528-2338/src/cicycode-ops.js +0 -222
  27. package/workers/render.bak.20260528-2338/src/components/BackendCard.css +0 -299
  28. package/workers/render.bak.20260528-2338/src/components/BackendCard.jsx +0 -133
  29. package/workers/render.bak.20260528-2338/src/components/BackendModal.css +0 -161
  30. package/workers/render.bak.20260528-2338/src/components/BackendModal.jsx +0 -199
  31. package/workers/render.bak.20260528-2338/src/components/Button.css +0 -72
  32. package/workers/render.bak.20260528-2338/src/components/Button.jsx +0 -37
  33. package/workers/render.bak.20260528-2338/src/components/Card.css +0 -42
  34. package/workers/render.bak.20260528-2338/src/components/Card.jsx +0 -21
  35. package/workers/render.bak.20260528-2338/src/components/Icon.jsx +0 -30
  36. package/workers/render.bak.20260528-2338/src/components/Menu.css +0 -55
  37. package/workers/render.bak.20260528-2338/src/components/Menu.jsx +0 -91
  38. package/workers/render.bak.20260528-2338/src/components/SidecarBanner.css +0 -79
  39. package/workers/render.bak.20260528-2338/src/components/SidecarBanner.jsx +0 -84
  40. package/workers/render.bak.20260528-2338/src/components/StatusChip.css +0 -19
  41. package/workers/render.bak.20260528-2338/src/components/StatusChip.jsx +0 -31
  42. package/workers/render.bak.20260528-2338/src/components/Toast.css +0 -31
  43. package/workers/render.bak.20260528-2338/src/components/Toast.jsx +0 -23
  44. package/workers/render.bak.20260528-2338/src/components/WslSetupBanner.css +0 -464
  45. package/workers/render.bak.20260528-2338/src/components/WslSetupBanner.jsx +0 -716
  46. package/workers/render.bak.20260528-2338/src/dockerInstaller.js +0 -0
  47. package/workers/render.bak.20260528-2338/src/i18n/en.json +0 -116
  48. package/workers/render.bak.20260528-2338/src/i18n/fr.json +0 -116
  49. package/workers/render.bak.20260528-2338/src/i18n/index.js +0 -69
  50. package/workers/render.bak.20260528-2338/src/i18n/ja.json +0 -116
  51. package/workers/render.bak.20260528-2338/src/i18n/zh-CN.json +0 -121
  52. package/workers/render.bak.20260528-2338/src/main.js +0 -475
  53. package/workers/render.bak.20260528-2338/src/main.jsx +0 -18
  54. package/workers/render.bak.20260528-2338/src/style.css +0 -275
  55. package/workers/render.bak.20260528-2338/src/styles/base.css +0 -98
  56. package/workers/render.bak.20260528-2338/src/styles/tokens.css +0 -90
  57. package/workers/render.bak.20260528-2338/src/tos.js +0 -72
  58. package/workers/render.bak.20260528-2338/src/worker.js +0 -40
  59. package/workers/render.bak.20260528-2338/src/wslInstaller.js +0 -1563
  60. package/workers/render.bak.20260528-2338/vite.config.js +0 -36
  61. package/workers/render.bak.20260528-2338/wrangler.toml +0 -17
@@ -1,299 +0,0 @@
1
- /* ── Square BackendCard ─────────────────────────────────────────────────
2
- Aspect 1:1, brand-accented top stripe, large name, prominent CTA.
3
- */
4
- .bcard {
5
- position: relative;
6
- /* Fixed footprint — does not stretch with window width. The grid is
7
- repeat(auto-fill, 200px) so columns are always exactly 200px wide. */
8
- width: 200px;
9
- height: 200px;
10
- background: var(--bg-elev-1);
11
- border: 1px solid var(--hairline);
12
- border-radius: var(--r-lg);
13
- padding: var(--sp-4);
14
- display: flex;
15
- flex-direction: column;
16
- overflow: hidden;
17
- cursor: default;
18
- transition: transform var(--dur-base) var(--ease),
19
- box-shadow var(--dur-base) var(--ease),
20
- border-color var(--dur-base) var(--ease);
21
- }
22
- .bcard:hover {
23
- transform: translateY(-2px);
24
- border-color: var(--hairline-strong, var(--hairline));
25
- box-shadow: 0 8px 24px -8px rgba(0,0,0,0.18), 0 1px 0 rgba(255,255,255,0.04) inset;
26
- }
27
-
28
- /* top accent stripe — colored bar that runs across the top edge */
29
- .bcard__accent {
30
- position: absolute;
31
- top: 0; left: 0; right: 0;
32
- height: 3px;
33
- background: var(--brand);
34
- opacity: 0.85;
35
- }
36
-
37
- /* Glowing background circle for online cards (subtle) */
38
- .bcard--online::before {
39
- content: "";
40
- position: absolute;
41
- bottom: -40%;
42
- right: -20%;
43
- width: 140%;
44
- height: 100%;
45
- background: radial-gradient(circle at center, var(--brand-soft) 0%, transparent 60%);
46
- pointer-events: none;
47
- opacity: 0.5;
48
- }
49
-
50
- /* ── top row: status pill + menu ── */
51
- .bcard__top {
52
- display: flex;
53
- align-items: center;
54
- justify-content: space-between;
55
- position: relative;
56
- z-index: 1;
57
- }
58
- .bcard__status-pill {
59
- display: inline-flex;
60
- align-items: center;
61
- gap: 6px;
62
- padding: 4px 8px;
63
- background: var(--bg);
64
- border: 1px solid var(--hairline);
65
- border-radius: var(--r-pill);
66
- color: var(--fg-2);
67
- }
68
- .bcard__status-pill svg { color: var(--fg-3); }
69
- .bcard__dot {
70
- width: 7px; height: 7px;
71
- border-radius: 50%;
72
- background: var(--fg-3);
73
- flex-shrink: 0;
74
- }
75
- .bcard__dot--up { background: var(--ok); box-shadow: 0 0 0 2px color-mix(in srgb, var(--ok) 30%, transparent); }
76
- .bcard__dot--warn { background: var(--warn); }
77
- .bcard__dot--down { background: var(--err); }
78
- .bcard__dot--unknown { background: var(--fg-3); }
79
-
80
- .bcard__menu-trigger { color: var(--fg-3); }
81
- .bcard__menu-trigger:hover { color: var(--fg); }
82
-
83
- /* ── body: name + host + meta ── */
84
- .bcard__body {
85
- flex: 1;
86
- display: flex;
87
- flex-direction: column;
88
- gap: var(--sp-1);
89
- padding-top: var(--sp-3);
90
- padding-bottom: var(--sp-3);
91
- position: relative;
92
- z-index: 1;
93
- min-width: 0;
94
- }
95
- .bcard__name {
96
- margin: 0;
97
- font-size: 17px;
98
- font-weight: 700;
99
- color: var(--fg);
100
- letter-spacing: -0.015em;
101
- line-height: 1.25;
102
- overflow: hidden;
103
- text-overflow: ellipsis;
104
- white-space: nowrap;
105
- }
106
- .bcard__host {
107
- font-family: var(--font-mono);
108
- font-size: 11px;
109
- color: var(--fg-2);
110
- overflow: hidden;
111
- text-overflow: ellipsis;
112
- white-space: nowrap;
113
- }
114
- .bcard__meta {
115
- display: flex;
116
- flex-wrap: wrap;
117
- gap: 4px;
118
- font-size: 11px;
119
- color: var(--fg-3);
120
- }
121
- .bcard__ver {
122
- font-family: var(--font-mono);
123
- color: var(--fg-2);
124
- background: var(--bg);
125
- padding: 1px 6px;
126
- border-radius: var(--r-sm);
127
- border: 1px solid var(--hairline);
128
- }
129
- .bcard__sep { opacity: 0.4; }
130
- .bcard__badge {
131
- display: inline-flex; align-items: center;
132
- align-self: flex-start;
133
- padding: 2px 8px;
134
- border-radius: var(--r-pill);
135
- background: var(--brand-soft);
136
- color: var(--brand);
137
- font-size: 10px;
138
- font-weight: 700;
139
- text-transform: uppercase;
140
- letter-spacing: 0.4px;
141
- }
142
-
143
- /* ── primary CTA button ── */
144
- .bcard__cta {
145
- position: relative; z-index: 1;
146
- display: inline-flex;
147
- align-items: center;
148
- justify-content: center;
149
- gap: 8px;
150
- width: 100%;
151
- height: 38px;
152
- border: none;
153
- border-radius: var(--r-md);
154
- background: var(--brand);
155
- color: white;
156
- font-size: var(--t-sm);
157
- font-weight: 600;
158
- letter-spacing: 0.1px;
159
- cursor: pointer;
160
- transition: transform 0.1s var(--ease), background var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
161
- box-shadow: 0 2px 6px -1px color-mix(in srgb, var(--brand) 35%, transparent);
162
- }
163
- .bcard__cta:hover {
164
- background: color-mix(in srgb, var(--brand) 90%, white);
165
- box-shadow: 0 4px 10px -2px color-mix(in srgb, var(--brand) 50%, transparent);
166
- }
167
- .bcard__cta:active { transform: translateY(1px); }
168
- .bcard__cta:disabled {
169
- background: var(--bg);
170
- color: var(--fg-3);
171
- cursor: not-allowed;
172
- box-shadow: none;
173
- border: 1px solid var(--hairline);
174
- }
175
- .bcard__cta--ghost {
176
- background: var(--bg);
177
- color: var(--fg);
178
- border: 1px solid var(--hairline);
179
- box-shadow: none;
180
- }
181
- .bcard__cta--ghost:hover {
182
- background: var(--bg-elev-2, var(--bg));
183
- border-color: var(--brand);
184
- color: var(--brand);
185
- }
186
- .bcard__cta-spinner {
187
- width: 14px; height: 14px;
188
- border: 2px solid currentColor;
189
- border-top-color: transparent;
190
- border-radius: 50%;
191
- animation: bcard-spin 0.8s linear infinite;
192
- }
193
- @keyframes bcard-spin { to { transform: rotate(360deg); } }
194
-
195
- /* ── progress overlay — replaces CTA ── */
196
- .bcard__progress {
197
- position: relative; z-index: 1;
198
- display: flex;
199
- flex-direction: column;
200
- gap: 6px;
201
- }
202
- .bcard__progress-text {
203
- display: flex;
204
- justify-content: space-between;
205
- font-size: 12px;
206
- font-weight: 500;
207
- color: var(--fg);
208
- }
209
- .bcard__progress-pct { color: var(--brand); font-weight: 700; }
210
- .bcard__progress-bar {
211
- height: 5px;
212
- background: var(--bg);
213
- border-radius: var(--r-pill);
214
- overflow: hidden;
215
- border: 1px solid var(--hairline);
216
- }
217
- .bcard__progress-fill {
218
- height: 100%;
219
- background: linear-gradient(90deg, var(--brand), color-mix(in srgb, var(--brand) 60%, white));
220
- transition: width 0.3s var(--ease);
221
- border-radius: var(--r-pill);
222
- }
223
- .bcard__progress-bar.is-indeterminate .bcard__progress-fill {
224
- animation: bcard-indeterminate 1.4s ease-in-out infinite;
225
- }
226
- @keyframes bcard-indeterminate {
227
- 0% { transform: translateX(-100%); }
228
- 100% { transform: translateX(400%); }
229
- }
230
- .bcard__progress-meta {
231
- display: flex;
232
- justify-content: space-between;
233
- align-items: center;
234
- font-size: 11px;
235
- color: var(--fg-3);
236
- font-family: var(--font-mono);
237
- }
238
- .bcard__cancel {
239
- background: transparent;
240
- border: none;
241
- color: var(--fg-3);
242
- font-size: 11px;
243
- cursor: pointer;
244
- padding: 0;
245
- font-family: inherit;
246
- }
247
- .bcard__cancel:hover { color: var(--err); }
248
-
249
- /* Scrollable log panel under the progress bar — surfaces every shell command
250
- and its summarized output so the user knows the install is alive. */
251
- /* When the install log is showing, let the card span the entire grid row
252
- so the scrollable log has room (otherwise it's clamped to one card width). */
253
- .bcard.bcard--has-log {
254
- grid-column: 1 / -1;
255
- }
256
-
257
- /* Install-time scrolling shell log. Each entry is one shell command preview
258
- and its summarized output so the user knows the install is alive. */
259
- .bcard__progress-log {
260
- margin-top: 10px;
261
- max-height: 55vh;
262
- min-height: 200px;
263
- overflow-y: auto;
264
- font-family: var(--font-mono);
265
- font-size: 12px;
266
- line-height: 1.5;
267
- color: var(--fg-3);
268
- background: color-mix(in srgb, var(--bg-1, #0d1117) 70%, transparent);
269
- border: 1px solid var(--border, #30363d);
270
- border-radius: 6px;
271
- padding: 10px 12px;
272
- white-space: pre-wrap;
273
- word-break: break-word;
274
- user-select: text;
275
- }
276
-
277
- /* ── kind variants ── */
278
- .bcard--local .bcard__accent { background: var(--brand); }
279
- .bcard--cloud .bcard__accent { background: var(--accent-cloud, #f59e0b); }
280
- .bcard--cloud .bcard__cta { background: var(--accent-cloud, #f59e0b); box-shadow: 0 2px 6px -1px color-mix(in srgb, var(--accent-cloud, #f59e0b) 35%, transparent); }
281
- .bcard--cloud .bcard__cta:hover { background: color-mix(in srgb, var(--accent-cloud, #f59e0b) 90%, white); }
282
-
283
-
284
- /* Minimal in-progress state — used when the WSL banner above the grid
285
- already shows the full step timeline. The card just says "安装中…"
286
- to avoid duplicating that information. */
287
- .bcard__progress--minimal {
288
- display: flex;
289
- flex-direction: row !important;
290
- align-items: center;
291
- justify-content: center;
292
- gap: 8px;
293
- flex: 1;
294
- font-size: var(--t-sm);
295
- color: var(--fg-2);
296
- }
297
- .bcard__progress--minimal .bcard__cta-spinner {
298
- border-color: var(--fg-3) transparent transparent transparent;
299
- }
@@ -1,133 +0,0 @@
1
- import Card from "./Card.jsx";
2
- import Button from "./Button.jsx";
3
- import Menu from "./Menu.jsx";
4
- import StatusChip, { dotKind } from "./StatusChip.jsx";
5
- import Icon from "./Icon.jsx";
6
- import { useT } from "../i18n";
7
- import "./BackendCard.css";
8
-
9
- /**
10
- * Square BackendCard — single tile in the grid. 1:1 aspect ratio.
11
- *
12
- * Visual layout (top-down):
13
- * ┌──────────────────────┐
14
- * │ ● ⋯ │ meta row: status dot, kind icon, menu
15
- * │ │
16
- * │ Local │ name (large, bold)
17
- * │ 127.0.0.1:8008 │ host (mono, dim)
18
- * │ v2.0.7 · 3h │ version + uptime
19
- * │ │
20
- * │ ┌──────────────────┐ │
21
- * │ │ ↗ Open │ │ primary action (full-width)
22
- * │ └──────────────────┘ │
23
- * └──────────────────────┘
24
- */
25
- export default function BackendCard({
26
- backend, health, onOpen, menuItems = [],
27
- badge, openLoading = false, openDisabled = false,
28
- primaryButton, progress, progressLog, onCancel,
29
- }) {
30
- const t = useT();
31
- const isLocal = backend.kind === "local";
32
- const kind = dotKind(health);
33
-
34
- const hasProgress = !!progress;
35
- const pct = hasProgress && typeof progress.progress === "number"
36
- ? Math.round(progress.progress * 100) : null;
37
-
38
- const accent = isLocal ? "var(--brand)" : "var(--accent-cloud)";
39
-
40
- return (
41
- <div className={`bcard ${isLocal ? "bcard--local" : "bcard--cloud"} ${kind === "up" ? "bcard--online" : ""} ${hasProgress && progressLog && progressLog.length > 0 ? "bcard--has-log" : ""}`}>
42
- <div className="bcard__accent" style={{ background: accent }} />
43
-
44
- <div className="bcard__top">
45
- <div className="bcard__status-pill">
46
- <span className={`bcard__dot bcard__dot--${kind}`} />
47
- <Icon name={isLocal ? "laptop" : "globe"} size={12} />
48
- </div>
49
- {menuItems.length > 0 && !hasProgress && (
50
- <Menu
51
- trigger={<Button variant="ghost" size="sm" className="btn--icon bcard__menu-trigger" icon={<Icon name="more" />} />}
52
- items={menuItems}
53
- />
54
- )}
55
- </div>
56
-
57
- <div className="bcard__body">
58
- <h3 className="bcard__name" title={isLocal ? t("team.local") : backend.name}>
59
- {isLocal ? t("team.local") : backend.name}
60
- </h3>
61
- {badge && <span className="bcard__badge">{badge}</span>}
62
- </div>
63
-
64
- {hasProgress ? (
65
- progress.minimal ? (
66
- // Minimal state: just say "安装中…" with a small spinner. The
67
- // detailed timeline + progress bar lives in the WSL banner
68
- // above the grid; the card avoids duplicating it.
69
- <div className="bcard__progress bcard__progress--minimal">
70
- <span className="bcard__cta-spinner" />
71
- <span>{t("card.installing")}</span>
72
- </div>
73
- ) : (
74
- <div className="bcard__progress">
75
- <div className="bcard__progress-text">
76
- <span>{progress.message || t("card.installing")}</span>
77
- <span className="bcard__progress-pct">{pct == null ? "" : `${pct}%`}</span>
78
- </div>
79
- <div className={`bcard__progress-bar ${pct == null ? "is-indeterminate" : ""}`}>
80
- <div className="bcard__progress-fill" style={{ width: pct == null ? "30%" : `${pct}%` }} />
81
- </div>
82
- <div className="bcard__progress-meta">
83
- <span>
84
- {progress.received != null && progress.total
85
- ? `${formatBytes(progress.received)} / ${formatBytes(progress.total)}`
86
- : (progress.phase || "")}
87
- </span>
88
- {onCancel && (
89
- <button type="button" className="bcard__cancel" onClick={onCancel}>{t("card.cancel")}</button>
90
- )}
91
- </div>
92
- {progressLog && progressLog.length > 0 && (
93
- <pre className="bcard__progress-log" ref={(el) => {
94
- // Auto-scroll to the bottom whenever a new line lands. ref callback
95
- // runs on every render — cheaper than a useEffect for a leaf div.
96
- if (el) el.scrollTop = el.scrollHeight;
97
- }}>
98
- {progressLog.join("\n")}
99
- </pre>
100
- )}
101
- </div>
102
- )
103
- ) : (
104
- <button
105
- type="button"
106
- className={`bcard__cta ${primaryButton?.variant === "ghost" ? "bcard__cta--ghost" : ""}`}
107
- /* openDisabled is intended for the default Open button (which
108
- would launch into a not-yet-running container). When the
109
- caller supplies a primaryButton (Install / Start / Retry /
110
- Update), it has its own onClick and shouldn't inherit that
111
- gating — otherwise e.g. the Install button in `missing` state
112
- is disabled by the very condition (no daemon) that requires
113
- clicking Install. The primaryButton can still opt in
114
- explicitly via its own `disabled: true`. */
115
- disabled={primaryButton ? !!primaryButton.disabled : openDisabled}
116
- onClick={primaryButton?.onClick || onOpen}
117
- >
118
- {(primaryButton?.loading ?? openLoading)
119
- ? <span className="bcard__cta-spinner" />
120
- : <Icon name={primaryButton?.icon || "open"} size={14} />}
121
- <span>{primaryButton?.label || t("card.open")}</span>
122
- </button>
123
- )}
124
- </div>
125
- );
126
- }
127
-
128
- function formatBytes(n) {
129
- if (n == null) return "?";
130
- if (n < 1024) return `${n} B`;
131
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
132
- return `${(n / (1024 * 1024)).toFixed(1)} MB`;
133
- }
@@ -1,161 +0,0 @@
1
- .modal-backdrop {
2
- position: fixed;
3
- inset: 0;
4
- background: rgba(5, 8, 12, 0.6);
5
- backdrop-filter: blur(6px);
6
- -webkit-backdrop-filter: blur(6px);
7
- display: grid;
8
- place-items: center;
9
- z-index: 2000;
10
- animation: modal-fade var(--dur-base) var(--ease);
11
- padding: var(--sp-4);
12
- }
13
- @keyframes modal-fade {
14
- from { opacity: 0; }
15
- to { opacity: 1; }
16
- }
17
-
18
- .modal {
19
- width: 100%;
20
- max-width: 480px;
21
- background: var(--bg-elev-1);
22
- border: 1px solid var(--hairline-2);
23
- border-radius: var(--r-lg);
24
- box-shadow: 0 24px 48px -12px rgba(0,0,0,0.6), 0 4px 12px rgba(0,0,0,0.3);
25
- display: flex;
26
- flex-direction: column;
27
- overflow: hidden;
28
- animation: modal-rise var(--dur-base) var(--ease);
29
- }
30
- @keyframes modal-rise {
31
- from { opacity: 0; transform: translateY(8px) scale(0.98); }
32
- to { opacity: 1; transform: translateY(0) scale(1); }
33
- }
34
-
35
- .modal__head {
36
- display: flex;
37
- align-items: center;
38
- justify-content: space-between;
39
- padding: var(--sp-4) var(--sp-5);
40
- border-bottom: 1px solid var(--hairline);
41
- }
42
- .modal__title {
43
- margin: 0;
44
- font-size: var(--t-md);
45
- font-weight: 600;
46
- color: var(--fg);
47
- letter-spacing: -0.01em;
48
- }
49
- .modal__close {
50
- display: grid; place-items: center;
51
- width: 28px; height: 28px;
52
- border-radius: var(--r-sm);
53
- color: var(--fg-3);
54
- transition: all var(--dur-fast) var(--ease);
55
- }
56
- .modal__close:hover { color: var(--fg); background: var(--bg-elev-2); }
57
-
58
- .modal__body {
59
- padding: var(--sp-5);
60
- display: flex;
61
- flex-direction: column;
62
- gap: var(--sp-4);
63
- }
64
- .modal__field {
65
- display: flex;
66
- flex-direction: column;
67
- gap: 6px;
68
- }
69
- .modal__label {
70
- font-size: 11px;
71
- font-weight: 600;
72
- color: var(--fg-2);
73
- text-transform: uppercase;
74
- letter-spacing: 0.04em;
75
- }
76
- .modal__required { color: var(--brand); }
77
- .modal__input {
78
- background: var(--bg);
79
- border: 1px solid var(--hairline-2);
80
- border-radius: var(--r-sm);
81
- padding: 10px 12px;
82
- font-size: var(--t-sm);
83
- color: var(--fg);
84
- font-family: inherit;
85
- transition: all var(--dur-fast) var(--ease);
86
- user-select: text;
87
- -webkit-user-select: text;
88
- }
89
- .modal__input:focus {
90
- border-color: var(--brand);
91
- box-shadow: 0 0 0 3px var(--brand-soft);
92
- outline: none;
93
- }
94
- .modal__input::placeholder { color: var(--fg-3); }
95
-
96
- .modal__status {
97
- font-size: var(--t-xs);
98
- padding: 8px 12px;
99
- border-radius: var(--r-sm);
100
- }
101
- .modal__status--idle { display: none; }
102
- .modal__status--probing { background: var(--brand-soft); color: var(--brand); }
103
- .modal__status--ok { background: var(--success-soft); color: var(--success); }
104
- .modal__status--err { background: var(--danger-soft); color: var(--danger); }
105
-
106
- .modal__foot {
107
- display: flex;
108
- justify-content: flex-end;
109
- gap: var(--sp-2);
110
- padding: var(--sp-3) var(--sp-5) var(--sp-4);
111
- border-top: 1px solid var(--hairline);
112
- }
113
-
114
- .modal__input[readonly] {
115
- color: var(--fg-3);
116
- cursor: not-allowed;
117
- background: var(--bg-elev-2);
118
- border-color: var(--hairline);
119
- }
120
- .modal__input[readonly]:focus {
121
- border-color: var(--hairline);
122
- box-shadow: none;
123
- }
124
- .modal__locked {
125
- font-size: 10px;
126
- color: var(--fg-3);
127
- font-weight: 400;
128
- text-transform: none;
129
- letter-spacing: normal;
130
- margin-left: 6px;
131
- }
132
-
133
- .modal__token-wrap {
134
- position: relative;
135
- display: flex;
136
- align-items: stretch;
137
- }
138
- .modal__token-input {
139
- flex: 1;
140
- padding-right: 40px; /* leave room for the eye button */
141
- }
142
- .modal__token-toggle {
143
- position: absolute;
144
- right: 4px;
145
- top: 50%;
146
- transform: translateY(-50%);
147
- width: 32px;
148
- height: 32px;
149
- display: grid;
150
- place-items: center;
151
- border-radius: var(--r-sm);
152
- color: var(--fg-3);
153
- cursor: pointer;
154
- background: transparent;
155
- border: 0;
156
- transition: all var(--dur-fast) var(--ease);
157
- }
158
- .modal__token-toggle:hover {
159
- color: var(--fg);
160
- background: var(--bg-elev-2);
161
- }