@tidegap/cli 0.0.0-stage → 0.19.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.
Files changed (113) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +136 -2
  3. package/dist/commands/clients.d.ts +20 -0
  4. package/dist/commands/clients.d.ts.map +1 -0
  5. package/dist/commands/clients.js +36 -0
  6. package/dist/commands/clients.js.map +1 -0
  7. package/dist/commands/env-file.d.ts +54 -0
  8. package/dist/commands/env-file.d.ts.map +1 -0
  9. package/dist/commands/env-file.js +153 -0
  10. package/dist/commands/env-file.js.map +1 -0
  11. package/dist/commands/install.d.ts +83 -0
  12. package/dist/commands/install.d.ts.map +1 -0
  13. package/dist/commands/install.js +297 -0
  14. package/dist/commands/install.js.map +1 -0
  15. package/dist/commands/queue.d.ts +139 -0
  16. package/dist/commands/queue.d.ts.map +1 -0
  17. package/dist/commands/queue.js +491 -0
  18. package/dist/commands/queue.js.map +1 -0
  19. package/dist/commands/receipts.d.ts +15 -0
  20. package/dist/commands/receipts.d.ts.map +1 -0
  21. package/dist/commands/receipts.js +70 -0
  22. package/dist/commands/receipts.js.map +1 -0
  23. package/dist/commands/register-wake.d.ts +21 -0
  24. package/dist/commands/register-wake.d.ts.map +1 -0
  25. package/dist/commands/register-wake.js +76 -0
  26. package/dist/commands/register-wake.js.map +1 -0
  27. package/dist/commands/stats.d.ts +31 -0
  28. package/dist/commands/stats.d.ts.map +1 -0
  29. package/dist/commands/stats.js +165 -0
  30. package/dist/commands/stats.js.map +1 -0
  31. package/dist/commands/tick.d.ts +73 -0
  32. package/dist/commands/tick.d.ts.map +1 -0
  33. package/dist/commands/tick.js +294 -0
  34. package/dist/commands/tick.js.map +1 -0
  35. package/dist/commands/ui.d.ts +33 -0
  36. package/dist/commands/ui.d.ts.map +1 -0
  37. package/dist/commands/ui.js +119 -0
  38. package/dist/commands/ui.js.map +1 -0
  39. package/dist/commands/verify.d.ts +32 -0
  40. package/dist/commands/verify.d.ts.map +1 -0
  41. package/dist/commands/verify.js +135 -0
  42. package/dist/commands/verify.js.map +1 -0
  43. package/dist/env.d.ts +57 -0
  44. package/dist/env.d.ts.map +1 -0
  45. package/dist/env.js +105 -0
  46. package/dist/env.js.map +1 -0
  47. package/dist/index.d.ts +25 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +366 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/platform/index.d.ts +30 -0
  52. package/dist/platform/index.d.ts.map +1 -0
  53. package/dist/platform/index.js +66 -0
  54. package/dist/platform/index.js.map +1 -0
  55. package/dist/platform/linux.d.ts +81 -0
  56. package/dist/platform/linux.d.ts.map +1 -0
  57. package/dist/platform/linux.js +158 -0
  58. package/dist/platform/linux.js.map +1 -0
  59. package/dist/platform/macos.d.ts +69 -0
  60. package/dist/platform/macos.d.ts.map +1 -0
  61. package/dist/platform/macos.js +151 -0
  62. package/dist/platform/macos.js.map +1 -0
  63. package/dist/platform/windows.d.ts +31 -0
  64. package/dist/platform/windows.d.ts.map +1 -0
  65. package/dist/platform/windows.js +58 -0
  66. package/dist/platform/windows.js.map +1 -0
  67. package/dist/ui/api.d.ts +66 -0
  68. package/dist/ui/api.d.ts.map +1 -0
  69. package/dist/ui/api.js +613 -0
  70. package/dist/ui/api.js.map +1 -0
  71. package/dist/ui/clients.d.ts +65 -0
  72. package/dist/ui/clients.d.ts.map +1 -0
  73. package/dist/ui/clients.js +179 -0
  74. package/dist/ui/clients.js.map +1 -0
  75. package/dist/ui/discovery.d.ts +25 -0
  76. package/dist/ui/discovery.d.ts.map +1 -0
  77. package/dist/ui/discovery.js +46 -0
  78. package/dist/ui/discovery.js.map +1 -0
  79. package/dist/ui/dispatcher.d.ts +84 -0
  80. package/dist/ui/dispatcher.d.ts.map +1 -0
  81. package/dist/ui/dispatcher.js +150 -0
  82. package/dist/ui/dispatcher.js.map +1 -0
  83. package/dist/ui/events.d.ts +27 -0
  84. package/dist/ui/events.d.ts.map +1 -0
  85. package/dist/ui/events.js +85 -0
  86. package/dist/ui/events.js.map +1 -0
  87. package/dist/ui/server.d.ts +84 -0
  88. package/dist/ui/server.d.ts.map +1 -0
  89. package/dist/ui/server.js +322 -0
  90. package/dist/ui/server.js.map +1 -0
  91. package/dist/ui/summary.d.ts +47 -0
  92. package/dist/ui/summary.d.ts.map +1 -0
  93. package/dist/ui/summary.js +120 -0
  94. package/dist/ui/summary.js.map +1 -0
  95. package/package.json +53 -3
  96. package/ui/agenda.js +256 -0
  97. package/ui/api.js +114 -0
  98. package/ui/app.css +713 -0
  99. package/ui/app.js +599 -0
  100. package/ui/clients.js +104 -0
  101. package/ui/detail.js +431 -0
  102. package/ui/dialog.js +284 -0
  103. package/ui/dnd.js +131 -0
  104. package/ui/dom.js +255 -0
  105. package/ui/index.html +38 -0
  106. package/ui/journal.js +207 -0
  107. package/ui/keys.js +92 -0
  108. package/ui/row.js +153 -0
  109. package/ui/state.js +412 -0
  110. package/ui/timeline.js +202 -0
  111. package/ui/toast.js +69 -0
  112. package/ui/tokens.css +108 -0
  113. package/ui/views.js +31 -0
package/ui/app.css ADDED
@@ -0,0 +1,713 @@
1
+ /* tidegap ui styles. Every colour, size and duration comes from tokens.css. */
2
+
3
+ * { box-sizing: border-box; }
4
+ [hidden] { display: none !important; }
5
+
6
+ html { -webkit-text-size-adjust: 100%; }
7
+ body {
8
+ margin: 0;
9
+ min-height: 100vh;
10
+ background: var(--bg);
11
+ color: var(--fg);
12
+ font: var(--w-regular) var(--fs-md) / var(--lh-md) var(--font);
13
+ -webkit-font-smoothing: antialiased;
14
+ }
15
+ body.drawer-open { overflow: hidden; }
16
+
17
+ a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
18
+ code, kbd, .mono { font-family: var(--mono); font-size: 0.92em; }
19
+ code { background: var(--surface-2); padding: 1px var(--sp-1); border-radius: 4px; }
20
+ kbd {
21
+ display: inline-block;
22
+ min-width: 22px;
23
+ padding: 0 6px;
24
+ border: 1px solid var(--line);
25
+ border-bottom-width: 2px;
26
+ border-radius: var(--r-1);
27
+ background: var(--surface);
28
+ text-align: center;
29
+ font-size: var(--fs-xs);
30
+ line-height: 20px;
31
+ }
32
+ .num, .row-time, .day-count, .day-clean, .axis-label { font-variant-numeric: tabular-nums; }
33
+ .muted { color: var(--fg-muted); }
34
+ .small { font-size: var(--fs-sm); line-height: var(--lh-sm); }
35
+ .sr-only {
36
+ position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
37
+ overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
38
+ }
39
+
40
+ :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-1); }
41
+
42
+ .skip {
43
+ position: absolute; left: var(--sp-4); top: -48px; z-index: 50;
44
+ padding: var(--sp-2) var(--sp-3); background: var(--accent); color: var(--accent-fg);
45
+ border-radius: var(--r-1); text-decoration: none;
46
+ }
47
+ .skip:focus { top: var(--sp-2); }
48
+
49
+ /* ── header ─────────────────────────────────────────────────────────── */
50
+
51
+ .top {
52
+ position: sticky; top: 0; z-index: 20;
53
+ display: flex; align-items: center; gap: var(--sp-4);
54
+ height: var(--header-h);
55
+ padding: 0 var(--sp-6);
56
+ background: var(--bg);
57
+ border-bottom: 1px solid var(--line);
58
+ }
59
+ .brand {
60
+ display: inline-flex; align-items: center; gap: var(--sp-2);
61
+ color: var(--fg); text-decoration: none;
62
+ font-size: var(--fs-lg); font-weight: var(--w-bold); letter-spacing: -0.01em;
63
+ }
64
+ .brand-mark {
65
+ flex: none;
66
+ width: 32px; height: 11px;
67
+ color: var(--brand-ink);
68
+ }
69
+ .tabs {
70
+ display: flex; gap: 2px; padding: 3px;
71
+ background: var(--surface-2); border-radius: var(--r-2);
72
+ }
73
+ .tab {
74
+ display: inline-flex; align-items: center; gap: var(--sp-2);
75
+ height: 32px; padding: 0 var(--sp-3);
76
+ border-radius: 8px;
77
+ color: var(--fg-muted); text-decoration: none;
78
+ font-size: var(--fs-sm); font-weight: var(--w-medium);
79
+ transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
80
+ }
81
+ .tab:hover { color: var(--fg); }
82
+ .tab[aria-current="page"] { background: var(--surface); color: var(--fg); box-shadow: 0 1px 2px rgb(0 0 0 / 0.08); }
83
+ .tab-glyph { display: none; }
84
+ .count {
85
+ min-width: 20px; height: 20px; padding: 0 6px;
86
+ border-radius: var(--r-pill);
87
+ background: var(--accent); color: var(--accent-fg);
88
+ font-size: var(--fs-xs); line-height: 20px; text-align: center; font-weight: var(--w-bold);
89
+ font-variant-numeric: tabular-nums;
90
+ }
91
+ .top-end { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }
92
+
93
+ .pill {
94
+ display: inline-flex; align-items: center; gap: var(--sp-2);
95
+ height: 32px; padding: 0 var(--sp-3);
96
+ border: 1px solid var(--line); border-radius: var(--r-pill);
97
+ background: var(--surface); color: var(--fg-muted);
98
+ font: inherit; font-size: var(--fs-sm); cursor: pointer;
99
+ font-variant-numeric: tabular-nums;
100
+ }
101
+ .pill:hover { color: var(--fg); }
102
+ .pill-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--fg-muted); }
103
+ .pill[data-state="running"] .pill-dot { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
104
+ .pill[data-state="stale"] .pill-dot { background: var(--warn); }
105
+ .pill[data-state="never"] .pill-dot { background: var(--danger); }
106
+
107
+ .icon-btn {
108
+ display: inline-grid; place-items: center;
109
+ width: 32px; height: 32px; padding: 0;
110
+ border: 1px solid transparent; border-radius: var(--r-1);
111
+ background: transparent; color: var(--fg-muted);
112
+ font: inherit; font-size: var(--fs-lg); line-height: 1; cursor: pointer;
113
+ }
114
+ .icon-btn:hover { background: var(--surface-2); color: var(--fg); }
115
+ #help-btn { border-color: var(--line); font-size: var(--fs-sm); font-weight: var(--w-bold); }
116
+
117
+ /* ── banners ────────────────────────────────────────────────────────── */
118
+
119
+ .banner {
120
+ display: flex; align-items: center; gap: var(--sp-3);
121
+ max-width: 960px; margin: var(--sp-4) auto 0; padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4);
122
+ border-radius: var(--r-2);
123
+ background: var(--surface-2); color: var(--fg);
124
+ font-size: var(--fs-sm); line-height: var(--lh-sm);
125
+ }
126
+ .banner[data-tone="warn"] { background: var(--warn-soft); }
127
+ .banner[data-tone="warn"] .banner-icon { background: var(--warn); color: var(--surface); }
128
+ .banner[data-tone="info"] .banner-icon { background: var(--accent); color: var(--accent-fg); font-size: 8px; }
129
+ .banner-icon {
130
+ flex: none; display: inline-grid; place-items: center;
131
+ width: 20px; height: 20px; border-radius: 50%;
132
+ background: var(--fg-muted); color: var(--surface);
133
+ font-weight: var(--w-bold); font-size: var(--fs-xs);
134
+ }
135
+ .banner-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
136
+ .banner .btn { flex: none; }
137
+ .conn {
138
+ position: fixed; left: 50%; top: calc(var(--header-h) + var(--sp-2)); z-index: 30;
139
+ transform: translateX(-50%);
140
+ padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill);
141
+ background: var(--warn-soft); color: var(--warn);
142
+ font-size: var(--fs-sm); font-weight: var(--w-medium);
143
+ }
144
+
145
+ /* ── view frame ─────────────────────────────────────────────────────── */
146
+
147
+ .view { display: block; max-width: 960px; margin: 0 auto; padding: var(--sp-5) var(--sp-6) 120px; outline: none; }
148
+ .view-head { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-4); }
149
+ .view-title { margin: 0; font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: var(--w-bold); letter-spacing: -0.01em; }
150
+ .view-sub { margin: 0; color: var(--fg-muted); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
151
+
152
+ .group { margin-top: var(--sp-5); }
153
+ .group:first-of-type { margin-top: 0; }
154
+ .view-head + .group, .view-head + .empty, .filters + .group { margin-top: 0; }
155
+
156
+ /* ── day headers (also drop targets) ────────────────────────────────── */
157
+
158
+ .day-head {
159
+ position: relative;
160
+ display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
161
+ min-height: 40px; margin-bottom: var(--sp-2); padding: var(--sp-1) var(--sp-2);
162
+ border-radius: var(--r-1);
163
+ transition: background var(--t-fast) var(--ease), outline-color var(--t-fast) var(--ease);
164
+ }
165
+ .day-title { margin: 0; font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: var(--w-bold); }
166
+ .day-sub { color: var(--fg-muted); font-weight: var(--w-regular); }
167
+ .day-count {
168
+ padding: 0 var(--sp-2); border-radius: var(--r-pill);
169
+ background: var(--surface-2); color: var(--fg-muted);
170
+ font-size: var(--fs-xs); line-height: 20px; font-weight: var(--w-medium);
171
+ }
172
+ .day-clean { margin-left: auto; display: inline-flex; align-items: center; gap: var(--sp-1); color: var(--fg-muted); font-size: var(--fs-sm); }
173
+ .day-head-attention .day-title { color: var(--warn); }
174
+ .drop-hint { display: none; }
175
+
176
+ body.dragging .day-head[data-drop-day] { outline: 1px dashed var(--fg-muted); outline-offset: -1px; }
177
+ .day-head.drop-over, .dock-target.drop-over {
178
+ background: var(--accent-soft);
179
+ outline: 2px solid var(--accent) !important;
180
+ outline-offset: -2px;
181
+ }
182
+ .day-head.drop-over .drop-hint {
183
+ display: inline; margin-left: var(--sp-2);
184
+ color: var(--accent); font-size: var(--fs-sm); font-weight: var(--w-bold);
185
+ }
186
+ .day-head.drop-over .day-clean { display: none; }
187
+
188
+ /* ── rows ───────────────────────────────────────────────────────────── */
189
+
190
+ .rows {
191
+ list-style: none; margin: 0; padding: 0;
192
+ background: var(--surface);
193
+ border: 1px solid var(--line); border-radius: var(--r-2);
194
+ overflow: hidden;
195
+ }
196
+ .row {
197
+ position: relative;
198
+ display: grid;
199
+ grid-template-columns: 8px 72px 92px minmax(0, 1fr) 156px 136px;
200
+ align-items: center; column-gap: var(--sp-3);
201
+ min-height: var(--row-h); padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-4);
202
+ border-top: 1px solid var(--line);
203
+ cursor: pointer;
204
+ transition: background var(--t-fast) var(--ease), opacity var(--t-med) var(--ease);
205
+ }
206
+ .rows > :first-child { border-top: 0; }
207
+ .row:hover { background: var(--surface-2); }
208
+ .row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 0; }
209
+ .row-selected, .row-selected:hover { background: var(--surface-2); box-shadow: inset 3px 0 0 var(--accent); }
210
+ .row[draggable="true"] { cursor: grab; }
211
+ .row.is-dragging { opacity: 0.5; }
212
+ .row-pending { opacity: 0.6; }
213
+
214
+ .row-dot { width: 8px; height: 8px; border-radius: 50%; }
215
+ .row-unread .row-dot { background: var(--accent); }
216
+ .row-time { font-size: var(--fs-sm); font-weight: var(--w-medium); color: var(--fg); white-space: nowrap; }
217
+ .row-failed .row-time { color: var(--danger); }
218
+ .row-cancelled .row-time, .row-cancelled .row-title { color: var(--fg-muted); }
219
+ .group-attention .row-scheduled .row-time, .group-attention .row-queued .row-time { color: var(--warn); }
220
+ .row-band { display: flex; min-width: 0; }
221
+ .row-main { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
222
+ .row-line1 { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
223
+ .row-title {
224
+ flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
225
+ color: var(--fg); text-decoration: none; font-weight: var(--w-medium);
226
+ }
227
+ .row-unread .row-title { font-weight: var(--w-bold); }
228
+ .row-line2 {
229
+ display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
230
+ color: var(--fg-muted); font-size: var(--fs-sm); line-height: var(--lh-sm);
231
+ }
232
+ .row-line2 .sep { color: var(--line); }
233
+ .row-pm { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--fg-muted); font-size: var(--fs-sm); white-space: nowrap; }
234
+ .view-journal .row { grid-template-columns: 8px 72px 92px minmax(0, 1fr) 156px 40px; }
235
+ .group-attention .row { grid-template-columns: 8px 72px 92px minmax(0, 1fr) 156px 180px; }
236
+ .row-actions { display: flex; align-items: center; justify-content: flex-end; gap: var(--sp-1); min-width: 32px; }
237
+ .row-hover { display: flex; gap: 2px; opacity: 0; transition: opacity var(--t-fast) var(--ease); }
238
+ .row:hover .row-hover, .row:focus-within .row-hover, .row:focus .row-hover { opacity: 1; }
239
+ .row-more { opacity: 0.55; }
240
+ .row:hover .row-more, .row:focus .row-more, .row:focus-within .row-more { opacity: 1; }
241
+ .row-op { color: var(--accent); font-weight: var(--w-medium); }
242
+
243
+ .row-btn {
244
+ display: inline-grid; place-items: center;
245
+ width: 32px; height: 32px; padding: 0;
246
+ border: 0; border-radius: var(--r-1);
247
+ background: transparent; color: var(--fg-muted);
248
+ font: inherit; font-size: var(--fs-md); line-height: 1; cursor: pointer;
249
+ }
250
+ .row-btn:hover { background: var(--surface); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); }
251
+ .row-btn-danger:hover { color: var(--danger); }
252
+ .row-expand { font-size: var(--fs-lg); transition: transform var(--t-fast) var(--ease); }
253
+ .row-expand.is-open { transform: rotate(90deg); }
254
+
255
+ .row-projected { cursor: default; color: var(--fg-muted); background: transparent; }
256
+ .row-projected:hover { background: transparent; }
257
+ .row-projected::after {
258
+ content: ""; position: absolute; inset: 4px 6px;
259
+ border: 1px dashed var(--line); border-radius: var(--r-1); pointer-events: none;
260
+ }
261
+ .row-projected .row-title, .row-projected .row-time { color: var(--fg-muted); font-weight: var(--w-regular); }
262
+
263
+ /* ── chips, badges, tags ────────────────────────────────────────────── */
264
+
265
+ .chip {
266
+ display: inline-flex; align-items: center;
267
+ height: 20px; padding: 0 var(--sp-2);
268
+ border-radius: var(--r-pill);
269
+ font-size: var(--fs-xs); line-height: 20px; font-weight: var(--w-bold);
270
+ white-space: nowrap;
271
+ }
272
+ .band-very_clean { color: var(--band-very-clean); background: var(--band-very-clean-bg); }
273
+ .band-clean { color: var(--band-clean); background: var(--band-clean-bg); }
274
+ .band-average { color: var(--band-average); background: var(--band-average-bg); }
275
+ .band-dirty { color: var(--band-dirty); background: var(--band-dirty-bg); }
276
+ .band-very_dirty { color: var(--band-very-dirty); background: var(--band-very-dirty-bg); }
277
+
278
+ .badge {
279
+ flex: 0 0 auto;
280
+ display: inline-flex; align-items: center;
281
+ height: 20px; padding: 0 var(--sp-2);
282
+ border: 1px solid var(--line); border-radius: var(--r-pill);
283
+ color: var(--fg-muted); font-size: var(--fs-xs); line-height: 18px; white-space: nowrap;
284
+ }
285
+ .badge-repeat { border-color: transparent; background: var(--accent-soft); color: var(--accent); font-weight: var(--w-medium); }
286
+ .badge-quota { border-color: transparent; background: var(--surface-2); }
287
+
288
+ .tag { font-weight: var(--w-medium); }
289
+ .tag-completed, .tag-accent, .tag-running { color: var(--accent); }
290
+ .tag-failed { color: var(--danger); }
291
+ .tag-cancelled, .tag-muted { color: var(--fg-muted); }
292
+ .tag-warn { color: var(--warn); }
293
+ .tag-submitted, .tag-scheduled, .tag-queued { color: var(--fg); }
294
+
295
+ .spinner {
296
+ display: inline-block; width: 16px; height: 16px; vertical-align: -3px;
297
+ border: 2px solid var(--line); border-top-color: var(--accent); border-radius: 50%;
298
+ animation: spin 800ms linear infinite;
299
+ }
300
+ @keyframes spin { to { transform: rotate(360deg); } }
301
+
302
+ /* ── buttons and inputs ─────────────────────────────────────────────── */
303
+
304
+ .btn {
305
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
306
+ height: 36px; padding: 0 var(--sp-4);
307
+ border: 1px solid var(--line); border-radius: var(--r-1);
308
+ background: var(--surface); color: var(--fg);
309
+ font: inherit; font-size: var(--fs-sm); font-weight: var(--w-medium);
310
+ text-decoration: none; white-space: nowrap; cursor: pointer;
311
+ transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
312
+ }
313
+ .btn:hover { background: var(--surface-2); }
314
+ .btn:disabled { opacity: 0.5; cursor: not-allowed; }
315
+ .btn-sm { height: 28px; padding: 0 var(--sp-3); font-size: var(--fs-sm); }
316
+ .btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
317
+ .btn-primary:hover { background: var(--accent); filter: brightness(1.08); }
318
+ .btn-danger { color: var(--danger); }
319
+ .btn-danger:hover { background: var(--danger-soft); border-color: var(--danger); }
320
+ .btn-danger-solid { background: var(--danger); border-color: var(--danger); color: var(--surface); }
321
+ .btn-danger-solid:hover { background: var(--danger); filter: brightness(1.08); }
322
+ .btn-ghost { background: transparent; border-color: transparent; }
323
+
324
+ .input, .select {
325
+ height: 40px; padding: 0 var(--sp-3);
326
+ border: 1px solid var(--line); border-radius: var(--r-1);
327
+ background: var(--surface); color: var(--fg);
328
+ font: inherit; font-size: var(--fs-md);
329
+ }
330
+ .select { height: 36px; padding-right: var(--sp-6); font-size: var(--fs-sm); }
331
+
332
+ /* ── journal ────────────────────────────────────────────────────────── */
333
+
334
+ .filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-3); margin-bottom: var(--sp-5); }
335
+ .filter { display: flex; flex-direction: column; gap: var(--sp-1); }
336
+ .filter-label { color: var(--fg-muted); font-size: var(--fs-xs); font-weight: var(--w-medium); text-transform: uppercase; letter-spacing: 0.04em; }
337
+ .expand {
338
+ display: flex; flex-direction: column; gap: var(--sp-3);
339
+ padding: var(--sp-3) var(--sp-4) var(--sp-4) calc(var(--sp-4) + 8px + 72px + 2 * var(--sp-3));
340
+ border-top: 1px dashed var(--line);
341
+ background: var(--surface-2);
342
+ }
343
+ .expand-text {
344
+ margin: 0; padding: var(--sp-3);
345
+ background: var(--surface); border-radius: var(--r-1);
346
+ font: inherit; font-size: var(--fs-sm); line-height: var(--lh-sm);
347
+ white-space: pre-wrap; overflow-wrap: anywhere;
348
+ }
349
+ .expand-text.is-error { color: var(--danger); }
350
+ .expand-facts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1); font-size: var(--fs-sm); }
351
+ .expand-facts .btn { margin-left: var(--sp-2); }
352
+
353
+ /* ── empty, error, loading ──────────────────────────────────────────── */
354
+
355
+ .empty {
356
+ display: flex; flex-direction: column; align-items: center; text-align: center;
357
+ margin: var(--sp-4) 0 var(--sp-5); padding: var(--sp-7) var(--sp-5);
358
+ border: 1px dashed var(--line); border-radius: var(--r-2);
359
+ }
360
+ .empty-full { border: 0; margin-top: var(--sp-7); }
361
+ .empty-glyph {
362
+ display: grid; place-items: center;
363
+ width: 48px; height: 48px; margin-bottom: var(--sp-3);
364
+ border-radius: 50%; background: var(--accent-soft); color: var(--accent);
365
+ font-size: var(--fs-xl);
366
+ }
367
+ .empty-title { margin: 0; font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: var(--w-bold); }
368
+ .empty-body code { white-space: nowrap; }
369
+ .empty-body { max-width: 460px; margin: var(--sp-2) 0 0; color: var(--fg-muted); }
370
+ .empty-link { margin-top: var(--sp-4); font-weight: var(--w-medium); }
371
+
372
+ .error-card {
373
+ display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
374
+ margin-bottom: var(--sp-4); padding: var(--sp-3) var(--sp-4);
375
+ border-radius: var(--r-2);
376
+ background: var(--danger-soft); color: var(--danger);
377
+ font-size: var(--fs-sm); font-weight: var(--w-medium);
378
+ }
379
+
380
+ .sk {
381
+ display: block; border-radius: var(--r-1);
382
+ background: var(--surface-2);
383
+ animation: pulse 1.4s var(--ease) infinite;
384
+ }
385
+ @keyframes pulse { 50% { opacity: 0.45; } }
386
+ .sk-title { width: 160px; height: 20px; }
387
+ .sk-time { width: 44px; height: 14px; }
388
+ .sk-chip { width: 64px; height: 20px; border-radius: var(--r-pill); }
389
+ .sk-line { width: 70%; height: 14px; }
390
+ .sk-line.sk-short, .sk-short { width: 45%; }
391
+ .sk-sub { width: 35%; height: 12px; margin-top: var(--sp-1); }
392
+ .sk-pm { width: 96px; height: 12px; }
393
+ .sk-block { height: 72px; margin-top: var(--sp-4); }
394
+ .sk-chart { height: 220px; margin-bottom: var(--sp-5); border-radius: var(--r-2); }
395
+ .skeleton-wrap .day-head { margin-top: var(--sp-5); }
396
+ .skeleton-wrap .day-head:first-child { margin-top: 0; }
397
+ .row-skeleton { cursor: default; }
398
+ .row-skeleton:hover { background: transparent; }
399
+ .row-skeleton .sk-chip { justify-self: start; }
400
+
401
+ /* ── timeline ───────────────────────────────────────────────────────── */
402
+
403
+ .chart-wrap {
404
+ position: relative;
405
+ margin: 0 0 var(--sp-5); padding: var(--sp-4) 0 var(--sp-3);
406
+ background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-2);
407
+ overflow: hidden;
408
+ }
409
+ .chart { display: block; max-width: 100%; height: auto; }
410
+ .chart .area-very_clean { fill: var(--band-very-clean-bg); }
411
+ .chart .area-clean { fill: var(--band-clean-bg); }
412
+ .chart .area-average { fill: var(--band-average-bg); }
413
+ .chart .area-dirty { fill: var(--band-dirty-bg); }
414
+ .chart .area-very_dirty { fill: var(--band-very-dirty-bg); }
415
+ .chart .curve { fill: none; stroke: var(--fg); stroke-width: 1.75; stroke-linejoin: round; }
416
+ .chart .axis { stroke: var(--line); }
417
+ .chart .guide { stroke: var(--line); stroke-dasharray: 2 4; }
418
+ .chart .day-line { stroke: var(--line); }
419
+ .chart .axis-label, .chart .day-label { fill: var(--fg-muted); font-size: 11px; font-family: var(--font); }
420
+ .chart .day-label { font-weight: var(--w-bold); }
421
+ .chart .now-line { stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 4 3; }
422
+ .chart .now-label { fill: var(--accent); font-size: 11px; font-weight: var(--w-bold); font-family: var(--font); }
423
+ .chart .deadline-tick { stroke: var(--fg-muted); stroke-width: 2; }
424
+ .chart .marker { cursor: pointer; outline: none; }
425
+ .chart .marker-halo { fill: transparent; stroke: transparent; stroke-width: 2; }
426
+ .chart .marker:hover .marker-halo, .chart .marker:focus-visible .marker-halo, .chart .marker.is-selected .marker-halo { stroke: var(--accent); fill: var(--surface); }
427
+ .chart .marker-dot { fill: var(--fg); stroke: var(--surface); stroke-width: 2; }
428
+ .chart .marker-very_clean .marker-dot { fill: var(--band-very-clean); }
429
+ .chart .marker-clean .marker-dot { fill: var(--band-clean); }
430
+ .chart .marker-average .marker-dot { fill: var(--band-average); }
431
+ .chart .marker-dirty .marker-dot { fill: var(--band-dirty); }
432
+ .chart .marker-very_dirty .marker-dot { fill: var(--band-very-dirty); }
433
+ .chart .marker-count { fill: var(--surface); font-size: 10px; font-weight: var(--w-bold); font-family: var(--font); pointer-events: none; }
434
+ .chart-empty {
435
+ position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%);
436
+ margin: 0; padding: var(--sp-1) var(--sp-3);
437
+ border-radius: var(--r-pill); background: var(--surface); color: var(--fg-muted);
438
+ font-size: var(--fs-sm); box-shadow: var(--shadow);
439
+ }
440
+ .chart-legend {
441
+ display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
442
+ padding: var(--sp-3) var(--sp-4) 0;
443
+ }
444
+ .legend-note { color: var(--fg-muted); font-size: var(--fs-xs); line-height: var(--lh-xs); }
445
+
446
+ /* ── drag dock ──────────────────────────────────────────────────────── */
447
+
448
+ .drop-dock {
449
+ position: fixed; left: 0; right: 0; top: var(--header-h); z-index: 25;
450
+ display: flex; align-items: stretch; gap: var(--sp-2);
451
+ padding: var(--sp-2) var(--sp-6);
452
+ background: var(--surface); border-bottom: 1px solid var(--line); box-shadow: var(--shadow);
453
+ overflow-x: auto;
454
+ animation: slide-down var(--t-med) var(--ease);
455
+ }
456
+ @keyframes slide-down { from { transform: translateY(-12px); opacity: 0; } }
457
+ .dock-label { align-self: center; color: var(--fg-muted); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.04em; margin-right: var(--sp-1); }
458
+ .dock-target {
459
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
460
+ min-width: 76px; padding: var(--sp-2) var(--sp-3);
461
+ border: 1px dashed var(--fg-muted); border-radius: var(--r-1);
462
+ font-size: var(--fs-sm); font-weight: var(--w-medium); line-height: var(--lh-sm);
463
+ }
464
+ .dock-run { flex-direction: row; gap: var(--sp-2); color: var(--accent); border-color: var(--accent); }
465
+ .dock-date { color: var(--fg-muted); font-size: var(--fs-xs); font-weight: var(--w-regular); }
466
+ .dock-target.is-current { opacity: 0.4; }
467
+
468
+ /* ── drawer ─────────────────────────────────────────────────────────── */
469
+
470
+ .scrim { position: fixed; inset: 0; z-index: 35; background: var(--scrim); animation: fade var(--t-med) var(--ease); }
471
+ @keyframes fade { from { opacity: 0; } }
472
+ .drawer {
473
+ position: fixed; top: 0; right: 0; bottom: 0; z-index: 40;
474
+ width: min(var(--drawer-w), 100vw);
475
+ padding: var(--sp-5) var(--sp-5) var(--sp-7);
476
+ overflow-y: auto; overscroll-behavior: contain;
477
+ background: var(--surface); border-left: 1px solid var(--line); box-shadow: var(--shadow);
478
+ animation: slide-in var(--t-med) var(--ease);
479
+ }
480
+ @keyframes slide-in { from { transform: translateX(24px); opacity: 0; } }
481
+ .drawer-head { display: flex; align-items: flex-start; gap: var(--sp-3); }
482
+ .drawer-title {
483
+ flex: 1; min-width: 0; margin: 0;
484
+ font-size: var(--fs-2xl); line-height: var(--lh-2xl); font-weight: var(--w-bold); letter-spacing: -0.015em;
485
+ overflow-wrap: anywhere; outline: none;
486
+ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden;
487
+ }
488
+ .drawer-close { flex: none; margin-top: 2px; font-size: var(--fs-xl); }
489
+ .drawer-meta { margin: var(--sp-2) 0 0; color: var(--fg-muted); font-size: var(--fs-sm); line-height: var(--lh-sm); display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-1); }
490
+ .drawer-badges { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: var(--sp-2) 0 0; font-size: var(--fs-sm); }
491
+ .action-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-4); padding-bottom: var(--sp-4); border-bottom: 1px solid var(--line); }
492
+
493
+ .d-section { margin-top: var(--sp-5); }
494
+ .d-h {
495
+ display: flex; align-items: center; gap: var(--sp-3);
496
+ margin: 0 0 var(--sp-3);
497
+ color: var(--fg-muted); font-size: var(--fs-xs); line-height: var(--lh-xs); font-weight: var(--w-bold);
498
+ text-transform: uppercase; letter-spacing: 0.06em;
499
+ }
500
+ .d-h::after { content: ""; flex: 1; height: 1px; background: var(--line); }
501
+ .pre {
502
+ margin: 0; padding: var(--sp-3) var(--sp-4);
503
+ max-height: 60vh; overflow: auto;
504
+ background: var(--surface-2); border-radius: var(--r-1);
505
+ font: inherit; font-size: var(--fs-md); line-height: var(--lh-md);
506
+ white-space: pre-wrap; overflow-wrap: anywhere;
507
+ }
508
+ .pre.mono { font-family: var(--mono); font-size: var(--fs-xs); line-height: var(--lh-xs); }
509
+ .pre.is-error { background: var(--danger-soft); color: var(--danger); }
510
+ .raw { margin-top: var(--sp-3); }
511
+ .raw summary { cursor: pointer; color: var(--fg-muted); font-size: var(--fs-sm); font-weight: var(--w-medium); padding: var(--sp-1) 0; }
512
+ .raw[open] summary { margin-bottom: var(--sp-2); }
513
+
514
+ .turns { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
515
+ .turn { display: flex; flex-direction: column; gap: var(--sp-1); }
516
+ .turn-role { color: var(--fg-muted); font-size: var(--fs-xs); font-weight: var(--w-bold); text-transform: uppercase; letter-spacing: 0.04em; }
517
+ .turn-user .turn-text { background: var(--surface-2); }
518
+ .turn-assistant .turn-text { background: var(--accent-soft); }
519
+ .turn-text { max-height: 40vh; font-size: var(--fs-sm); line-height: var(--lh-sm); }
520
+
521
+ .reply { margin-top: var(--sp-4); }
522
+ .reply-input {
523
+ display: block; width: 100%; min-height: 84px; resize: vertical;
524
+ padding: var(--sp-3);
525
+ border: 1px solid var(--line); border-radius: var(--r-1);
526
+ background: var(--surface); color: var(--fg);
527
+ font: inherit;
528
+ }
529
+ .reply-input:focus-visible { outline-offset: 0; }
530
+ .reply-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-2); font-size: var(--fs-xs); line-height: var(--lh-xs); }
531
+
532
+ .kv { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: var(--sp-2) var(--sp-3); margin: 0; font-size: var(--fs-sm); line-height: var(--lh-sm); }
533
+ .kv dt { color: var(--fg-muted); }
534
+ .kv dd { margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
535
+
536
+ .cmd {
537
+ display: flex; align-items: center; gap: var(--sp-2);
538
+ margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3);
539
+ background: var(--surface-2); border-radius: var(--r-1);
540
+ }
541
+ .cmd-text {
542
+ flex: 1; min-width: 0; padding: 0; background: none;
543
+ font-size: var(--fs-xs); line-height: var(--lh-xs);
544
+ white-space: nowrap; overflow-x: auto; user-select: all;
545
+ }
546
+ .links { margin: 0 0 var(--sp-2); padding-left: var(--sp-4); font-size: var(--fs-sm); line-height: var(--lh-sm); }
547
+ .links li + li { margin-top: var(--sp-1); }
548
+ .d-section p { margin: 0 0 var(--sp-2); }
549
+
550
+ /* ── dialogs ────────────────────────────────────────────────────────── */
551
+
552
+ .dialog {
553
+ width: min(440px, calc(100vw - 2 * var(--sp-4)));
554
+ max-height: calc(100vh - 2 * var(--sp-6));
555
+ padding: var(--sp-5);
556
+ border: 1px solid var(--line); border-radius: var(--r-2);
557
+ background: var(--surface); color: var(--fg);
558
+ box-shadow: var(--shadow);
559
+ }
560
+ .dialog-wide { width: min(560px, calc(100vw - 2 * var(--sp-4))); }
561
+ .dialog::backdrop { background: var(--scrim); }
562
+ .dialog[open] { animation: pop var(--t-med) var(--ease); }
563
+ @keyframes pop { from { transform: scale(0.98); opacity: 0; } }
564
+ .dialog-head { margin-bottom: var(--sp-4); }
565
+ .dialog-title { margin: 0; font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: var(--w-bold); }
566
+ .dialog-sub { margin: var(--sp-1) 0 0; color: var(--fg-muted); font-size: var(--fs-sm); line-height: var(--lh-sm); overflow-wrap: anywhere; }
567
+ .dialog-body { margin: 0 0 var(--sp-4); color: var(--fg-muted); }
568
+ .dialog-foot { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-5); }
569
+ .dialog-form { margin: 0; }
570
+ .radios { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0 0 var(--sp-4); padding: 0; border: 0; }
571
+ .radio {
572
+ display: flex; align-items: flex-start; gap: var(--sp-3);
573
+ padding: var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-1); cursor: pointer;
574
+ }
575
+ .radio:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
576
+ .radio input { margin: 3px 0 0; accent-color: var(--accent); }
577
+ .radio-body { display: flex; flex-direction: column; }
578
+ .radio-label { font-weight: var(--w-medium); }
579
+ .radio-hint { color: var(--fg-muted); font-size: var(--fs-sm); line-height: var(--lh-sm); }
580
+ .field-row { display: flex; gap: var(--sp-3); }
581
+ .app-list { list-style: none; margin: 0 0 var(--sp-4); padding: 0; }
582
+ .app-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--line); }
583
+ .app-name { flex: 1 1 auto; font-weight: var(--w-medium); overflow-wrap: anywhere; }
584
+ .app-meta { color: var(--fg-muted); font-size: var(--fs-sm); }
585
+ .token-box { margin: 0 0 var(--sp-4); }
586
+ .token-field { flex: 1; min-width: 0; font-family: var(--mono); }
587
+ .field { display: flex; flex: 1; flex-direction: column; gap: var(--sp-1); }
588
+ .field-label { color: var(--fg-muted); font-size: var(--fs-xs); font-weight: var(--w-medium); text-transform: uppercase; letter-spacing: 0.04em; }
589
+ .form-error { margin: var(--sp-3) 0 0; color: var(--danger); font-size: var(--fs-sm); }
590
+ .menu { display: flex; flex-direction: column; gap: 2px; }
591
+ .menu-item {
592
+ display: flex; align-items: center; gap: var(--sp-3);
593
+ min-height: var(--touch); padding: 0 var(--sp-3);
594
+ border: 0; border-radius: var(--r-1);
595
+ background: transparent; color: var(--fg);
596
+ font: inherit; text-align: left; cursor: pointer;
597
+ }
598
+ .menu-item:hover, .menu-item:focus-visible { background: var(--surface-2); outline-offset: -2px; }
599
+ .menu-item:disabled { opacity: 0.45; cursor: default; }
600
+ .menu-glyph { width: 20px; color: var(--fg-muted); text-align: center; }
601
+ .menu-label { flex: 1; font-weight: var(--w-medium); }
602
+ .menu-hint { color: var(--fg-muted); font-size: var(--fs-sm); }
603
+ .menu-danger .menu-label, .menu-danger .menu-glyph { color: var(--danger); }
604
+ .keys { display: grid; grid-template-columns: max-content 1fr; gap: var(--sp-2) var(--sp-4); margin: 0; align-items: center; }
605
+ .keys dt { white-space: nowrap; color: var(--fg-muted); }
606
+ .keys dd { margin: 0; }
607
+
608
+ /* ── toasts ─────────────────────────────────────────────────────────── */
609
+
610
+ .toasts {
611
+ position: fixed; left: 50%; bottom: var(--sp-5); z-index: 60;
612
+ display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
613
+ width: min(560px, calc(100vw - 2 * var(--sp-4)));
614
+ transform: translateX(-50%);
615
+ pointer-events: none;
616
+ }
617
+ .toast {
618
+ position: relative; overflow: hidden;
619
+ display: flex; align-items: center; gap: var(--sp-3);
620
+ max-width: 100%; padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4);
621
+ border: 1px solid var(--line); border-radius: var(--r-2);
622
+ background: var(--surface); color: var(--fg); box-shadow: var(--shadow);
623
+ font-size: var(--fs-sm); line-height: var(--lh-sm);
624
+ pointer-events: auto;
625
+ animation: rise var(--t-med) var(--ease);
626
+ }
627
+ @keyframes rise { from { transform: translateY(8px); opacity: 0; } }
628
+ .toast-out { opacity: 0; transform: translateY(4px); transition: opacity var(--t-med) var(--ease), transform var(--t-med) var(--ease); }
629
+ .toast-error { border-left: 4px solid var(--danger); }
630
+ .toast-msg { flex: 1; min-width: 0; overflow-wrap: anywhere; }
631
+ .toast-action {
632
+ flex: none; height: 28px; padding: 0 var(--sp-3);
633
+ border: 0; border-radius: var(--r-1);
634
+ background: var(--accent-soft); color: var(--accent);
635
+ font: inherit; font-weight: var(--w-bold); cursor: pointer;
636
+ }
637
+ .toast-close {
638
+ flex: none; width: 28px; height: 28px; padding: 0;
639
+ border: 0; border-radius: var(--r-1);
640
+ background: transparent; color: var(--fg-muted);
641
+ font: inherit; font-size: var(--fs-lg); cursor: pointer;
642
+ }
643
+ .toast-close:hover { background: var(--surface-2); }
644
+ .toast-bar {
645
+ position: absolute; left: 0; bottom: 0; height: 3px; width: 100%;
646
+ background: var(--accent); transform-origin: left;
647
+ animation: countdown linear forwards;
648
+ }
649
+ @keyframes countdown { to { transform: scaleX(0); } }
650
+
651
+ /* ── narrow screens: bottom tab bar, full-screen drawer ─────────────── */
652
+
653
+ @media (max-width: 719px) {
654
+ .top { padding: 0 var(--sp-4); gap: var(--sp-3); }
655
+ .tabs {
656
+ position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
657
+ height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
658
+ padding: 0 0 env(safe-area-inset-bottom);
659
+ gap: 0; border-radius: 0;
660
+ background: var(--surface); border-top: 1px solid var(--line);
661
+ }
662
+ .tab {
663
+ position: relative; flex: 1; flex-direction: column; justify-content: center; gap: 2px;
664
+ height: var(--tabbar-h); border-radius: 0; font-size: var(--fs-xs);
665
+ }
666
+ .tab[aria-current="page"] { background: transparent; box-shadow: none; color: var(--accent); }
667
+ .tab-glyph { display: block; font-size: var(--fs-lg); line-height: 1; }
668
+ .tab .count { position: absolute; top: 6px; left: calc(50% + 8px); }
669
+ #help-btn { display: none; }
670
+ .pill { height: 30px; font-size: var(--fs-xs); padding: 0 var(--sp-2); }
671
+ .banner { margin: var(--sp-3) var(--sp-4) 0; flex-wrap: wrap; }
672
+ .view { padding: var(--sp-4) var(--sp-4) calc(var(--tabbar-h) + 96px); }
673
+ .row, .view-journal .row, .group-attention .row {
674
+ grid-template-columns: 8px 80px minmax(0, 1fr) auto;
675
+ grid-template-areas: "dot time main act" "dot band main act";
676
+ column-gap: var(--sp-2);
677
+ padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3);
678
+ }
679
+ .row-dot { grid-area: dot; }
680
+ .row-time { grid-area: time; }
681
+ .row-band { grid-area: band; }
682
+ .row-main { grid-area: main; }
683
+ .row-actions { grid-area: act; }
684
+ .row-pm { display: none; }
685
+ .row-hover, .row-actions .btn { display: none; }
686
+ .row-more { opacity: 1; }
687
+ .row-btn { width: var(--touch); height: var(--touch); }
688
+ .row-line1 .badge { display: none; }
689
+ .row-line1 { flex-wrap: nowrap; }
690
+ .day-clean { margin-left: 0; width: 100%; }
691
+ .expand { padding-left: var(--sp-4); }
692
+ .drawer { width: 100vw; border-left: 0; padding: var(--sp-4) var(--sp-4) var(--sp-7); }
693
+ .drawer-title { font-size: var(--fs-xl); line-height: var(--lh-xl); }
694
+ .toasts { bottom: calc(var(--tabbar-h) + var(--sp-3)); }
695
+ .drop-dock { padding: var(--sp-2) var(--sp-4); }
696
+ .btn { min-height: 40px; }
697
+ .btn-sm { min-height: 32px; }
698
+ .field-row { flex-direction: column; }
699
+ .filters { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-2); }
700
+ .filters .select { width: 100%; padding-right: var(--sp-5); }
701
+ .filters > .btn { grid-column: 1 / -1; justify-self: start; }
702
+ }
703
+
704
+ @media (hover: none) {
705
+ .row-hover { display: none; }
706
+ .row-more { opacity: 1; }
707
+ }
708
+
709
+ @media (prefers-reduced-motion: reduce) {
710
+ *, *::before, *::after { animation-duration: 0ms !important; animation-iteration-count: 1 !important; transition-duration: 0ms !important; scroll-behavior: auto !important; }
711
+ .toast-bar { display: none; }
712
+ .spinner { border-top-color: var(--accent); border-right-color: var(--accent); }
713
+ }