@gotcos/glasses-server 6.98.1 → 6.99.16

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 (98) hide show
  1. package/CHANGELOG.md +227 -0
  2. package/package.json +2 -1
  3. package/server/index.ts +170 -11
  4. package/server/lib/api-auth.ts +31 -14
  5. package/server/lib/claude-bridge.ts +21 -2
  6. package/server/lib/codex-bridge.ts +21 -2
  7. package/server/lib/cos-thread.ts +582 -0
  8. package/server/lib/display-bus.ts +3 -0
  9. package/server/lib/drop-attachments.ts +55 -0
  10. package/server/lib/drop-destinations.ts +134 -0
  11. package/server/lib/drop-history-search.ts +97 -0
  12. package/server/lib/drop-p2-boot.ts +60 -0
  13. package/server/lib/drop-p2-runtime.ts +237 -0
  14. package/server/lib/drop-p2-settings.ts +174 -0
  15. package/server/lib/drop-resolution.ts +168 -0
  16. package/server/lib/drop-router.ts +325 -0
  17. package/server/lib/drop-service.ts +830 -0
  18. package/server/lib/drop-settings.ts +56 -0
  19. package/server/lib/drop-store.ts +450 -0
  20. package/server/lib/drop-when.ts +265 -0
  21. package/server/lib/glasses-pairing.ts +15 -0
  22. package/server/lib/learning-needs-you.ts +111 -0
  23. package/server/lib/live-cues-v2-settings.ts +2 -1
  24. package/server/lib/live-cues-v2.ts +6 -4
  25. package/server/lib/media-store.ts +80 -0
  26. package/server/lib/meeting-batch-transcribe.ts +15 -2
  27. package/server/lib/meeting-consolidation-run.ts +169 -0
  28. package/server/lib/meeting-store.ts +61 -0
  29. package/server/lib/meeting-title-steer.ts +200 -0
  30. package/server/lib/network-policy.ts +84 -6
  31. package/server/lib/permission-broker.ts +13 -0
  32. package/server/lib/phone-recording.ts +1 -1
  33. package/server/lib/ping-budget.ts +149 -0
  34. package/server/lib/ping-engine.ts +245 -0
  35. package/server/lib/ping-feed-sink.ts +33 -0
  36. package/server/lib/ping-sources.ts +192 -0
  37. package/server/lib/query-job-coordinator.ts +5 -2
  38. package/server/lib/query-job-runtime.ts +45 -4
  39. package/server/lib/query-job-types.ts +10 -1
  40. package/server/lib/reminder-scheduler.ts +153 -0
  41. package/server/lib/tailnet-self-name.ts +103 -0
  42. package/server/lib/tailscale-nudge.ts +40 -2
  43. package/server/lib/task-store.ts +32 -0
  44. package/server/lib/web-ask-admission.ts +56 -0
  45. package/server/lib/web-live-chunks.ts +273 -0
  46. package/server/lib/web-memories-bridge.ts +323 -0
  47. package/server/lib/web-session-auth.ts +492 -0
  48. package/server/lib/web-usage-bridge.ts +154 -0
  49. package/server/lib/work-search.ts +14 -1
  50. package/server/lib/your-move-count.ts +58 -0
  51. package/server/routes/cos-thread.ts +79 -0
  52. package/server/routes/display.ts +11 -1
  53. package/server/routes/drops.ts +262 -0
  54. package/server/routes/health.ts +16 -0
  55. package/server/routes/live-cues.ts +5 -4
  56. package/server/routes/meeting.ts +61 -5
  57. package/server/routes/permission-broker.ts +23 -3
  58. package/server/routes/transcribe-stream.ts +43 -4
  59. package/server/routes/web-control.ts +569 -0
  60. package/server/routes/welcome-context.ts +2 -1
  61. package/server/scripts/web-live-cls/cdp.mjs +57 -0
  62. package/server/scripts/web-live-cls/measure.mjs +80 -0
  63. package/server/scripts/web-live-cls/mock.mjs +97 -0
  64. package/server/scripts/web-live-cls/render.mjs +26 -0
  65. package/server/web-control/app.css +519 -0
  66. package/server/web-control/app.js +3643 -0
  67. package/server/web-control/control.css +325 -0
  68. package/server/web-control/fonts/DMSans.ttf +0 -0
  69. package/server/web-control/fonts/Fraunces.ttf +0 -0
  70. package/server/web-control/fonts/JetBrainsMono.ttf +0 -0
  71. package/server/web-control/index.html +275 -0
  72. package/server/web-control/mark.svg +1 -0
  73. package/server/web-control/memories/d3.min.js +2 -0
  74. package/server/web-control/memories/graph-explorer.css +200 -0
  75. package/server/web-control/memories/graph-explorer.js +748 -0
  76. package/server/web-control/memories/memories-app.js +1561 -0
  77. package/server/web-control/memories/memories-theme.css +73 -0
  78. package/server/web-control/memories/memories.html +72 -0
  79. package/server/web-control/memories/memory-stewardship.js +63 -0
  80. package/server/web-control/memories/memory-workspace.js +216 -0
  81. package/server/web-control/panes/cos-chat.css +174 -0
  82. package/server/web-control/panes/cos-chat.js +1118 -0
  83. package/server/web-control/panes/dictation.js +173 -0
  84. package/server/web-control/panes/meetings.css +314 -0
  85. package/server/web-control/panes/meetings.js +2568 -0
  86. package/server/web-control/panes/messages.js +718 -0
  87. package/server/web-control/panes/questions.css +32 -0
  88. package/server/web-control/panes/questions.js +275 -0
  89. package/server/web-control/panes/sessions.css +452 -0
  90. package/server/web-control/panes/settings.js +292 -0
  91. package/server/web-control/panes/speakers.css +269 -0
  92. package/server/web-control/panes/speakers.js +2755 -0
  93. package/server/web-control/panes/threads.js +200 -0
  94. package/server/web-control/panes/work.css +261 -0
  95. package/server/web-control/panes/work.js +1667 -0
  96. package/server/web-control/shell.js +294 -0
  97. package/server/web-control/theme.js +25 -0
  98. package/server/web-control/vendor/qrcode-encoder.js +10 -0
@@ -0,0 +1,452 @@
1
+ /* COS Control Web: sessions pane styles, on top of control.css.
2
+ Control's Sessions pane (ActivityWindow.swift 2288-2933, 6341-6890) and its Usage and COS cost
3
+ views (SessionUsageView.swift). Phone first: the list, then the reader as a pushed screen; from
4
+ 760px the list sits beside the reader. Nothing here is fixed to the bottom of the screen. */
5
+
6
+ .sx {
7
+ --pv-claude: rgb(199, 115, 56);
8
+ --pv-codex: rgb(26, 140, 122);
9
+ --pv-cursor: rgb(107, 97, 219);
10
+ --run-green: rgb(56, 145, 99);
11
+ }
12
+ :root[data-theme='dark'] .sx { --pv-claude: rgb(226, 146, 92); --pv-codex: rgb(72, 190, 168); --pv-cursor: rgb(158, 150, 245); --run-green: rgb(108, 207, 143); }
13
+ @media (prefers-color-scheme: dark) {
14
+ :root:not([data-theme='light']) .sx { --pv-claude: rgb(226, 146, 92); --pv-codex: rgb(72, 190, 168); --pv-cursor: rgb(158, 150, 245); --run-green: rgb(108, 207, 143); }
15
+ }
16
+
17
+ /* ── header, views, clock ─────────────────────────────── */
18
+ .sx-views { justify-content: space-between; margin: 10px 0 8px; }
19
+ .sx-clock { margin-left: auto; }
20
+ .sx-split { margin-top: 4px; }
21
+ @media (max-width: 599px) {
22
+ .sx-views { gap: 2px 18px; }
23
+ .sx-clock { margin-left: 0; }
24
+ .sx-views .cx-switch button { min-height: 38px; }
25
+ }
26
+ /* A reader on a narrow screen is a pushed page: the header and switches step aside. */
27
+ @media (max-width: 759px) {
28
+ #pane-sessions.reading .sx-hero,
29
+ #pane-sessions.reading .sx-views { display: none; }
30
+ }
31
+
32
+ /* ── search ───────────────────────────────────────────── */
33
+ .sx-tools { display: flex; gap: 8px; align-items: center; margin: 2px 0 8px; }
34
+ .sx-search { flex: 1 1 auto; max-width: none; min-width: 0; }
35
+ .sx-search .field { width: 100%; }
36
+ .sx-select {
37
+ min-height: 36px; height: 36px; padding: 0 30px 0 11px; font-size: 13.5px; border-radius: 9px;
38
+ background-position: calc(100% - 16px) 15px, calc(100% - 11px) 15px; width: auto; max-width: 210px; flex: none; color: var(--ink);
39
+ }
40
+ .sx-hint { margin: 0 2px 8px; }
41
+ @media (max-width: 599px) {
42
+ .sx-search { order: 0; flex: 1 1 auto; }
43
+ .sx-search .cx-clear { min-height: 40px; padding: 0 2px; }
44
+ .sx-select { min-height: 40px; height: 40px; font-size: 16px; background-position: calc(100% - 16px) 17px, calc(100% - 11px) 17px; }
45
+ #sessions-recency { max-width: 128px; }
46
+ .sx-ufilters .sx-select { flex: 1 1 150px; max-width: none; }
47
+ .sx-utable .hp { display: none; }
48
+ }
49
+
50
+ .sx-hooks { display: flex; gap: 9px; align-items: flex-start; padding: 9px 12px; margin: 0 0 10px; border-radius: 10px; background: var(--qopen); border: 1px solid var(--panel-border); font-size: 12.5px; line-height: 1.4; color: var(--sub); }
51
+ .sx-hooks-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); margin-top: 5px; flex: none; }
52
+ .sx-hooks-where { color: var(--tertiary); }
53
+
54
+ /* ── rows ─────────────────────────────────────────────── */
55
+ .sx-row { grid-template-columns: 28px minmax(0, 1fr) auto; gap: 11px; padding: 11px 12px 11px 12px; align-items: start; }
56
+ .cx-row.sx-row + .cx-row.sx-row::before { left: 51px; }
57
+ .sx-row[aria-selected='true'] { background: var(--qopen); box-shadow: inset 3px 0 0 var(--accent); }
58
+ .sx-glyph { width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; margin-top: 1px; color: var(--pv-claude); background: color-mix(in srgb, var(--pv-claude) 16%, transparent); }
59
+ .sx-glyph.codex { color: var(--pv-codex); background: color-mix(in srgb, var(--pv-codex) 16%, transparent); }
60
+ .sx-glyph.cursor { color: var(--pv-cursor); background: color-mix(in srgb, var(--pv-cursor) 16%, transparent); }
61
+ .sx-glyph svg { width: 16px; height: 16px; fill: currentColor; fill-rule: evenodd; stroke: none; }
62
+ .sx-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; font: 600 15px/1.3 var(--body); color: var(--ink); }
63
+ .sx-snippet { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; margin-top: 3px; font-size: 12.5px; line-height: 1.4; color: var(--sub); }
64
+ .sx-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 5px; min-width: 0; }
65
+ .sx-badge { display: inline-flex; align-items: center; height: 17px; padding: 0 6px; border-radius: 9px; font: 700 9px/1 var(--mono); letter-spacing: 0.06em; color: var(--pv-claude); background: color-mix(in srgb, var(--pv-claude) 14%, transparent); white-space: nowrap; }
66
+ .sx-badge.codex { color: var(--pv-codex); background: color-mix(in srgb, var(--pv-codex) 14%, transparent); }
67
+ .sx-badge.cursor { color: var(--pv-cursor); background: color-mix(in srgb, var(--pv-cursor) 14%, transparent); }
68
+ .sx-pinned { display: inline-flex; align-items: center; height: 17px; padding: 0 6px; border-radius: 9px; font: 700 8.5px/1 var(--mono); letter-spacing: 0.06em; color: var(--sub); background: color-mix(in srgb, var(--ink) 8%, transparent); }
69
+ .sx-chip { font: 600 11.5px/1.3 var(--body); color: var(--sub); }
70
+ .sx-chip.waiting { color: var(--amber); }
71
+ .sx-chip.running { color: var(--run-green); }
72
+ .sx-when, .sx-ws { font-size: 11.5px; line-height: 1.3; color: var(--sub); }
73
+ .sx-ws { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
74
+ .sx-opened { font: 500 11.5px/1.3 var(--body); color: var(--amber); }
75
+ .sx-side { display: flex; align-items: center; gap: 8px; align-self: center; }
76
+ .sx-match { font: 600 9.5px/1 var(--mono); padding: 4px 7px; border-radius: 10px; white-space: nowrap; color: var(--ink); background: color-mix(in srgb, var(--tint) 16%, transparent); }
77
+ .sx-looking { padding: 10px 4px; }
78
+ @media (min-width: 760px) {
79
+ .sx-title { -webkit-line-clamp: 1; font-size: 13.5px; }
80
+ .sx-snippet { font-size: 11.5px; }
81
+ .sx-when, .sx-ws, .sx-chip, .sx-opened { font-size: 10.5px; }
82
+ .sx-row { padding: 10px 12px; }
83
+ }
84
+
85
+ /* ── reader ───────────────────────────────────────────── */
86
+ .sx-reader { min-width: 0; }
87
+ .sx-reader-head { padding: 4px 0 12px; border-bottom: 1px solid var(--hairline); margin-bottom: 14px; }
88
+ .sx-head-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
89
+ .sx-head-line .sx-badge { height: 19px; font-size: 9.5px; padding: 0 7px; }
90
+ .sx-reader-title { font: 500 22px/1.2 var(--display); margin: 0; color: var(--ink); overflow-wrap: anywhere; min-width: 0; letter-spacing: -0.005em; }
91
+ .sx-subtitle { margin: 6px 0 0; font-size: 12.5px; color: var(--sub); overflow-wrap: anywhere; }
92
+ .sx-retry { margin: 10px 0; }
93
+
94
+ /* ACTIVITY keeps one size in every state, so nothing below it moves while you read. Each row has a
95
+ fixed height; the tail of tool lines and reply text is anchored to its bottom and clips above. */
96
+ .sx-activity {
97
+ --act-state: 34px; --act-prompt: 20px; --act-tail: 48px;
98
+ padding: 11px 14px 10px; border-radius: 10px; background: var(--qopen); border: 1px solid var(--panel-border); margin-bottom: 14px; overflow: hidden;
99
+ }
100
+ @media (min-width: 760px) { .sx-activity { --act-tail: 64px; } }
101
+ .sx-act-label { display: flex; align-items: center; gap: 12px; height: 14px; font: 600 9.5px/14px var(--mono); letter-spacing: 0.12em; color: var(--sub); white-space: nowrap; overflow: hidden; }
102
+ .sx-act-bits { display: flex; gap: 10px; margin-left: auto; min-width: 0; overflow: hidden; font: 400 10px/14px var(--mono); letter-spacing: 0; color: var(--tertiary); }
103
+ .sx-act-bits .warn { color: var(--amber); }
104
+ .sx-act-bits .accent { color: var(--accent); }
105
+ .sx-act-state { display: flex; align-items: center; gap: 8px; height: var(--act-state); margin-top: 4px; white-space: nowrap; overflow: hidden; }
106
+ .sx-act-state strong { flex: none; font: 600 13.5px/1.3 var(--body); color: var(--ink); }
107
+ .sx-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--tertiary); flex: none; }
108
+ .sx-dot.working { background: var(--run-green); animation: pulse 2s ease-out infinite; }
109
+ .sx-dot.waiting { background: var(--amber); }
110
+ .sx-dot.failed { background: var(--hot); }
111
+ .sx-act-detail { flex: 1 1 auto; min-width: 0; font-size: 12.5px; color: var(--sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
112
+ .sx-act-clock { flex: none; margin-left: auto; font: 400 11px/1.3 var(--mono); color: var(--tertiary); font-variant-numeric: tabular-nums; }
113
+ .sx-act-stop.cx-btn { flex: none; height: 30px; padding: 0 11px; font-size: 13px; }
114
+ .sx-act-prompt { height: var(--act-prompt); margin: 0; font-size: 13.5px; line-height: var(--act-prompt); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
115
+ .sx-act-tail { height: var(--act-tail); margin-top: 4px; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; }
116
+ .sx-act-tool { flex: none; font: 400 11px/16px var(--mono); color: var(--sub); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
117
+ .sx-act-prose { flex: none; margin-top: 2px; font-size: 13px; line-height: 16px; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
118
+ .sx-act-fallback { height: calc(var(--act-state) + var(--act-prompt) + var(--act-tail) + 8px); margin: 0; padding-top: 6px; font-size: 12.5px; line-height: 1.4; color: var(--sub); overflow: hidden; box-sizing: border-box; }
119
+ @media (max-width: 599px) { .sx-activity { --act-state: 38px; } .sx-act-stop.cx-btn { height: 36px; } }
120
+ .sx-note { font-size: 12px; color: var(--sub); margin: 0 2px 12px; }
121
+
122
+ /* YOU and ASSISTANT cards (Control: card fill, a tinted hairline; sessions tint for you, green for the reply). */
123
+ #session-turns.sx-turns { display: grid; gap: 12px; margin-top: 0; }
124
+ .sx-turns .turn {
125
+ max-width: none; justify-self: stretch; min-width: 0; color: var(--ink); background: var(--panel);
126
+ border: 1px solid color-mix(in srgb, var(--green) 24%, var(--panel-border)); border-radius: 13px;
127
+ padding: 13px 16px 14px; white-space: normal; font-size: 15px; line-height: 1.5;
128
+ }
129
+ .sx-turns .turn.user { border-color: color-mix(in srgb, var(--tint) 30%, var(--panel-border)); background: var(--panel); color: var(--ink); }
130
+ .sx-turns .turn .who { display: flex; justify-content: space-between; gap: 10px; opacity: 1; margin-bottom: 9px; font: 600 9.5px/1 var(--mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--sub); }
131
+ .sx-turn-when { font: 400 10.5px/1 var(--mono); letter-spacing: 0; text-transform: none; color: var(--tertiary); }
132
+ .sx-turns .turn.pending { white-space: pre-wrap; opacity: 0.75; overflow-wrap: anywhere; }
133
+ .sx-turns .turn.user code { background: color-mix(in srgb, var(--row-border) 70%, transparent); }
134
+ .sx-plain { white-space: pre-wrap; overflow-wrap: anywhere; }
135
+ .sx-turns .reader-placeholder { padding: 12px 4px; }
136
+
137
+ /* Markdown in a reply. */
138
+ .sx-md { overflow-wrap: anywhere; min-width: 0; }
139
+ .sx-md > :first-child { margin-top: 0; }
140
+ .sx-md > :last-child { margin-bottom: 0; }
141
+ .sx-md p { margin: 0 0 0.7em; }
142
+ .sx-md h3, .sx-md h4, .sx-md h5, .sx-md h6 { font: 600 15.5px/1.3 var(--body); margin: 1em 0 0.45em; color: var(--ink); }
143
+ .sx-md h3 { font-size: 17px; }
144
+ .sx-md h5, .sx-md h6 { font-size: 14px; color: var(--sub); }
145
+ .sx-md ul, .sx-md ol { margin: 0 0 0.7em; padding-left: 1.35em; }
146
+ .sx-md li { margin: 0.18em 0; }
147
+ .sx-md li > ul, .sx-md li > ol { margin: 0.2em 0 0.2em; }
148
+ .sx-md code { font: 400 13px/1.4 var(--mono); background: color-mix(in srgb, var(--row-border) 70%, transparent); padding: 1px 5px; border-radius: 5px; }
149
+ .sx-md pre { margin: 0 0 0.8em; padding: 10px 12px; border-radius: 9px; background: var(--qopen); border: 1px solid var(--hairline); overflow-x: auto; max-width: 100%; }
150
+ .sx-md pre code { background: none; padding: 0; font-size: 12.5px; line-height: 1.5; white-space: pre; }
151
+ .sx-md blockquote { margin: 0 0 0.7em; padding: 2px 0 2px 12px; border-left: 3px solid var(--panel-border); color: var(--sub); }
152
+ .sx-md hr { border: 0; border-top: 1px solid var(--hairline); margin: 1em 0; }
153
+ .sx-md a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
154
+ .sx-md del { color: var(--sub); }
155
+ .sx-table { overflow-x: auto; max-width: 100%; margin: 0 0 0.8em; }
156
+ .sx-table table { border-collapse: collapse; font-size: 13.5px; line-height: 1.4; min-width: 100%; }
157
+ .sx-table th, .sx-table td { border: 1px solid var(--hairline); padding: 6px 9px; text-align: left; vertical-align: top; }
158
+ .sx-table th { font-weight: 600; background: var(--qopen); }
159
+
160
+ .sx-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 16px 0 4px; }
161
+ .sx-foot-note { font-size: 11.5px; color: var(--tertiary); }
162
+ .sx-copy-note { margin: 6px 2px 0; font-size: 12px; color: var(--sub); }
163
+
164
+ /* Continue: refusal and caution boxes, the park hint, the field, the queue. */
165
+ .sx-chat { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hairline); }
166
+ #pane-sessions .composer { position: relative; bottom: auto; margin-top: 4px; }
167
+ #pane-sessions .composer .btn.small { min-height: 38px; }
168
+ .sx-box { padding: 11px 13px; border-radius: 10px; margin-bottom: 10px; font-size: 13px; line-height: 1.45; color: var(--sub); }
169
+ .sx-box p { margin: 0; overflow-wrap: anywhere; }
170
+ .sx-box .sx-box-sub { margin-top: 4px; font-size: 12px; color: var(--tertiary); }
171
+ .sx-box.refusal { background: var(--amber-bg); }
172
+ .sx-box.confirm { background: var(--panel); border: 1px solid var(--amber); box-shadow: var(--shadow); }
173
+ .sx-box.confirm strong { display: block; font: 600 14.5px/1.3 var(--body); color: var(--ink); margin-bottom: 4px; }
174
+ .sx-box-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 9px; }
175
+ .cx-btn.danger { border-color: var(--hot); color: var(--hot); background: var(--btn-bg); }
176
+ .sx-park { margin-bottom: 10px; font-size: 12.5px; line-height: 1.45; color: var(--sub); }
177
+ .sx-park p { margin: 0; }
178
+ .sx-caution { margin: 6px 4px 0; font-size: 11.5px; line-height: 1.4; color: var(--tertiary); }
179
+ .sx-queue { margin-top: 12px; display: grid; gap: 6px; }
180
+ .sx-queue-head { margin: 0 2px 2px; font-size: 12px; color: var(--accent); }
181
+ .sx-queue-row { display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; gap: 8px 10px; align-items: center; padding: 8px 10px; border-radius: 9px; background: var(--panel); border: 1px solid var(--panel-border); }
182
+ .sx-queue-state { font: 700 9.5px/1.2 var(--mono); color: var(--accent); }
183
+ .sx-queue-text { font-size: 13px; line-height: 1.4; color: var(--ink); overflow-wrap: anywhere; }
184
+ @media (max-width: 599px) {
185
+ .sx-queue-row { grid-template-columns: minmax(0, 1fr) auto; }
186
+ .sx-queue-state { grid-column: 1 / -1; }
187
+ }
188
+ @media (min-width: 760px) {
189
+ .sx-reader-title { font-size: 24px; }
190
+ }
191
+
192
+ /* ── Usage view ───────────────────────────────────────── */
193
+ .sx-usage { margin-top: 2px; }
194
+ .sx-ufilters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 4px 0 6px; }
195
+ .sx-link { font: 600 13px/1 var(--body); color: var(--accent); min-height: 36px; padding: 0 4px; }
196
+ .sx-fresh { margin-left: auto; font-size: 12px; color: var(--sub); font-variant-numeric: tabular-nums; white-space: nowrap; }
197
+ .sx-unote { margin: 6px 2px 0; }
198
+ .sx-uempty { margin-top: 14px; padding: 22px 16px; border-radius: 10px; background: var(--qopen); color: var(--sub); font-size: 14px; line-height: 1.45; }
199
+ .sx-uempty .sx-unote { margin-top: 8px; }
200
+ .sx-figures { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 14px; margin-top: 18px; }
201
+ .sx-figure { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
202
+ .sx-figure b { font: 500 24px/1.1 var(--display); color: var(--ink); font-variant-numeric: tabular-nums; }
203
+ .sx-figure.lead b { font-size: 30px; }
204
+ .sx-figure-title { font: 500 12px/1.3 var(--body); color: var(--ink); }
205
+ .sx-figure-note { font-size: 11px; color: var(--sub); }
206
+ @media (min-width: 760px) { .sx-figures { grid-template-columns: repeat(4, minmax(0, 1fr)); } .sx-figure.lead b { font-size: 32px; } }
207
+ .sx-uhead { font: 600 15px/1.2 var(--body); color: var(--ink); margin: 26px 2px 10px; }
208
+ .sx-utable table { width: 100%; background: var(--panel); }
209
+ .sx-utable th { font-size: 11.5px; color: var(--sub); }
210
+ .sx-utable td { font-size: 13px; }
211
+ .sx-utable .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
212
+ .sx-days { padding: 2px 0; }
213
+ .sx-day { display: grid; grid-template-columns: 96px minmax(0, 1fr) 58px 56px; gap: 10px; align-items: center; padding: 7px 14px; font-size: 13px; }
214
+ .sx-day + .sx-day { border-top: 1px solid var(--hairline); }
215
+ .sx-day-date { color: var(--ink); white-space: nowrap; }
216
+ .sx-day-bar { height: 7px; border-radius: 4px; background: color-mix(in srgb, var(--hairline) 70%, transparent); overflow: hidden; }
217
+ .sx-day-bar span { display: block; height: 100%; border-radius: 4px; background: var(--accent); }
218
+ .sx-day-tok, .sx-day-usd { text-align: right; font-variant-numeric: tabular-nums; color: var(--sub); white-space: nowrap; }
219
+ .sx-day-usd { color: var(--ink); }
220
+ .sx-ufoot { margin: 18px 2px 0; padding-top: 12px; border-top: 1px solid var(--hairline); font-size: 12px; line-height: 1.5; color: var(--sub); }
221
+ .sx-how { margin: 10px 2px 0; font-size: 12px; color: var(--sub); }
222
+ .sx-how summary { cursor: pointer; color: var(--accent); font-weight: 600; min-height: 32px; display: flex; align-items: center; }
223
+ .sx-how p { margin: 8px 0 0; max-width: 680px; line-height: 1.5; }
224
+ .sx-reading { padding: 18px 4px; }
225
+
226
+ /* ── COS cost view ────────────────────────────────────── */
227
+ .sx-cost-head { font: 500 26px/1.28 var(--display); color: var(--ink); margin: 10px 0 0; max-width: 800px; letter-spacing: -0.005em; }
228
+ .sx-cost-head span { color: var(--sub); }
229
+ .sx-cost-api { margin: 12px 0 0; font-size: 13px; color: var(--sub); }
230
+ .sx-cost-status { margin-top: 10px; display: grid; gap: 6px; font-size: 13px; }
231
+ .sx-cost-status p { margin: 0; color: var(--sub); }
232
+ .sx-cost-status .warn { color: var(--amber); }
233
+ .sx-cost-rows { margin-top: 22px; border-bottom: 1px solid var(--hairline); }
234
+ .sx-cost-row { display: grid; grid-template-columns: minmax(0, 340px) minmax(80px, 1fr) 170px; gap: 22px; align-items: center; padding: 13px 0; border-top: 1px solid var(--hairline); }
235
+ .sx-cost-name { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
236
+ .sx-cost-name b { font: 500 14px/1.3 var(--body); color: var(--ink); }
237
+ .sx-cost-name span { font-size: 12.5px; color: var(--sub); font-variant-numeric: tabular-nums; }
238
+ .sx-cost-name .mix { font-size: 12px; }
239
+ .sx-cost-bar { display: flex; height: 7px; border-radius: 4px; overflow: hidden; background: color-mix(in srgb, var(--hairline) 55%, transparent); }
240
+ .sx-cost-bar .m { background: var(--accent); min-width: 3px; }
241
+ .sx-cost-bar .e { background: color-mix(in srgb, var(--accent) 28%, transparent); min-width: 3px; }
242
+ .sx-cost-fig { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; text-align: right; }
243
+ .sx-cost-fig b { font: 500 14px/1.2 var(--body); color: var(--sub); font-variant-numeric: tabular-nums; }
244
+ .sx-cost-fig.measured b { font: 500 19px/1.15 var(--display); color: var(--ink); }
245
+ .sx-cost-fig span { font-size: 12px; color: var(--sub); font-variant-numeric: tabular-nums; }
246
+ .sx-work { margin-top: 24px; display: grid; gap: 8px; }
247
+ .sx-work-top { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; }
248
+ .sx-work-top > div:first-child { display: flex; flex-direction: column; gap: 3px; }
249
+ .sx-work-title { font: 500 19px/1.15 var(--display); color: var(--ink); }
250
+ .sx-work-count { font-size: 12.5px; color: var(--sub); }
251
+ .sx-work-fig { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; text-align: right; }
252
+ .sx-work-fig b { font: 500 19px/1.15 var(--display); color: var(--ink); font-variant-numeric: tabular-nums; }
253
+ .sx-work-fig span { font-size: 12px; color: var(--sub); }
254
+ .sx-work p { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--sub); max-width: 760px; }
255
+ .sx-work p.strong { font: 500 13px/1.45 var(--body); color: var(--ink); }
256
+ .sx-cost-foot { margin-top: 26px; display: grid; gap: 8px; }
257
+ .sx-cost-foot > p { margin: 0; font-size: 12px; line-height: 1.5; color: var(--sub); max-width: 760px; }
258
+ @media (max-width: 759px) {
259
+ .sx-cost-head { font-size: 22px; }
260
+ .sx-cost-row { grid-template-columns: minmax(0, 1fr) auto; gap: 8px 14px; }
261
+ .sx-cost-bar { grid-column: 1 / -1; grid-row: 2; }
262
+ .sx-day { grid-template-columns: 84px minmax(0, 1fr) 52px 50px; gap: 8px; padding: 7px 12px; }
263
+ }
264
+
265
+ /* ── Usage, wide (860 px and up): the Mac's desktop layout (SessionUsageView, SessionUsageSplitLayout) ──
266
+ Chart left and the summary card right, the day-by-day calendar and the Tool and model table full width below.
267
+ Under 860 px none of this applies and the vertical view above is unchanged. Series colours are the Mac's
268
+ (SessionUsageChart.seriesColor), fixed in both themes except Cursor, which follows the ink. */
269
+ .sx-usage {
270
+ --u-gold: rgb(201, 168, 110); --u-codex: rgb(5, 150, 158); --u-cursor: color-mix(in srgb, var(--ink) 72%, transparent);
271
+ --u-purple: rgb(135, 102, 196); --u-input: rgb(51, 125, 199); --u-output: rgb(219, 110, 41); --u-read: rgb(156, 148, 135);
272
+ --u-gray: rgb(142, 142, 147); --u-brown: rgb(140, 107, 51);
273
+ --u-blue: rgb(0, 122, 255); --u-green: rgb(52, 199, 89); --u-pink: rgb(255, 45, 85); --u-indigo: rgb(88, 86, 214); --u-tan: rgb(162, 132, 94);
274
+ }
275
+ .u-sw { display: inline-block; flex: none; width: 9px; height: 9px; border-radius: 2px; }
276
+ .u-chev { width: 9px; height: 6px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
277
+ .u-rangebtn {
278
+ appearance: none; -webkit-appearance: none; text-align: left; cursor: pointer; padding-right: 30px; color: var(--ink);
279
+ background-image: linear-gradient(45deg, transparent 50%, var(--sub) 50%), linear-gradient(135deg, var(--sub) 50%, transparent 50%);
280
+ background-repeat: no-repeat; background-size: 5px 5px;
281
+ }
282
+ .u-wide .sx-figures.five { grid-template-columns: repeat(5, minmax(0, 1fr)); }
283
+ .u-split { display: grid; grid-template-columns: minmax(0, 1fr) clamp(300px, 31%, 340px); gap: 28px; align-items: stretch; margin-top: 26px; }
284
+ .u-chartcol { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
285
+ .u-sentence { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; font: 500 15px/1.2 var(--body); color: var(--ink); }
286
+ .u-grow { flex: 1; }
287
+ .u-word { position: relative; display: inline-flex; align-items: center; gap: 3px; min-height: 36px; color: var(--accent); cursor: pointer; border-radius: 6px; }
288
+ .u-word select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; font-size: 16px; appearance: none; -webkit-appearance: none; border: 0; }
289
+ .u-word:focus-within { outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent); outline-offset: 2px; }
290
+ .u-style { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 8px; color: color-mix(in srgb, var(--sub) 70%, transparent); }
291
+ .u-style[aria-pressed='true'] { color: var(--accent); }
292
+ .u-style svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
293
+ .u-chart { position: relative; min-height: 300px; border-radius: 8px; }
294
+ .u-chart:focus-visible { outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent); outline-offset: 3px; }
295
+ .u-svg { display: block; overflow: visible; font-family: var(--body); }
296
+ .u-svg .u-grid { stroke: var(--hairline); stroke-width: 1; }
297
+ .u-svg text { font-size: 11px; fill: var(--sub); font-variant-numeric: tabular-nums; }
298
+ .u-svg .u-col { transition: opacity 160ms ease; }
299
+ .u-svg .u-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
300
+ .u-svg .u-avg { stroke: color-mix(in srgb, var(--sub) 75%, transparent); stroke-width: 1; stroke-dasharray: 2 4; }
301
+ .u-svg .u-avglab { paint-order: stroke; stroke: var(--page); stroke-width: 4px; stroke-linejoin: round; }
302
+ .u-svg .u-hover { stroke: color-mix(in srgb, var(--sub) 60%, transparent); stroke-dasharray: 3 3; pointer-events: none; }
303
+ .u-svg .u-hover.hidden { display: none; }
304
+ /* The scrub layer: a finger dragging sideways reads the bars, a finger dragging up or down scrolls the page. */
305
+ .u-svg .u-hit { fill: transparent; touch-action: pan-y; cursor: pointer; }
306
+ .u-chart-empty { display: grid; place-items: center; min-height: 300px; margin: 0; color: var(--sub); font-size: 13.5px; text-align: center; }
307
+ .u-tip {
308
+ position: absolute; left: 0; top: 6px; z-index: 2; padding: 10px; border-radius: 8px; pointer-events: none;
309
+ background: var(--panel); border: 1px solid var(--panel-border); box-shadow: 0 6px 20px rgba(43, 33, 26, 0.12);
310
+ font-size: 12px; line-height: 1.35; font-variant-numeric: tabular-nums; transition: opacity 120ms ease;
311
+ }
312
+ .u-tip.hidden { display: none; }
313
+ .u-tip p { margin: 0 0 5px; font-weight: 600; color: var(--ink); }
314
+ .u-tiprow { display: flex; align-items: center; gap: 6px; color: var(--sub); margin-top: 3px; }
315
+ .u-tiprow span:not(.u-sw) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
316
+ .u-tiprow b { font-weight: 400; }
317
+ .u-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12px; color: var(--sub); }
318
+ .u-key { display: inline-flex; align-items: center; gap: 6px; }
319
+
320
+ .u-card { min-width: 0; padding: 16px; border-radius: 10px; background: var(--panel); border: 1px solid var(--row-border); font-size: 12px; color: var(--ink); align-self: stretch; }
321
+ .u-card-top { display: flex; align-items: center; gap: 4px; }
322
+ .u-card-title { flex: 1; min-width: 0; margin: 0; font: 400 12.5px/1.3 var(--body); color: var(--sub); text-align: left; }
323
+ .u-rangelink { display: inline-flex; align-items: center; gap: 5px; min-height: 36px; color: var(--accent); font-weight: 600; flex: 1 1 auto; justify-content: flex-start; }
324
+ .u-step { display: inline-grid; place-items: center; width: 34px; height: 34px; flex: none; border-radius: 8px; border: 1px solid var(--panel-border); color: var(--ink); }
325
+ .u-step:disabled { opacity: 0.4; }
326
+ .u-step svg { width: 10px; height: 10px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
327
+ .u-card-head { margin: 10px 0 0; font: 500 26px/1.15 var(--display); font-variant-numeric: tabular-nums; }
328
+ .u-card-sub { margin: 4px 0 0; font-size: 13px; color: var(--sub); font-variant-numeric: tabular-nums; }
329
+ .u-mixes { display: grid; gap: 9px; margin-top: 14px; }
330
+ .u-mix > span { display: block; font-size: 11px; color: var(--sub); margin-bottom: 4px; }
331
+ .u-strip { display: flex; gap: 2px; height: 10px; }
332
+ .u-strip i { display: block; flex-basis: 0; flex-shrink: 1; min-width: 3px; border-radius: 2px; }
333
+ .u-ch { margin: 16px 0 3px; font: 600 12px/1.3 var(--body); color: var(--ink); }
334
+ .u-crow { display: flex; align-items: center; gap: 6px; padding: 3px 0; font-variant-numeric: tabular-nums; }
335
+ .u-cname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
336
+ .u-cval { min-width: 52px; text-align: right; color: var(--sub); }
337
+ .u-cnote { margin: 3px 0 0; font-size: 11px; line-height: 1.4; color: var(--sub); }
338
+ .u-rule-h { border: 0; border-top: 1px solid var(--hairline); margin: 14px 0 10px; }
339
+ .u-cline { margin: 8px 0 0; font-size: 12px; line-height: 1.45; color: var(--sub); font-variant-numeric: tabular-nums; }
340
+ .u-peak { display: block; text-align: left; font-size: 12px; line-height: 1.45; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; min-height: 28px; }
341
+ .u-whole { margin-top: 10px; padding: 0; }
342
+
343
+ .u-daysec { margin-top: 34px; }
344
+ .u-h { margin: 0 0 12px; }
345
+ .u-cal { display: grid; row-gap: 3px; font-size: 11px; color: var(--sub); }
346
+ .u-cal-row { display: flex; align-items: center; gap: 8px; height: 16px; }
347
+ .u-cal.numbers .u-cal-row { height: 26px; }
348
+ .u-cal-row.u-cal-months { height: 14px; }
349
+ .u-cal-lab { width: 26px; flex: none; }
350
+ .u-cal-weeks { flex: 1; min-width: 0; display: grid; height: 100%; }
351
+ .u-cal-month { white-space: nowrap; overflow: visible; line-height: 14px; }
352
+ .u-cal-avg { width: 150px; flex: none; display: flex; align-items: center; gap: 8px; white-space: nowrap; }
353
+ .u-avgbar { width: 88px; flex: none; display: flex; align-items: center; }
354
+ .u-avgbar i { display: block; height: 14px; max-height: 100%; border-radius: 2px; background: var(--u-gold); }
355
+ .u-cal:not(.numbers) .u-avgbar i { height: 12px; }
356
+ .u-avgnum { font-variant-numeric: tabular-nums; }
357
+ .u-cell { display: block; min-width: 0; height: 100%; border-radius: 3px; }
358
+ .u-cell.day { padding: 0; font: 400 11px/1 var(--body); font-variant-numeric: tabular-nums; color: var(--ink); overflow: hidden; white-space: nowrap; }
359
+ .u-cell.day.deep { color: #1f1712; }
360
+ .u-cell.day.on { box-shadow: inset 0 0 0 1.5px var(--ink); }
361
+ .u-cell.none { border: 1px solid var(--hairline); }
362
+ .u-cell.faint { background: color-mix(in srgb, var(--hairline) 45%, transparent); border-radius: 2px; }
363
+
364
+ .u-tablesec { margin-top: 34px; }
365
+ .u-thead { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
366
+ .u-thead .u-h { margin: 0; }
367
+ .u-cols { position: relative; }
368
+ .u-cols summary { list-style: none; display: inline-flex; align-items: center; gap: 5px; min-height: 36px; padding: 0 4px; font: 500 12.5px/1 var(--body); color: var(--ink); cursor: pointer; }
369
+ .u-cols summary::-webkit-details-marker { display: none; }
370
+ .u-cols summary .u-chev { color: var(--accent); }
371
+ .u-cols-menu { position: absolute; right: 0; top: 100%; z-index: 5; display: grid; min-width: 180px; padding: 6px; border-radius: 10px; background: var(--panel); border: 1px solid var(--panel-border); box-shadow: 0 10px 28px rgba(43, 33, 26, 0.16); }
372
+ .u-colopt { display: flex; align-items: center; gap: 9px; min-height: 40px; padding: 0 8px; font-size: 13.5px; color: var(--ink); border-radius: 7px; cursor: pointer; }
373
+ .u-colopt input { width: 16px; height: 16px; accent-color: var(--accent); }
374
+ .u-tablewrap { overflow-x: auto; }
375
+ .u-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
376
+ .u-table th { font: 500 11px/1.2 var(--body); color: var(--sub); padding: 0 0 8px 18px; white-space: nowrap; border-bottom: 1px solid var(--hairline); }
377
+ .u-table th.name { text-align: left; padding-left: 0; }
378
+ .u-table th.num { text-align: right; }
379
+ .u-table td { padding: 0 0 0 18px; border-bottom: 1px solid var(--hairline); white-space: nowrap; }
380
+ .u-table td:first-child { padding-left: 0; width: 40%; }
381
+ .u-table td.num { text-align: right; }
382
+ .u-sort { display: inline-flex; align-items: center; gap: 3px; color: var(--sub); font: inherit; min-height: 28px; }
383
+ .u-sort.on { color: var(--ink); }
384
+ .u-dir { width: 8px; height: 5px; fill: none; stroke: currentColor; stroke-width: 1.6; }
385
+ .u-namebtn { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 40px; text-align: left; color: inherit; font: inherit; }
386
+ .u-tool td { font-weight: 600; font-size: 14px; }
387
+ .u-tool td.num { padding-top: 4px; }
388
+ .u-model td { color: var(--sub); }
389
+ .u-model .u-namebtn { padding-left: 17px; min-height: 36px; }
390
+ .u-model .u-namebtn.on { color: var(--ink); font-weight: 600; }
391
+ .u-namebtn.u-more { color: var(--accent); }
392
+ .u-sharecell { display: table-cell; }
393
+ .u-sharebar { display: inline-flex; vertical-align: middle; width: 56px; height: 5px; margin-right: 8px; border-radius: 3px; background: var(--hairline); overflow: hidden; }
394
+ .u-sharebar[data-empty] { background: transparent; }
395
+ .u-sharebar i { display: block; height: 100%; border-radius: 3px; }
396
+
397
+ .u-breakdown { margin-top: 20px; font-size: 13px; }
398
+ .u-breakdown summary { cursor: pointer; font-weight: 500; color: var(--ink); min-height: 36px; display: flex; align-items: center; }
399
+ .u-brow { display: grid; grid-template-columns: minmax(0, 1fr) 90px 60px 92px 110px; gap: 10px; align-items: center; width: 100%; min-height: 34px; padding: 0; text-align: left; font: 400 12px/1.2 var(--body); font-variant-numeric: tabular-nums; color: var(--ink); border-bottom: 1px solid var(--hairline); }
400
+ .u-brow > span:not(:first-child) { text-align: right; }
401
+ .u-brow > span:nth-child(3), .u-brow > span:nth-child(4) { color: var(--sub); }
402
+ .u-brow.on > span:first-child { font-weight: 600; }
403
+ .u-bhead { font-size: 11px; font-weight: 500; color: var(--sub); min-height: 30px; }
404
+
405
+ /* Touch screens get 44 px targets (the unfolded Duo has no mouse). */
406
+ @media (pointer: coarse) {
407
+ .u-word, .u-style, .u-step, .u-rangelink, .u-cols summary, .u-namebtn, .u-brow { min-height: 44px; }
408
+ .u-word { min-width: 44px; justify-content: center; }
409
+ .u-style, .u-step { width: 44px; height: 44px; }
410
+ }
411
+ @media (prefers-reduced-motion: reduce) {
412
+ .u-svg .u-col, .u-tip, .u-range { transition: none; animation: none; }
413
+ }
414
+
415
+ /* The date range sheet: a popover beside its button when wide, a bottom sheet on a phone. */
416
+ .u-range-back { position: fixed; inset: 0; z-index: 55; }
417
+ .u-range-back.hidden { display: none; }
418
+ .u-range-back.bottom { background: rgba(23, 18, 14, 0.45); display: flex; align-items: flex-end; justify-content: center; }
419
+ .u-range {
420
+ width: 100%; max-height: 88dvh; overflow: auto; overscroll-behavior: contain; background: var(--page); color: var(--ink);
421
+ padding: 16px var(--gutter) calc(var(--safe-bottom) + 16px); border-radius: 18px 18px 0 0; box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.2);
422
+ animation: u-rise 200ms cubic-bezier(0.2, 0.8, 0.2, 1);
423
+ }
424
+ .u-range-back.pop .u-range { position: fixed; width: min(380px, calc(100vw - 32px)); padding: 16px; border-radius: 14px; border: 1px solid var(--panel-border); background: var(--panel); box-shadow: 0 18px 50px rgba(0, 0, 0, 0.22); animation: u-fade 140ms ease; }
425
+ @keyframes u-rise { from { transform: translateY(24px); opacity: 0.6; } }
426
+ @keyframes u-fade { from { opacity: 0; } }
427
+ .u-range-title { margin: 0 0 10px; font: 500 20px/1.2 var(--display); }
428
+ .u-presets { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 10px; }
429
+ .u-preset { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-height: 48px; padding: 7px 10px; border-radius: 9px; text-align: left; font: 500 14px/1.2 var(--body); color: var(--ink); }
430
+ .u-preset .u-preset-dates { font-size: 11.5px; font-weight: 400; color: var(--sub); font-variant-numeric: tabular-nums; }
431
+ .u-preset:hover { background: var(--qopen); }
432
+ .u-preset[aria-checked='true'] { background: var(--qopen); box-shadow: inset 3px 0 0 var(--accent); font-weight: 600; }
433
+ .u-range-field { display: grid; gap: 5px; font-size: 12.5px; color: var(--sub); margin-top: 12px; }
434
+ .u-range-field .field { min-height: 44px; padding: 8px 12px; color: var(--ink); }
435
+ .u-range-field select.field { background-position: calc(100% - 20px) 19px, calc(100% - 15px) 19px; }
436
+ .u-custom { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hairline); }
437
+ .u-custom-title { margin: 0; font: 600 14px/1.2 var(--body); color: var(--ink); }
438
+ .u-custom.on .u-custom-title { color: var(--accent); }
439
+ .u-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
440
+ .u-dates .u-range-field { margin-top: 8px; }
441
+ .u-range-err { margin: 8px 0 0; font-size: 12.5px; color: var(--hot); min-height: 0; }
442
+ .u-range-err:empty { display: none; }
443
+ .u-range-note { margin: 12px 0 0; font-size: 12px; line-height: 1.45; color: var(--sub); }
444
+ .u-range-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 14px; }
445
+ .u-range-actions .cx-btn { height: 40px; padding: 0 16px; }
446
+ @media (max-width: 359px) { .u-presets, .u-dates { grid-template-columns: 1fr; } }
447
+ .u-chartcol .u-chart { flex: 1 1 auto; }
448
+ .u-cell.day { text-align: center; }
449
+ .u-breakdown summary { gap: 6px; }
450
+ .u-breakdown summary::-webkit-details-marker { display: none; }
451
+ .u-breakdown summary .u-chev { color: var(--accent); transform: rotate(-90deg); transition: transform 120ms ease; }
452
+ .u-breakdown[open] summary .u-chev { transform: none; }