pyhttp-app 2.0.1__py3-none-any.whl

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.
@@ -0,0 +1,585 @@
1
+ /* Inter, bundled so the default font works offline (SIL OFL 1.1, see vendor/fonts/Inter-OFL.txt) */
2
+ @font-face {
3
+ font-family: "Inter Variable"; font-style: normal; font-display: swap; font-weight: 100 900;
4
+ src: url(/static/vendor/fonts/inter-latin-ext-wght-normal.woff2) format("woff2-variations");
5
+ unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
6
+ }
7
+ @font-face {
8
+ font-family: "Inter Variable"; font-style: normal; font-display: swap; font-weight: 100 900;
9
+ src: url(/static/vendor/fonts/inter-latin-wght-normal.woff2) format("woff2-variations");
10
+ unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
11
+ }
12
+ :root {
13
+ color-scheme: dark;
14
+ --bg: #111418;
15
+ --bg-2: #181c22;
16
+ --bg-3: #1f242c;
17
+ --bg-4: #272d37;
18
+ --border: #2d3440;
19
+ --text: #e4e8ee;
20
+ --muted: #8b94a3;
21
+ --primary: #3b82f6;
22
+ --primary-2: #2563eb;
23
+ --accent: #10b981;
24
+ --accent-2: #059669;
25
+ --danger: #ef4444;
26
+ --warn: #f59e0b;
27
+ --ok: #22c55e;
28
+ --mono: ui-monospace, "Cascadia Code", "JetBrains Mono", Menlo, Consolas, monospace;
29
+ /* Settings > Appearance > Font picks these; the head script applies the saved choice before first paint */
30
+ --sans: "Inter Variable", Inter, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
31
+ }
32
+ * { box-sizing: border-box; }
33
+ html, body { height: 100%; margin: 0; }
34
+ body { background: var(--bg); color: var(--text); font: 14px/1.45 var(--sans); overflow: hidden; display: flex; flex-direction: column; }
35
+ .topbar { flex: none; }
36
+ button, input, select, textarea { font: inherit; color: inherit; }
37
+ code { font-family: var(--mono); background: var(--bg-4); padding: 1px 5px; border-radius: 4px; font-size: 12px; }
38
+ .mono { font-family: var(--mono); font-size: 13px; }
39
+ .muted { color: var(--muted); }
40
+ .small { font-size: 12px; }
41
+ .grow { flex: 1 1 auto; min-width: 0; }
42
+ [hidden] { display: none !important; }
43
+
44
+ /* ---------------------------------------------------------------- inputs */
45
+ input, select, textarea {
46
+ background: var(--bg-3); border: 1px solid var(--border); border-radius: 6px;
47
+ padding: 7px 10px; outline: none; min-width: 0;
48
+ }
49
+ input:hover:not(:focus):not([type=checkbox]), select:hover:not(:focus), textarea:hover:not(:focus) { border-color: color-mix(in srgb, var(--muted) 45%, var(--border)); }
50
+ input:focus, select:focus, textarea:focus { border-color: var(--primary); }
51
+ /* one caret on every select, drawn, so it matches the theme instead of the OS widget */
52
+ select {
53
+ appearance: none; -webkit-appearance: none; padding-right: 26px;
54
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.5 6.5 8 10l3.5-3.5' fill='none' stroke='%238b94a3' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
55
+ background-repeat: no-repeat; background-position: right 7px center; background-size: 15px;
56
+ }
57
+ /* checkboxes: one larger, theme-aware box everywhere (sidebar, bodies, headers, params, dialogs) */
58
+ input[type=checkbox] {
59
+ appearance: none; -webkit-appearance: none; flex: none; width: 18px; height: 18px; margin: 0; padding: 0;
60
+ border: 1.5px solid var(--muted); border-radius: 4px; background: var(--bg-3) center / 14px 14px no-repeat;
61
+ cursor: pointer; vertical-align: -4px; transition: background-color .1s, border-color .1s;
62
+ }
63
+ input[type=checkbox]:hover:not(:disabled) { border-color: var(--text); }
64
+ input[type=checkbox]:checked, input[type=checkbox]:indeterminate { background-color: var(--accent); border-color: var(--accent); }
65
+ input[type=checkbox]:checked { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
66
+ input[type=checkbox]:indeterminate { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8h8' stroke='%23fff' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E"); }
67
+ input[type=checkbox]:focus { border-color: var(--muted); }
68
+ input[type=checkbox]:checked:focus { border-color: var(--accent); }
69
+ input[type=checkbox]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
70
+ input[type=checkbox]:disabled { opacity: .45; cursor: not-allowed; }
71
+ :where(label:has(> input[type=checkbox])) { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
72
+ textarea { resize: vertical; width: 100%; }
73
+ button {
74
+ background: var(--bg-4); border: 1px solid var(--border); border-radius: 6px;
75
+ padding: 7px 12px; cursor: pointer; white-space: nowrap;
76
+ }
77
+ button:hover { background: #313947; }
78
+ button:disabled { opacity: .45; cursor: not-allowed; }
79
+ button.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
80
+ button.primary:hover { background: var(--primary-2); }
81
+ button.accent { background: var(--accent); border-color: var(--accent); color: #042b1f; font-weight: 600; }
82
+ button.accent:hover { background: var(--accent-2); }
83
+ button.danger { color: var(--danger); }
84
+ button.danger:hover { background: rgba(239,68,68,.15); }
85
+ button.link { background: none; border: none; color: var(--primary); padding: 4px 6px; }
86
+ button.link:hover { text-decoration: underline; background: none; }
87
+ /* icon buttons: one larger, square hit target for every glyph button (✕ ⋯ ▲▼ 🗑 ⧉), to match the checkboxes */
88
+ button.icon {
89
+ display: inline-flex; align-items: center; justify-content: center; flex: none;
90
+ min-width: 28px; height: 28px; padding: 2px 6px; font-size: 16px; line-height: 1;
91
+ }
92
+ button.icon svg { width: 17px; height: 17px; }
93
+ :where(button, select, .chip, [tabindex]):focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
94
+
95
+ /* ---------------------------------------------------------------- layout */
96
+ .topbar {
97
+ height: 48px; display: flex; align-items: center; gap: 16px; padding: 0 16px;
98
+ background: var(--bg-2); border-bottom: 1px solid var(--border);
99
+ }
100
+ .brand { display: flex; align-items: center; gap: 9px; flex: none; user-select: none; -webkit-user-select: none; }
101
+ .brand-mark { display: block; flex: none; filter: drop-shadow(0 2px 6px rgba(16,185,129,.25)); }
102
+ .brand-word { font-weight: 700; font-size: 17px; letter-spacing: -.2px; line-height: 1; }
103
+ .brand-word span {
104
+ background: linear-gradient(90deg, #60a5fa, #34d399); -webkit-background-clip: text; background-clip: text; color: transparent;
105
+ }
106
+ :root[data-theme="light"] .brand-word span { background-image: linear-gradient(90deg, #2563eb, #059669); }
107
+ .topbar-actions { display: flex; gap: 6px; align-items: center; margin-left: auto; }
108
+ .topbar-actions > button:not(.update-pill) { background: none; border-color: transparent; color: var(--muted); }
109
+ .topbar-actions > button:not(.update-pill):hover { background: var(--bg-4); border-color: var(--border); color: var(--text); }
110
+ .layout {
111
+ display: grid; grid-template-columns: var(--side-w, 320px) minmax(480px, 1fr) var(--runs-w, 380px);
112
+ flex: 1 1 auto; min-height: 0;
113
+ }
114
+ .sidebar, .runs { background: var(--bg-2); display: flex; flex-direction: column; min-height: 0; position: relative; }
115
+ .sidebar { border-right: 1px solid var(--border); }
116
+ .runs { border-left: 1px solid var(--border); }
117
+ .editor { display: flex; flex-direction: column; min-height: 0; overflow: auto; padding: 14px 16px; }
118
+ .empty { color: var(--muted); padding: 24px 16px; text-align: center; }
119
+ .editor > .empty { margin: auto; max-width: 560px; }
120
+ .empty-keys { display: flex; gap: 8px 18px; justify-content: center; flex-wrap: wrap; margin: 16px 0 6px; font-size: 12px; }
121
+ .empty-keys span { white-space: nowrap; }
122
+ .empty-mark { opacity: .55; margin-bottom: 4px; }
123
+ .empty p { margin: 6px 0; }
124
+ .row { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
125
+ .title-input { font-weight: 600; font-size: 15px; }
126
+ .url-row { margin-top: 4px; }
127
+ .method-select { font-family: var(--mono); font-weight: 700; }
128
+
129
+ /* --------------------------------------------------------------- sidebar */
130
+ .sidebar-head { display: flex; gap: 8px; padding: 12px; border-bottom: 1px solid var(--border); }
131
+ .sidebar-head input { flex: 1; }
132
+ .tag-filter { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 12px; border-bottom: 1px solid var(--border); max-height: 110px; overflow: auto; }
133
+ .tag-filter:empty { display: none; }
134
+ .chip {
135
+ background: var(--bg-4); border: 1px solid var(--border); border-radius: 999px;
136
+ padding: 2px 10px; font-size: 12px; cursor: pointer; user-select: none;
137
+ }
138
+ .chip:hover { border-color: var(--primary); }
139
+ .chip.active { background: var(--primary); border-color: var(--primary); color: #fff; }
140
+ .chip .n { color: var(--muted); margin-left: 4px; }
141
+ .chip.active .n { color: #dbeafe; }
142
+ .select-bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--border); }
143
+ .select-bar label { display: flex; gap: 6px; align-items: center; font-size: 13px; cursor: pointer; }
144
+ .select-bar #btn-run { margin-left: auto; }
145
+ .req-list { list-style: none; margin: 0; padding: 6px 0; overflow: auto; flex: 1; }
146
+ .req-item {
147
+ display: grid; grid-template-columns: 22px 54px 1fr 28px; gap: 8px; align-items: center;
148
+ padding: 7px 6px 7px 12px; cursor: pointer; border-left: 3px solid transparent;
149
+ }
150
+ .req-item:hover { background: var(--bg-3); }
151
+ .req-item.active { background: var(--bg-3); border-left-color: var(--primary); }
152
+ .req-item.selected { background: rgba(16,185,129,.08); }
153
+ .req-item.kb-focus { background: var(--bg-3); box-shadow: inset 0 0 0 1px var(--primary); }
154
+ .req-item .name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 500; }
155
+ .req-item .sub { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
156
+ .req-item .tag { color: var(--accent); margin-right: 6px; }
157
+ .method { font-family: var(--mono); font-weight: 700; font-size: 11px; text-align: center; padding: 2px 4px; border-radius: 4px; background: color-mix(in srgb, currentColor 12%, transparent); }
158
+ /* the URL row's method select takes the same color as the method it shows */
159
+ .method-select { padding-right: 26px; }
160
+ .m-GET { color: #4ade80; } .m-POST { color: #fbbf24; } .m-PUT { color: #60a5fa; }
161
+ .m-PATCH { color: #c084fc; } .m-DELETE { color: #f87171; } .m-HEAD, .m-OPTIONS { color: var(--muted); }
162
+
163
+ /* ------------------------------------------------------------------ tabs */
164
+ .tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 10px; }
165
+ .tabs button {
166
+ background: none; border: none; border-bottom: 2px solid transparent; border-radius: 0;
167
+ padding: 8px 12px; color: var(--muted);
168
+ }
169
+ .tabs button:hover { color: var(--text); background: none; }
170
+ .tabs button.active { color: var(--text); border-bottom-color: var(--primary); }
171
+ .tabs.small button { padding: 4px 10px; font-size: 12px; }
172
+ .tabs.small { border: none; margin: 0; }
173
+ .runs .tabs { margin: 0; padding: 0 40px 0 6px; position: relative; flex-wrap: wrap; }
174
+ .grow-panels { flex: 1; min-height: 0; display: flex; flex-direction: column; }
175
+ .grow-panels .tab-panel { flex: 1; min-height: 0; overflow: auto; }
176
+
177
+ /* ------------------------------------------------------------- kv editor */
178
+ .kv-rows { display: flex; flex-direction: column; gap: 4px; }
179
+ .kv-row { display: grid; grid-template-columns: 22px 1fr 2fr 28px; gap: 6px; align-items: center; }
180
+ .kv-row input[type=text], .kv-row input:not([type]) { padding: 5px 8px; }
181
+ .kv-row .kv-del {
182
+ display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0;
183
+ background: none; border: none; border-radius: 6px; color: var(--muted); font-size: 15px; line-height: 1;
184
+ }
185
+ .kv-row .kv-del:hover { color: var(--danger); background: var(--bg-4); }
186
+ .kv.no-enable .kv-row { grid-template-columns: 1fr 2fr 28px; }
187
+ .field { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
188
+ .field input[type=number] { width: 100px; }
189
+ .body-input { min-height: 180px; }
190
+
191
+ /* -------------------------------------------------------------- response */
192
+ .response { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 10px; display: flex; flex-direction: column; min-height: 220px; }
193
+ .response-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
194
+ .status { font-weight: 700; padding: 2px 8px; border-radius: 4px; background: var(--bg-4); }
195
+ .status.ok { color: var(--ok); } .status.warn { color: var(--warn); } .status.err { color: var(--danger); }
196
+ .status.ok, .status.warn, .status.err { background: color-mix(in srgb, currentColor 13%, var(--bg-4)); }
197
+ pre { margin: 0; background: var(--bg-2); border: 1px solid var(--border); border-radius: 6px; padding: 10px; overflow: auto; white-space: pre-wrap; word-break: break-word; max-height: 50vh; }
198
+
199
+ /* ------------------------------------------------------------------ runs */
200
+ .run-panel { padding: 10px; }
201
+ .run-head { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
202
+ .run-head .title { font-weight: 600; display: flex; align-items: center; gap: 8px; }
203
+ .badge { font-size: 11px; padding: 2px 8px; border-radius: 999px; background: var(--bg-4); text-transform: uppercase; letter-spacing: .4px; }
204
+ .badge.running { background: rgba(59,130,246,.2); color: #93c5fd; }
205
+ .badge.completed { background: rgba(34,197,94,.18); color: #86efac; }
206
+ .badge.stopped, .badge.cancelled, .badge.interrupted { background: rgba(245,158,11,.2); color: #fcd34d; }
207
+ .badge.error, .badge.failed { background: rgba(239,68,68,.2); color: #fca5a5; }
208
+ .badge.ok { background: rgba(34,197,94,.18); color: #86efac; }
209
+ .progress { height: 6px; background: var(--bg-4); border-radius: 3px; overflow: hidden; }
210
+ .progress > div { height: 100%; background: var(--primary); transition: width .3s; }
211
+ .progress.has-fail > div { background: linear-gradient(90deg, var(--primary), var(--warn)); }
212
+ .run-actions { display: flex; gap: 6px; flex-wrap: wrap; }
213
+ .path { font-family: var(--mono); font-size: 11px; color: var(--muted); word-break: break-all; }
214
+ .result-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
215
+ .result-item {
216
+ display: grid; grid-template-columns: 24px 1fr auto; gap: 8px; align-items: center;
217
+ padding: 7px 10px; background: var(--bg-3); border-radius: 6px; cursor: pointer; border: 1px solid transparent;
218
+ }
219
+ .result-item:hover { border-color: var(--border); }
220
+ .result-item .pos { color: var(--muted); font-size: 12px; }
221
+ .result-item .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
222
+ .result-item .meta { font-size: 12px; font-family: var(--mono); display: flex; gap: 8px; }
223
+ .result-item.pending { opacity: .5; }
224
+ .result-item.active-now .pos { color: var(--primary); }
225
+ .history-item { display: flex; flex-direction: column; gap: 3px; padding: 8px 10px; background: var(--bg-3); border-radius: 6px; cursor: pointer; margin-bottom: 6px; border: 1px solid transparent; }
226
+ .history-item:hover { border-color: var(--border); }
227
+ .history-item .line { display: flex; align-items: center; gap: 8px; }
228
+ .history-item .name { font-weight: 500; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
229
+
230
+ /* ----------------------------------------------------------------- modal */
231
+ .modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; z-index: 50; animation: fade-in .12s ease-out; }
232
+ .modal { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; width: min(820px, 94vw); max-height: 90vh; display: flex; flex-direction: column; animation: pop-in .14s ease-out; }
233
+ .modal-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); }
234
+ .modal-head h3 { margin: 0; font-size: 16px; }
235
+ /* the ✕ in a dialog header: a real 30px target, not a 13px glyph */
236
+ .modal-head button.link {
237
+ display: inline-flex; align-items: center; justify-content: center; flex: none;
238
+ width: 30px; height: 30px; padding: 0; border-radius: 6px; color: var(--muted); font-size: 18px; line-height: 1;
239
+ }
240
+ .modal-head button.link:hover { color: var(--text); background: var(--bg-4); text-decoration: none; }
241
+ .modal-body { padding: 14px 16px; overflow: auto; }
242
+ .modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--border); }
243
+ .modal-foot:empty { display: none; }
244
+ .order-list { list-style: none; padding: 0; margin: 8px 0 14px; display: flex; flex-direction: column; gap: 4px; max-height: 260px; overflow: auto; }
245
+ .order-list li { display: grid; grid-template-columns: 24px 54px 1fr auto; gap: 8px; align-items: center; padding: 5px 8px; background: var(--bg-3); border-radius: 6px; }
246
+ .order-list .ctl { display: flex; gap: 2px; }
247
+ .opts { display: flex; flex-direction: column; gap: 8px; }
248
+ .opts label { display: flex; align-items: center; gap: 8px; }
249
+ .opts input[type=number] { width: 90px; }
250
+ .detail-section h4 { margin: 14px 0 6px; font-size: 13px; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; }
251
+ .detail-section pre { max-height: 40vh; }
252
+ .files { display: flex; gap: 10px; flex-wrap: wrap; }
253
+ .files a { color: var(--primary); }
254
+
255
+ /* ----------------------------------------------------------------- toast */
256
+ .toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: var(--bg-4); border: 1px solid var(--border); border-left-width: 3px; padding: 10px 16px; border-radius: 8px; z-index: 100; box-shadow: 0 6px 24px rgba(0,0,0,.4); animation: toast-in .18s ease-out; }
257
+ @keyframes toast-in { from { opacity: 0; transform: translate(-50%, 10px); } }
258
+ .toast.error { border-left-color: var(--danger); color: #fecaca; }
259
+ .toast.ok { border-left-color: var(--accent); }
260
+ .toast .toast-act { margin-left: 12px; background: none; border: none; color: var(--primary); font-weight: 600; padding: 2px 4px; }
261
+ .toast .toast-act:hover { text-decoration: underline; background: none; }
262
+
263
+ @media (max-width: 1180px) {
264
+ .layout { grid-template-columns: var(--side-w, 280px) minmax(380px, 1fr) var(--runs-w, 320px); }
265
+ }
266
+ @media (max-width: 960px) {
267
+ body { overflow: auto; }
268
+ .layout { grid-template-columns: 1fr; height: auto; }
269
+ .sidebar, .runs { max-height: 50vh; border: none; border-bottom: 1px solid var(--border); }
270
+ }
271
+
272
+ /* ------------------------------------------------- native window polish */
273
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
274
+ ::-webkit-scrollbar-track { background: transparent; }
275
+ ::-webkit-scrollbar-thumb { background: var(--bg-4); border-radius: 6px; border: 2px solid var(--bg-2); }
276
+ ::-webkit-scrollbar-thumb:hover { background: #3a4352; }
277
+ .topbar, .sidebar-head, .select-bar, .tag-filter, .req-list, .tabs, .result-list,
278
+ .history-item, .run-actions, .modal-head, .modal-foot, .order-list, button, label {
279
+ user-select: none; -webkit-user-select: none;
280
+ }
281
+ body.native button, body.native .req-item, body.native .chip,
282
+ body.native .result-item, body.native .history-item { cursor: default; }
283
+
284
+ /* --------------------------------------------------------- named bodies */
285
+ .row.tight { margin-bottom: 6px; gap: 6px; }
286
+ .bodies { display: grid; grid-template-columns: 240px 1fr; gap: 12px; min-height: 260px; }
287
+ .bodies-side { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--border); padding-right: 12px; }
288
+ .bodies-main { min-width: 0; }
289
+ .body-list { list-style: none; margin: 0; padding: 0; overflow: auto; max-height: 340px; display: flex; flex-direction: column; gap: 2px; user-select: none; }
290
+ .body-item { display: grid; grid-template-columns: 20px 1fr; gap: 6px; align-items: center; padding: 6px 8px; border-radius: 6px; cursor: pointer; border-left: 3px solid transparent; }
291
+ .body-item:hover { background: var(--bg-3); }
292
+ .body-item.active { background: var(--bg-3); border-left-color: var(--primary); }
293
+ .body-item .bname { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
294
+ .body-item .bprev { font-family: var(--mono); font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
295
+ .body-item.off .bname { color: var(--muted); text-decoration: line-through; }
296
+ .body-list .none { color: var(--muted); font-size: 12px; padding: 8px; }
297
+ .bcount { font-size: 10px; color: var(--accent); border: 1px solid var(--border); border-radius: 999px; padding: 0 6px; margin-left: 6px; }
298
+ .result-item .bn { color: var(--accent); }
299
+ .multi-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
300
+ @media (max-width: 1180px) { .bodies { grid-template-columns: 1fr; } .bodies-side { border: none; padding: 0; } }
301
+
302
+ /* ------------------------------------------- compact header + autosave */
303
+ .url-row { margin-top: 0; }
304
+ .meta-bar { display: flex; align-items: center; gap: 8px; margin: -2px 0 8px; min-height: 28px; }
305
+ .name-inline {
306
+ background: transparent; border: 1px solid transparent; padding: 3px 6px; margin-left: -6px;
307
+ font-weight: 600; font-size: 14px; field-sizing: content; min-width: 120px; max-width: 45%;
308
+ }
309
+ .name-inline:hover { border-color: var(--border); }
310
+ .name-inline:focus { background: var(--bg-3); border-color: var(--primary); }
311
+ .meta-tags { display: flex; gap: 4px; flex-wrap: nowrap; overflow: hidden; min-width: 0; }
312
+ .meta-tags .chip { cursor: pointer; padding: 0 8px; font-size: 11px; }
313
+ .details { background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px; padding: 10px; margin-bottom: 10px; }
314
+ .details .field { margin-bottom: 8px; }
315
+ .details textarea { min-height: 44px; }
316
+ .save-state { font-size: 12px; color: var(--muted); white-space: nowrap; }
317
+ .save-state.saving { color: var(--warn); }
318
+ .save-state.saved { color: var(--accent); }
319
+ .save-state.error { color: var(--danger); }
320
+ .icon-btn {
321
+ display: inline-flex; align-items: center; justify-content: center; flex: none;
322
+ min-width: 30px; height: 30px; padding: 3px 8px; font-size: 16px; line-height: 1;
323
+ background: none; border-color: transparent;
324
+ }
325
+ .icon-btn:hover { border-color: var(--border); }
326
+
327
+ /* ------------------------------------------------------------ bulk edit */
328
+ .kv-bar { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
329
+ .kv-bulk { width: 100%; min-height: 110px; line-height: 1.6; }
330
+
331
+ /* ------------------------------------------------------- sidebar menu */
332
+ .req-item .more {
333
+ background: none; border: 1px solid transparent; color: var(--muted); padding: 0; width: 28px; height: 28px;
334
+ border-radius: 6px; font-size: 19px; line-height: 1; opacity: 0; transition: opacity .1s;
335
+ }
336
+ .req-item:hover .more, .req-item.active .more, .req-item.menu-open .more, .req-item .more:focus-visible { opacity: 1; }
337
+ .req-item .more:hover, .req-item.menu-open .more { background: var(--bg-4); border-color: var(--border); color: var(--text); }
338
+ .menu {
339
+ position: fixed; z-index: 60; min-width: 160px; padding: 4px; background: var(--bg-3);
340
+ border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,.45);
341
+ display: flex; flex-direction: column; user-select: none; animation: pop-in .1s ease-out;
342
+ }
343
+ .menu button {
344
+ display: flex; align-items: center; gap: 10px; background: none; border: none; text-align: left;
345
+ padding: 7px 10px; border-radius: 5px; width: 100%;
346
+ }
347
+ .menu button:hover, .menu button:focus { background: var(--bg-4); outline: none; }
348
+ .menu button.danger { color: var(--danger); }
349
+ .menu button.danger:hover, .menu button.danger:focus { background: rgba(239,68,68,.15); }
350
+ .menu .mi { width: 18px; text-align: center; font-size: 15px; }
351
+ @media (hover: none) { .req-item .more { opacity: 1; } }
352
+
353
+ /* -------------------------------------------------------------- dialogs */
354
+ .dialog-backdrop {
355
+ position: fixed; inset: 0; z-index: 80; display: flex; align-items: center; justify-content: center;
356
+ background: rgba(5, 8, 12, .6); backdrop-filter: blur(2px); animation: fade-in .12s ease-out;
357
+ }
358
+ .dialog {
359
+ width: min(440px, calc(100vw - 32px)); background: var(--bg-2); border: 1px solid var(--border);
360
+ border-radius: 12px; box-shadow: 0 24px 60px rgba(0,0,0,.55); padding: 18px 18px 14px;
361
+ animation: pop-in .14s ease-out;
362
+ }
363
+ .dialog-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
364
+ .dialog-head h3 { margin: 0; font-size: 15px; }
365
+ .dialog-icon {
366
+ flex: none; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
367
+ font-weight: 700; background: rgba(59,130,246,.18); color: #93c5fd;
368
+ }
369
+ .dialog.danger .dialog-icon { background: rgba(239,68,68,.18); color: #fca5a5; }
370
+ .dialog-msg { color: var(--muted); margin: 0 0 14px 42px; line-height: 1.5; }
371
+ .dialog-msg strong { color: var(--text); font-weight: 600; }
372
+ .dialog-field { margin: 4px 0 14px 42px; display: flex; flex-direction: column; gap: 6px; }
373
+ .dialog-field label { font-size: 12px; color: var(--muted); }
374
+ .dialog-field input, .dialog-field select { width: 100%; }
375
+ .dialog-foot { display: flex; justify-content: flex-end; gap: 8px; }
376
+ button.danger-solid { background: var(--danger); border-color: var(--danger); color: #fff; }
377
+ button.danger-solid:hover { background: #dc2626; }
378
+ @keyframes fade-in { from { opacity: 0; } }
379
+ @keyframes pop-in { from { opacity: 0; transform: translateY(6px) scale(.98); } }
380
+
381
+ /* -------------------------------------------------------------- folders */
382
+ .sidebar-head { align-items: center; }
383
+ .folder-btn { display: grid; place-items: center; padding: 5px 7px; color: var(--muted); }
384
+ .folder-btn:hover { color: var(--text); }
385
+ .req-item, .folder-item { padding-left: calc(12px + var(--depth, 0) * 16px); }
386
+ .folder-item {
387
+ display: grid; grid-template-columns: 22px 1fr auto 28px; gap: 8px; align-items: center;
388
+ padding-top: 6px; padding-bottom: 6px; padding-right: 6px; cursor: pointer; user-select: none;
389
+ }
390
+ .folder-item:hover { background: var(--bg-3); }
391
+ .folder-item .fname { display: flex; align-items: center; gap: 6px; min-width: 0; font-weight: 600; }
392
+ .folder-item .fname span.t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
393
+ .folder-item .caret { width: 14px; color: var(--muted); font-size: 12px; transition: transform .12s; display: inline-block; }
394
+ .folder-item.open .caret { transform: rotate(90deg); }
395
+ .folder-item .ficon { color: #fbbf24; flex: none; }
396
+ .folder-item .fcount { font-size: 11px; color: var(--muted); }
397
+ .folder-item .more { background: none; border: 1px solid transparent; color: var(--muted); padding: 0; width: 28px; height: 28px; border-radius: 6px; font-size: 19px; line-height: 1; opacity: 0; }
398
+ .folder-item:hover .more, .folder-item.menu-open .more, .folder-item .more:focus-visible { opacity: 1; }
399
+ .folder-item .more:hover, .folder-item.menu-open .more { background: var(--bg-4); border-color: var(--border); color: var(--text); }
400
+ .req-list.drop-root { outline: 2px dashed var(--primary); outline-offset: -4px; }
401
+ .folder-item.drop-target { background: rgba(59,130,246,.18); box-shadow: inset 0 0 0 1px var(--primary); }
402
+ .dragging { opacity: .45; }
403
+ .crumb { color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 30%; }
404
+ .crumb:empty { display: none; }
405
+ .menu .sep { height: 1px; background: var(--border); margin: 4px 2px; }
406
+ @media (hover: none) { .folder-item .more { opacity: 1; } }
407
+
408
+ /* --------------------------------------------------------- environments */
409
+ .env-picker { position: relative; display: flex; align-items: center; }
410
+ .env-picker .env-dot { position: absolute; left: 10px; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); pointer-events: none; }
411
+ .env-picker select { padding-left: 24px; min-width: 170px; max-width: 220px; }
412
+ .env-picker.on .env-dot { background: var(--accent); }
413
+ .env-picker.on select { border-color: rgba(16,185,129,.55); }
414
+ .env-picker.prod .env-dot { background: var(--danger); }
415
+ .env-picker.prod select { border-color: rgba(239,68,68,.6); }
416
+ .env-manager { display: grid; grid-template-columns: 200px 1fr; gap: 16px; min-height: 340px; }
417
+ .env-list { display: flex; flex-direction: column; gap: 4px; border-right: 1px solid var(--border); padding-right: 12px; }
418
+ .env-item { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 6px; cursor: pointer; border-left: 3px solid transparent; }
419
+ .env-item:hover { background: var(--bg-3); }
420
+ .env-item.active-edit { background: var(--bg-3); border-left-color: var(--primary); }
421
+ .env-item .live { font-size: 10px; color: var(--accent); margin-left: auto; text-transform: uppercase; letter-spacing: .4px; }
422
+ .env-quick { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
423
+ .env-quick .chip { cursor: pointer; }
424
+ .env-edit-head { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
425
+ .env-edit-head input { flex: 1; font-weight: 600; }
426
+ .env-note { margin: 0 0 10px; }
427
+ .run-env { font-size: 11px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); }
428
+ @media (max-width: 700px) { .env-manager { grid-template-columns: 1fr; } .env-list { border: none; padding: 0; } }
429
+
430
+ /* ------------------------------------------------------------ status bar */
431
+ .statusbar {
432
+ flex: none; height: 30px; display: flex; align-items: center; gap: 12px; padding: 0 8px;
433
+ background: var(--bg-2); border-top: 1px solid var(--border); font-size: 12px; user-select: none;
434
+ }
435
+ .status-btn {
436
+ display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 9px; font-size: 12px;
437
+ background: none; border: 1px solid transparent; color: var(--muted); border-radius: 5px;
438
+ }
439
+ .status-btn:hover, .status-btn.on { color: var(--text); background: var(--bg-4); border-color: var(--border); }
440
+ .status-btn svg { width: 16px; height: 16px; }
441
+ .sb-count { font-family: var(--mono); font-size: 11px; padding: 0 6px; border-radius: 999px; background: var(--bg-4); color: var(--muted); }
442
+ .sb-count:empty { display: none; }
443
+ .sb-count.err { background: rgba(239,68,68,.2); color: #fca5a5; }
444
+ .sb-last { color: var(--muted); font-family: var(--mono); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
445
+ .sb-last .ok { color: var(--ok); } .sb-last .warn { color: var(--warn); } .sb-last .err { color: var(--danger); }
446
+ .sb-env { color: var(--muted); white-space: nowrap; }
447
+
448
+ /* --------------------------------------------------------------- console */
449
+ .console {
450
+ flex: none; height: var(--console-h, 280px); min-height: 120px; max-height: 80vh;
451
+ display: flex; flex-direction: column; background: var(--bg-2); border-top: 1px solid var(--border); position: relative;
452
+ }
453
+ .console-resize { position: absolute; top: -3px; left: 0; right: 0; height: 6px; cursor: ns-resize; z-index: 2; }
454
+ .console-resize:hover, .console.resizing .console-resize { background: var(--primary); opacity: .6; }
455
+ .console-bar { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-bottom: 1px solid var(--border); flex: none; }
456
+ .console-bar input[type=search] { width: 280px; padding: 4px 8px; font-size: 12px; }
457
+ .console-bar label { display: flex; align-items: center; gap: 5px; color: var(--muted); cursor: pointer; }
458
+ .console-list { flex: 1; overflow: auto; font-family: var(--mono); font-size: 12px; }
459
+ .c-row {
460
+ display: grid; grid-template-columns: 14px 92px 120px 62px 74px minmax(0, 1fr) 76px 70px; gap: 10px; align-items: center;
461
+ padding: 4px 10px; border-bottom: 1px solid rgba(45,52,64,.5); cursor: pointer;
462
+ }
463
+ .c-row:hover { background: var(--bg-3); }
464
+ .c-row.open { background: var(--bg-3); }
465
+ .c-row.err { background: rgba(239,68,68,.06); }
466
+ .c-row .caret { color: var(--muted); font-size: 9px; transition: transform .1s; }
467
+ .c-row.open .caret { transform: rotate(90deg); }
468
+ .c-row .ts, .c-row .dur, .c-row .size { color: var(--muted); }
469
+ .c-row .dur, .c-row .size { text-align: right; }
470
+ .c-row .src { font-family: var(--sans); font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
471
+ .c-row .url { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
472
+ .c-row .code.ok { color: var(--ok); } .c-row .code.warn { color: var(--warn); } .c-row .code.err { color: var(--danger); }
473
+ .c-detail { padding: 8px 12px 12px 34px; background: var(--bg); border-bottom: 1px solid var(--border); font-family: var(--sans); }
474
+ .c-detail details { margin: 4px 0; }
475
+ .c-detail summary { cursor: pointer; color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .4px; padding: 3px 0; user-select: none; }
476
+ .c-detail summary:hover { color: var(--text); }
477
+ .c-kv { display: grid; grid-template-columns: minmax(140px, max-content) 1fr; gap: 2px 14px; font-family: var(--mono); font-size: 12px; padding: 4px 0 6px 14px; }
478
+ .c-kv .k { color: #93c5fd; }
479
+ .c-kv .v { word-break: break-all; }
480
+ .c-detail pre { margin: 4px 0 6px 14px; max-height: 320px; font-size: 12px; }
481
+ .c-err { color: #fca5a5; font-family: var(--mono); font-size: 12px; padding: 4px 0 6px 14px; }
482
+ .c-empty { padding: 18px; color: var(--muted); font-family: var(--sans); text-align: center; }
483
+ @media (max-width: 960px) { .c-row { grid-template-columns: 14px 70px 56px 64px minmax(0, 1fr) 70px; } .c-row .src, .c-row .size { display: none; } }
484
+
485
+ /* ------------------------------------------------------- settings dialog */
486
+ .settings-btn { display: grid; place-items: center; padding: 6px 7px; color: var(--muted); }
487
+ .settings-btn:hover { color: var(--text); }
488
+ .set-section { margin-bottom: 18px; }
489
+ .set-section h4 { margin: 0 0 8px; font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
490
+ .seg { display: inline-flex; background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px; padding: 3px; gap: 3px; }
491
+ .seg button { border: none; background: none; padding: 6px 14px; border-radius: 6px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
492
+ .seg button:hover { color: var(--text); background: none; }
493
+ .seg button.on { background: var(--bg-2); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.25); }
494
+ .switch-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 12px; background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px; }
495
+ .switch-row .txt { flex: 1; }
496
+ .switch-row .txt b { display: block; font-weight: 600; margin-bottom: 2px; }
497
+ .switch { position: relative; width: 38px; height: 22px; flex: none; margin-top: 2px; }
498
+ .switch input { opacity: 0; width: 0; height: 0; position: absolute; }
499
+ .switch span { position: absolute; inset: 0; background: var(--bg-4); border: 1px solid var(--border); border-radius: 999px; transition: background .15s; cursor: pointer; }
500
+ .switch span::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--muted); transition: transform .15s, background .15s; }
501
+ .switch input:checked + span { background: var(--accent); border-color: var(--accent); }
502
+ .switch input:checked + span::after { transform: translateX(16px); background: #fff; }
503
+ .switch input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: 2px; }
504
+ .ssl-warn { margin-top: 8px; color: var(--warn); font-size: 12px; }
505
+ .sb-ssl { background: none; border: none; color: var(--warn); font-size: 12px; padding: 0 6px; height: 24px; white-space: nowrap; }
506
+ .sb-ssl:hover { text-decoration: underline; background: none; }
507
+
508
+ /* ---------------------------------------------------- per-body responses */
509
+ .resp-bodies { display: flex; gap: 4px; overflow-x: auto; border-bottom: 1px solid var(--border); margin-bottom: 10px; padding-bottom: 0; }
510
+ .rb-tab {
511
+ display: flex; align-items: center; gap: 7px; flex: none; padding: 6px 12px; font-size: 12px;
512
+ background: none; border: 1px solid transparent; border-bottom: none; border-radius: 6px 6px 0 0; color: var(--muted);
513
+ margin-bottom: -1px;
514
+ }
515
+ .rb-tab:hover { color: var(--text); background: var(--bg-3); }
516
+ .rb-tab.active { color: var(--text); background: var(--bg-2); border-color: var(--border); box-shadow: inset 0 2px 0 var(--primary); }
517
+ .rb-tab .rb-code { font-family: var(--mono); font-weight: 700; }
518
+ .rb-tab .rb-code.ok { color: var(--ok); } .rb-tab .rb-code.warn { color: var(--warn); } .rb-tab .rb-code.err { color: var(--danger); }
519
+ .rb-tab .rb-ms { font-family: var(--mono); color: var(--muted); }
520
+ .rb-tab.pending { opacity: .6; }
521
+ .rb-run { margin-left: auto; display: flex; align-items: center; gap: 8px; flex: none; padding: 0 4px 4px; font-size: 12px; color: var(--muted); }
522
+ .resp-pending { color: var(--muted); padding: 18px; text-align: center; border: 1px dashed var(--border); border-radius: 6px; }
523
+
524
+ /* ============================================================ light theme */
525
+ :root[data-theme="light"] {
526
+ color-scheme: light;
527
+ --bg: #f6f7f9;
528
+ --bg-2: #ffffff;
529
+ --bg-3: #f0f2f5;
530
+ --bg-4: #e5e9ef;
531
+ --border: #d6dbe3;
532
+ --text: #1c2330;
533
+ --muted: #5d6877;
534
+ --primary: #2563eb;
535
+ --primary-2: #1d4ed8;
536
+ --accent: #059669;
537
+ --accent-2: #047857;
538
+ --danger: #dc2626;
539
+ --warn: #b45309;
540
+ --ok: #15803d;
541
+ }
542
+ :root[data-theme="light"] button:hover { background: #dde2ea; }
543
+ :root[data-theme="light"] button.primary:hover { background: var(--primary-2); }
544
+ :root[data-theme="light"] button.accent { color: #fff; }
545
+ :root[data-theme="light"] button.accent:hover { background: var(--accent-2); }
546
+ :root[data-theme="light"] button.link:hover, :root[data-theme="light"] .tabs button:hover,
547
+ :root[data-theme="light"] .seg button:hover, :root[data-theme="light"] .sb-ssl:hover { background: none; }
548
+ :root[data-theme="light"] .icon-btn:hover { background: var(--bg-4); }
549
+ :root[data-theme="light"] .m-GET { color: #15803d; }
550
+ :root[data-theme="light"] .m-POST { color: #b45309; }
551
+ :root[data-theme="light"] .m-PUT { color: #1d4ed8; }
552
+ :root[data-theme="light"] .m-PATCH { color: #7e22ce; }
553
+ :root[data-theme="light"] .m-DELETE { color: #dc2626; }
554
+ :root[data-theme="light"] .badge.running { color: #1d4ed8; }
555
+ :root[data-theme="light"] .badge.completed, :root[data-theme="light"] .badge.ok { color: #15803d; }
556
+ :root[data-theme="light"] .badge.stopped, :root[data-theme="light"] .badge.cancelled, :root[data-theme="light"] .badge.interrupted { color: #92400e; }
557
+ :root[data-theme="light"] .badge.error, :root[data-theme="light"] .badge.failed { color: #b91c1c; }
558
+ :root[data-theme="light"] .toast { box-shadow: 0 6px 24px rgba(15,23,42,.15); }
559
+ :root[data-theme="light"] .toast.error { color: #b91c1c; }
560
+ :root[data-theme="light"] ::-webkit-scrollbar-thumb { background: #cfd5de; border-color: var(--bg-2); }
561
+ :root[data-theme="light"] ::-webkit-scrollbar-thumb:hover { background: #b7bfcb; }
562
+ :root[data-theme="light"] .modal-backdrop { background: rgba(15,23,42,.35); }
563
+ :root[data-theme="light"] .modal, :root[data-theme="light"] .dialog { box-shadow: 0 24px 60px rgba(15,23,42,.22); }
564
+ :root[data-theme="light"] .menu { box-shadow: 0 10px 30px rgba(15,23,42,.16); }
565
+ :root[data-theme="light"] .dialog-backdrop { background: rgba(15,23,42,.35); }
566
+ :root[data-theme="light"] .dialog-icon { color: #1d4ed8; }
567
+ :root[data-theme="light"] .dialog.danger .dialog-icon { color: #b91c1c; }
568
+ :root[data-theme="light"] .folder-item .ficon { color: #d97706; }
569
+ :root[data-theme="light"] .sb-count.err, :root[data-theme="light"] .c-err { color: #b91c1c; }
570
+ :root[data-theme="light"] .c-row { border-bottom-color: #e7eaf0; }
571
+ :root[data-theme="light"] .c-kv .k { color: #1d4ed8; }
572
+ :root[data-theme="light"] .c-detail { background: var(--bg-3); }
573
+ :root[data-theme="light"] .seg button.on { box-shadow: 0 1px 3px rgba(15,23,42,.15); }
574
+ :root[data-theme="light"] .switch input:checked + span::after { background: #fff; }
575
+ :root[data-theme="light"] pre { background: var(--bg-3); }
576
+
577
+ /* ------------------------------------------------------- response copy */
578
+ .copy-btn {
579
+ display: flex; align-items: center; gap: 6px; padding: 5px 10px; font-size: 12px;
580
+ background: none; border: 1px solid var(--border); color: var(--muted); border-radius: 6px; flex: none;
581
+ }
582
+ .copy-btn svg { width: 16px; height: 16px; }
583
+ .copy-btn:hover { color: var(--text); background: var(--bg-3); }
584
+ .copy-btn.done { color: var(--ok); border-color: var(--ok); }
585
+ .copy-btn:disabled { opacity: .4; }