@gotcos/glasses-server 6.98.1 → 6.99.12
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.
- package/CHANGELOG.md +149 -0
- package/package.json +2 -1
- package/server/index.ts +147 -9
- package/server/lib/api-auth.ts +31 -14
- package/server/lib/claude-bridge.ts +21 -2
- package/server/lib/codex-bridge.ts +21 -2
- package/server/lib/display-bus.ts +3 -0
- package/server/lib/drop-destinations.ts +134 -0
- package/server/lib/drop-history-search.ts +97 -0
- package/server/lib/drop-p2-boot.ts +60 -0
- package/server/lib/drop-p2-runtime.ts +237 -0
- package/server/lib/drop-p2-settings.ts +174 -0
- package/server/lib/drop-resolution.ts +168 -0
- package/server/lib/drop-router.ts +325 -0
- package/server/lib/drop-service.ts +739 -0
- package/server/lib/drop-settings.ts +45 -0
- package/server/lib/drop-store.ts +428 -0
- package/server/lib/drop-when.ts +265 -0
- package/server/lib/glasses-pairing.ts +15 -0
- package/server/lib/learning-needs-you.ts +111 -0
- package/server/lib/live-cues-v2-settings.ts +2 -1
- package/server/lib/live-cues-v2.ts +6 -4
- package/server/lib/meeting-consolidation-run.ts +169 -0
- package/server/lib/meeting-store.ts +61 -0
- package/server/lib/meeting-title-steer.ts +200 -0
- package/server/lib/network-policy.ts +84 -6
- package/server/lib/permission-broker.ts +11 -0
- package/server/lib/ping-budget.ts +149 -0
- package/server/lib/ping-engine.ts +245 -0
- package/server/lib/ping-feed-sink.ts +33 -0
- package/server/lib/ping-sources.ts +192 -0
- package/server/lib/query-job-coordinator.ts +5 -2
- package/server/lib/query-job-runtime.ts +45 -4
- package/server/lib/query-job-types.ts +10 -1
- package/server/lib/reminder-scheduler.ts +153 -0
- package/server/lib/tailnet-self-name.ts +103 -0
- package/server/lib/tailscale-nudge.ts +40 -2
- package/server/lib/task-store.ts +32 -0
- package/server/lib/web-ask-admission.ts +56 -0
- package/server/lib/web-live-chunks.ts +273 -0
- package/server/lib/web-memories-bridge.ts +323 -0
- package/server/lib/web-session-auth.ts +492 -0
- package/server/lib/web-usage-bridge.ts +154 -0
- package/server/lib/work-search.ts +14 -1
- package/server/lib/your-move-count.ts +58 -0
- package/server/routes/display.ts +11 -1
- package/server/routes/drops.ts +260 -0
- package/server/routes/health.ts +16 -0
- package/server/routes/live-cues.ts +5 -4
- package/server/routes/meeting.ts +61 -5
- package/server/routes/permission-broker.ts +23 -3
- package/server/routes/transcribe-stream.ts +34 -3
- package/server/routes/web-control.ts +569 -0
- package/server/routes/welcome-context.ts +2 -1
- package/server/web-control/app.css +519 -0
- package/server/web-control/app.js +3643 -0
- package/server/web-control/control.css +312 -0
- package/server/web-control/fonts/DMSans.ttf +0 -0
- package/server/web-control/fonts/Fraunces.ttf +0 -0
- package/server/web-control/fonts/JetBrainsMono.ttf +0 -0
- package/server/web-control/index.html +275 -0
- package/server/web-control/mark.svg +1 -0
- package/server/web-control/memories/d3.min.js +2 -0
- package/server/web-control/memories/graph-explorer.css +200 -0
- package/server/web-control/memories/graph-explorer.js +748 -0
- package/server/web-control/memories/memories-app.js +1561 -0
- package/server/web-control/memories/memories-theme.css +73 -0
- package/server/web-control/memories/memories.html +72 -0
- package/server/web-control/memories/memory-stewardship.js +63 -0
- package/server/web-control/memories/memory-workspace.js +216 -0
- package/server/web-control/panes/cos-chat.css +157 -0
- package/server/web-control/panes/cos-chat.js +973 -0
- package/server/web-control/panes/dictation.js +173 -0
- package/server/web-control/panes/meetings.css +257 -0
- package/server/web-control/panes/meetings.js +2264 -0
- package/server/web-control/panes/messages.js +711 -0
- package/server/web-control/panes/questions.css +32 -0
- package/server/web-control/panes/questions.js +275 -0
- package/server/web-control/panes/sessions.css +452 -0
- package/server/web-control/panes/settings.js +292 -0
- package/server/web-control/panes/speakers.css +269 -0
- package/server/web-control/panes/speakers.js +2755 -0
- package/server/web-control/panes/threads.js +200 -0
- package/server/web-control/panes/work.css +261 -0
- package/server/web-control/panes/work.js +1667 -0
- package/server/web-control/shell.js +294 -0
- package/server/web-control/theme.js +25 -0
- 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; }
|