@bongos/core 1.19.444 → 1.19.446
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/.bongos-core.json +154 -49
- package/docs/adr/0054-session-token-reward-cost-plus.md +17 -0
- package/docs/copy-inventory.md +353 -352
- package/docs/copy-registry.json +397 -388
- package/docs/design/hall-direction-v2.md +295 -0
- package/docs/design/mocks/hall/_tokens.css +370 -0
- package/docs/design/mocks/hall/board/v1.html +846 -0
- package/docs/design/mocks/hall/board/v2.html +858 -0
- package/docs/design/mocks/hall/board/v3.html +884 -0
- package/docs/design/mocks/hall/goals/v1.html +1212 -0
- package/docs/design/mocks/hall/goals/v2.html +1192 -0
- package/docs/design/mocks/hall/goals/v3.html +1205 -0
- package/docs/design/mocks/hall/hall-sheet.html +244 -0
- package/docs/design/mocks/hall/reading/v1.html +1125 -0
- package/docs/design/mocks/hall/reading/v2.html +1177 -0
- package/docs/design/mocks/hall/reading/v3.html +1150 -0
- package/docs/design/mocks/hall/settings/v1.html +1238 -0
- package/docs/design/mocks/hall/settings/v2.html +1235 -0
- package/docs/design/mocks/hall/settings/v3.html +1299 -0
- package/docs/design/mocks/hall/task/v1.html +637 -0
- package/docs/design/mocks/hall/task/v2.html +646 -0
- package/docs/design/mocks/hall/task/v3.html +651 -0
- package/docs/design/vanilla-hall-ui-redesign-scope.md +2 -0
- package/docs/module-api-changelog.md +4 -0
- package/modules/economy/credits.js +46 -13
- package/modules/hall-ui/public/atlas.html +1 -2
- package/modules/hall-ui/public/collab.html +1 -2
- package/modules/hall-ui/public/copy-desk.css +11 -11
- package/modules/hall-ui/public/copy-desk.html +1 -2
- package/modules/hall-ui/public/diagrams.html +1 -2
- package/modules/hall-ui/public/drachmae.html +1 -2
- package/modules/hall-ui/public/gate.html +1 -2
- package/modules/hall-ui/public/goals.html +1 -2
- package/modules/hall-ui/public/government.html +1 -2
- package/modules/hall-ui/public/harbor.html +1 -2
- package/modules/hall-ui/public/idea.html +1 -2
- package/modules/hall-ui/public/ideas.css +6 -8
- package/modules/hall-ui/public/ideas.html +1 -2
- package/modules/hall-ui/public/index.html +3 -4
- package/modules/hall-ui/public/modules.html +1 -2
- package/modules/hall-ui/public/my-projects.html +1 -2
- package/modules/hall-ui/public/not-ready.html +1 -2
- package/modules/hall-ui/public/pair.html +1 -2
- package/modules/hall-ui/public/people.html +1 -2
- package/modules/hall-ui/public/primer.html +1 -2
- package/modules/hall-ui/public/profile.html +1 -2
- package/modules/hall-ui/public/ranks.html +1 -2
- package/modules/hall-ui/public/roadmap.html +1 -2
- package/modules/hall-ui/public/scouting.html +1 -2
- package/modules/hall-ui/public/sessions.html +1 -2
- package/modules/hall-ui/public/settings.html +1 -2
- package/modules/hall-ui/public/shell.js +35 -2
- package/modules/hall-ui/public/style.css +818 -392
- package/modules/hall-ui/public/task.html +1 -2
- package/modules/hall-ui/public/watch.css +1 -1
- package/modules/hall-ui/public/watch.html +1 -2
- package/modules/hall-ui/public/work.html +1 -2
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/backfill-subagent-rewards.js +485 -0
- package/src/module-api.js +1 -1
- package/tests/backfill_subagent_rewards.mjs +308 -0
- package/tests/hall_tokens.mjs +371 -0
|
@@ -1,132 +1,323 @@
|
|
|
1
|
-
/* builders hall — the vanilla Cloud Bongos dashboard shell (task 1723)
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
/* builders hall — the vanilla Cloud Bongos dashboard shell (task 1723), rebuilt
|
|
2
|
+
into the chrome world by task 1003303 (goal 1000081).
|
|
3
|
+
|
|
4
|
+
THE WORLD. DESIGN.md at the repo root is this surface's world; the tier below
|
|
5
|
+
is its "Reuse: the hall and the status ledger" recipe followed literally, and
|
|
6
|
+
it is the tier the composition round authored and verified as
|
|
7
|
+
docs/design/mocks/hall/_tokens.css (task 1003302). The round's pick is v3
|
|
8
|
+
"the glass hall" — a 64px rail at every width, glass chrome, content on
|
|
9
|
+
--bg-card panels at the full radius with tone doing the separation. Record:
|
|
10
|
+
docs/design/hall-direction-v2.md.
|
|
11
|
+
|
|
12
|
+
THEMING CONTRACT (do not rename): the 13 color vars + 2 font vars at the head
|
|
13
|
+
of :root are the instance-pack API — serve-internal.js themeMarkup()
|
|
14
|
+
re-declares exactly these from config/branding.*.json AFTER this file, so an
|
|
15
|
+
instance's palette/fonts win. Their values here are branding.neutral.json's
|
|
16
|
+
theme.ui, byte for byte, so the served page and this sheet agree. Everything
|
|
17
|
+
else derives from them (var / color-mix), so any pack reskins the whole kit.
|
|
18
|
+
|
|
19
|
+
FOUR THINGS THIS TIER DOES THAT world.css DOES NOT, each a hall problem the
|
|
20
|
+
landing never had:
|
|
21
|
+
|
|
22
|
+
a. THE STATUS VOCABULARY IS FIXED, AND IT IS THE ONE SANCTIONED EXCEPTION TO
|
|
23
|
+
THE FIFTEEN RULE. DESIGN.md §Reuse: a surface that renders VERIFICATION
|
|
24
|
+
state — the hall's chips, CI marks — keeps its own green/amber/red and
|
|
25
|
+
must not adopt the world's warm accent-derived ok/warn/err. A grade that
|
|
26
|
+
failed must not be salmon on a page whose claim button is also salmon.
|
|
27
|
+
Three of the four values MOVED, and that is a measurement, not a taste:
|
|
28
|
+
the shipped values were tuned against the hall's retired ground
|
|
29
|
+
(--bg #f5f6f8), and against the world's darker paper (--bg #edecee) they
|
|
30
|
+
fail AA — ok 4.27:1, warn 4.13:1, info 3.85:1 and 4.36:1, and 4.19:1 on
|
|
31
|
+
the dark card. Re-solved here so all eight pairs clear 4.5:1 on both
|
|
32
|
+
grounds in both modes with ~9% of headroom. tests/hall_tokens.mjs measures
|
|
33
|
+
them; do not hand-tune one without re-running it.
|
|
34
|
+
|
|
35
|
+
b. THE HALL KEEPS BOTH MODES, ON ITS OWN SWITCH. The apex went dark only
|
|
36
|
+
(ADR 0204), so light is the hall's alone. shell.js writes
|
|
37
|
+
html[data-theme] — NOT the world's html[data-mode] — so the dark tier is
|
|
38
|
+
written twice on THAT pair: html[data-theme="dark"] and, for first paint
|
|
39
|
+
before the script runs, @media (prefers-color-scheme: dark)
|
|
40
|
+
html:not([data-theme]). Both bodies are byte-identical; the twins rule is
|
|
41
|
+
what keeps them so. html[data-theme="dark"] is (0,1,1) and outranks the
|
|
42
|
+
pack's injected :root (0,1,0), which is what lets dark win over the pack
|
|
43
|
+
while the instance's accent survives.
|
|
44
|
+
|
|
45
|
+
c. --line IS A WIDTH HERE, NOT A COLOUR (DESIGN.md warns about exactly this
|
|
46
|
+
name). The hairline's COLOUR is --rule / --rule-soft.
|
|
47
|
+
|
|
48
|
+
d. THE COMPAT ALIASES ARE LOAD-BEARING. ~450 rules across 20 page sheets
|
|
49
|
+
derive from --surface / --surface-2 / --border / --border-strong /
|
|
50
|
+
--accent-weak / --accent-text, so they are re-derived in the world's terms
|
|
51
|
+
rather than deleted: a page this task does not re-skin degrades into the
|
|
52
|
+
new palette instead of breaking. They retire page family by page family as
|
|
53
|
+
tasks 1003304-1003308 land.
|
|
54
|
+
|
|
55
|
+
Composition — rail/drawer breakpoints, panel padding, page layout — is NOT in
|
|
56
|
+
here. It lives on the shell rules below and on a page's own body, because a
|
|
57
|
+
body declaration beats an inherited :root value at every width and a token
|
|
58
|
+
tier that carries a breakpoint silently defeats its own media query. */
|
|
11
59
|
|
|
12
60
|
:root {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
--bg
|
|
17
|
-
--bg-
|
|
18
|
-
|
|
19
|
-
--
|
|
20
|
-
--ink
|
|
21
|
-
--ink-
|
|
22
|
-
--
|
|
23
|
-
--rule
|
|
24
|
-
--
|
|
25
|
-
--accent
|
|
26
|
-
--
|
|
27
|
-
--
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
--font-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
--
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
--
|
|
42
|
-
--
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
color-scheme: light;
|
|
62
|
+
|
|
63
|
+
/* ---- the contract tier: the thirteen colours + two faces a pack overrides ---- */
|
|
64
|
+
--bg: #edecee;
|
|
65
|
+
--bg-card: #fbfafc;
|
|
66
|
+
--bg-deep: #e2e1e4;
|
|
67
|
+
--bg-frame: #f6f5f7;
|
|
68
|
+
--ink: #17181a;
|
|
69
|
+
--ink-soft: #55565a;
|
|
70
|
+
--ink-faint: #65656a;
|
|
71
|
+
--rule: #c6c6c8;
|
|
72
|
+
--rule-soft: #dcdbdd;
|
|
73
|
+
--accent: #fb9569;
|
|
74
|
+
--accent-deep: #a3481a;
|
|
75
|
+
--sea: #5b6fd0;
|
|
76
|
+
--terracotta: #c9512c;
|
|
77
|
+
|
|
78
|
+
--font-display: "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
79
|
+
--font-body: "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
80
|
+
|
|
81
|
+
/* ---- derived: the third face. Mono is where the hall quotes the machine —
|
|
82
|
+
task ids, column heads, eyebrows, a credit figure's unit. ---- */
|
|
83
|
+
--font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
|
|
84
|
+
|
|
85
|
+
/* ---- derived: glass. The blur is a token because light glass over paper is
|
|
86
|
+
a tint, not a frost — light sets it to 0px and stays paper. ---- */
|
|
87
|
+
--glass: rgba(23, 24, 26, .05);
|
|
88
|
+
--glass-strong: rgba(23, 24, 26, .08);
|
|
89
|
+
--glass-edge: rgba(23, 24, 26, .12);
|
|
90
|
+
--glass-blur: 0px;
|
|
91
|
+
|
|
92
|
+
/* ---- derived: the void. The hall has no hero; the void is what a control
|
|
93
|
+
needs when it sits over a plate, and the seam for one. ---- */
|
|
94
|
+
--void: #050508;
|
|
95
|
+
--void-ink: #ffffff;
|
|
96
|
+
--void-edge: rgba(23, 24, 26, .12);
|
|
97
|
+
|
|
98
|
+
/* ---- derived: the skeleton tone. --bg-deep is the obvious choice and it is
|
|
99
|
+
WRONG: DESIGN.md collapses deep back to black in dark, so --bg-deep
|
|
100
|
+
and --bg are the same value there and a skeleton painted with it is
|
|
101
|
+
invisible. This mix reads in both modes and needs no dark twin,
|
|
102
|
+
because both of its terms already flip. ---- */
|
|
103
|
+
--skeleton: color-mix(in srgb, var(--ink) 10%, var(--bg-card));
|
|
104
|
+
|
|
105
|
+
/* ---- derived: the reading measure. A `ch` is the width of the font's ZERO
|
|
106
|
+
glyph, not a character, and Manrope's zero is much wider than its
|
|
107
|
+
average lowercase — primer.css's `max-width: 72ch` renders about 90
|
|
108
|
+
characters under a comment claiming 60-72. This token is MEASURED:
|
|
109
|
+
48ch renders ~60 characters at the hall's body size. Re-measure rather
|
|
110
|
+
than doing the ch maths. ---- */
|
|
111
|
+
--measure: 48ch;
|
|
112
|
+
|
|
113
|
+
/* ---- derived: accent behaviours. The One Warm Thing Rule holds in the hall
|
|
114
|
+
too — the accent lights only what is pressable or live (the claim
|
|
115
|
+
button, the current nav item, the active tab, a focus ring). A credit
|
|
116
|
+
figure is data, not live, so it is ink. --accent-on is the DARK ink
|
|
117
|
+
that goes on an accent fill: white on this salmon fails AA. ---- */
|
|
118
|
+
--accent-ink: color-mix(in srgb, var(--accent) 45%, #240e00);
|
|
119
|
+
--accent-lift: color-mix(in srgb, var(--accent) 58%, #ffffff);
|
|
120
|
+
--accent-tint: color-mix(in srgb, var(--accent) 30%, #fffdf9);
|
|
121
|
+
--accent-on: #2a1305;
|
|
122
|
+
--accent-glow: 0 0 0 0 transparent;
|
|
123
|
+
|
|
124
|
+
/* ---- the status vocabulary: fixed, not pack-driven, not accent-derived.
|
|
125
|
+
See note (a) — these values are measured, not chosen. ---- */
|
|
126
|
+
--ok: #187444;
|
|
127
|
+
--ok-weak: color-mix(in srgb, #187444 12%, var(--bg-card));
|
|
128
|
+
--warn: #895c00;
|
|
129
|
+
--warn-weak: color-mix(in srgb, #895c00 14%, var(--bg-card));
|
|
45
130
|
--danger: #b42318;
|
|
46
131
|
--danger-weak: color-mix(in srgb, #b42318 10%, var(--bg-card));
|
|
47
|
-
--info
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
--
|
|
57
|
-
--
|
|
58
|
-
|
|
59
|
-
/*
|
|
132
|
+
/* --info is the one state that is NOT a bright colour, because it derives
|
|
133
|
+
from the contract's --sea rather than a chosen hex, and that makes its
|
|
134
|
+
own weak fill the binding pair rather than the grounds. The round
|
|
135
|
+
measured info against --bg and --bg-card only; measured against
|
|
136
|
+
--info-weak too (tests/hall_tokens.mjs), dark's 91% sea fell to 4.12:1,
|
|
137
|
+
so dark lightens to 80% for 5.00:1 with the ~9% headroom the rest of
|
|
138
|
+
the vocabulary holds. Both weak fills mix the STATE colour into the
|
|
139
|
+
card, which is the shape ok/warn/danger already use — mixing the raw
|
|
140
|
+
--sea instead is what made the two drift apart. ---- */
|
|
141
|
+
--info: color-mix(in srgb, var(--sea) 86%, #000000);
|
|
142
|
+
--info-weak: color-mix(in srgb, var(--info) 9%, var(--bg-card));
|
|
143
|
+
|
|
144
|
+
/* ---- derived: focus. The world's two-tone ring — a 2px accent-derived
|
|
145
|
+
outline at 3px offset inside an 8px --bg halo, so the indicator keeps
|
|
146
|
+
its own edge over whatever it lands on. ---- */
|
|
147
|
+
--focus: color-mix(in srgb, var(--accent-deep) 82%, #3a1400);
|
|
148
|
+
|
|
149
|
+
/* ---- derived: the label face flips. Mono caps read as precise on paper and
|
|
150
|
+
thin on black, so light takes the mono and dark takes the body face.
|
|
151
|
+
Take the token, never the family. ---- */
|
|
152
|
+
--label-face: var(--font-mono);
|
|
153
|
+
--label-size: 11px;
|
|
154
|
+
--label-space: .12em;
|
|
155
|
+
--label-case: uppercase;
|
|
156
|
+
|
|
157
|
+
/* ---- derived: the type halo. Only type over a plate needs one, and in light
|
|
158
|
+
there is nothing behind it. Never a coloured glow. ---- */
|
|
159
|
+
--type-halo: none;
|
|
160
|
+
|
|
161
|
+
/* ---- structure. --line is a WIDTH (note c). ---- */
|
|
162
|
+
--line: 1px;
|
|
163
|
+
--radius: 16px;
|
|
164
|
+
--radius-sm: 10px;
|
|
165
|
+
--radius-pill: 999px;
|
|
166
|
+
|
|
167
|
+
/* ---- the shell's metrics. --topbar-h stays under the kit's 80px top-bar
|
|
168
|
+
floor; --sidebar-w IS the rail, because v3 pins the rail at every
|
|
169
|
+
width and the drawer is the phone's disclosure. ---- */
|
|
170
|
+
--top-h: 56px;
|
|
171
|
+
--topbar-h: 56px;
|
|
172
|
+
--sidebar-w-rail: 64px;
|
|
173
|
+
--sidebar-w: var(--sidebar-w-rail);
|
|
174
|
+
--rail-open: 246px;
|
|
175
|
+
--content-max: 1120px;
|
|
176
|
+
|
|
177
|
+
/* ---- spacing: DESIGN.md's rhythm (6/10/14/22/34/52). The four-step
|
|
178
|
+
--space-* scale task 2179 named aliases onto it, so no ported rule
|
|
179
|
+
breaks; hairlines separate, padding does not. ---- */
|
|
180
|
+
--sp-hair: 6px;
|
|
181
|
+
--sp-xs: 10px;
|
|
182
|
+
--sp-sm: 14px;
|
|
183
|
+
--sp-md: 22px;
|
|
184
|
+
--sp-lg: 34px;
|
|
185
|
+
--sp-xl: 52px;
|
|
186
|
+
--space-1: var(--sp-hair);
|
|
187
|
+
--space-2: var(--sp-xs);
|
|
188
|
+
--space-3: var(--sp-sm);
|
|
189
|
+
--space-4: var(--sp-md);
|
|
190
|
+
|
|
191
|
+
/* ---- the compat aliases (note d) ---- */
|
|
192
|
+
--surface: var(--bg-card);
|
|
193
|
+
--surface-2: color-mix(in srgb, var(--ink) 5%, var(--bg-card));
|
|
194
|
+
--border: var(--rule-soft);
|
|
195
|
+
--border-strong: var(--rule);
|
|
196
|
+
--accent-weak: var(--accent-tint);
|
|
197
|
+
--accent-text: var(--accent-ink);
|
|
198
|
+
/* The world has no shadow vocabulary for UI, so this is spent only where an
|
|
199
|
+
element floats over a scrim (the phone drawer, the deep-link card). Pure
|
|
200
|
+
black with alpha is the one literal the Fifteen Rule allows, as a scrim. */
|
|
201
|
+
--shadow-pop: 0 18px 40px rgba(0, 0, 0, .28);
|
|
202
|
+
|
|
203
|
+
/* ---- z ladder — content overlays (rank tips z-50, modals z-50, toast z-100,
|
|
60
204
|
copy-toast z-1000, deeplink z-2000, diagram fullscreen z-9999) must beat
|
|
61
|
-
the chrome; the mobile drawer sits above chrome but below dialogs. */
|
|
205
|
+
the chrome; the mobile drawer sits above chrome but below dialogs. ---- */
|
|
62
206
|
--z-topbar: 30;
|
|
63
207
|
--z-sidebar: 40;
|
|
64
208
|
--z-scrim: 140;
|
|
65
209
|
--z-drawer: 150;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/* ---------- spacing scale (task 2179) ----------
|
|
69
|
-
Four steps, deliberately matching the values the sheet had already converged
|
|
70
|
-
on (a census found 6/10/16/20 dominant), so this NAMES the existing rhythm
|
|
71
|
-
rather than restyling the hall. It governs the three things that decide
|
|
72
|
-
density — card padding, card gap, section gap — and is not a mandate to
|
|
73
|
-
rewrite every inset; chip and control padding stay as authored.
|
|
74
210
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
:root {
|
|
84
|
-
--space-1: 6px;
|
|
85
|
-
--space-2: 10px;
|
|
86
|
-
--space-3: 16px;
|
|
87
|
-
--space-4: 20px;
|
|
211
|
+
/* ---- the hall's own plate: the declared seam, deferred by the owner
|
|
212
|
+
("decide after the shell lands", 2026-08-30). The hall's plate was
|
|
213
|
+
never shot, so it resolves to none and the shell is a complete
|
|
214
|
+
composition without one — which is exactly what light does anyway.
|
|
215
|
+
Adding one later is a change to these three values, not a re-layout. */
|
|
216
|
+
--plate: none;
|
|
217
|
+
--plate-blend: lighten;
|
|
218
|
+
--plate-veil: none;
|
|
88
219
|
}
|
|
89
220
|
|
|
90
221
|
/* ---------- dark theme ----------
|
|
91
|
-
Only the NEUTRALS flip; the
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
shell.js owns the
|
|
96
|
-
|
|
222
|
+
Only the NEUTRALS and the mode-dependent derivations flip; the pack's
|
|
223
|
+
accent/sea/terracotta + fonts survive (the Unpinned Accent Rule — a dark
|
|
224
|
+
block may pin no accent literal, or a re-themed instance cannot reach dark),
|
|
225
|
+
and every color-mix on them re-derives for free. Written twice, byte-
|
|
226
|
+
identical: the [data-theme] switch shell.js owns, and the media block that
|
|
227
|
+
covers first paint for OS-dark users before the script runs. */
|
|
97
228
|
|
|
98
229
|
html[data-theme="dark"] {
|
|
99
230
|
color-scheme: dark;
|
|
100
|
-
--bg:
|
|
101
|
-
--bg-card:
|
|
102
|
-
--bg-deep:
|
|
103
|
-
--bg-frame:
|
|
104
|
-
--ink: #
|
|
105
|
-
--ink-soft: #
|
|
106
|
-
--ink-faint: #
|
|
107
|
-
--rule:
|
|
108
|
-
--rule-soft:
|
|
109
|
-
--
|
|
231
|
+
--bg: #000000;
|
|
232
|
+
--bg-card: #101012;
|
|
233
|
+
--bg-deep: #000000;
|
|
234
|
+
--bg-frame: #08080a;
|
|
235
|
+
--ink: #ffffff;
|
|
236
|
+
--ink-soft: #c0c0c0;
|
|
237
|
+
--ink-faint: #a8a8a8;
|
|
238
|
+
--rule: rgba(255, 255, 255, .16);
|
|
239
|
+
--rule-soft: rgba(255, 255, 255, .08);
|
|
240
|
+
--glass: rgba(255, 255, 255, .11);
|
|
241
|
+
--glass-strong: rgba(255, 255, 255, .17);
|
|
242
|
+
--glass-edge: rgba(255, 255, 255, .13);
|
|
243
|
+
--glass-blur: 18px;
|
|
244
|
+
--void: #000000;
|
|
245
|
+
--void-ink: var(--ink);
|
|
246
|
+
--void-edge: rgba(255, 255, 255, .16);
|
|
247
|
+
--accent-ink: var(--accent);
|
|
248
|
+
--accent-tint: color-mix(in srgb, var(--accent) 22%, #0b0a09);
|
|
249
|
+
--accent-glow: 0 8px 28px color-mix(in srgb, var(--accent) 38%, transparent);
|
|
250
|
+
--ok: #4ade80;
|
|
251
|
+
--ok-weak: color-mix(in srgb, #4ade80 14%, var(--bg-card));
|
|
252
|
+
--warn: #fbbf24;
|
|
253
|
+
--warn-weak: color-mix(in srgb, #fbbf24 14%, var(--bg-card));
|
|
254
|
+
--danger: #f87171;
|
|
255
|
+
--danger-weak: color-mix(in srgb, #f87171 14%, var(--bg-card));
|
|
256
|
+
--info: color-mix(in srgb, var(--sea) 80%, #ffffff);
|
|
257
|
+
--info-weak: color-mix(in srgb, var(--info) 14%, var(--bg-card));
|
|
258
|
+
--focus: var(--accent);
|
|
259
|
+
--label-face: var(--font-body);
|
|
260
|
+
--label-size: 11.5px;
|
|
261
|
+
--label-space: .1em;
|
|
262
|
+
--type-halo: 0 2px 18px rgba(0, 0, 0, .94), 0 0 54px rgba(0, 0, 0, .72);
|
|
263
|
+
--surface-2: color-mix(in srgb, var(--ink) 6%, var(--bg-card));
|
|
264
|
+
--shadow-pop: 0 18px 40px rgba(0, 0, 0, .62);
|
|
265
|
+
--plate-veil: linear-gradient(to bottom, rgba(0, 0, 0, .82), rgba(0, 0, 0, .93));
|
|
110
266
|
}
|
|
111
267
|
html[data-theme="dark"] body { background: var(--bg); }
|
|
112
268
|
|
|
113
269
|
@media (prefers-color-scheme: dark) {
|
|
114
270
|
html:not([data-theme]) {
|
|
115
271
|
color-scheme: dark;
|
|
116
|
-
--bg:
|
|
117
|
-
--bg-card:
|
|
118
|
-
--bg-deep:
|
|
119
|
-
--bg-frame:
|
|
120
|
-
--ink: #
|
|
121
|
-
--ink-soft: #
|
|
122
|
-
--ink-faint: #
|
|
123
|
-
--rule:
|
|
124
|
-
--rule-soft:
|
|
125
|
-
--
|
|
272
|
+
--bg: #000000;
|
|
273
|
+
--bg-card: #101012;
|
|
274
|
+
--bg-deep: #000000;
|
|
275
|
+
--bg-frame: #08080a;
|
|
276
|
+
--ink: #ffffff;
|
|
277
|
+
--ink-soft: #c0c0c0;
|
|
278
|
+
--ink-faint: #a8a8a8;
|
|
279
|
+
--rule: rgba(255, 255, 255, .16);
|
|
280
|
+
--rule-soft: rgba(255, 255, 255, .08);
|
|
281
|
+
--glass: rgba(255, 255, 255, .11);
|
|
282
|
+
--glass-strong: rgba(255, 255, 255, .17);
|
|
283
|
+
--glass-edge: rgba(255, 255, 255, .13);
|
|
284
|
+
--glass-blur: 18px;
|
|
285
|
+
--void: #000000;
|
|
286
|
+
--void-ink: var(--ink);
|
|
287
|
+
--void-edge: rgba(255, 255, 255, .16);
|
|
288
|
+
--accent-ink: var(--accent);
|
|
289
|
+
--accent-tint: color-mix(in srgb, var(--accent) 22%, #0b0a09);
|
|
290
|
+
--accent-glow: 0 8px 28px color-mix(in srgb, var(--accent) 38%, transparent);
|
|
291
|
+
--ok: #4ade80;
|
|
292
|
+
--ok-weak: color-mix(in srgb, #4ade80 14%, var(--bg-card));
|
|
293
|
+
--warn: #fbbf24;
|
|
294
|
+
--warn-weak: color-mix(in srgb, #fbbf24 14%, var(--bg-card));
|
|
295
|
+
--danger: #f87171;
|
|
296
|
+
--danger-weak: color-mix(in srgb, #f87171 14%, var(--bg-card));
|
|
297
|
+
--info: color-mix(in srgb, var(--sea) 80%, #ffffff);
|
|
298
|
+
--info-weak: color-mix(in srgb, var(--info) 14%, var(--bg-card));
|
|
299
|
+
--focus: var(--accent);
|
|
300
|
+
--label-face: var(--font-body);
|
|
301
|
+
--label-size: 11.5px;
|
|
302
|
+
--label-space: .1em;
|
|
303
|
+
--type-halo: 0 2px 18px rgba(0, 0, 0, .94), 0 0 54px rgba(0, 0, 0, .72);
|
|
304
|
+
--surface-2: color-mix(in srgb, var(--ink) 6%, var(--bg-card));
|
|
305
|
+
--shadow-pop: 0 18px 40px rgba(0, 0, 0, .62);
|
|
306
|
+
--plate-veil: linear-gradient(to bottom, rgba(0, 0, 0, .82), rgba(0, 0, 0, .93));
|
|
126
307
|
}
|
|
127
308
|
html:not([data-theme]) body { background: var(--bg); }
|
|
128
309
|
}
|
|
129
310
|
|
|
311
|
+
/* The Kill Switch Rule (DESIGN.md). Nothing escapes it, and no motion is
|
|
312
|
+
authored in JavaScript, because JavaScript motion escapes it. */
|
|
313
|
+
@media (prefers-reduced-motion: reduce) {
|
|
314
|
+
*, *::before, *::after {
|
|
315
|
+
animation: none !important;
|
|
316
|
+
transition: none !important;
|
|
317
|
+
scroll-behavior: auto !important;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
130
321
|
/* ---------- table of contents (task 2166) ----------
|
|
131
322
|
Section banners in file order — grep "----------" to jump:
|
|
132
323
|
tokens + dark theme (ABOVE — the theming contract; never move/rename)
|
|
@@ -158,12 +349,12 @@ html {
|
|
|
158
349
|
|
|
159
350
|
* {
|
|
160
351
|
scrollbar-width: thin;
|
|
161
|
-
scrollbar-color: var(--
|
|
352
|
+
scrollbar-color: var(--rule) transparent;
|
|
162
353
|
}
|
|
163
354
|
::-webkit-scrollbar { width: 10px; height: 10px; }
|
|
164
355
|
::-webkit-scrollbar-track { background: transparent; }
|
|
165
356
|
::-webkit-scrollbar-thumb {
|
|
166
|
-
background: var(--
|
|
357
|
+
background: var(--rule);
|
|
167
358
|
border-radius: 5px;
|
|
168
359
|
border: 2px solid transparent;
|
|
169
360
|
background-clip: content-box;
|
|
@@ -182,33 +373,45 @@ body {
|
|
|
182
373
|
}
|
|
183
374
|
|
|
184
375
|
a {
|
|
185
|
-
color: var(--accent-
|
|
376
|
+
color: var(--accent-ink);
|
|
186
377
|
text-decoration: none;
|
|
187
378
|
}
|
|
188
|
-
a:hover { text-decoration: underline; text-underline-offset:
|
|
379
|
+
a:hover { text-decoration: underline; text-underline-offset: 3px; }
|
|
189
380
|
|
|
190
381
|
code, kbd, pre {
|
|
191
|
-
font-family:
|
|
382
|
+
font-family: var(--font-mono);
|
|
192
383
|
font-size: 0.92em;
|
|
193
384
|
}
|
|
194
385
|
|
|
386
|
+
/* The label voice. Mono in light, the body face in dark — take the token, never
|
|
387
|
+
the family (DESIGN.md, The label face flips). */
|
|
388
|
+
.lbl {
|
|
389
|
+
font-family: var(--label-face);
|
|
390
|
+
font-size: var(--label-size);
|
|
391
|
+
letter-spacing: var(--label-space);
|
|
392
|
+
text-transform: var(--label-case);
|
|
393
|
+
color: var(--ink-faint);
|
|
394
|
+
line-height: 1.2;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/* Every number the ledger produced is tabular, so a live refresh cannot reflow
|
|
398
|
+
the composition around it. */
|
|
399
|
+
.num, .tabular { font-variant-numeric: tabular-nums; }
|
|
400
|
+
|
|
195
401
|
select, input[type="text"], input[type="search"], textarea {
|
|
196
402
|
font-family: var(--font-body);
|
|
197
403
|
font-size: 14px;
|
|
198
404
|
color: var(--ink);
|
|
199
|
-
background:
|
|
200
|
-
border: 1px solid var(--
|
|
201
|
-
border-radius: var(--radius-
|
|
202
|
-
|
|
405
|
+
background: none;
|
|
406
|
+
border: 1px solid var(--rule);
|
|
407
|
+
border-radius: var(--radius-pill);
|
|
408
|
+
min-height: 30px;
|
|
409
|
+
padding: 5px 12px;
|
|
203
410
|
}
|
|
411
|
+
select:hover, input[type="text"]:hover, input[type="search"]:hover { border-color: var(--ink-faint); }
|
|
412
|
+
textarea { border-radius: var(--radius-sm); }
|
|
204
413
|
select:disabled { opacity: 0.55; cursor: not-allowed; }
|
|
205
|
-
select option { background: var(--
|
|
206
|
-
|
|
207
|
-
:focus-visible {
|
|
208
|
-
outline: 2px solid var(--accent);
|
|
209
|
-
outline-offset: 2px;
|
|
210
|
-
border-radius: 4px;
|
|
211
|
-
}
|
|
414
|
+
select option { background: var(--bg-card); color: var(--ink); }
|
|
212
415
|
|
|
213
416
|
button { font-family: var(--font-body); }
|
|
214
417
|
|
|
@@ -221,48 +424,118 @@ button { font-family: var(--font-body); }
|
|
|
221
424
|
white-space: nowrap;
|
|
222
425
|
}
|
|
223
426
|
|
|
224
|
-
/* ---------- app shell ----------
|
|
427
|
+
/* ---------- app shell ----------
|
|
428
|
+
v3 "the glass hall" (the owner's pick, 2026-08-30): the sidebar is the 64px
|
|
429
|
+
rail at EVERY width, opening on hover or focus-within over the page; the
|
|
430
|
+
topbar and sidebar are glass; content sits on --bg-card panels at the full
|
|
431
|
+
--radius with tone doing the separation and no hairline edge.
|
|
432
|
+
|
|
433
|
+
Two rules the round found the hard way and this section obeys:
|
|
434
|
+
- a rail label must LEAVE the layout, not fade to opacity 0. A faded label
|
|
435
|
+
still occupies width and pushes its own icon out of the 64px strip.
|
|
436
|
+
- the rail's breakpoints are composition, so they live here on the shell
|
|
437
|
+
rules and never in the token tier: a page that declares --sidebar-w on
|
|
438
|
+
`body` would beat an inherited :root value and silently defeat the query. */
|
|
225
439
|
|
|
226
440
|
.app { min-height: 100vh; }
|
|
227
441
|
|
|
442
|
+
/* The ground and its veil. Both are tokens; the hall's plate is not shot yet,
|
|
443
|
+
so both resolve to none in both modes and the shell is a complete composition
|
|
444
|
+
without one. Adding one later is a token change, not a re-layout. */
|
|
445
|
+
body::before {
|
|
446
|
+
content: "";
|
|
447
|
+
position: fixed;
|
|
448
|
+
inset: 0;
|
|
449
|
+
z-index: 0;
|
|
450
|
+
pointer-events: none;
|
|
451
|
+
background-image: var(--plate);
|
|
452
|
+
background-size: cover;
|
|
453
|
+
background-position: center;
|
|
454
|
+
mix-blend-mode: var(--plate-blend);
|
|
455
|
+
}
|
|
456
|
+
body::after {
|
|
457
|
+
content: "";
|
|
458
|
+
position: fixed;
|
|
459
|
+
inset: 0;
|
|
460
|
+
z-index: 0;
|
|
461
|
+
pointer-events: none;
|
|
462
|
+
background-image: var(--plate-veil);
|
|
463
|
+
}
|
|
464
|
+
|
|
228
465
|
.app-sidebar {
|
|
229
466
|
position: fixed;
|
|
230
467
|
inset: 0 auto 0 0;
|
|
231
|
-
width: var(--sidebar-w);
|
|
468
|
+
width: var(--sidebar-w-rail);
|
|
232
469
|
z-index: var(--z-sidebar);
|
|
233
470
|
display: flex;
|
|
234
471
|
flex-direction: column;
|
|
235
|
-
background: var(--
|
|
236
|
-
border-right: 1px solid var(--
|
|
472
|
+
background: var(--glass);
|
|
473
|
+
border-right: 1px solid var(--glass-edge);
|
|
474
|
+
backdrop-filter: blur(var(--glass-blur));
|
|
475
|
+
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
237
476
|
overflow: hidden;
|
|
238
477
|
}
|
|
478
|
+
/* The rail opens over the content — no transition, because the world animates
|
|
479
|
+
transform and filter only. `:focus-within` is what makes it keyboard-reachable
|
|
480
|
+
at all; without it a tab into the rail lands on unlabelled icons. */
|
|
481
|
+
.app-sidebar:hover,
|
|
482
|
+
.app-sidebar:focus-within { width: var(--rail-open); }
|
|
239
483
|
|
|
240
484
|
.app-sidebar__brand {
|
|
241
485
|
display: flex;
|
|
242
486
|
align-items: center;
|
|
487
|
+
justify-content: center;
|
|
243
488
|
min-height: var(--topbar-h);
|
|
244
|
-
padding: 0
|
|
245
|
-
border-bottom: 1px solid var(--
|
|
489
|
+
padding: 0;
|
|
490
|
+
border-bottom: 1px solid var(--glass-edge);
|
|
246
491
|
flex-shrink: 0;
|
|
247
492
|
}
|
|
493
|
+
/* The skip link — shell.js renders it as the first focusable thing in the
|
|
494
|
+
document and points it at a focusable, never-ringed <main>. Off-screen until
|
|
495
|
+
focused, then a pill in the top-left over everything. */
|
|
496
|
+
.skip {
|
|
497
|
+
position: absolute;
|
|
498
|
+
left: -9999px;
|
|
499
|
+
top: 8px;
|
|
500
|
+
z-index: 200;
|
|
501
|
+
background: var(--bg-card);
|
|
502
|
+
color: var(--ink);
|
|
503
|
+
border: 1px solid var(--rule);
|
|
504
|
+
border-radius: var(--radius-pill);
|
|
505
|
+
padding: 11px 18px;
|
|
506
|
+
font-size: 13.5px;
|
|
507
|
+
text-decoration: none;
|
|
508
|
+
}
|
|
509
|
+
.skip:focus { left: 12px; }
|
|
510
|
+
main:focus { outline: none; }
|
|
511
|
+
|
|
248
512
|
.brand-mark {
|
|
249
513
|
display: flex;
|
|
250
514
|
align-items: center;
|
|
515
|
+
justify-content: center;
|
|
251
516
|
gap: 10px;
|
|
517
|
+
/* The label leaves the layout in the closed rail, so the dot alone would be
|
|
518
|
+
an 11px target — the mark still has to clear the 24px control floor. */
|
|
519
|
+
min-width: 32px;
|
|
520
|
+
min-height: 32px;
|
|
252
521
|
font-family: var(--font-display);
|
|
253
|
-
font-weight:
|
|
522
|
+
font-weight: 500;
|
|
254
523
|
font-size: 15px;
|
|
524
|
+
letter-spacing: -0.015em;
|
|
255
525
|
color: var(--ink);
|
|
256
|
-
min-width: 0;
|
|
257
526
|
}
|
|
258
527
|
.brand-mark:hover { text-decoration: none; }
|
|
528
|
+
/* An outlined dot, not a filled one: the accent lights only what is pressable
|
|
529
|
+
or live, and a wordmark is neither. */
|
|
259
530
|
.brand-mark__dot {
|
|
260
|
-
width:
|
|
261
|
-
border-radius:
|
|
262
|
-
|
|
531
|
+
width: 11px; height: 11px;
|
|
532
|
+
border-radius: 50%;
|
|
533
|
+
border: 1px solid var(--ink);
|
|
534
|
+
background: none;
|
|
263
535
|
flex-shrink: 0;
|
|
264
536
|
}
|
|
265
537
|
.brand-mark__name {
|
|
538
|
+
display: none;
|
|
266
539
|
white-space: nowrap;
|
|
267
540
|
overflow: hidden;
|
|
268
541
|
text-overflow: ellipsis;
|
|
@@ -270,7 +543,7 @@ button { font-family: var(--font-body); }
|
|
|
270
543
|
|
|
271
544
|
.app-sidebar__nav {
|
|
272
545
|
flex: 1;
|
|
273
|
-
padding:
|
|
546
|
+
padding: 14px 0 22px;
|
|
274
547
|
display: flex;
|
|
275
548
|
flex-direction: column;
|
|
276
549
|
gap: 2px;
|
|
@@ -290,28 +563,39 @@ button { font-family: var(--font-body); }
|
|
|
290
563
|
}
|
|
291
564
|
.nav-group { display: flex; flex-direction: column; gap: 2px; }
|
|
292
565
|
.nav-group + .nav-group { margin-top: 14px; }
|
|
566
|
+
/* task 1003303: the items live in their own wrapper so the group head can carry
|
|
567
|
+
aria-controls (the frozen markup had aria-expanded pointing at nothing, which
|
|
568
|
+
fails the disclosure rule). The class deliberately does NOT start with
|
|
569
|
+
"nav-group" — tests/hall_nav.mjs splits the sidebar on that string to find
|
|
570
|
+
groups, and a wrapper that matched it would parse as a phantom sixth group. */
|
|
571
|
+
.nav-items { display: flex; flex-direction: column; gap: 2px; }
|
|
293
572
|
.nav-group__head {
|
|
294
|
-
|
|
295
|
-
font-weight: 600;
|
|
296
|
-
letter-spacing: 0.06em;
|
|
297
|
-
text-transform: uppercase;
|
|
298
|
-
color: var(--ink-faint);
|
|
299
|
-
padding: 4px 10px 2px;
|
|
300
|
-
}
|
|
301
|
-
.nav-group--collapsible .nav-group__head {
|
|
302
|
-
display: flex;
|
|
573
|
+
display: none;
|
|
303
574
|
align-items: center;
|
|
304
575
|
justify-content: space-between;
|
|
576
|
+
gap: 8px;
|
|
305
577
|
width: 100%;
|
|
578
|
+
min-height: 26px;
|
|
579
|
+
padding: 8px 22px 4px;
|
|
580
|
+
text-align: left;
|
|
306
581
|
background: none;
|
|
307
582
|
border: none;
|
|
308
583
|
cursor: pointer;
|
|
309
584
|
}
|
|
310
|
-
.nav-
|
|
585
|
+
.nav-group__head-label {
|
|
586
|
+
font-family: var(--label-face);
|
|
587
|
+
font-size: var(--label-size);
|
|
588
|
+
letter-spacing: var(--label-space);
|
|
589
|
+
text-transform: var(--label-case);
|
|
590
|
+
color: var(--ink-faint);
|
|
591
|
+
}
|
|
592
|
+
.nav-group--collapsible .nav-group__head:hover .nav-group__head-label { color: var(--ink-soft); }
|
|
311
593
|
.nav-group__chevron {
|
|
312
|
-
width:
|
|
313
|
-
height:
|
|
594
|
+
width: 10px;
|
|
595
|
+
height: 6px;
|
|
314
596
|
flex-shrink: 0;
|
|
597
|
+
stroke: currentColor;
|
|
598
|
+
color: var(--ink-faint);
|
|
315
599
|
transition: transform 0.15s ease;
|
|
316
600
|
}
|
|
317
601
|
.nav-group--collapsed .nav-group__chevron { transform: rotate(-90deg); }
|
|
@@ -321,42 +605,47 @@ button { font-family: var(--font-body); }
|
|
|
321
605
|
position: relative;
|
|
322
606
|
display: flex;
|
|
323
607
|
align-items: center;
|
|
608
|
+
justify-content: center;
|
|
324
609
|
gap: 10px;
|
|
325
|
-
height:
|
|
326
|
-
|
|
610
|
+
min-height: 40px;
|
|
611
|
+
margin: 0 8px;
|
|
612
|
+
padding: 0;
|
|
327
613
|
border-radius: var(--radius-sm);
|
|
328
614
|
color: var(--ink-soft);
|
|
329
|
-
font-weight: 500;
|
|
330
615
|
font-size: 14px;
|
|
616
|
+
text-transform: lowercase;
|
|
331
617
|
white-space: nowrap;
|
|
332
618
|
}
|
|
333
|
-
.nav-item:hover { background: var(--
|
|
334
|
-
.nav-item--active {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
619
|
+
.nav-item:hover { background: var(--glass); color: var(--ink); text-decoration: none; }
|
|
620
|
+
.nav-item--active { background: var(--glass-strong); color: var(--ink); }
|
|
621
|
+
/* The current item is the one live thing in the rail, so it takes the accent —
|
|
622
|
+
the lifecycle rail's lit-step grammar, one 2px bar on the leading edge. */
|
|
338
623
|
.nav-item--active::before {
|
|
339
624
|
content: "";
|
|
340
625
|
position: absolute;
|
|
341
|
-
left:
|
|
342
|
-
width:
|
|
343
|
-
border-radius:
|
|
626
|
+
left: 0; top: 8px; bottom: 8px;
|
|
627
|
+
width: 2px;
|
|
628
|
+
border-radius: 1px;
|
|
344
629
|
background: var(--accent);
|
|
345
630
|
}
|
|
346
|
-
.nav-
|
|
631
|
+
.nav-item__label { display: none; font-size: 14px; }
|
|
632
|
+
.nav-icon { width: 16px; height: 16px; flex-shrink: 0; }
|
|
347
633
|
|
|
348
634
|
.app-sidebar__foot {
|
|
349
|
-
padding:
|
|
350
|
-
border-top: 1px solid var(--
|
|
635
|
+
padding: 10px 0;
|
|
636
|
+
border-top: 1px solid var(--glass-edge);
|
|
351
637
|
display: flex;
|
|
352
638
|
flex-direction: column;
|
|
639
|
+
align-items: center;
|
|
353
640
|
gap: 8px;
|
|
354
641
|
flex-shrink: 0;
|
|
355
642
|
}
|
|
356
643
|
.shell-user {
|
|
357
644
|
display: flex;
|
|
358
645
|
align-items: center;
|
|
646
|
+
justify-content: center;
|
|
359
647
|
gap: 10px;
|
|
648
|
+
min-height: 36px;
|
|
360
649
|
padding: 4px 6px;
|
|
361
650
|
min-width: 0;
|
|
362
651
|
/* task 1831: the chip is now an <a> to /settings — strip link chrome, keep the
|
|
@@ -366,15 +655,15 @@ button { font-family: var(--font-body); }
|
|
|
366
655
|
border-radius: var(--radius-sm);
|
|
367
656
|
cursor: pointer;
|
|
368
657
|
}
|
|
369
|
-
.shell-user:hover { background: var(--
|
|
370
|
-
.shell-user:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
658
|
+
.shell-user:hover { background: var(--glass); text-decoration: none; }
|
|
371
659
|
.shell-user__avatar {
|
|
372
|
-
width:
|
|
660
|
+
width: 26px; height: 26px;
|
|
373
661
|
border-radius: 50%;
|
|
374
|
-
background: var(--
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
font-
|
|
662
|
+
background: var(--surface-2);
|
|
663
|
+
border: 1px solid var(--rule);
|
|
664
|
+
color: var(--ink-soft);
|
|
665
|
+
font-size: 11px;
|
|
666
|
+
font-weight: 500;
|
|
378
667
|
display: flex;
|
|
379
668
|
align-items: center;
|
|
380
669
|
justify-content: center;
|
|
@@ -382,43 +671,75 @@ button { font-family: var(--font-body); }
|
|
|
382
671
|
flex-shrink: 0;
|
|
383
672
|
}
|
|
384
673
|
.shell-user__avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
|
|
385
|
-
.shell-user__meta { display:
|
|
674
|
+
.shell-user__meta { display: none; flex-direction: column; min-width: 0; line-height: 1.3; }
|
|
386
675
|
.shell-user__name {
|
|
387
|
-
font-size:
|
|
388
|
-
font-weight: 600;
|
|
676
|
+
font-size: 13.5px;
|
|
389
677
|
white-space: nowrap;
|
|
390
678
|
overflow: hidden;
|
|
391
679
|
text-overflow: ellipsis;
|
|
392
680
|
}
|
|
393
|
-
.shell-user__rank {
|
|
681
|
+
.shell-user__rank {
|
|
682
|
+
font-family: var(--label-face);
|
|
683
|
+
font-size: 10.5px;
|
|
684
|
+
letter-spacing: var(--label-space);
|
|
685
|
+
text-transform: var(--label-case);
|
|
686
|
+
color: var(--ink-faint);
|
|
687
|
+
}
|
|
394
688
|
.shell-signin,
|
|
395
689
|
.shell-home,
|
|
396
690
|
.shell-signout {
|
|
397
691
|
display: flex;
|
|
398
692
|
align-items: center;
|
|
693
|
+
justify-content: center;
|
|
399
694
|
gap: 10px;
|
|
400
|
-
height:
|
|
401
|
-
padding: 0
|
|
695
|
+
min-height: 32px;
|
|
696
|
+
padding: 0 8px;
|
|
402
697
|
border-radius: var(--radius-sm);
|
|
403
698
|
font-size: 13.5px;
|
|
404
|
-
|
|
405
|
-
color: var(--ink-soft);
|
|
699
|
+
color: var(--ink-faint);
|
|
406
700
|
}
|
|
407
701
|
.shell-home { text-decoration: none; }
|
|
408
702
|
.shell-signin {
|
|
409
|
-
justify-content: center;
|
|
410
703
|
background: var(--accent);
|
|
411
|
-
color:
|
|
704
|
+
color: var(--accent-on);
|
|
705
|
+
border-radius: var(--radius-pill);
|
|
706
|
+
font-weight: 500;
|
|
707
|
+
min-height: 34px;
|
|
412
708
|
}
|
|
413
|
-
.shell-signin:hover { background: var(--accent-
|
|
709
|
+
.shell-signin:hover { background: var(--accent-lift); color: var(--accent-on); text-decoration: none; }
|
|
414
710
|
.shell-home:hover,
|
|
415
|
-
.shell-signout:hover { background: var(--
|
|
711
|
+
.shell-signout:hover { background: var(--glass); color: var(--ink); text-decoration: none; }
|
|
712
|
+
|
|
713
|
+
/* ---- the rail, open. Labels LEAVE the layout when closed and come back here;
|
|
714
|
+
the icon strip is what stays either way. ---- */
|
|
715
|
+
.app-sidebar:hover .brand-mark__name,
|
|
716
|
+
.app-sidebar:focus-within .brand-mark__name,
|
|
717
|
+
.app-sidebar:hover .nav-item__label,
|
|
718
|
+
.app-sidebar:focus-within .nav-item__label,
|
|
719
|
+
.app-sidebar:hover .shell-user__meta,
|
|
720
|
+
.app-sidebar:focus-within .shell-user__meta { display: block; }
|
|
721
|
+
.app-sidebar:hover .nav-group--collapsible .nav-group__head,
|
|
722
|
+
.app-sidebar:focus-within .nav-group--collapsible .nav-group__head { display: flex; }
|
|
723
|
+
.app-sidebar:hover .app-sidebar__brand,
|
|
724
|
+
.app-sidebar:focus-within .app-sidebar__brand { justify-content: flex-start; padding: 0 22px; }
|
|
725
|
+
.app-sidebar:hover .nav-item,
|
|
726
|
+
.app-sidebar:focus-within .nav-item { justify-content: flex-start; padding: 0 12px; }
|
|
727
|
+
.app-sidebar:hover .app-sidebar__foot,
|
|
728
|
+
.app-sidebar:focus-within .app-sidebar__foot { align-items: stretch; padding: 12px 16px; }
|
|
729
|
+
.app-sidebar:hover .shell-user,
|
|
730
|
+
.app-sidebar:focus-within .shell-user { justify-content: flex-start; }
|
|
731
|
+
.app-sidebar:hover .shell-home,
|
|
732
|
+
.app-sidebar:focus-within .shell-home,
|
|
733
|
+
.app-sidebar:hover .shell-signout,
|
|
734
|
+
.app-sidebar:focus-within .shell-signout { justify-content: flex-start; padding: 0 10px; }
|
|
416
735
|
|
|
417
736
|
.app-body {
|
|
418
|
-
margin-left: var(--sidebar-w);
|
|
737
|
+
margin-left: var(--sidebar-w-rail);
|
|
419
738
|
min-height: 100vh;
|
|
420
739
|
display: flex;
|
|
421
740
|
flex-direction: column;
|
|
741
|
+
position: relative;
|
|
742
|
+
z-index: 1;
|
|
422
743
|
}
|
|
423
744
|
|
|
424
745
|
.app-topbar {
|
|
@@ -427,29 +748,36 @@ button { font-family: var(--font-body); }
|
|
|
427
748
|
z-index: var(--z-topbar);
|
|
428
749
|
display: flex;
|
|
429
750
|
align-items: center;
|
|
430
|
-
gap:
|
|
751
|
+
gap: 14px;
|
|
431
752
|
height: var(--topbar-h);
|
|
432
|
-
padding: 0
|
|
433
|
-
background:
|
|
434
|
-
backdrop-filter: blur(
|
|
435
|
-
|
|
753
|
+
padding: 0 22px;
|
|
754
|
+
background: var(--glass);
|
|
755
|
+
backdrop-filter: blur(var(--glass-blur));
|
|
756
|
+
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
757
|
+
border-bottom: 1px solid var(--glass-edge);
|
|
436
758
|
}
|
|
759
|
+
/* Sentence case, not a mono label: v3's own divergence, picked with it. */
|
|
437
760
|
.topbar-title {
|
|
438
761
|
margin: 0;
|
|
439
762
|
font-family: var(--font-display);
|
|
440
|
-
font-
|
|
441
|
-
font-
|
|
442
|
-
letter-spacing: -0.
|
|
763
|
+
font-weight: 300;
|
|
764
|
+
font-size: 19px;
|
|
765
|
+
letter-spacing: -0.025em;
|
|
766
|
+
text-transform: lowercase;
|
|
767
|
+
color: var(--ink);
|
|
443
768
|
}
|
|
444
769
|
.topbar-side {
|
|
445
770
|
margin-left: auto;
|
|
446
771
|
display: flex;
|
|
447
772
|
align-items: center;
|
|
448
|
-
gap:
|
|
773
|
+
gap: 8px;
|
|
449
774
|
min-width: 0;
|
|
450
775
|
}
|
|
451
776
|
.topbar-note {
|
|
452
|
-
font-
|
|
777
|
+
font-family: var(--label-face);
|
|
778
|
+
font-size: var(--label-size);
|
|
779
|
+
letter-spacing: var(--label-space);
|
|
780
|
+
text-transform: var(--label-case);
|
|
453
781
|
color: var(--ink-faint);
|
|
454
782
|
white-space: nowrap;
|
|
455
783
|
overflow: hidden;
|
|
@@ -461,17 +789,19 @@ button { font-family: var(--font-body); }
|
|
|
461
789
|
display: flex;
|
|
462
790
|
align-items: baseline;
|
|
463
791
|
gap: 12px;
|
|
464
|
-
padding: 10px
|
|
792
|
+
padding: 10px 22px;
|
|
465
793
|
font-size: 13px;
|
|
466
794
|
color: var(--warn);
|
|
467
795
|
background: var(--warn-weak);
|
|
468
|
-
border-bottom: 1px solid var(--
|
|
796
|
+
border-bottom: 1px solid var(--rule-soft);
|
|
469
797
|
}
|
|
470
798
|
.denied-notice code {
|
|
471
799
|
font-size: 12px;
|
|
472
800
|
}
|
|
473
801
|
.denied-notice__close {
|
|
474
802
|
margin-left: auto;
|
|
803
|
+
min-width: 24px;
|
|
804
|
+
min-height: 24px;
|
|
475
805
|
border: 0;
|
|
476
806
|
background: none;
|
|
477
807
|
color: inherit;
|
|
@@ -483,31 +813,32 @@ button { font-family: var(--font-body); }
|
|
|
483
813
|
display: none;
|
|
484
814
|
align-items: center;
|
|
485
815
|
justify-content: center;
|
|
486
|
-
width:
|
|
487
|
-
border:
|
|
488
|
-
border-radius: var(--radius-
|
|
489
|
-
background:
|
|
816
|
+
width: 32px; height: 32px;
|
|
817
|
+
border: 0;
|
|
818
|
+
border-radius: var(--radius-pill);
|
|
819
|
+
background: none;
|
|
490
820
|
color: var(--ink-soft);
|
|
491
821
|
cursor: pointer;
|
|
492
822
|
padding: 0;
|
|
493
823
|
}
|
|
494
|
-
.topbar-menu
|
|
824
|
+
.topbar-menu:hover { color: var(--ink); }
|
|
825
|
+
.topbar-menu svg { width: 16px; height: 16px; }
|
|
495
826
|
|
|
496
827
|
.theme-toggle {
|
|
497
828
|
display: inline-flex;
|
|
498
829
|
align-items: center;
|
|
499
830
|
justify-content: center;
|
|
500
831
|
width: 32px; height: 32px;
|
|
501
|
-
border:
|
|
502
|
-
border-radius: var(--radius-
|
|
503
|
-
background:
|
|
832
|
+
border: 0;
|
|
833
|
+
border-radius: var(--radius-pill);
|
|
834
|
+
background: none;
|
|
504
835
|
color: var(--ink-soft);
|
|
505
836
|
cursor: pointer;
|
|
506
837
|
padding: 0;
|
|
507
838
|
flex-shrink: 0;
|
|
508
839
|
}
|
|
509
|
-
.theme-toggle:hover {
|
|
510
|
-
.theme-toggle svg { width:
|
|
840
|
+
.theme-toggle:hover { color: var(--ink); }
|
|
841
|
+
.theme-toggle svg { width: 16px; height: 16px; }
|
|
511
842
|
|
|
512
843
|
/* task 1475: the accessibility zoom control — sibling of the theme toggle.
|
|
513
844
|
Widens to fit the "125%"/"150%" label when zoom is active. */
|
|
@@ -518,24 +849,24 @@ button { font-family: var(--font-body); }
|
|
|
518
849
|
gap: 4px;
|
|
519
850
|
min-width: 32px; height: 32px;
|
|
520
851
|
padding: 0 8px;
|
|
521
|
-
border:
|
|
522
|
-
border-radius: var(--radius-
|
|
523
|
-
background:
|
|
852
|
+
border: 0;
|
|
853
|
+
border-radius: var(--radius-pill);
|
|
854
|
+
background: none;
|
|
524
855
|
color: var(--ink-soft);
|
|
525
856
|
cursor: pointer;
|
|
526
857
|
flex-shrink: 0;
|
|
527
858
|
}
|
|
528
|
-
.zoom-toggle:hover {
|
|
529
|
-
.zoom-toggle svg { width:
|
|
530
|
-
/* Active (zoomed-in) state reads as "on"
|
|
859
|
+
.zoom-toggle:hover { color: var(--ink); }
|
|
860
|
+
.zoom-toggle svg { width: 16px; height: 16px; }
|
|
861
|
+
/* Active (zoomed-in) state reads as "on" — the accent, because a live control
|
|
862
|
+
is exactly what the accent is for. */
|
|
531
863
|
.zoom-toggle--on {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
color: var(--accent-text);
|
|
864
|
+
background: var(--accent-tint);
|
|
865
|
+
color: var(--accent-ink);
|
|
535
866
|
}
|
|
536
867
|
.zoom-toggle__pct {
|
|
537
868
|
font-size: 12px;
|
|
538
|
-
font-weight:
|
|
869
|
+
font-weight: 500;
|
|
539
870
|
font-variant-numeric: tabular-nums;
|
|
540
871
|
line-height: 1;
|
|
541
872
|
}
|
|
@@ -544,15 +875,15 @@ button { font-family: var(--font-body); }
|
|
|
544
875
|
width: 100%;
|
|
545
876
|
max-width: calc(var(--content-max) + 64px);
|
|
546
877
|
margin: 0 auto;
|
|
547
|
-
padding:
|
|
878
|
+
padding: 26px 22px 108px;
|
|
548
879
|
flex: 1;
|
|
549
880
|
}
|
|
550
881
|
|
|
551
|
-
.app-views .view > .view-zone + .view-zone { margin-top: var(--
|
|
882
|
+
.app-views .view > .view-zone + .view-zone { margin-top: var(--sp-md); }
|
|
552
883
|
.view-zone--band {
|
|
553
884
|
display: grid;
|
|
554
885
|
grid-template-columns: 1fr 1fr;
|
|
555
|
-
gap: var(--
|
|
886
|
+
gap: var(--sp-md);
|
|
556
887
|
align-items: start;
|
|
557
888
|
}
|
|
558
889
|
.view-zone--band > .scroll { margin: 0; }
|
|
@@ -564,11 +895,13 @@ button { font-family: var(--font-body); }
|
|
|
564
895
|
gap: 12px;
|
|
565
896
|
padding: 18px 4px 0;
|
|
566
897
|
margin-top: 24px;
|
|
567
|
-
border-top: 1px solid var(--
|
|
898
|
+
border-top: 1px solid var(--rule-soft);
|
|
568
899
|
font-size: 12.5px;
|
|
569
900
|
color: var(--ink-faint);
|
|
570
901
|
}
|
|
571
|
-
|
|
902
|
+
/* 3px of vertical padding so a link in a row with no rhythm of its own still
|
|
903
|
+
clears the 24px control floor (DESIGN.md §The footer). */
|
|
904
|
+
.app-foot a { color: var(--ink-faint); display: inline-block; padding: 3px 0; min-height: 24px; }
|
|
572
905
|
.app-foot a:hover { color: var(--ink); }
|
|
573
906
|
.app-foot span { margin-right: auto; }
|
|
574
907
|
|
|
@@ -576,54 +909,67 @@ button { font-family: var(--font-body); }
|
|
|
576
909
|
position: fixed;
|
|
577
910
|
inset: 0;
|
|
578
911
|
z-index: var(--z-scrim);
|
|
579
|
-
background:
|
|
912
|
+
background: rgba(0, 0, 0, .55);
|
|
580
913
|
}
|
|
581
914
|
|
|
582
|
-
/*
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
.nav-item, .shell-home, .shell-signout { justify-content: center; padding: 0; }
|
|
592
|
-
.nav-item--active::before { left: -6px; }
|
|
593
|
-
.shell-user { justify-content: center; padding: 2px 0; }
|
|
594
|
-
.shell-signin { font-size: 0; padding: 0; height: 34px; }
|
|
595
|
-
.shell-signin::after { content: "→"; font-size: 15px; }
|
|
915
|
+
/* Focus: the world's two-tone ring — a 2px accent-derived outline at 3px offset
|
|
916
|
+
inside an 8px --bg halo, so the indicator keeps its own edge over whatever it
|
|
917
|
+
lands on (a bare outline measured 1.1:1 over the light bar). The rail's items
|
|
918
|
+
ring inside themselves instead, or the halo would spill out of the 64px strip. */
|
|
919
|
+
:focus-visible {
|
|
920
|
+
outline: 2px solid var(--focus);
|
|
921
|
+
outline-offset: 3px;
|
|
922
|
+
box-shadow: 0 0 0 8px var(--bg);
|
|
923
|
+
border-radius: var(--radius-sm);
|
|
596
924
|
}
|
|
925
|
+
.nav-item:focus-visible,
|
|
926
|
+
.shell-user:focus-visible,
|
|
927
|
+
.shell-home:focus-visible,
|
|
928
|
+
.shell-signout:focus-visible {
|
|
929
|
+
outline-offset: -2px;
|
|
930
|
+
box-shadow: none;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/* ---------- responsive shell (scope §10) ----------
|
|
934
|
+
The rail holds at every width (v3), so there is no 1024px collapse any more.
|
|
935
|
+
What is left is the phone: under 768 the rail becomes the drawer shell.js
|
|
936
|
+
already owns, and the hamburger appears to open it. */
|
|
597
937
|
|
|
598
938
|
@media (max-width: 768px) {
|
|
599
939
|
.app-sidebar {
|
|
600
|
-
width: var(--
|
|
940
|
+
width: var(--rail-open);
|
|
601
941
|
transform: translateX(-100%);
|
|
602
942
|
transition: transform 160ms ease;
|
|
603
943
|
z-index: var(--z-drawer);
|
|
604
944
|
}
|
|
945
|
+
/* The drawer is the rail already open — the hover expansion is off, because
|
|
946
|
+
there is no hover on a phone and a drawer that needed one could not open. */
|
|
947
|
+
.app-sidebar:hover,
|
|
948
|
+
.app-sidebar:focus-within { width: var(--rail-open); }
|
|
605
949
|
html.drawer-open .app-sidebar { transform: translateX(0); box-shadow: var(--shadow-pop); }
|
|
606
950
|
.app-body { margin-left: 0; }
|
|
607
|
-
.brand-mark__name, .nav-item__label, .
|
|
608
|
-
.nav-
|
|
951
|
+
.brand-mark__name, .nav-item__label, .shell-user__meta { display: block; }
|
|
952
|
+
.nav-group--collapsible .nav-group__head { display: flex; }
|
|
953
|
+
.app-sidebar__brand { justify-content: flex-start; padding: 0 22px; }
|
|
954
|
+
.nav-item, .shell-home, .shell-signout { justify-content: flex-start; padding: 0 12px; }
|
|
955
|
+
.app-sidebar__foot { align-items: stretch; padding: 12px 16px; }
|
|
609
956
|
.shell-user { justify-content: flex-start; }
|
|
610
|
-
.shell-signin { font-size: 13.5px; padding: 0 10px; }
|
|
611
|
-
.shell-signin::after { content: none; }
|
|
612
957
|
.topbar-menu { display: flex; }
|
|
613
958
|
.topbar-note { display: none; }
|
|
614
|
-
.app-content { padding:
|
|
959
|
+
.app-content { padding: 18px 14px 48px; }
|
|
615
960
|
.view-zone--band { grid-template-columns: 1fr; }
|
|
616
961
|
}
|
|
617
962
|
|
|
618
963
|
@media (max-width: 480px) {
|
|
619
|
-
.app-content { padding: 12px
|
|
964
|
+
.app-content { padding: 14px 12px 40px; }
|
|
620
965
|
}
|
|
621
966
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
967
|
+
/* ---------- cards (the .scroll legacy name is load-bearing) ----------
|
|
968
|
+
v3's panels: --bg-card at the full --radius, with TONE doing the separation
|
|
969
|
+
and no hairline edge. The world's "hairlines, not containers" rule is a
|
|
970
|
+
poster's rule; the owner's pick answers the container question for an
|
|
971
|
+
application surface with yes, and the compromise the pick makes is that a
|
|
972
|
+
panel is a tone, never a drawn box and never a shadow. */
|
|
627
973
|
|
|
628
974
|
/* The three sanctioned card levels (task 2179). Anything that looks like a card
|
|
629
975
|
is one of these — a fourth variant is a design decision, not a local override:
|
|
@@ -631,11 +977,11 @@ button { font-family: var(--font-body); }
|
|
|
631
977
|
.scroll--quiet secondary — a card INSIDE a card, or supporting detail
|
|
632
978
|
.scroll--bare none — layout-only, for stat rows and grids */
|
|
633
979
|
.scroll {
|
|
634
|
-
background: var(--
|
|
635
|
-
border: 1px solid
|
|
980
|
+
background: var(--bg-card);
|
|
981
|
+
border: 1px solid transparent;
|
|
636
982
|
border-radius: var(--radius);
|
|
637
|
-
padding: var(--
|
|
638
|
-
margin: 0 0 var(--
|
|
983
|
+
padding: var(--sp-md);
|
|
984
|
+
margin: 0 0 var(--sp-md);
|
|
639
985
|
/* anchor jumps must clear the 56px sticky top bar */
|
|
640
986
|
scroll-margin-top: calc(var(--topbar-h) + 16px);
|
|
641
987
|
}
|
|
@@ -646,88 +992,114 @@ button { font-family: var(--font-body); }
|
|
|
646
992
|
border-radius: 0;
|
|
647
993
|
padding: 0;
|
|
648
994
|
}
|
|
649
|
-
/* Secondary level:
|
|
650
|
-
|
|
995
|
+
/* Secondary level: a card inside a card recedes by tone, one step further from
|
|
996
|
+
the ground than its parent. Use for supporting detail — not to fit more onto
|
|
997
|
+
Home. */
|
|
651
998
|
.scroll--quiet {
|
|
652
999
|
background: var(--surface-2);
|
|
653
|
-
padding: var(--
|
|
1000
|
+
padding: var(--sp-sm);
|
|
654
1001
|
}
|
|
655
1002
|
.scroll--quiet > .scroll__h {
|
|
656
|
-
font-size:
|
|
1003
|
+
font-size: 14px;
|
|
657
1004
|
color: var(--ink-soft);
|
|
658
1005
|
}
|
|
659
1006
|
|
|
1007
|
+
/* Section headings take the display voice in sentence case — v3's own
|
|
1008
|
+
divergence from the mono label, picked with it. */
|
|
660
1009
|
.scroll__h {
|
|
661
|
-
margin: 0 0
|
|
1010
|
+
margin: 0 0 8px;
|
|
662
1011
|
font-family: var(--font-display);
|
|
663
|
-
font-
|
|
664
|
-
font-
|
|
665
|
-
|
|
1012
|
+
font-weight: 300;
|
|
1013
|
+
font-size: 21px;
|
|
1014
|
+
line-height: 1.15;
|
|
1015
|
+
letter-spacing: -0.03em;
|
|
1016
|
+
color: var(--ink);
|
|
1017
|
+
text-shadow: var(--type-halo);
|
|
666
1018
|
}
|
|
667
1019
|
.scroll__lede {
|
|
668
1020
|
margin: 0 0 14px;
|
|
669
1021
|
font-size: 13.5px;
|
|
670
1022
|
color: var(--ink-soft);
|
|
671
|
-
max-width:
|
|
1023
|
+
max-width: var(--measure);
|
|
672
1024
|
}
|
|
673
1025
|
.card-foot {
|
|
674
|
-
margin:
|
|
1026
|
+
margin: 14px 0 0;
|
|
675
1027
|
font-size: 13px;
|
|
676
1028
|
}
|
|
677
1029
|
|
|
678
1030
|
.pill-link,
|
|
679
1031
|
#welcome-reopen a {
|
|
680
|
-
display: inline-
|
|
681
|
-
|
|
682
|
-
|
|
1032
|
+
display: inline-flex;
|
|
1033
|
+
align-items: center;
|
|
1034
|
+
min-height: 28px;
|
|
1035
|
+
font-size: 13px;
|
|
1036
|
+
text-transform: lowercase;
|
|
683
1037
|
color: var(--ink-soft);
|
|
684
|
-
background:
|
|
685
|
-
border: 1px solid var(--
|
|
686
|
-
border-radius:
|
|
687
|
-
padding:
|
|
1038
|
+
background: none;
|
|
1039
|
+
border: 1px solid var(--rule);
|
|
1040
|
+
border-radius: var(--radius-pill);
|
|
1041
|
+
padding: 0 12px;
|
|
688
1042
|
}
|
|
689
1043
|
#welcome-reopen { margin: 0; }
|
|
690
|
-
.pill-link:hover { color: var(--ink); text-decoration: none;
|
|
1044
|
+
.pill-link:hover { color: var(--ink); text-decoration: none; border-color: var(--ink-faint); }
|
|
691
1045
|
|
|
692
|
-
/* ---------- stat tiles (Home) ----------
|
|
1046
|
+
/* ---------- stat tiles (Home) ----------
|
|
1047
|
+
v3's signature: ONE glass band of figures divided by vertical hairlines, the
|
|
1048
|
+
owner's dark reference exactly, rather than four separate objects. The figure
|
|
1049
|
+
is the display face at 300 with tabular numerals — every number the ledger
|
|
1050
|
+
produced holds its column when it refreshes (DESIGN.md, The Tabular Rule). */
|
|
693
1051
|
|
|
694
1052
|
.stat-row {
|
|
695
1053
|
display: grid;
|
|
696
1054
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
697
|
-
gap:
|
|
1055
|
+
gap: 0;
|
|
1056
|
+
background: var(--glass);
|
|
1057
|
+
border: 1px solid var(--glass-edge);
|
|
1058
|
+
border-radius: var(--radius);
|
|
1059
|
+
backdrop-filter: blur(var(--glass-blur));
|
|
1060
|
+
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
1061
|
+
overflow: hidden;
|
|
698
1062
|
}
|
|
699
1063
|
.stat-tile {
|
|
700
|
-
background:
|
|
701
|
-
border:
|
|
702
|
-
border-
|
|
703
|
-
|
|
1064
|
+
background: none;
|
|
1065
|
+
border: 0;
|
|
1066
|
+
border-left: 1px solid var(--glass-edge);
|
|
1067
|
+
border-radius: 0;
|
|
1068
|
+
padding: 20px 22px;
|
|
704
1069
|
min-height: 88px;
|
|
705
1070
|
display: flex;
|
|
706
1071
|
flex-direction: column;
|
|
707
1072
|
justify-content: center;
|
|
708
|
-
gap:
|
|
1073
|
+
gap: 8px;
|
|
709
1074
|
}
|
|
1075
|
+
.stat-tile:first-child { border-left: 0; }
|
|
710
1076
|
.stat-tile__label {
|
|
711
|
-
font-
|
|
712
|
-
font-
|
|
713
|
-
letter-spacing:
|
|
714
|
-
text-transform:
|
|
1077
|
+
font-family: var(--label-face);
|
|
1078
|
+
font-size: var(--label-size);
|
|
1079
|
+
letter-spacing: var(--label-space);
|
|
1080
|
+
text-transform: var(--label-case);
|
|
715
1081
|
color: var(--ink-faint);
|
|
716
1082
|
}
|
|
717
1083
|
.stat-tile__num {
|
|
718
|
-
font-
|
|
719
|
-
font-
|
|
720
|
-
|
|
1084
|
+
font-family: var(--font-display);
|
|
1085
|
+
font-size: clamp(26px, 2.6vw, 34px);
|
|
1086
|
+
font-weight: 300;
|
|
1087
|
+
letter-spacing: -0.035em;
|
|
721
1088
|
font-variant-numeric: tabular-nums;
|
|
722
|
-
line-height: 1
|
|
1089
|
+
line-height: 1;
|
|
1090
|
+
color: var(--ink);
|
|
1091
|
+
text-shadow: var(--type-halo);
|
|
723
1092
|
}
|
|
724
|
-
.stat-tile__num--badge { font-size: 15px; }
|
|
725
|
-
.stat-tile__sub { font-size:
|
|
1093
|
+
.stat-tile__num--badge { font-size: 15px; letter-spacing: -0.02em; }
|
|
1094
|
+
.stat-tile__sub { font-size: 12.5px; color: var(--ink-faint); }
|
|
726
1095
|
|
|
727
1096
|
@media (max-width: 480px) {
|
|
728
|
-
.stat-row { grid-template-columns: 1fr 1fr;
|
|
729
|
-
.stat-tile { padding:
|
|
730
|
-
.stat-tile__num { font-size: 21px; }
|
|
1097
|
+
.stat-row { grid-template-columns: 1fr 1fr; }
|
|
1098
|
+
.stat-tile { padding: 14px 16px; min-height: 72px; gap: 6px; }
|
|
1099
|
+
.stat-tile__num { font-size: clamp(21px, 6.6vw, 28px); }
|
|
1100
|
+
/* On two columns the band still divides, but now on both axes. */
|
|
1101
|
+
.stat-tile:nth-child(odd) { border-left: 0; }
|
|
1102
|
+
.stat-tile:nth-child(n + 3) { border-top: 1px solid var(--glass-edge); }
|
|
731
1103
|
}
|
|
732
1104
|
|
|
733
1105
|
/* ---------- Standing layout: section rail + panels ---------- */
|
|
@@ -746,15 +1118,28 @@ button { font-family: var(--font-body); }
|
|
|
746
1118
|
gap: 2px;
|
|
747
1119
|
}
|
|
748
1120
|
.rail-link {
|
|
749
|
-
display:
|
|
750
|
-
|
|
1121
|
+
display: flex;
|
|
1122
|
+
align-items: center;
|
|
1123
|
+
min-height: 28px;
|
|
1124
|
+
padding: 0 10px;
|
|
751
1125
|
border-radius: var(--radius-sm);
|
|
752
1126
|
font-size: 13px;
|
|
753
|
-
|
|
1127
|
+
text-transform: lowercase;
|
|
754
1128
|
color: var(--ink-soft);
|
|
1129
|
+
position: relative;
|
|
1130
|
+
}
|
|
1131
|
+
.rail-link:hover { background: var(--glass); color: var(--ink); text-decoration: none; }
|
|
1132
|
+
/* The current section is live, so it takes the accent — the same lit-step
|
|
1133
|
+
grammar the rail’s nav items use. */
|
|
1134
|
+
.rail-link--active { background: var(--glass-strong); color: var(--ink); }
|
|
1135
|
+
.rail-link--active::before {
|
|
1136
|
+
content: "";
|
|
1137
|
+
position: absolute;
|
|
1138
|
+
left: 0; top: 6px; bottom: 6px;
|
|
1139
|
+
width: 2px;
|
|
1140
|
+
border-radius: 1px;
|
|
1141
|
+
background: var(--accent);
|
|
755
1142
|
}
|
|
756
|
-
.rail-link:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
|
|
757
|
-
.rail-link--active { background: var(--accent-weak); color: var(--accent-text); }
|
|
758
1143
|
|
|
759
1144
|
/* task 2174: a Standing rail section — the scroll-spy anchor holding one or
|
|
760
1145
|
more cards. The extra air between groups is what makes the grouping legible
|
|
@@ -772,11 +1157,11 @@ button { font-family: var(--font-body); }
|
|
|
772
1157
|
overflow-x: auto;
|
|
773
1158
|
gap: 6px;
|
|
774
1159
|
padding: 8px 0;
|
|
775
|
-
background:
|
|
776
|
-
backdrop-filter: blur(6px);
|
|
1160
|
+
background: var(--bg);
|
|
777
1161
|
}
|
|
778
|
-
.rail-link { white-space: nowrap; border: 1px solid var(--
|
|
779
|
-
.rail-link--active { border-color:
|
|
1162
|
+
.rail-link { white-space: nowrap; border: 1px solid var(--rule); background: none; border-radius: var(--radius-pill); min-height: 26px; padding: 0 12px; font-size: 12.5px; }
|
|
1163
|
+
.rail-link--active { border-color: var(--accent); background: none; }
|
|
1164
|
+
.rail-link--active::before { content: none; }
|
|
780
1165
|
}
|
|
781
1166
|
|
|
782
1167
|
/* ---------- legacy page chrome compat (pre-shell pages) ---------- */
|
|
@@ -871,28 +1256,30 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
871
1256
|
.ledger th {
|
|
872
1257
|
position: sticky;
|
|
873
1258
|
top: var(--topbar-h);
|
|
874
|
-
background: var(--
|
|
1259
|
+
background: var(--bg-card);
|
|
875
1260
|
text-align: left;
|
|
876
|
-
font-
|
|
877
|
-
font-
|
|
878
|
-
|
|
879
|
-
|
|
1261
|
+
font-family: var(--label-face);
|
|
1262
|
+
font-size: var(--label-size);
|
|
1263
|
+
font-weight: 400;
|
|
1264
|
+
letter-spacing: var(--label-space);
|
|
1265
|
+
text-transform: var(--label-case);
|
|
880
1266
|
color: var(--ink-faint);
|
|
881
|
-
padding: 8px
|
|
882
|
-
border-bottom: 1px solid var(--
|
|
1267
|
+
padding: 0 12px 8px 0;
|
|
1268
|
+
border-bottom: 1px solid var(--rule);
|
|
883
1269
|
z-index: 1;
|
|
884
1270
|
}
|
|
885
1271
|
.ledger td {
|
|
886
|
-
padding: 12px;
|
|
1272
|
+
padding: 14px 12px 14px 0;
|
|
887
1273
|
border-bottom: 1px solid var(--rule-soft);
|
|
888
1274
|
vertical-align: top;
|
|
889
1275
|
}
|
|
1276
|
+
.ledger th:last-child, .ledger td:last-child { padding-right: 0; }
|
|
890
1277
|
.ledger tr:last-child td { border-bottom: none; }
|
|
891
|
-
.ledger tbody tr:hover td { background: var(--
|
|
1278
|
+
.ledger tbody tr:hover td { background: var(--glass); }
|
|
892
1279
|
/* task 1467: a builder name that links to their profile page reads as plain
|
|
893
1280
|
text in the dense leaderboard/roster, revealing itself as a link on hover. */
|
|
894
1281
|
.lb-name { color: inherit; }
|
|
895
|
-
.lb-name:hover { color: var(--accent-
|
|
1282
|
+
.lb-name:hover { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
|
|
896
1283
|
.ledger__empty {
|
|
897
1284
|
color: var(--ink-faint);
|
|
898
1285
|
font-size: 13px;
|
|
@@ -956,16 +1343,17 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
956
1343
|
.filter {
|
|
957
1344
|
display: flex;
|
|
958
1345
|
flex-direction: column;
|
|
959
|
-
gap:
|
|
960
|
-
font-
|
|
961
|
-
font-
|
|
962
|
-
letter-spacing:
|
|
963
|
-
text-transform:
|
|
1346
|
+
gap: 4px;
|
|
1347
|
+
font-family: var(--label-face);
|
|
1348
|
+
font-size: var(--label-size);
|
|
1349
|
+
letter-spacing: var(--label-space);
|
|
1350
|
+
text-transform: var(--label-case);
|
|
964
1351
|
color: var(--ink-faint);
|
|
965
1352
|
}
|
|
966
1353
|
.filter select {
|
|
967
1354
|
min-width: 150px;
|
|
968
|
-
height: 32px;
|
|
1355
|
+
min-height: 32px;
|
|
1356
|
+
font-family: var(--font-body);
|
|
969
1357
|
padding: 4px 8px;
|
|
970
1358
|
font-size: 13.5px;
|
|
971
1359
|
text-transform: none;
|
|
@@ -976,7 +1364,8 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
976
1364
|
selects it sits alongside. */
|
|
977
1365
|
.filter input[type="search"] {
|
|
978
1366
|
min-width: 200px;
|
|
979
|
-
height: 32px;
|
|
1367
|
+
min-height: 32px;
|
|
1368
|
+
font-family: var(--font-body);
|
|
980
1369
|
padding: 4px 8px;
|
|
981
1370
|
font-size: 13.5px;
|
|
982
1371
|
text-transform: none;
|
|
@@ -999,24 +1388,51 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
999
1388
|
gap: 12px;
|
|
1000
1389
|
margin-top: 12px;
|
|
1001
1390
|
}
|
|
1002
|
-
.pager__range { font-size:
|
|
1391
|
+
.pager__range { font-family: var(--font-mono); font-size: 12px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
|
|
1003
1392
|
|
|
1393
|
+
/* Pill or nothing (DESIGN.md, Shapes). A ghost button is a hairline pill; the
|
|
1394
|
+
one filled shape on a page is the accent door, and only where the action is
|
|
1395
|
+
the live thing. 28px of box plus the row’s own air clears the 24px floor. */
|
|
1004
1396
|
.btn-ghost {
|
|
1005
1397
|
display: inline-flex;
|
|
1006
1398
|
align-items: center;
|
|
1399
|
+
justify-content: center;
|
|
1007
1400
|
gap: 6px;
|
|
1008
|
-
height: 30px;
|
|
1009
|
-
|
|
1401
|
+
min-height: 30px;
|
|
1402
|
+
min-width: 56px;
|
|
1403
|
+
padding: 0 14px;
|
|
1010
1404
|
font-size: 13px;
|
|
1011
|
-
|
|
1405
|
+
text-transform: lowercase;
|
|
1012
1406
|
color: var(--ink-soft);
|
|
1013
|
-
background:
|
|
1014
|
-
border: 1px solid var(--
|
|
1015
|
-
border-radius: var(--radius-
|
|
1407
|
+
background: none;
|
|
1408
|
+
border: 1px solid var(--rule);
|
|
1409
|
+
border-radius: var(--radius-pill);
|
|
1410
|
+
cursor: pointer;
|
|
1411
|
+
}
|
|
1412
|
+
.btn-ghost:hover:not(:disabled) { border-color: var(--ink-faint); color: var(--ink); text-decoration: none; }
|
|
1413
|
+
.btn-ghost:disabled { color: var(--ink-faint); border-color: var(--rule-soft); cursor: default; }
|
|
1414
|
+
|
|
1415
|
+
/* The accent door: the page’s one primary action. --accent-on is the dark ink
|
|
1416
|
+
that goes on the salmon; white on it fails AA and is banned. */
|
|
1417
|
+
.btn-accent {
|
|
1418
|
+
display: inline-flex;
|
|
1419
|
+
align-items: center;
|
|
1420
|
+
justify-content: center;
|
|
1421
|
+
gap: 6px;
|
|
1422
|
+
min-height: 34px;
|
|
1423
|
+
min-width: 74px;
|
|
1424
|
+
padding: 0 16px;
|
|
1425
|
+
font-size: 13.5px;
|
|
1426
|
+
font-weight: 500;
|
|
1427
|
+
text-transform: lowercase;
|
|
1428
|
+
color: var(--accent-on);
|
|
1429
|
+
background: var(--accent);
|
|
1430
|
+
border: 0;
|
|
1431
|
+
border-radius: var(--radius-pill);
|
|
1016
1432
|
cursor: pointer;
|
|
1017
1433
|
}
|
|
1018
|
-
.btn-
|
|
1019
|
-
.btn-
|
|
1434
|
+
.btn-accent:hover:not(:disabled) { background: var(--accent-lift); color: var(--accent-on); text-decoration: none; }
|
|
1435
|
+
.btn-accent:disabled { background: var(--surface-2); color: var(--ink-faint); cursor: default; }
|
|
1020
1436
|
|
|
1021
1437
|
/* ---------- profile / standing ---------- */
|
|
1022
1438
|
|
|
@@ -1139,7 +1555,7 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1139
1555
|
.conn-reqs { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
|
|
1140
1556
|
.conn-req {
|
|
1141
1557
|
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
|
|
1142
|
-
padding: 8px 10px; border: 1px solid var(--border); border-radius:
|
|
1558
|
+
padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2);
|
|
1143
1559
|
}
|
|
1144
1560
|
.conn-req__note { flex: 1 1 100%; margin: 0; font-size: 13px; color: var(--ink-soft); }
|
|
1145
1561
|
.conn-req__state { font-size: 13px; color: var(--ink-faint); }
|
|
@@ -1429,20 +1845,29 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1429
1845
|
|
|
1430
1846
|
.setup { margin-top: 12px; }
|
|
1431
1847
|
.setup__intro { font-size: 13px; color: var(--ink-soft); }
|
|
1432
|
-
.setup__toggle { display:
|
|
1848
|
+
.setup__toggle { display: flex; border: 0; border-bottom: 1px solid var(--rule); margin: 8px 0 12px; flex-wrap: wrap; }
|
|
1849
|
+
/* An open tab is the live thing in the strip, so it is what the accent lights:
|
|
1850
|
+
a 2px underline sitting on the strip’s own hairline. */
|
|
1433
1851
|
.setup__tab {
|
|
1434
|
-
|
|
1435
|
-
|
|
1852
|
+
display: inline-flex;
|
|
1853
|
+
align-items: baseline;
|
|
1854
|
+
gap: 8px;
|
|
1855
|
+
min-height: 38px;
|
|
1856
|
+
border: 0;
|
|
1857
|
+
border-bottom: 2px solid transparent;
|
|
1858
|
+
margin-bottom: -1px;
|
|
1859
|
+
background: none;
|
|
1436
1860
|
color: var(--ink-soft);
|
|
1437
|
-
font-size:
|
|
1438
|
-
|
|
1439
|
-
padding:
|
|
1861
|
+
font-size: 14px;
|
|
1862
|
+
text-transform: lowercase;
|
|
1863
|
+
padding: 0 16px;
|
|
1440
1864
|
cursor: pointer;
|
|
1441
1865
|
}
|
|
1442
|
-
.setup__tab
|
|
1443
|
-
.setup__tab
|
|
1444
|
-
.setup__tab-
|
|
1445
|
-
.setup__tab-tag
|
|
1866
|
+
.setup__tab:first-child { padding-left: 0; }
|
|
1867
|
+
.setup__tab:hover { color: var(--ink); }
|
|
1868
|
+
.setup__tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--accent); }
|
|
1869
|
+
.setup__tab-tag { font-family: var(--label-face); font-size: 10.5px; letter-spacing: var(--label-space); text-transform: var(--label-case); margin-left: 6px; color: var(--ink-faint); }
|
|
1870
|
+
.setup__tab-tag--rec { color: var(--ok); }
|
|
1446
1871
|
.setup__pane { display: none; }
|
|
1447
1872
|
.setup[data-config="desktop"] .setup__pane--desktop { display: block; }
|
|
1448
1873
|
.setup[data-config="online"] .setup__pane--online { display: block; }
|
|
@@ -1537,40 +1962,50 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1537
1962
|
|
|
1538
1963
|
/* ---------- landing (signed-out) ---------- */
|
|
1539
1964
|
|
|
1540
|
-
.landing { max-width:
|
|
1965
|
+
.landing { max-width: var(--measure); }
|
|
1541
1966
|
.landing__lede { font-size: 14px; color: var(--ink-soft); }
|
|
1967
|
+
/* A link inside landing prose is still a control: 3px of vertical padding is
|
|
1968
|
+
what clears the 24px floor in a line that has no rhythm of its own
|
|
1969
|
+
(DESIGN.md §The footer applies the same rule to its links). */
|
|
1970
|
+
.landing p a:not(.landing__btn) {
|
|
1971
|
+
display: inline-block;
|
|
1972
|
+
padding: 3px 0;
|
|
1973
|
+
min-height: 24px;
|
|
1974
|
+
line-height: 18px;
|
|
1975
|
+
}
|
|
1542
1976
|
.landing__cta { margin: 14px 0; }
|
|
1543
1977
|
.landing__btn {
|
|
1544
1978
|
display: inline-flex;
|
|
1545
1979
|
align-items: center;
|
|
1546
1980
|
justify-content: center;
|
|
1547
|
-
height:
|
|
1548
|
-
padding: 0
|
|
1549
|
-
border-radius: var(--radius-
|
|
1550
|
-
border:
|
|
1981
|
+
min-height: 46px;
|
|
1982
|
+
padding: 0 22px;
|
|
1983
|
+
border-radius: var(--radius-pill);
|
|
1984
|
+
border: 0;
|
|
1551
1985
|
background: var(--accent);
|
|
1552
|
-
color:
|
|
1553
|
-
font-size:
|
|
1554
|
-
font-weight:
|
|
1986
|
+
color: var(--accent-on);
|
|
1987
|
+
font-size: 14px;
|
|
1988
|
+
font-weight: 500;
|
|
1989
|
+
text-transform: lowercase;
|
|
1555
1990
|
cursor: pointer;
|
|
1556
1991
|
}
|
|
1557
|
-
.landing__btn:hover { background: var(--accent-
|
|
1992
|
+
.landing__btn:hover { background: var(--accent-lift); text-decoration: none; color: var(--accent-on); }
|
|
1558
1993
|
.landing__note { font-size: 12.5px; color: var(--ink-faint); }
|
|
1559
1994
|
.landing__error { color: var(--danger); }
|
|
1560
1995
|
.landing__error-h { color: var(--danger); margin: 0 0 4px; font-size: 14px; }
|
|
1561
1996
|
.landing__request {
|
|
1562
|
-
border:
|
|
1997
|
+
border: 0;
|
|
1563
1998
|
border-radius: var(--radius);
|
|
1564
1999
|
background: var(--surface-2);
|
|
1565
|
-
padding:
|
|
2000
|
+
padding: 18px 20px;
|
|
1566
2001
|
margin: 16px 0;
|
|
1567
2002
|
}
|
|
1568
|
-
.landing__request-h { margin: 0 0
|
|
2003
|
+
.landing__request-h { margin: 0 0 6px; font-family: var(--font-display); font-size: 18px; font-weight: 300; letter-spacing: -0.025em; }
|
|
1569
2004
|
.landing__request-lede { margin: 0 0 12px; font-size: 13px; color: var(--ink-soft); }
|
|
1570
2005
|
.landing__request-lede--soft { color: var(--ink-faint); }
|
|
1571
2006
|
.landing__form { display: flex; flex-direction: column; gap: 10px; }
|
|
1572
|
-
.landing__field { display: flex; flex-direction: column; gap:
|
|
1573
|
-
.landing__field input {
|
|
2007
|
+
.landing__field { display: flex; flex-direction: column; gap: 4px; font-family: var(--label-face); font-size: var(--label-size); letter-spacing: var(--label-space); text-transform: var(--label-case); color: var(--ink-faint); }
|
|
2008
|
+
.landing__field input { font-family: var(--font-body); font-size: 14px; text-transform: none; letter-spacing: normal; }
|
|
1574
2009
|
.landing__req-mark { color: var(--danger); }
|
|
1575
2010
|
.landing__opt { color: var(--ink-faint); font-weight: 400; }
|
|
1576
2011
|
.landing__form-hint { font-size: 12.5px; color: var(--ink-faint); margin: 0; }
|
|
@@ -1748,10 +2183,10 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1748
2183
|
transform: translate(-50%, 12px);
|
|
1749
2184
|
z-index: 100;
|
|
1750
2185
|
background: var(--ink);
|
|
1751
|
-
color: var(--bg
|
|
2186
|
+
color: var(--bg);
|
|
1752
2187
|
font-size: 13.5px;
|
|
1753
|
-
padding:
|
|
1754
|
-
border-radius: var(--radius);
|
|
2188
|
+
padding: 11px 20px;
|
|
2189
|
+
border-radius: var(--radius-pill);
|
|
1755
2190
|
box-shadow: var(--shadow-pop);
|
|
1756
2191
|
opacity: 0;
|
|
1757
2192
|
visibility: hidden;
|
|
@@ -1782,7 +2217,7 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1782
2217
|
position: fixed;
|
|
1783
2218
|
inset: 0;
|
|
1784
2219
|
z-index: 2000;
|
|
1785
|
-
background:
|
|
2220
|
+
background: rgba(0, 0, 0, .55);
|
|
1786
2221
|
display: flex;
|
|
1787
2222
|
align-items: center;
|
|
1788
2223
|
justify-content: center;
|
|
@@ -1790,8 +2225,8 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1790
2225
|
}
|
|
1791
2226
|
.deeplink-card__panel {
|
|
1792
2227
|
position: relative;
|
|
1793
|
-
background: var(--
|
|
1794
|
-
border: 1px solid var(--
|
|
2228
|
+
background: var(--bg-card);
|
|
2229
|
+
border: 1px solid var(--rule);
|
|
1795
2230
|
border-radius: var(--radius);
|
|
1796
2231
|
box-shadow: var(--shadow-pop);
|
|
1797
2232
|
max-width: 560px;
|
|
@@ -1804,15 +2239,15 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1804
2239
|
position: absolute;
|
|
1805
2240
|
top: 10px; right: 10px;
|
|
1806
2241
|
width: 28px; height: 28px;
|
|
1807
|
-
border: 1px solid var(--
|
|
1808
|
-
border-radius: var(--radius-
|
|
1809
|
-
background:
|
|
2242
|
+
border: 1px solid var(--rule);
|
|
2243
|
+
border-radius: var(--radius-pill);
|
|
2244
|
+
background: none;
|
|
1810
2245
|
color: var(--ink-soft);
|
|
1811
2246
|
font-size: 16px;
|
|
1812
2247
|
line-height: 1;
|
|
1813
2248
|
cursor: pointer;
|
|
1814
2249
|
}
|
|
1815
|
-
.deeplink-card__close:hover {
|
|
2250
|
+
.deeplink-card__close:hover { border-color: var(--ink-faint); color: var(--ink); }
|
|
1816
2251
|
.deeplink-card__kind {
|
|
1817
2252
|
font-size: 11px;
|
|
1818
2253
|
font-weight: 600;
|
|
@@ -1821,7 +2256,7 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1821
2256
|
color: var(--ink-faint);
|
|
1822
2257
|
margin: 0 0 4px;
|
|
1823
2258
|
}
|
|
1824
|
-
.deeplink-card__title { font-size:
|
|
2259
|
+
.deeplink-card__title { font-family: var(--font-display); font-size: 21px; font-weight: 300; letter-spacing: -0.03em; margin: 0 0 8px; }
|
|
1825
2260
|
.deeplink-card__meta { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12.5px; color: var(--ink-soft); margin: 0 0 10px; }
|
|
1826
2261
|
.deeplink-card__summary { font-size: 13.5px; margin: 0 0 10px; }
|
|
1827
2262
|
.deeplink-card__note { font-size: 12.5px; color: var(--ink-faint); margin: 0; }
|
|
@@ -1995,40 +2430,47 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
1995
2430
|
/* filter-bar disclosure ("Filters" button) + removable active-filter chips */
|
|
1996
2431
|
.filters__more-count { margin-left: 6px; }
|
|
1997
2432
|
.filters--overflow {
|
|
1998
|
-
padding:
|
|
1999
|
-
border:
|
|
2433
|
+
padding: 12px 14px;
|
|
2434
|
+
border: 0;
|
|
2000
2435
|
border-radius: var(--radius-sm);
|
|
2001
2436
|
background: var(--surface-2);
|
|
2002
2437
|
margin-bottom: 14px;
|
|
2003
2438
|
}
|
|
2004
2439
|
.filter-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
|
|
2440
|
+
/* An active filter IS live, so the chip is the one place in a filter bar the
|
|
2441
|
+
accent belongs. */
|
|
2005
2442
|
.chip {
|
|
2006
|
-
display: inline-flex; align-items: center; gap: 6px;
|
|
2007
|
-
|
|
2443
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
2444
|
+
min-height: 26px;
|
|
2445
|
+
padding: 0 12px;
|
|
2008
2446
|
font-size: 12.5px;
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
border
|
|
2447
|
+
text-transform: lowercase;
|
|
2448
|
+
color: var(--accent-ink);
|
|
2449
|
+
background: var(--accent-tint);
|
|
2450
|
+
border: 0;
|
|
2451
|
+
border-radius: var(--radius-pill);
|
|
2013
2452
|
cursor: pointer;
|
|
2014
2453
|
}
|
|
2015
|
-
.chip:hover {
|
|
2454
|
+
.chip:hover { color: var(--ink); }
|
|
2016
2455
|
|
|
2017
2456
|
/* tab strip — the .setup__tab idiom in the .setup__toggle frame, promoted */
|
|
2457
|
+
/* A tab strip is hairlines, not a segmented box: one rule under the row and a
|
|
2458
|
+
2px accent underline on the open tab, the lit-step grammar again. */
|
|
2018
2459
|
.kit-tabs {
|
|
2019
|
-
display:
|
|
2460
|
+
display: flex;
|
|
2020
2461
|
max-width: 100%;
|
|
2021
2462
|
overflow-x: auto;
|
|
2022
|
-
border:
|
|
2023
|
-
border-
|
|
2463
|
+
border: 0;
|
|
2464
|
+
border-bottom: 1px solid var(--rule);
|
|
2465
|
+
border-radius: 0;
|
|
2024
2466
|
margin: 0 0 14px;
|
|
2025
2467
|
}
|
|
2026
2468
|
.kit-tabs .setup__tab { white-space: nowrap; }
|
|
2027
2469
|
.kit-tabs .setup__tab .count-pill { margin-left: 6px; }
|
|
2028
2470
|
|
|
2029
2471
|
/* empty state — one short line + at most one action link */
|
|
2030
|
-
.empty-state { padding:
|
|
2031
|
-
.empty-state p { margin: 0; font-size:
|
|
2472
|
+
.empty-state { padding: 8px 0; }
|
|
2473
|
+
.empty-state p { margin: 0; font-size: 13.5px; color: var(--ink-soft); }
|
|
2032
2474
|
.empty-state__action { display: inline-block; margin-top: 6px; font-size: 13px; }
|
|
2033
2475
|
|
|
2034
2476
|
/* skeleton shimmer — standard-height placeholder rows while data loads, so
|
|
@@ -2038,22 +2480,10 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
2038
2480
|
width: 60%;
|
|
2039
2481
|
min-width: 80px;
|
|
2040
2482
|
height: 12px;
|
|
2041
|
-
border-radius:
|
|
2042
|
-
background:
|
|
2043
|
-
color-mix(in srgb, var(--ink) 7%, var(--bg-card)) 25%,
|
|
2044
|
-
color-mix(in srgb, var(--ink) 13%, var(--bg-card)) 45%,
|
|
2045
|
-
color-mix(in srgb, var(--ink) 7%, var(--bg-card)) 65%);
|
|
2046
|
-
background-size: 200% 100%;
|
|
2047
|
-
animation: kit-skel-shimmer 1.2s ease-in-out infinite;
|
|
2483
|
+
border-radius: 2px;
|
|
2484
|
+
background: var(--skeleton);
|
|
2048
2485
|
}
|
|
2049
2486
|
.kit-skel-row td { border-bottom: 1px solid var(--rule-soft); }
|
|
2050
|
-
@keyframes kit-skel-shimmer {
|
|
2051
|
-
from { background-position: 120% 0; }
|
|
2052
|
-
to { background-position: -80% 0; }
|
|
2053
|
-
}
|
|
2054
|
-
@media (prefers-reduced-motion: reduce) {
|
|
2055
|
-
.kit-skel { animation: none; }
|
|
2056
|
-
}
|
|
2057
2487
|
|
|
2058
2488
|
/* collapsible card body — the Work-backlog <details> idiom, generalized */
|
|
2059
2489
|
.kit-collapse__summary {
|
|
@@ -2068,11 +2498,8 @@ main [id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }
|
|
|
2068
2498
|
/* ---- Home dashboard (task 2169) ---- */
|
|
2069
2499
|
/* Stat tiles are links now — inherit ink, reveal affordance on hover. */
|
|
2070
2500
|
a.stat-tile { color: inherit; }
|
|
2071
|
-
a.stat-tile:hover {
|
|
2072
|
-
|
|
2073
|
-
border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
|
|
2074
|
-
background: color-mix(in srgb, var(--accent) 3%, var(--surface));
|
|
2075
|
-
}
|
|
2501
|
+
a.stat-tile:hover { text-decoration: none; background: var(--glass); }
|
|
2502
|
+
a.stat-tile:hover .stat-tile__sub { color: var(--ink-soft); }
|
|
2076
2503
|
/* The over-budget "More" row — one quiet line, not a card. */
|
|
2077
2504
|
.home-more { margin: 0; font-size: 13px; color: var(--ink-soft); }
|
|
2078
2505
|
|
|
@@ -2096,14 +2523,13 @@ a.stat-tile:hover {
|
|
|
2096
2523
|
display: flex;
|
|
2097
2524
|
flex-direction: column;
|
|
2098
2525
|
gap: 2px;
|
|
2099
|
-
padding:
|
|
2100
|
-
border:
|
|
2101
|
-
border-left: 3px solid color-mix(in srgb, var(--accent) 55%, var(--border));
|
|
2526
|
+
padding: 10px 14px;
|
|
2527
|
+
border: 0;
|
|
2102
2528
|
border-radius: var(--radius-sm);
|
|
2103
2529
|
background: var(--surface-2);
|
|
2104
2530
|
}
|
|
2105
|
-
.next-up__title { font-weight:
|
|
2106
|
-
.next-up__title:hover { color: var(--accent-
|
|
2531
|
+
.next-up__title { font-weight: 500; font-size: 13.5px; color: var(--ink); }
|
|
2532
|
+
.next-up__title:hover { color: var(--accent-ink); }
|
|
2107
2533
|
.next-up__meta { font-size: 12px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
|
|
2108
2534
|
.next-up__foot { margin: 0 0 14px; font-size: 13px; }
|
|
2109
2535
|
|