daily-focus 2.0.0-dev.14 → 2.0.0-dev.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/public/style.css CHANGED
@@ -1,18 +1,75 @@
1
1
  /*
2
- * Tokens come from the validated reference palette: the eight categorical hues
3
- * carry source identity, the four status colours are reserved for state only.
4
- * Both modes are selected, not flipped — dark has its own steps.
2
+ * The page is a day-book: one page for one day. The date is its masthead, the
3
+ * objective its headline, the agenda a ruled timeline in the margin. Prose —
4
+ * the objective, the agent's headline, a court's hint — is written straight on
5
+ * the paper. Anything tabular — a list of rows, the day's numbers, the
6
+ * timeline, a settings group — sits on a white sheet with an edge, and the
7
+ * rows on a sheet are ruled apart. That edge is what tells one block from the
8
+ * next; the first cut of this design ruled everything on the paper alone, and
9
+ * where a row ended was anyone's guess.
10
+ *
11
+ * Two faces, each with a job. The words the brief is made of — the date, the
12
+ * objective, the agent's headline, its reports and the assistant's answers,
13
+ * setup's questions — are set in Plex Serif, the face for reading. Everything
14
+ * operational — rows, meta, pills, controls, times — is Plex Sans. Both are
15
+ * served from `fonts/`, since this dashboard is private and may be offline, and
16
+ * nothing it shows should fetch from a third party on every open.
17
+ *
18
+ * The masthead is a band of navy across the top of every page: the date, the
19
+ * readout and the tabs, and on Today the objective, the day's numbers and the
20
+ * agent's note too, since those are the morning's masthead as much as the date
21
+ * is. Amber is the one accent, for what can be pressed: the selected tab, the
22
+ * primary button, the pressed gear, the rank of a row. The eight source hues
23
+ * carry source identity and the four status colours are reserved for state, so
24
+ * a coloured thing on the paper is a fact about the content or a thing to press.
25
+ * A blue accent used to compete with GitHub's blue for the same job.
26
+ *
27
+ * Both modes are selected, not flipped — dark has its own steps. Each token
28
+ * names both and `light-dark()` picks one, so the dark palette lives here and
29
+ * nowhere else; a second hand-kept copy inside a `prefers-color-scheme` block
30
+ * used to drift from this one with nothing to notice.
5
31
  *
6
32
  * Source colour is never the only cue: every dot sits beside its source name in
7
33
  * text, which is what lets the lighter light-mode hues (aqua, yellow, magenta)
8
34
  * sit below 3:1 contrast without losing meaning.
9
- *
10
- * Each token names both its steps and `light-dark()` picks one, so the dark
11
- * palette lives here and nowhere else. It used to be a second, hand-kept copy of
12
- * this list inside a `prefers-color-scheme` block — twenty-two values one edit
13
- * away from disagreeing with the ones above them, with nothing to notice.
14
35
  */
15
36
 
37
+ @font-face {
38
+ font-family: 'Plex Sans';
39
+ src: url('/fonts/IBMPlexSans-Variable.woff2') format('woff2');
40
+ font-weight: 100 700;
41
+ font-style: normal;
42
+ font-display: swap;
43
+ }
44
+ @font-face {
45
+ font-family: 'Plex Serif';
46
+ src: url('/fonts/IBMPlexSerif-Regular.woff2') format('woff2');
47
+ font-weight: 400;
48
+ font-style: normal;
49
+ font-display: swap;
50
+ }
51
+ @font-face {
52
+ font-family: 'Plex Serif';
53
+ src: url('/fonts/IBMPlexSerif-Medium.woff2') format('woff2');
54
+ font-weight: 500;
55
+ font-style: normal;
56
+ font-display: swap;
57
+ }
58
+ @font-face {
59
+ font-family: 'Plex Serif';
60
+ src: url('/fonts/IBMPlexSerif-SemiBold.woff2') format('woff2');
61
+ font-weight: 600;
62
+ font-style: normal;
63
+ font-display: swap;
64
+ }
65
+ @font-face {
66
+ font-family: 'Plex Serif';
67
+ src: url('/fonts/IBMPlexSerif-Italic.woff2') format('woff2');
68
+ font-weight: 400;
69
+ font-style: italic;
70
+ font-display: swap;
71
+ }
72
+
16
73
  :root {
17
74
  /*
18
75
  * Both keywords, which is the state the toggle calls "system": `light-dark()`
@@ -21,22 +78,41 @@
21
78
  */
22
79
  color-scheme: light dark;
23
80
 
24
- --page: light-dark(#f9f9f7, #0d0d0d);
25
- --surface: light-dark(#fcfcfb, #1a1a19);
26
- --surface-sunken: light-dark(#f2f1ed, #131312);
27
- --ink-1: light-dark(#0b0b0b, #ffffff);
28
- --ink-2: light-dark(#52514e, #c3c2b7);
29
- --ink-3: #898781; /* Shared deliberately: the muted step clears both pages. */
30
- --hairline: light-dark(#e1e0d9, #2c2c2a);
31
- --border: light-dark(rgba(11, 11, 11, 0.1), rgba(255, 255, 255, 0.1));
81
+ --page: light-dark(#f2f1ec, #0f1012);
82
+ --surface: light-dark(#ffffff, #1e2025);
83
+ --surface-sunken: light-dark(#eceae4, #2a2c32);
84
+ --ink-1: light-dark(#1b1f2a, #e9ebef);
85
+ --ink-2: light-dark(#4d5362, #aeb4c0);
86
+ --ink-3: light-dark(#6e7484, #868c9a);
87
+ /* A rule between rows on a sheet, and a rule on the paper: the paper's is darker, to show at all. */
88
+ --rule: light-dark(#e6e5df, #2e3037);
89
+ --hairline: light-dark(#d7d6ce, #33353c);
90
+ --border: light-dark(rgba(27, 31, 42, 0.2), rgba(233, 235, 239, 0.16));
91
+
92
+ /*
93
+ * The band. Navy in both modes: in light it is the dark thing on a light
94
+ * page, in dark the blue thing on a near-black one, so hue carries it where
95
+ * lightness can't. Its own steps for text and rules, since nothing on it is
96
+ * the paper's ink.
97
+ */
98
+ --band: light-dark(#1c2541, #1a2140);
99
+ --band-ink: #ffffff;
100
+ --band-muted: light-dark(#a9b3cc, #9aa4c3);
101
+ --band-rule: rgba(255, 255, 255, 0.18);
102
+ --band-sheet: rgba(255, 255, 255, 0.07);
103
+ --band-critical: #ffb3b3;
104
+ --band-good: #7ee2a8;
32
105
  /*
33
106
  * Dark wants no shadow at all. Written as transparent steps rather than as a
34
107
  * `none` somewhere else, because anywhere else means a selector that knows
35
108
  * which mode it is in — and that is the duplicate copy coming back for one
36
109
  * property.
37
110
  */
38
- --shadow: 0 1px 2px light-dark(rgba(11, 11, 11, 0.05), transparent),
39
- 0 4px 16px light-dark(rgba(11, 11, 11, 0.04), transparent);
111
+ --shadow: 0 1px 2px light-dark(rgba(27, 31, 42, 0.05), transparent),
112
+ 0 6px 20px light-dark(rgba(27, 31, 42, 0.06), transparent);
113
+ /* The panel and the menus float, so they cast more. */
114
+ --shadow-float: 0 1px 2px light-dark(rgba(27, 31, 42, 0.06), transparent),
115
+ 0 14px 40px light-dark(rgba(27, 31, 42, 0.14), rgba(0, 0, 0, 0.5));
40
116
 
41
117
  --good: #0ca30c;
42
118
  --warning: #fab219;
@@ -55,15 +131,24 @@
55
131
  --src-reminders: light-dark(#8a5a2b, #c89058);
56
132
  --src-messages: light-dark(#9b3fc0, #c07ae8);
57
133
  --src-eboks: light-dark(#c42b3a, #e5535f);
58
- --src-other: #898781;
134
+ --src-other: #7d8392;
59
135
 
60
- --accent: light-dark(#2a78d6, #3987e5);
61
- --accent-wash: light-dark(#e8f1fd, #14263a);
62
- --focus-ring: light-dark(#2a78d6, #3987e5);
136
+ /*
137
+ * Amber, for what can be pressed. As a fill it carries dark text; as text on
138
+ * the paper it is darkened until it clears the page, which `--accent-ink` is.
139
+ */
140
+ --accent: #e0962a;
141
+ --accent-ink: light-dark(#a86a14, #e8a743);
142
+ --on-accent: #1b1f2a;
143
+ --accent-wash: light-dark(#fbefd9, #3a3220);
144
+ --focus-ring: var(--ink-1);
63
145
 
64
146
  --radius: 10px;
65
147
  --radius-sm: 6px;
66
- --font: system-ui, -apple-system, 'Segoe UI', sans-serif;
148
+ --page-width: 1180px;
149
+ --font: 'Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
150
+ --font-serif: 'Plex Serif', 'Iowan Old Style', Georgia, serif;
151
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
67
152
  }
68
153
 
69
154
  /*
@@ -86,22 +171,23 @@
86
171
 
87
172
  /*
88
173
  * The UA stylesheet's `[hidden] { display: none }` loses to any class that sets
89
- * display, so `.toast` rendered as an empty box
90
- * while "hidden". Assert it once here rather than remembering per component.
174
+ * display, so `.toast` rendered as an empty box while "hidden". Assert it once
175
+ * here rather than remembering per component.
91
176
  */
92
177
  [hidden] {
93
178
  display: none !important;
94
179
  }
95
180
 
96
181
  body {
182
+ --gutter: clamp(16px, 4vw, 48px);
97
183
  margin: 0;
98
- padding: 0 clamp(16px, 4vw, 40px) 64px;
99
184
  background: var(--page);
100
185
  color: var(--ink-1);
101
186
  font-family: var(--font);
102
- font-size: 15px;
187
+ font-size: 14.5px;
103
188
  line-height: 1.5;
104
189
  -webkit-font-smoothing: antialiased;
190
+ text-rendering: optimizeLegibility;
105
191
  }
106
192
 
107
193
  :focus-visible {
@@ -110,10 +196,15 @@ body {
110
196
  border-radius: 3px;
111
197
  }
112
198
 
199
+ /* Links are ink, told apart by the underline alone; it darkens under the pointer. */
113
200
  a {
114
- color: var(--accent);
201
+ color: var(--ink-1);
202
+ text-decoration-color: var(--ink-3);
115
203
  text-underline-offset: 2px;
116
204
  }
205
+ a:hover {
206
+ text-decoration-color: currentColor;
207
+ }
117
208
 
118
209
  .skip-link {
119
210
  position: absolute;
@@ -129,50 +220,104 @@ a {
129
220
  border-radius: var(--radius-sm);
130
221
  }
131
222
 
223
+ /*
224
+ * The page's margins are the root's padding, not the body's, so that the root
225
+ * spans the viewport: the band paints a viewport past each edge of the page,
226
+ * and the root clips it at the viewport's. Not on `body`, whose overflow would
227
+ * be handed to the viewport and clip nothing itself; and `clip` rather than
228
+ * `hidden`, which would make this a scroll container and unstick the agenda.
229
+ */
230
+ #app {
231
+ padding: 0 var(--gutter) 72px;
232
+ overflow-x: clip;
233
+ }
234
+
235
+ /* ---------- the band ---------- */
236
+
237
+ /*
238
+ * The band behind the masthead, painted by a pseudo-element that runs a
239
+ * viewport past each edge, since the page's own margins keep the content in.
240
+ * Behind the content at `z-index: -1`, which in the root stacking context is
241
+ * above the page colour and below everything in flow — so a sheet that sits on
242
+ * it, like the agenda's, is simply drawn on top. On Today the morning's
243
+ * masthead paints its own band all the way up to the top of the page, so the
244
+ * banners between the tabs and the objective sit on navy however many there
245
+ * are, and there is no seam for them to fall through.
246
+ */
247
+ .band {
248
+ position: relative;
249
+ color: var(--band-ink);
250
+ }
251
+ .band::before,
252
+ .today__masthead::before {
253
+ content: '';
254
+ position: absolute;
255
+ top: 0;
256
+ bottom: 0;
257
+ left: -100vw;
258
+ right: -100vw;
259
+ background: var(--band);
260
+ z-index: -1;
261
+ }
262
+ .band :focus-visible,
263
+ .today__masthead :focus-visible {
264
+ outline-color: var(--band-ink);
265
+ }
266
+
132
267
  /* ---------- header ---------- */
133
268
 
269
+ /*
270
+ * The masthead. The date is the biggest thing on the page, because the day is
271
+ * the subject; the name above it is a small wordmark, since whoever is reading
272
+ * already knows which tab this is.
273
+ */
134
274
  .page-header {
135
275
  display: flex;
136
276
  align-items: flex-end;
137
277
  justify-content: space-between;
138
278
  gap: 16px;
139
279
  flex-wrap: wrap;
140
- max-width: 1280px;
280
+ max-width: var(--page-width);
141
281
  margin: 0 auto;
142
- padding: 28px 0 20px;
282
+ padding: 30px 0 18px;
143
283
  }
144
284
 
145
285
  .page-header h1 {
146
286
  margin: 0;
147
- font-size: 22px;
287
+ font-size: 13px;
148
288
  font-weight: 600;
149
- letter-spacing: -0.01em;
289
+ color: var(--band-muted);
150
290
  }
151
291
 
152
292
  .page-header__date {
153
293
  margin: 2px 0 0;
154
- color: var(--ink-2);
155
- font-size: 14px;
294
+ font-family: var(--font-serif);
295
+ font-size: 32px;
296
+ font-weight: 400;
297
+ line-height: 1.1;
298
+ letter-spacing: -0.01em;
299
+ color: var(--band-ink);
156
300
  }
157
301
 
158
302
  .page-header__meta {
159
303
  display: flex;
160
304
  align-items: center;
161
305
  gap: 8px;
306
+ padding-bottom: 4px;
162
307
  }
163
308
 
164
309
  .page-header__zone {
165
- margin: 3px 0 0;
166
- color: var(--ink-2);
167
- font-size: 12px;
310
+ margin: 8px 0 0;
311
+ color: var(--band-muted);
312
+ font-size: 12.5px;
168
313
  }
169
314
 
170
315
  .freshness {
171
- color: var(--ink-3);
316
+ color: var(--band-muted);
172
317
  font-size: 13px;
173
318
  }
174
319
  .freshness[data-stale='true'] {
175
- color: var(--critical);
320
+ color: var(--band-critical);
176
321
  font-weight: 500;
177
322
  }
178
323
  /*
@@ -189,7 +334,7 @@ a {
189
334
  }
190
335
  .freshness__link:hover {
191
336
  text-decoration: underline;
192
- text-decoration-color: var(--accent);
337
+ text-underline-offset: 2px;
193
338
  }
194
339
 
195
340
  .icon-button {
@@ -199,7 +344,7 @@ a {
199
344
  place-items: center;
200
345
  border: 1px solid var(--border);
201
346
  border-radius: var(--radius-sm);
202
- background: var(--surface);
347
+ background: transparent;
203
348
  color: var(--ink-2);
204
349
  font-size: 14px;
205
350
  cursor: pointer;
@@ -207,16 +352,28 @@ a {
207
352
  .icon-button:hover {
208
353
  color: var(--ink-1);
209
354
  border-color: var(--ink-3);
355
+ background: var(--surface-sunken);
356
+ }
357
+ /* On the band, drawn in its light. */
358
+ .band .icon-button {
359
+ border-color: rgba(255, 255, 255, 0.28);
360
+ color: #e5e7eb;
361
+ }
362
+ .band .icon-button:hover {
363
+ color: var(--band-ink);
364
+ border-color: rgba(255, 255, 255, 0.5);
365
+ background: rgba(255, 255, 255, 0.1);
210
366
  }
211
367
  .icon-button__icon {
212
368
  width: 15px;
213
369
  height: 15px;
214
370
  }
215
- /* A toggle that is on, such as the gear while Settings is open: drawn as the selected tab is, in the accent. */
216
- .icon-button[aria-pressed='true'] {
217
- color: var(--accent);
371
+ /* A toggle that is on, such as the gear while Settings is open: filled in amber, as the selected tab is underlined in it. */
372
+ .icon-button[aria-pressed='true'],
373
+ .band .icon-button[aria-pressed='true'] {
374
+ color: var(--on-accent);
218
375
  border-color: var(--accent);
219
- background: var(--accent-wash);
376
+ background: var(--accent);
220
377
  }
221
378
 
222
379
  /*
@@ -231,10 +388,10 @@ a {
231
388
  gap: 6px;
232
389
  height: 30px;
233
390
  padding: 0 10px;
234
- border: 1px solid var(--border);
391
+ border: 1px solid rgba(255, 255, 255, 0.28);
235
392
  border-radius: 999px;
236
- background: var(--surface);
237
- color: var(--ink-2);
393
+ background: rgba(255, 255, 255, 0.1);
394
+ color: var(--band-ink);
238
395
  font-size: 13px;
239
396
  white-space: nowrap;
240
397
  cursor: help;
@@ -306,12 +463,12 @@ body[data-view='tickets'] #brief-refresh {
306
463
  }
307
464
  /* Reads as the Today tab's "updated … ago" does, so the three tabs match. */
308
465
  .refresh-label {
309
- color: var(--ink-3);
466
+ color: var(--band-muted);
310
467
  font-size: 13px;
311
468
  font-variant-numeric: tabular-nums;
312
469
  }
313
470
  .refresh-label[data-stale='true'] {
314
- color: var(--critical);
471
+ color: var(--band-critical);
315
472
  font-weight: 500;
316
473
  }
317
474
  /*
@@ -334,9 +491,10 @@ body[data-view='tickets'] #brief-refresh {
334
491
  .refresh-button[data-fetching='true'] .refresh-button__icon {
335
492
  animation: refresh-spin 0.9s linear infinite;
336
493
  }
337
- .refresh-button[data-stale='true'] {
338
- color: var(--critical);
339
- border-color: var(--critical);
494
+ .refresh-button[data-stale='true'],
495
+ .band .refresh-button[data-stale='true'] {
496
+ color: var(--band-critical);
497
+ border-color: var(--band-critical);
340
498
  }
341
499
  @keyframes refresh-spin {
342
500
  to {
@@ -354,34 +512,47 @@ body[data-view='tickets'] #brief-refresh {
354
512
  /* ---------- banners ---------- */
355
513
 
356
514
  .banners {
357
- max-width: 1280px;
515
+ max-width: var(--page-width);
358
516
  margin: 0 auto;
359
517
  }
360
518
 
519
+ /*
520
+ * A sheet of its own, one line tall, with a bar in the tone's colour. Its
521
+ * button is taller than its line, so the line is centred on the button rather
522
+ * than left at the top with the button's extra height beneath it.
523
+ */
361
524
  .banner {
362
525
  display: flex;
363
526
  gap: 10px;
364
- align-items: flex-start;
365
- padding: 10px 14px;
527
+ align-items: center;
528
+ padding: 10px 14px 10px 12px;
366
529
  margin-bottom: 10px;
367
- border-radius: var(--radius-sm);
368
530
  border: 1px solid var(--border);
531
+ border-left: 3px solid var(--ink-3);
532
+ border-radius: var(--radius-sm);
369
533
  background: var(--surface);
370
- font-size: 14px;
534
+ font-size: 13.5px;
371
535
  color: var(--ink-2);
372
536
  }
373
537
  .banner__icon {
374
538
  flex: none;
539
+ width: 14px;
540
+ text-align: center;
541
+ font-weight: 600;
375
542
  line-height: 1.5;
376
543
  }
544
+ /* The fold's own line keeps the icon on its first line, since the facts open beneath it. */
545
+ .failure__summary .banner__icon {
546
+ align-self: flex-start;
547
+ }
377
548
  .banner--critical {
378
- border-left: 3px solid var(--critical);
549
+ border-left-color: var(--critical);
379
550
  }
380
551
  .banner--critical .banner__icon {
381
552
  color: var(--critical);
382
553
  }
383
554
  .banner--warning {
384
- border-left: 3px solid var(--warning);
555
+ border-left-color: var(--warning);
385
556
  }
386
557
  .banner--warning .banner__icon {
387
558
  color: var(--serious);
@@ -430,7 +601,7 @@ body[data-view='tickets'] #brief-refresh {
430
601
  }
431
602
  /* Under the message, not under the icon. */
432
603
  .banner .failure__body {
433
- margin-left: 20px;
604
+ margin-left: 24px;
434
605
  }
435
606
  .failure__facts {
436
607
  display: flex;
@@ -453,9 +624,9 @@ body[data-view='tickets'] #brief-refresh {
453
624
  padding: 8px 10px;
454
625
  max-height: 16em;
455
626
  overflow: auto;
456
- border-radius: 6px;
627
+ border-radius: var(--radius-sm);
457
628
  background: var(--surface-sunken);
458
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
629
+ font-family: var(--font-mono);
459
630
  font-size: 12px;
460
631
  line-height: 1.45;
461
632
  color: var(--ink-2);
@@ -479,15 +650,15 @@ body[data-view='tickets'] #brief-refresh {
479
650
  white-space: nowrap;
480
651
  }
481
652
 
482
- /* A banner that is a way in, as a card is: the whole strip is the target. */
653
+ /* A banner that is a way in, as a row is: the whole strip is the target. */
483
654
  .banner--link {
484
655
  cursor: pointer;
485
656
  }
486
657
  .banner--link:hover {
487
- border-color: var(--ink-3);
658
+ background: var(--accent-wash);
488
659
  }
489
660
  .banner--link:focus-visible {
490
- outline: 2px solid var(--accent);
661
+ outline: 2px solid var(--focus-ring);
491
662
  outline-offset: 1px;
492
663
  }
493
664
 
@@ -505,6 +676,27 @@ body[data-view='tickets'] #brief-refresh {
505
676
  font-size: 13px;
506
677
  color: var(--ink-3);
507
678
  }
679
+ .agent-run__list summary:hover {
680
+ color: var(--ink-1);
681
+ }
682
+ /* The one line of a run still going: what it is on now, so it reads a step darker than a finished run's fold. */
683
+ .agent-run__list--working > summary {
684
+ color: var(--ink-2);
685
+ white-space: normal;
686
+ }
687
+ /* That line and Stop on one row; opened, the steps grow under the line and Stop stays put at the top. */
688
+ .agent-run__live {
689
+ display: flex;
690
+ align-items: flex-start;
691
+ gap: 10px;
692
+ }
693
+ .agent-run__live > details {
694
+ flex: 1 1 auto;
695
+ min-width: 0;
696
+ }
697
+ .agent-run__live > .button {
698
+ flex: none;
699
+ }
508
700
  /* What the agent said along the way, one fold per message, under its first line. */
509
701
  .agent-run__messages {
510
702
  display: flex;
@@ -517,7 +709,7 @@ body[data-view='tickets'] #brief-refresh {
517
709
  .agent-run__message {
518
710
  border: 1px solid var(--hairline);
519
711
  border-radius: var(--radius-sm);
520
- background: var(--surface-sunken);
712
+ background: var(--page);
521
713
  }
522
714
  .agent-run__message summary {
523
715
  padding: 6px 10px;
@@ -539,7 +731,9 @@ body[data-view='tickets'] #brief-refresh {
539
731
  display: inline;
540
732
  }
541
733
  .agent-run__message .assistant__reply {
734
+ margin: 0;
542
735
  padding: 0 10px 8px;
736
+ border-left: 0;
543
737
  }
544
738
  /*
545
739
  * A run's steps, the assistant's look: what it said in its own words between
@@ -550,8 +744,9 @@ body[data-view='tickets'] #brief-refresh {
550
744
  }
551
745
  .agent-run__said {
552
746
  margin: 6px 0;
553
- font-size: 12.5px;
554
- line-height: 1.45;
747
+ font-family: var(--font-serif);
748
+ font-size: 13.5px;
749
+ line-height: 1.5;
555
750
  color: var(--ink-1);
556
751
  overflow-wrap: anywhere;
557
752
  }
@@ -613,7 +808,7 @@ body[data-view='tickets'] #brief-refresh {
613
808
  padding: 7px 10px;
614
809
  border: 1px solid var(--hairline);
615
810
  border-radius: var(--radius-sm);
616
- background: var(--surface-sunken);
811
+ background: var(--page);
617
812
  text-align: left;
618
813
  font: inherit;
619
814
  color: var(--ink-2);
@@ -639,7 +834,7 @@ body[data-view='tickets'] #brief-refresh {
639
834
 
640
835
  /* Explanation, not status — so it borrows the accent, not one of the four state hues. */
641
836
  .banner--info {
642
- border-left: 3px solid var(--accent);
837
+ border-left-color: var(--accent);
643
838
  }
644
839
  .banner--info .banner__icon {
645
840
  color: var(--accent);
@@ -649,147 +844,275 @@ body[data-view='tickets'] #brief-refresh {
649
844
 
650
845
  .layout {
651
846
  display: grid;
652
- grid-template-columns: minmax(0, 1fr) 320px;
653
- gap: 24px;
847
+ grid-template-columns: minmax(0, 1fr) 300px;
848
+ gap: 48px;
654
849
  align-items: start;
655
- max-width: 1280px;
850
+ max-width: var(--page-width);
656
851
  margin: 0 auto;
657
852
  }
658
853
 
659
854
  @media (max-width: 900px) {
660
855
  .layout {
661
856
  grid-template-columns: minmax(0, 1fr);
857
+ gap: 32px;
662
858
  }
663
859
  .layout__side {
664
860
  order: -1;
665
861
  }
666
862
  }
667
863
 
668
- /* ---------- standing objective ---------- */
864
+ /* ---------- Today's masthead: the objective, the numbers, the note ---------- */
669
865
 
670
866
  /*
671
- * Deliberately heavier than the agent's headline below it. The headline changes
672
- * daily; this doesn't, and it should be the first thing read on the page.
867
+ * The rest of the morning's masthead, on the band with the date. Its band is
868
+ * its own pseudo-element (see `.band`), run up past the top of the page so it
869
+ * and the tabs' are one navy whatever sits between them, and it keeps a clear
870
+ * margin under the agent's note so the last line never sits on the edge.
871
+ */
872
+ .today__masthead {
873
+ position: relative;
874
+ padding: 2px 0 40px;
875
+ color: var(--band-ink);
876
+ }
877
+ .today__masthead::before {
878
+ top: -9999px;
879
+ }
880
+
881
+ /*
882
+ * A notice about the morning — the agent at work, a brief gone stale, a run
883
+ * that failed — is part of its masthead, so on Today it is drawn in the band's
884
+ * materials: the stats sheet's translucent white, the band's rule, its light
885
+ * ink. A sheet of paper laid on the band read as something from another page.
886
+ * The tone keeps its bar; the icons take the band's steps of red and amber.
887
+ */
888
+ body[data-view='today']:has(.today__masthead) .banner {
889
+ background: var(--band-sheet);
890
+ border-color: var(--band-rule);
891
+ color: #d9deea;
892
+ }
893
+ body[data-view='today']:has(.today__masthead) .banner--critical {
894
+ border-left-color: var(--band-critical);
895
+ }
896
+ body[data-view='today']:has(.today__masthead) .banner--critical .banner__icon {
897
+ color: var(--band-critical);
898
+ }
899
+ body[data-view='today']:has(.today__masthead) .banner--warning {
900
+ border-left-color: var(--warning);
901
+ }
902
+ body[data-view='today']:has(.today__masthead) .banner--info {
903
+ border-left-color: var(--accent);
904
+ }
905
+ body[data-view='today']:has(.today__masthead) .banner--link:hover {
906
+ background: rgba(255, 255, 255, 0.12);
907
+ }
908
+ body[data-view='today']:has(.today__masthead) .banner .button {
909
+ border-color: rgba(255, 255, 255, 0.28);
910
+ background: transparent;
911
+ color: var(--band-ink);
912
+ }
913
+ body[data-view='today']:has(.today__masthead) .banner .button:hover {
914
+ border-color: rgba(255, 255, 255, 0.5);
915
+ background: rgba(255, 255, 255, 0.1);
916
+ }
917
+ body[data-view='today']:has(.today__masthead) .banner a {
918
+ color: var(--band-ink);
919
+ }
920
+ body[data-view='today']:has(.today__masthead) .failure__facts {
921
+ color: var(--band-muted);
922
+ }
923
+ body[data-view='today']:has(.today__masthead) .failure__detail {
924
+ background: rgba(0, 0, 0, 0.28);
925
+ color: #d9deea;
926
+ }
927
+ .today__masthead + #sections {
928
+ margin-top: 30px;
929
+ }
930
+
931
+ /*
932
+ * The headline of the day-book: set in the serif, large, and without a box.
933
+ * Deliberately heavier than the agent's note below it. That one changes daily;
934
+ * this doesn't, and it should be the first thing read on the page.
673
935
  */
674
936
  .objective {
675
- margin-bottom: 20px;
676
- padding: 14px 16px;
677
- background: var(--surface);
678
- border: 1px solid var(--border);
679
- border-left: 3px solid var(--accent);
680
- border-radius: var(--radius);
681
- box-shadow: var(--shadow);
937
+ margin: 4px 0 26px;
682
938
  }
683
939
 
684
940
  .objective__label {
685
- margin: 0 0 4px;
686
- font-size: 11px;
687
- font-weight: 600;
688
- letter-spacing: 0.07em;
689
- text-transform: uppercase;
690
- color: var(--ink-3);
941
+ display: flex;
942
+ align-items: baseline;
943
+ gap: 10px;
944
+ margin: 0 0 6px;
945
+ font-size: 12.5px;
946
+ font-weight: 500;
947
+ color: var(--accent);
691
948
  }
692
949
 
693
950
  .objective__text {
694
951
  margin: 0;
695
- font-size: 17px;
696
- font-weight: 600;
697
- line-height: 1.35;
698
- letter-spacing: -0.01em;
699
- color: var(--ink-1);
952
+ max-width: 38ch;
953
+ font-family: var(--font-serif);
954
+ font-size: 24px;
955
+ font-weight: 500;
956
+ line-height: 1.25;
957
+ letter-spacing: -0.005em;
958
+ color: var(--band-ink);
959
+ text-wrap: pretty;
700
960
  }
701
961
 
702
962
  .objective__blocker {
703
- margin: 6px 0 0;
963
+ margin: 8px 0 0;
964
+ max-width: 70ch;
704
965
  font-size: 13.5px;
705
- color: var(--ink-2);
966
+ color: var(--band-muted);
706
967
  }
707
968
  .objective__blocker-label {
708
- color: var(--critical);
709
- font-weight: 500;
969
+ color: var(--band-critical);
970
+ font-weight: 600;
710
971
  }
711
972
 
712
973
  .objective__note {
713
974
  margin: 8px 0 0;
714
- font-size: 13px;
715
- color: var(--ink-3);
975
+ max-width: 70ch;
976
+ font-size: 13.5px;
977
+ color: var(--band-muted);
716
978
  }
717
979
 
718
- /* A reminder, not a headline: no accent, no shadow, nothing competing with the brief. */
980
+ /* A reminder, not a headline: nothing competing with the brief. */
719
981
  .objective--empty {
720
- padding: 10px 16px;
721
- background: transparent;
722
- border-style: dashed;
723
- border-left-width: 1px;
724
- box-shadow: none;
982
+ padding: 6px 0 6px 14px;
983
+ border-left: 2px dashed var(--band-rule);
984
+ }
985
+ .objective--empty .objective__label {
986
+ margin: 0;
987
+ font-size: 14px;
988
+ color: var(--band-ink);
725
989
  }
726
990
  .objective--empty .objective__note {
727
991
  margin-top: 2px;
728
992
  }
993
+ .objective--empty .link-button {
994
+ color: var(--band-ink);
995
+ }
996
+ .objective--empty code {
997
+ color: var(--band-ink);
998
+ }
729
999
 
730
1000
  /* ---------- stat row ---------- */
731
1001
 
1002
+ /*
1003
+ * The day's numbers on one sheet, each a figure with its name beneath and a
1004
+ * rule between them, the way a planner's margin keeps its counts. One sheet
1005
+ * rather than five tiles: the figures are read as a line, not compared as boxes.
1006
+ */
732
1007
  .stats {
733
- display: grid;
734
- grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
735
- gap: 12px;
736
- margin-bottom: 20px;
1008
+ display: flex;
1009
+ flex-wrap: wrap;
1010
+ gap: 12px 0;
1011
+ margin: 0;
1012
+ padding: 14px 20px;
1013
+ background: var(--band-sheet);
1014
+ border: 1px solid var(--band-rule);
1015
+ border-radius: var(--radius);
737
1016
  }
738
1017
 
739
1018
  .stat {
740
- padding: 12px 14px;
741
- background: var(--surface);
742
- border: 1px solid var(--border);
743
- border-radius: var(--radius);
744
- box-shadow: var(--shadow);
1019
+ display: flex;
1020
+ flex-direction: column;
1021
+ flex: 1 1 120px;
1022
+ min-width: 0;
1023
+ padding: 0 20px;
1024
+ border-left: 1px solid var(--band-rule);
1025
+ }
1026
+ .stat:first-child {
1027
+ padding-left: 0;
1028
+ border-left: 0;
745
1029
  }
746
1030
  .stat__label {
747
- margin: 0;
748
- color: var(--ink-2);
749
- font-size: 12px;
1031
+ order: 2;
1032
+ margin: 2px 0 0;
1033
+ color: var(--band-muted);
1034
+ font-size: 12.5px;
1035
+ line-height: 1.35;
750
1036
  }
751
1037
  .stat__value {
752
- margin: 2px 0 0;
753
- font-size: 26px;
1038
+ order: 1;
1039
+ margin: 0;
1040
+ font-size: 22px;
754
1041
  font-weight: 600;
755
1042
  line-height: 1.15;
756
- letter-spacing: -0.02em;
1043
+ letter-spacing: -0.01em;
1044
+ font-variant-numeric: tabular-nums;
1045
+ white-space: nowrap; /* "5 h 15 min" is one figure, however narrow the column. */
1046
+ color: var(--band-ink);
757
1047
  }
758
1048
  .stat__value[data-tone='critical'] {
759
- color: var(--critical);
1049
+ color: var(--band-critical);
760
1050
  }
761
1051
  .stat__value[data-tone='good'] {
762
- color: var(--good-ink);
1052
+ color: var(--band-good);
763
1053
  }
764
1054
  .stat__footnote {
765
- margin: 3px 0 0;
766
- color: var(--ink-3);
767
- font-size: 11.5px;
1055
+ order: 3;
1056
+ margin: 4px 0 0;
1057
+ color: var(--band-muted);
1058
+ font-size: 12px;
768
1059
  line-height: 1.35;
769
- /* The last thing completed can be a full title; keep the tile from growing. */
1060
+ /* The last thing completed can be a full title; keep the line from growing. */
770
1061
  display: -webkit-box;
771
1062
  -webkit-line-clamp: 2;
772
1063
  -webkit-box-orient: vertical;
773
1064
  overflow: hidden;
774
1065
  }
775
1066
 
1067
+ /* Two to a line on a phone, the pairs ruled apart, rather than a ragged wrap. */
1068
+ @media (max-width: 600px) {
1069
+ .stats {
1070
+ display: grid;
1071
+ grid-template-columns: 1fr 1fr;
1072
+ gap: 14px 0;
1073
+ }
1074
+ .stat:nth-child(odd) {
1075
+ padding-left: 0;
1076
+ border-left: 0;
1077
+ }
1078
+ }
1079
+
1080
+ /*
1081
+ * The agent's one-line reading of the day, set as a note in the margin: the
1082
+ * serif's italic, against a rule. Yours above it is roman and heavy; this is
1083
+ * what it made of it. Anything bold in it steps back to roman, which is how
1084
+ * emphasis inside italic is made.
1085
+ */
776
1086
  .headline {
777
- margin: 0 0 20px;
778
- padding: 12px 14px;
779
- background: var(--surface);
780
- border: 1px solid var(--border);
781
- border-left: 3px solid var(--accent);
782
- border-radius: var(--radius);
783
- color: var(--ink-2);
784
- font-size: 14px;
1087
+ margin: 28px 0 0;
1088
+ padding: 2px 0 2px 16px;
1089
+ max-width: 64ch;
1090
+ border-left: 2px solid var(--accent);
1091
+ font-family: var(--font-serif);
1092
+ font-style: italic;
1093
+ font-size: 16px;
1094
+ line-height: 1.5;
1095
+ color: #c9d0e2;
1096
+ }
1097
+ .headline strong {
1098
+ font-style: normal;
1099
+ font-weight: 500;
1100
+ color: var(--band-ink);
1101
+ }
1102
+ .headline code {
1103
+ font-family: var(--font-mono);
1104
+ font-style: normal;
1105
+ font-size: 0.9em;
1106
+ color: var(--band-ink);
785
1107
  }
786
1108
 
787
1109
  /* ---------- sections ---------- */
788
1110
 
789
1111
  .section {
790
- margin-bottom: 22px;
1112
+ margin-bottom: 30px;
791
1113
  }
792
1114
 
1115
+ /* The heading stands on the paper above its sheet, naming what the sheet holds. */
793
1116
  .section__header {
794
1117
  display: flex;
795
1118
  align-items: baseline;
@@ -799,15 +1122,13 @@ body[data-view='tickets'] #brief-refresh {
799
1122
  }
800
1123
  .section__title {
801
1124
  margin: 0;
802
- font-size: 12px;
1125
+ font-size: 14px;
803
1126
  font-weight: 600;
804
- letter-spacing: 0.06em;
805
- text-transform: uppercase;
806
- color: var(--ink-2);
1127
+ color: var(--ink-1);
807
1128
  }
808
1129
  .section__count {
809
1130
  color: var(--ink-3);
810
- font-size: 12px;
1131
+ font-size: 12.5px;
811
1132
  font-variant-numeric: tabular-nums;
812
1133
  }
813
1134
  .section__dot {
@@ -818,40 +1139,52 @@ body[data-view='tickets'] #brief-refresh {
818
1139
  align-self: center;
819
1140
  }
820
1141
 
1142
+ /* A stack of cards with air between them; the heading stands on the paper above. */
821
1143
  .list {
822
1144
  list-style: none;
823
1145
  margin: 0;
824
1146
  padding: 0;
825
1147
  display: flex;
826
1148
  flex-direction: column;
827
- gap: 2px; /* the surface gap doing the separating, not a border */
1149
+ gap: 8px;
828
1150
  }
829
1151
 
830
1152
  /* ---------- item ---------- */
831
1153
 
1154
+ /*
1155
+ * A row is a card: its own sheet, with an edge, so where one ends and the next
1156
+ * begins is never in doubt. The one under the pointer darkens its edge, the
1157
+ * keyboard's cursor wears a ring, and the one the panel is open on carries a
1158
+ * bar on the edge the panel sits past.
1159
+ */
832
1160
  .item {
833
1161
  position: relative;
834
1162
  display: grid;
835
- grid-template-columns: auto minmax(0, 1fr);
836
- gap: 10px;
837
- padding: 11px 13px;
1163
+ grid-template-columns: 30px minmax(0, 1fr);
1164
+ gap: 0 8px;
1165
+ padding: 12px 14px 12px 8px;
838
1166
  background: var(--surface);
839
1167
  border: 1px solid var(--border);
840
1168
  border-radius: var(--radius);
841
1169
  box-shadow: var(--shadow);
1170
+ cursor: pointer; /* A click anywhere on the row opens the panel, and the cursor says so. */
842
1171
  scroll-margin: 90px;
843
1172
  }
1173
+ .item:hover {
1174
+ border-color: var(--ink-3);
1175
+ }
844
1176
  /*
845
1177
  * Two states used to share one look: selected and priority were both "accent
846
1178
  * border", so the ranked rows were indistinguishable from a keyboard cursor.
847
- * Selected is the quieter of the two.
1179
+ * The cursor is a ring; a rank is the numeral in the margin.
848
1180
  */
849
1181
  .item[data-selected='true'] {
850
- border-color: var(--ink-3);
851
- box-shadow: 0 0 0 1px var(--ink-3);
1182
+ border-color: var(--ink-2);
1183
+ box-shadow: 0 0 0 1px var(--ink-2);
852
1184
  }
853
- .item[data-priority='true'] {
854
- border-left: 3px solid var(--accent);
1185
+ .item[data-detail='true'] {
1186
+ border-color: var(--accent);
1187
+ box-shadow: inset -3px 0 0 var(--accent);
855
1188
  }
856
1189
  .item[data-status='done'] .item__title,
857
1190
  .item[data-status='dismissed'] .item__title {
@@ -863,18 +1196,44 @@ body[data-view='tickets'] #brief-refresh {
863
1196
  }
864
1197
 
865
1198
  .item__mark {
866
- padding-top: 4px;
1199
+ display: flex;
1200
+ justify-content: center;
1201
+ align-items: flex-start;
1202
+ padding-top: 6px;
867
1203
  }
868
1204
 
869
1205
  .item__dot {
870
- width: 9px;
871
- height: 9px;
1206
+ width: 8px;
1207
+ height: 8px;
872
1208
  border-radius: 50%;
873
1209
  display: block;
874
1210
  }
875
1211
 
1212
+ /*
1213
+ * A ranked row's number, in the margin where the dot would be. Drawn in the
1214
+ * serif at the title's cap height, so the three ranks read as a column down
1215
+ * the top of the page. The dot gives way: the source is named in text on the
1216
+ * line beneath, and the rank is what this row is for.
1217
+ */
1218
+ .item__mark[data-rank] {
1219
+ padding-top: 0;
1220
+ }
1221
+ .item__mark[data-rank]::before {
1222
+ content: attr(data-rank);
1223
+ font-family: var(--font-serif);
1224
+ font-size: 18px;
1225
+ font-weight: 500;
1226
+ line-height: 1.15;
1227
+ color: var(--accent-ink);
1228
+ font-variant-numeric: tabular-nums;
1229
+ }
1230
+ .item__mark[data-rank] .item__dot {
1231
+ display: none;
1232
+ }
1233
+
876
1234
  .item__body {
877
1235
  min-width: 0;
1236
+ max-width: 72ch;
878
1237
  }
879
1238
 
880
1239
  .item__title {
@@ -891,7 +1250,7 @@ body[data-view='tickets'] #brief-refresh {
891
1250
  }
892
1251
  .item__title a:hover {
893
1252
  text-decoration: underline;
894
- text-decoration-color: var(--accent);
1253
+ text-decoration-color: var(--ink-3);
895
1254
  }
896
1255
 
897
1256
  /*
@@ -909,9 +1268,9 @@ body[data-view='tickets'] #brief-refresh {
909
1268
  display: flex;
910
1269
  flex-wrap: wrap;
911
1270
  align-items: center;
912
- gap: 6px;
1271
+ gap: 4px 6px;
913
1272
  margin-top: 5px;
914
- font-size: 12px;
1273
+ font-size: 12.5px;
915
1274
  color: var(--ink-3);
916
1275
  }
917
1276
 
@@ -922,21 +1281,22 @@ body[data-view='tickets'] #brief-refresh {
922
1281
 
923
1282
  .item__detail {
924
1283
  margin: 6px 0 0;
925
- font-size: 13px;
1284
+ font-size: 13.5px;
1285
+ line-height: 1.5;
926
1286
  color: var(--ink-2);
927
1287
  overflow-wrap: anywhere;
928
1288
  }
929
1289
  /*
930
1290
  * The assistant's answer, asked ahead, in a line: the verdict on the row, so
931
- * the card says what to do about the pull request before it is opened.
1291
+ * the row says what to do about the pull request before it is opened.
932
1292
  */
933
1293
  .item__ahead {
934
1294
  display: -webkit-box;
935
- margin: 6px 0 0;
1295
+ margin: 7px 0 0;
936
1296
  padding: 4px 8px;
937
1297
  border-radius: var(--radius-sm);
938
1298
  background: var(--accent-wash);
939
- font-size: 12.5px;
1299
+ font-size: 13px;
940
1300
  color: var(--ink-1);
941
1301
  overflow: hidden;
942
1302
  overflow-wrap: anywhere;
@@ -950,7 +1310,7 @@ body[data-view='tickets'] #brief-refresh {
950
1310
  }
951
1311
  .item__ahead-mark {
952
1312
  margin-right: 6px;
953
- color: var(--accent);
1313
+ color: var(--accent-ink);
954
1314
  font-weight: 600;
955
1315
  }
956
1316
  .item__ahead[data-status='running'] .item__ahead-mark {
@@ -971,16 +1331,8 @@ body[data-view='tickets'] #brief-refresh {
971
1331
  padding: 1px 4px;
972
1332
  background: var(--surface-sunken);
973
1333
  border-radius: 3px;
974
- font-size: 0.92em;
975
- }
976
-
977
- /* A click anywhere on the card opens the panel, and the cursor says so. */
978
- .item {
979
- cursor: pointer;
980
- }
981
- /* The row the panel is open on: a bar on the edge the panel sits past. */
982
- .item[data-detail='true'] {
983
- border-right: 3px solid var(--accent);
1334
+ font-family: var(--font-mono);
1335
+ font-size: 0.9em;
984
1336
  }
985
1337
 
986
1338
  /* pills */
@@ -997,16 +1349,9 @@ body[data-view='tickets'] #brief-refresh {
997
1349
  color: var(--ink-2);
998
1350
  white-space: nowrap;
999
1351
  }
1000
- .pill--priority {
1001
- border-color: transparent;
1002
- background: var(--accent);
1003
- color: #fff;
1004
- font-weight: 600;
1005
- font-variant-numeric: tabular-nums;
1006
- }
1007
1352
  .pill--objective {
1008
- border-color: var(--accent);
1009
- color: var(--accent);
1353
+ border-color: var(--accent-ink);
1354
+ color: var(--accent-ink);
1010
1355
  font-weight: 500;
1011
1356
  }
1012
1357
  .pill--overdue {
@@ -1034,10 +1379,14 @@ body[data-view='tickets'] #brief-refresh {
1034
1379
 
1035
1380
  /* actions */
1036
1381
 
1382
+ /*
1383
+ * The strip sits over the card's top right on the card's own white, so the
1384
+ * tail of a long title is covered rather than shown through it.
1385
+ */
1037
1386
  .item__actions {
1038
1387
  position: absolute;
1039
- top: 8px;
1040
- right: 10px;
1388
+ top: 9px;
1389
+ right: 12px;
1041
1390
  display: flex;
1042
1391
  gap: 4px;
1043
1392
  opacity: 0;
@@ -1053,43 +1402,69 @@ body[data-view='tickets'] #brief-refresh {
1053
1402
  @media (hover: none) {
1054
1403
  .item__actions {
1055
1404
  opacity: 1;
1405
+ background: transparent;
1406
+ }
1407
+ }
1408
+ /*
1409
+ * On a phone the title runs the whole width, so a strip laid over its end
1410
+ * covers the words. There it takes a line of its own under the row instead.
1411
+ */
1412
+ @media (max-width: 600px) {
1413
+ .item__actions,
1414
+ .item:hover .item__actions,
1415
+ .item[data-selected='true'] .item__actions,
1416
+ .item[data-detail='true'] .item__actions {
1417
+ position: static;
1418
+ grid-column: 2;
1419
+ margin-top: 8px;
1420
+ padding-left: 0;
1421
+ opacity: 1;
1422
+ background: transparent;
1056
1423
  }
1057
1424
  }
1058
1425
 
1059
1426
  .button {
1060
- padding: 3px 9px;
1427
+ padding: 4px 10px;
1061
1428
  border: 1px solid var(--border);
1062
1429
  border-radius: var(--radius-sm);
1063
1430
  background: var(--surface);
1064
- color: var(--ink-2);
1431
+ color: var(--ink-1);
1065
1432
  font: inherit;
1066
- font-size: 12px;
1433
+ font-size: 12.5px;
1434
+ font-weight: 500;
1435
+ line-height: 1.5;
1067
1436
  cursor: pointer;
1068
1437
  white-space: nowrap;
1069
1438
  }
1070
1439
  .button:hover {
1071
- color: var(--ink-1);
1072
- border-color: var(--ink-3);
1440
+ border-color: var(--ink-2);
1441
+ background: var(--surface-sunken);
1073
1442
  }
1074
1443
  .button--primary {
1075
- border-color: transparent;
1444
+ border-color: var(--accent);
1076
1445
  background: var(--accent);
1077
- color: #fff;
1446
+ color: var(--on-accent);
1078
1447
  }
1079
1448
  .button--primary:hover {
1080
- color: #fff;
1081
- filter: brightness(1.08);
1449
+ border-color: #c9841f;
1450
+ background: #c9841f;
1451
+ color: var(--on-accent);
1082
1452
  }
1083
1453
  /* Not yet: it reads as waiting, not as the next thing to press. */
1084
1454
  .button:disabled,
1085
1455
  .button:disabled:hover {
1086
1456
  opacity: 0.45;
1087
1457
  cursor: not-allowed;
1088
- filter: none;
1458
+ background: var(--surface);
1089
1459
  border-color: var(--border);
1460
+ color: var(--ink-1);
1461
+ }
1462
+ .button--primary:disabled,
1463
+ .button--primary:disabled:hover {
1464
+ background: var(--accent);
1465
+ border-color: var(--accent);
1466
+ color: var(--on-accent);
1090
1467
  }
1091
-
1092
- /* note composer */
1093
1468
 
1094
1469
  /* snooze menu */
1095
1470
 
@@ -1119,12 +1494,12 @@ body[data-view='tickets'] #brief-refresh {
1119
1494
  background: var(--surface);
1120
1495
  border: 1px solid var(--border);
1121
1496
  border-radius: var(--radius-sm);
1122
- box-shadow: 0 6px 24px rgba(11, 11, 11, 0.14);
1497
+ box-shadow: var(--shadow-float);
1123
1498
  }
1124
1499
  .menu button {
1125
1500
  display: block;
1126
1501
  width: 100%;
1127
- padding: 5px 9px;
1502
+ padding: 6px 9px;
1128
1503
  border: 0;
1129
1504
  border-radius: 4px;
1130
1505
  background: none;
@@ -1177,23 +1552,27 @@ body[data-view='tickets'] #brief-refresh {
1177
1552
 
1178
1553
  /* ---------- agenda ---------- */
1179
1554
 
1555
+ /*
1556
+ * The day's timeline, in the margin: a column of times, a rule running down
1557
+ * the day, a mark on it per event, and the red line of now crossing it. The
1558
+ * list is a sheet like the brief's, under a heading on the paper like theirs,
1559
+ * and sticky so the morning's meetings stay beside the afternoon's rows.
1560
+ */
1180
1561
  .agenda {
1181
- padding: 14px;
1182
- background: var(--surface);
1183
- border: 1px solid var(--border);
1184
- border-radius: var(--radius);
1185
- box-shadow: var(--shadow);
1186
1562
  position: sticky;
1187
1563
  top: 16px;
1188
1564
  }
1189
1565
 
1190
1566
  .agenda__title {
1191
- margin: 0 0 10px;
1192
- font-size: 12px;
1567
+ margin: 0 0 8px;
1568
+ padding: 0 2px;
1569
+ font-size: 14px;
1193
1570
  font-weight: 600;
1194
- letter-spacing: 0.06em;
1195
- text-transform: uppercase;
1196
- color: var(--ink-2);
1571
+ color: var(--ink-1);
1572
+ }
1573
+ /* Level with the masthead, the agenda's heading stands on the band. */
1574
+ body:has(.today__masthead) .agenda__title {
1575
+ color: var(--band-ink);
1197
1576
  }
1198
1577
 
1199
1578
  /*
@@ -1203,12 +1582,13 @@ body[data-view='tickets'] #brief-refresh {
1203
1582
  .agenda__note {
1204
1583
  margin: 0 0 10px;
1205
1584
  padding: 6px 8px;
1206
- border-radius: 6px;
1207
- font-size: 11px;
1585
+ border: 1px solid var(--border);
1586
+ border-left: 2px solid var(--ink-3);
1587
+ border-radius: var(--radius-sm);
1588
+ font-size: 11.5px;
1208
1589
  line-height: 1.4;
1209
1590
  color: var(--ink-2);
1210
- background: var(--surface-sunken);
1211
- border-left: 2px solid var(--ink-3);
1591
+ background: var(--surface);
1212
1592
  }
1213
1593
 
1214
1594
  /* Falling back to the brief is a louder thing than a merely stale read. */
@@ -1217,22 +1597,46 @@ body[data-view='tickets'] #brief-refresh {
1217
1597
  }
1218
1598
 
1219
1599
  .agenda__list {
1600
+ position: relative;
1220
1601
  list-style: none;
1221
1602
  margin: 0;
1222
- padding: 0;
1603
+ padding: 8px 14px;
1604
+ background: var(--surface);
1605
+ border: 1px solid var(--border);
1606
+ border-radius: var(--radius);
1607
+ box-shadow: var(--shadow);
1608
+ }
1609
+ /* The rule the day runs down, between the times and the names. */
1610
+ .agenda__list::before {
1611
+ content: '';
1612
+ position: absolute;
1613
+ top: 14px;
1614
+ bottom: 14px;
1615
+ left: 77px;
1616
+ width: 1px;
1617
+ background: var(--hairline);
1223
1618
  }
1224
1619
 
1225
1620
  .agenda__row {
1621
+ position: relative;
1226
1622
  display: grid;
1227
1623
  /* Wide enough for a 12-hour "09:30 AM" without wrapping. */
1228
- grid-template-columns: 64px minmax(0, 1fr);
1229
- gap: 10px;
1230
- padding: 6px 0;
1231
- border-top: 1px solid var(--hairline);
1624
+ grid-template-columns: 56px minmax(0, 1fr);
1625
+ gap: 16px;
1626
+ padding: 7px 0;
1232
1627
  font-size: 13px;
1233
1628
  }
1234
- .agenda__row:first-child {
1235
- border-top: 0;
1629
+ /* The event's mark on the rule, ringed in the sheet so the rule doesn't run through it. */
1630
+ .agenda__row::before {
1631
+ content: '';
1632
+ position: absolute;
1633
+ left: 60px;
1634
+ top: 13px;
1635
+ width: 7px;
1636
+ height: 7px;
1637
+ border-radius: 50%;
1638
+ background: var(--ink-2);
1639
+ box-shadow: 0 0 0 2px var(--surface);
1236
1640
  }
1237
1641
 
1238
1642
  .agenda__time {
@@ -1240,11 +1644,13 @@ body[data-view='tickets'] #brief-refresh {
1240
1644
  font-size: 12px;
1241
1645
  font-variant-numeric: tabular-nums; /* a column of times, so tabular is right here */
1242
1646
  white-space: nowrap;
1647
+ text-align: right;
1243
1648
  padding-top: 1px;
1244
1649
  }
1245
1650
 
1246
1651
  .agenda__name {
1247
1652
  color: var(--ink-1);
1653
+ line-height: 1.4;
1248
1654
  overflow-wrap: anywhere;
1249
1655
  }
1250
1656
  /* Event links take the row's ink so past events actually read as past. */
@@ -1254,12 +1660,15 @@ body[data-view='tickets'] #brief-refresh {
1254
1660
  }
1255
1661
  .agenda__name a:hover {
1256
1662
  text-decoration: underline;
1257
- text-decoration-color: var(--accent);
1663
+ text-decoration-color: var(--ink-3);
1258
1664
  }
1259
1665
  .agenda__row[data-past='true'] .agenda__name,
1260
1666
  .agenda__row[data-past='true'] .agenda__time {
1261
1667
  color: var(--ink-3);
1262
1668
  }
1669
+ .agenda__row[data-past='true']::before {
1670
+ background: var(--rule);
1671
+ }
1263
1672
 
1264
1673
  /*
1265
1674
  * An event that sits on the day without taking any of it: a delivery window, a
@@ -1267,11 +1676,15 @@ body[data-view='tickets'] #brief-refresh {
1267
1676
  * dimming, because being home for the delivery is the entire point of it being
1268
1677
  * on the agenda — a 14:30 slot that reads as already over is a worse mistake
1269
1678
  * than one that reads as a meeting. The row also says "marked free" in text,
1270
- * since ink is never the only cue here.
1679
+ * since ink is never the only cue here; its mark is hollow for the same reason.
1271
1680
  */
1272
1681
  .agenda__row[data-blocking='false'] .agenda__name {
1273
1682
  color: var(--ink-2);
1274
1683
  }
1684
+ .agenda__row[data-blocking='false']::before {
1685
+ background: var(--surface);
1686
+ box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 1.5px var(--ink-3);
1687
+ }
1275
1688
  .agenda__sub {
1276
1689
  display: block;
1277
1690
  color: var(--ink-3);
@@ -1282,10 +1695,16 @@ body[data-view='tickets'] #brief-refresh {
1282
1695
  color: var(--good-ink);
1283
1696
  font-weight: 500;
1284
1697
  }
1698
+ .agenda__row--free::before {
1699
+ background: var(--surface);
1700
+ box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 1.5px var(--good-ink);
1701
+ }
1285
1702
  .agenda__row--now {
1286
1703
  align-items: center;
1287
1704
  padding: 2px 0;
1288
- border-top: 0;
1705
+ }
1706
+ .agenda__row--now::before {
1707
+ display: none;
1289
1708
  }
1290
1709
  .agenda__now-label {
1291
1710
  color: var(--critical);
@@ -1293,36 +1712,40 @@ body[data-view='tickets'] #brief-refresh {
1293
1712
  font-weight: 600;
1294
1713
  font-variant-numeric: tabular-nums;
1295
1714
  white-space: nowrap;
1715
+ text-align: right;
1296
1716
  }
1717
+ /* Starts back across the rule, so now is seen to cut the day. */
1297
1718
  .agenda__now-line {
1298
1719
  height: 2px;
1720
+ margin-left: -14px;
1299
1721
  background: var(--critical);
1300
1722
  border-radius: 1px;
1301
1723
  }
1302
1724
 
1303
1725
  .empty {
1304
1726
  margin: 0;
1305
- padding: 18px 4px;
1727
+ padding: 16px 0;
1306
1728
  color: var(--ink-3);
1307
- font-size: 13.5px;
1308
- text-align: center;
1729
+ font-family: var(--font-serif);
1730
+ font-style: italic;
1731
+ font-size: 14.5px;
1309
1732
  }
1310
1733
 
1311
1734
  /* ---------- done drawer ---------- */
1312
1735
 
1313
1736
  .drawer {
1314
- margin-top: 8px;
1315
- border: 1px solid var(--border);
1316
- border-radius: var(--radius);
1317
- background: var(--surface);
1737
+ margin-top: 12px;
1318
1738
  }
1319
1739
  .drawer > summary {
1320
- padding: 9px 13px;
1740
+ padding: 10px 8px;
1321
1741
  cursor: pointer;
1322
1742
  color: var(--ink-2);
1323
1743
  font-size: 13px;
1324
1744
  list-style: none;
1325
1745
  }
1746
+ .drawer > summary:hover {
1747
+ color: var(--ink-1);
1748
+ }
1326
1749
  .drawer > summary::-webkit-details-marker {
1327
1750
  display: none;
1328
1751
  }
@@ -1334,10 +1757,7 @@ body[data-view='tickets'] #brief-refresh {
1334
1757
  content: '▾ ';
1335
1758
  }
1336
1759
  .drawer .list {
1337
- padding: 0 8px 8px;
1338
- }
1339
- .drawer .item {
1340
- box-shadow: none;
1760
+ padding: 0 0 8px;
1341
1761
  }
1342
1762
 
1343
1763
  /* ---------- toast ---------- */
@@ -1351,12 +1771,12 @@ body[data-view='tickets'] #brief-refresh {
1351
1771
  display: flex;
1352
1772
  align-items: center;
1353
1773
  gap: 12px;
1354
- padding: 9px 14px;
1774
+ padding: 9px 16px;
1355
1775
  background: var(--ink-1);
1356
1776
  color: var(--page);
1357
1777
  border-radius: 999px;
1358
1778
  font-size: 13px;
1359
- box-shadow: 0 6px 24px rgba(11, 11, 11, 0.25);
1779
+ box-shadow: 0 8px 28px rgba(0, 0, 0, 0.25);
1360
1780
  }
1361
1781
  .toast button {
1362
1782
  border: 0;
@@ -1365,6 +1785,7 @@ body[data-view='tickets'] #brief-refresh {
1365
1785
  font: inherit;
1366
1786
  font-weight: 600;
1367
1787
  text-decoration: underline;
1788
+ text-underline-offset: 2px;
1368
1789
  cursor: pointer;
1369
1790
  padding: 0;
1370
1791
  }
@@ -1372,24 +1793,27 @@ body[data-view='tickets'] #brief-refresh {
1372
1793
  /* ---------- help dialog ---------- */
1373
1794
 
1374
1795
  .help {
1375
- max-width: 420px;
1376
- padding: 22px;
1796
+ max-width: 440px;
1797
+ padding: 24px 26px;
1377
1798
  border: 1px solid var(--border);
1378
- border-radius: var(--radius);
1799
+ border-radius: 12px;
1379
1800
  background: var(--surface);
1380
1801
  color: var(--ink-1);
1802
+ box-shadow: var(--shadow-float);
1381
1803
  }
1382
1804
  .help::backdrop {
1383
- background: rgba(11, 11, 11, 0.4);
1805
+ background: rgba(10, 12, 20, 0.55);
1384
1806
  }
1385
1807
  .help h2 {
1386
- margin: 0 0 14px;
1387
- font-size: 16px;
1808
+ margin: 0 0 16px;
1809
+ font-family: var(--font-serif);
1810
+ font-size: 20px;
1811
+ font-weight: 500;
1388
1812
  }
1389
1813
  .help dl {
1390
- margin: 0 0 14px;
1814
+ margin: 0 0 16px;
1391
1815
  display: grid;
1392
- gap: 6px;
1816
+ gap: 7px;
1393
1817
  }
1394
1818
  .help dl > div {
1395
1819
  display: grid;
@@ -1405,8 +1829,9 @@ body[data-view='tickets'] #brief-refresh {
1405
1829
  color: var(--ink-2);
1406
1830
  }
1407
1831
  .help__note {
1408
- margin: 0 0 16px;
1832
+ margin: 0 0 18px;
1409
1833
  font-size: 13px;
1834
+ line-height: 1.5;
1410
1835
  color: var(--ink-3);
1411
1836
  }
1412
1837
  kbd {
@@ -1415,7 +1840,7 @@ kbd {
1415
1840
  border-bottom-width: 2px;
1416
1841
  border-radius: 4px;
1417
1842
  background: var(--surface-sunken);
1418
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1843
+ font-family: var(--font-mono);
1419
1844
  font-size: 11.5px;
1420
1845
  color: var(--ink-1);
1421
1846
  }
@@ -1429,38 +1854,38 @@ kbd {
1429
1854
  /* ---------- tabs ---------- */
1430
1855
 
1431
1856
  /*
1432
- * Two views, one page. Today is the brief; the board is the live list of pull
1433
- * requests. They're tabs rather than one long page because the brief is edited
1434
- * down to a short list on purpose, and a wall of PRs beneath it would undo that.
1857
+ * Three views, one page. Today is the brief; the boards are the live lists.
1858
+ * They're tabs rather than one long page because the brief is edited down to
1859
+ * a short list on purpose, and a wall of PRs beneath it would undo that.
1435
1860
  */
1436
1861
  .tabs {
1437
1862
  display: flex;
1438
- gap: 4px;
1439
- max-width: 1280px;
1440
- margin: -6px auto 14px;
1441
- border-bottom: 1px solid var(--hairline);
1863
+ gap: 2px;
1864
+ max-width: var(--page-width);
1865
+ margin: 0 auto 24px;
1866
+ border-bottom: 1px solid var(--band-rule);
1442
1867
  }
1443
1868
 
1444
1869
  .tab {
1445
1870
  display: inline-flex;
1446
1871
  align-items: center;
1447
1872
  gap: 7px;
1448
- padding: 7px 12px 9px;
1873
+ padding: 8px 12px 10px;
1449
1874
  margin-bottom: -1px;
1450
1875
  border: 0;
1451
1876
  border-bottom: 2px solid transparent;
1452
1877
  background: none;
1453
- color: var(--ink-2);
1878
+ color: var(--band-muted);
1454
1879
  font: inherit;
1455
- font-size: 13.5px;
1880
+ font-size: 14px;
1456
1881
  font-weight: 500;
1457
1882
  cursor: pointer;
1458
1883
  }
1459
1884
  .tab:hover {
1460
- color: var(--ink-1);
1885
+ color: var(--band-ink);
1461
1886
  }
1462
1887
  .tab[aria-selected='true'] {
1463
- color: var(--ink-1);
1888
+ color: var(--band-ink);
1464
1889
  border-bottom-color: var(--accent);
1465
1890
  }
1466
1891
 
@@ -1534,7 +1959,6 @@ body[data-view='settings'] .layout {
1534
1959
 
1535
1960
  /* ---------- the pull request board ---------- */
1536
1961
 
1537
-
1538
1962
  /* The line under a waiting-on-you row that says why. Reads as the row's detail. */
1539
1963
  .item__reason {
1540
1964
  margin: 6px 0 0;
@@ -1574,29 +1998,27 @@ body[data-view='settings'] .layout {
1574
1998
  /*
1575
1999
  * Two columns, by measurement rather than by taste: the rows were
1576
2000
  * 1200px wide for a summary that runs 520px at the median and 683px at the
1577
- * longest, so half of every card was empty and thirty of them came to 2527px of
2001
+ * longest, so half of every row was empty and thirty of them came to 2527px of
1578
2002
  * scrolling. At 460px a column the same thirty fit in half that.
1579
2003
  *
1580
2004
  * Multicol rather than a grid, which is what this was and which was wrong for a
1581
- * board whose cards disagree about height. A grid lays out in *rows*, so a
1582
- * one-line card beside a card carrying a note gets the note's height reserved
2005
+ * board whose rows disagree about height. A grid lays out in *rows*, so a
2006
+ * one-line row beside a row carrying a note gets the note's height reserved
1583
2007
  * next to it and left empty — `align-items: start` stops it stretching but
1584
- * cannot reclaim the row, and one noted card on a real board cost about a
2008
+ * cannot reclaim the row, and one noted row on a real board cost about a
1585
2009
  * hundred pixels of nothing. A column flow has no rows to align against: each
1586
- * card starts where the one above it ended.
2010
+ * row starts where the one above it ended.
1587
2011
  *
1588
- * `break-inside: avoid` so a card is never split down the middle of a column,
1589
- * and the vertical rhythm is a margin rather than `gap`, which a multicol
1590
- * container does not have.
2012
+ * `break-inside: avoid` so a row is never split down the middle of a column.
1591
2013
  *
1592
2014
  * Never more than two, so the board keeps the shared page width and its edges
1593
2015
  * line up with the other tabs' however wide the display is. The 460px floor is
1594
2016
  * what drops it to one column on a narrow window rather than squeezing two.
1595
2017
  *
1596
2018
  * An absolutely positioned child is still fragmented by the columns, and counts
1597
- * toward balancing them. `.item__actions` stays inside its card, so it travels
1598
- * with the card into its column and nothing notices. Anything that hangs below a
1599
- * card must not be in here at all: the row menus once were, and were split
2019
+ * toward balancing them. `.item__actions` stays inside its row, so it travels
2020
+ * with the row into its column and nothing notices. Anything that hangs below a
2021
+ * row must not be in here at all: the row menus once were, and were split
1600
2022
  * across both columns and pushed the next section down. They are popovers now.
1601
2023
  */
1602
2024
  #tickets .list {
@@ -1606,7 +2028,7 @@ body[data-view='settings'] .layout {
1606
2028
  }
1607
2029
  #tickets .list > .item {
1608
2030
  break-inside: avoid;
1609
- margin-bottom: 4px;
2031
+ margin-bottom: 8px;
1610
2032
  }
1611
2033
 
1612
2034
  /*
@@ -1617,13 +2039,14 @@ body[data-view='settings'] .layout {
1617
2039
  * column.
1618
2040
  */
1619
2041
  #tickets .item--ticket {
1620
- padding: 8px 11px;
2042
+ padding: 9px 14px 9px 8px;
1621
2043
  }
1622
2044
  #tickets .item__body {
1623
2045
  display: grid;
1624
2046
  grid-template-columns: 6rem minmax(0, 1fr);
1625
2047
  align-items: baseline;
1626
2048
  gap: 4px 9px;
2049
+ max-width: none;
1627
2050
  }
1628
2051
  #tickets .item__meta--status {
1629
2052
  grid-column: 1;
@@ -1633,7 +2056,7 @@ body[data-view='settings'] .layout {
1633
2056
  }
1634
2057
  /*
1635
2058
  * The reserve on the right is the action strip's width. `.item__actions` is
1636
- * absolutely positioned over the card's top right and opaque, so without this it
2059
+ * absolutely positioned over the row's top right and opaque, so without this it
1637
2060
  * covers the tail of any summary long enough to reach it — on hover, and
1638
2061
  * permanently on the selected row, which is the row being read. Measured rather
1639
2062
  * than guessed: reserving the pull request board's three buttons cost 142px of
@@ -1662,10 +2085,8 @@ body[data-view='settings'] .layout {
1662
2085
  * The switch between the ticket tab's two views: what is out of sync, and what
1663
2086
  * you are working on. A segmented control rather than a second row of tabs, so it
1664
2087
  * reads as a way of looking at this tab and not as more places to go — the tabs
1665
- * above are underlined words, the status line below is a bordered bar, and this
1666
- * is neither.
1667
- */
1668
- /*
2088
+ * above are underlined words, and this is a pair of pills with one filled in.
2089
+ *
1669
2090
  * The switch and the key to the dots share a line: both describe the view
1670
2091
  * below rather than being part of it, and stacked they made a third tier under
1671
2092
  * the tabs, with the key hanging off the switch like a caption. The key goes
@@ -1677,7 +2098,7 @@ body[data-view='settings'] .layout {
1677
2098
  align-items: center;
1678
2099
  justify-content: space-between;
1679
2100
  gap: 8px 24px;
1680
- margin: 0 0 18px;
2101
+ margin: 0 0 22px;
1681
2102
  }
1682
2103
  .mode-switch {
1683
2104
  display: inline-flex;
@@ -1705,15 +2126,18 @@ body[data-view='settings'] .layout {
1705
2126
  color: var(--ink-1);
1706
2127
  }
1707
2128
  .mode-switch__option[aria-selected='true'] {
1708
- background: var(--surface);
1709
- color: var(--ink-1);
1710
- box-shadow: var(--shadow);
2129
+ background: var(--band);
2130
+ color: var(--band-ink);
1711
2131
  }
1712
2132
  .mode-switch__count {
1713
2133
  color: var(--ink-3);
1714
2134
  font-size: 12px;
1715
2135
  font-variant-numeric: tabular-nums;
1716
2136
  }
2137
+ .mode-switch__option[aria-selected='true'] .mode-switch__count {
2138
+ color: inherit;
2139
+ opacity: 0.7;
2140
+ }
1717
2141
 
1718
2142
  /*
1719
2143
  * On a Working on row whose ticket is also out of sync. The border is the due
@@ -1737,7 +2161,7 @@ body[data-view='settings'] .layout {
1737
2161
  gap: 4px 14px;
1738
2162
  /* A <p>, and its default margins made the switch's line taller whenever the key was on it. */
1739
2163
  margin: 0;
1740
- font-size: 12px;
2164
+ font-size: 12.5px;
1741
2165
  color: var(--ink-3);
1742
2166
  }
1743
2167
  .legend__entry {
@@ -1746,8 +2170,8 @@ body[data-view='settings'] .layout {
1746
2170
  gap: 6px;
1747
2171
  }
1748
2172
  .legend__dot {
1749
- width: 9px;
1750
- height: 9px;
2173
+ width: 8px;
2174
+ height: 8px;
1751
2175
  border-radius: 50%;
1752
2176
  display: block;
1753
2177
  }
@@ -1758,10 +2182,8 @@ body[data-view='settings'] .layout {
1758
2182
  * every single morning is one you stop reading by the end of the week.
1759
2183
  */
1760
2184
  .tab__badge--quiet {
1761
- background: var(--surface-sunken);
1762
- /* A shadow, not a border, so it adds nothing to the padding that centres the digits. */
1763
- box-shadow: inset 0 0 0 1px var(--hairline);
1764
- color: var(--ink-2);
2185
+ background: rgba(255, 255, 255, 0.14);
2186
+ color: var(--band-ink);
1765
2187
  }
1766
2188
 
1767
2189
  /*
@@ -1773,8 +2195,8 @@ body[data-view='settings'] .layout {
1773
2195
  * here" is actually worth knowing.
1774
2196
  */
1775
2197
  .court-hint {
1776
- margin: -6px 0 18px;
1777
- padding-left: 26px;
2198
+ margin: -10px 0 26px;
2199
+ padding: 0 8px;
1778
2200
  font-size: 12.5px;
1779
2201
  line-height: 1.5;
1780
2202
  color: var(--ink-3);
@@ -1800,8 +2222,8 @@ body[data-view='settings'] .layout {
1800
2222
 
1801
2223
  /*
1802
2224
  * Hung from the pill's left edge, where the park menu hangs from its button's
1803
- * right: the pill sits in the card's left gutter, so each menu opens toward the
1804
- * middle of its own card.
2225
+ * right: the pill sits in the row's left gutter, so each menu opens toward the
2226
+ * middle of its own row.
1805
2227
  */
1806
2228
  .menu--status {
1807
2229
  right: auto;
@@ -1811,7 +2233,7 @@ body[data-view='settings'] .layout {
1811
2233
 
1812
2234
  /* The status the ticket claims — the row's own subject, so it carries weight. */
1813
2235
  .pill--status {
1814
- border-color: var(--hairline);
2236
+ border-color: var(--border);
1815
2237
  background: var(--surface-sunken);
1816
2238
  color: var(--ink-1);
1817
2239
  font-weight: 500;
@@ -1827,28 +2249,28 @@ a.button {
1827
2249
  /* ---------- the assistant ---------- */
1828
2250
 
1829
2251
  .pill--assistant {
1830
- color: var(--accent);
2252
+ color: var(--ink-1);
1831
2253
  background: var(--accent-wash);
2254
+ border-color: transparent;
1832
2255
  }
1833
2256
 
1834
2257
  /*
1835
- * ---------- the assistant ----------
1836
- *
1837
2258
  * A section of the item panel, so the transcript scrolls with the panel's body;
1838
- * the field is pinned in the panel's foot. It used to be a box under the card
1839
- * with its own scroll region; now the panel is the box.
2259
+ * the field is pinned in the panel's foot. What was asked is set in the sans,
2260
+ * as a row is; what came back is set in the serif, as the brief is — it is the
2261
+ * part written to be read.
1840
2262
  */
1841
2263
 
1842
2264
  .assistant__turns {
1843
2265
  display: flex;
1844
2266
  flex-direction: column;
1845
- gap: 12px;
2267
+ gap: 14px;
1846
2268
  margin-bottom: 14px;
1847
2269
  }
1848
2270
 
1849
2271
  .assistant__request {
1850
2272
  margin: 0;
1851
- font-size: 12.5px;
2273
+ font-size: 13px;
1852
2274
  color: var(--ink-2);
1853
2275
  }
1854
2276
  .assistant__request strong {
@@ -1856,17 +2278,16 @@ a.button {
1856
2278
  font-weight: 600;
1857
2279
  }
1858
2280
  .assistant__auto {
1859
- color: var(--accent);
2281
+ color: var(--ink-3);
1860
2282
  }
1861
2283
 
1862
2284
  .assistant__reply {
1863
- margin-top: 5px;
1864
- padding: 7px 10px;
1865
- border-left: 2px solid var(--accent);
1866
- background: var(--surface);
1867
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
1868
- font-size: 13px;
1869
- line-height: 1.45;
2285
+ margin-top: 6px;
2286
+ padding: 2px 0 2px 12px;
2287
+ border-left: 2px solid var(--hairline);
2288
+ font-family: var(--font-serif);
2289
+ font-size: 14px;
2290
+ line-height: 1.55;
1870
2291
  color: var(--ink-1);
1871
2292
  overflow-wrap: anywhere;
1872
2293
  }
@@ -1874,7 +2295,7 @@ a.button {
1874
2295
  margin: 0;
1875
2296
  }
1876
2297
  .assistant__reply > * + * {
1877
- margin-top: 7px;
2298
+ margin-top: 8px;
1878
2299
  }
1879
2300
  .assistant__reply ul,
1880
2301
  .assistant__reply ol {
@@ -1884,14 +2305,17 @@ a.button {
1884
2305
  margin-top: 3px;
1885
2306
  }
1886
2307
  .assistant__reply pre {
1887
- padding: 7px 9px;
2308
+ padding: 8px 10px;
1888
2309
  border-radius: var(--radius-sm);
1889
2310
  background: var(--surface-sunken);
2311
+ font-family: var(--font-mono);
1890
2312
  font-size: 12px;
2313
+ line-height: 1.5;
1891
2314
  overflow-x: auto;
1892
2315
  white-space: pre-wrap;
1893
2316
  }
1894
2317
  .assistant__reply code {
2318
+ font-family: var(--font-mono);
1895
2319
  font-size: 12px;
1896
2320
  }
1897
2321
  .assistant__reply blockquote {
@@ -1920,6 +2344,7 @@ a.button {
1920
2344
  background: var(--surface);
1921
2345
  color: var(--ink-3);
1922
2346
  font: inherit;
2347
+ font-family: var(--font);
1923
2348
  font-size: 11px;
1924
2349
  cursor: pointer;
1925
2350
  }
@@ -1930,7 +2355,7 @@ a.button {
1930
2355
 
1931
2356
  .assistant__status {
1932
2357
  margin: 4px 0 0;
1933
- font-size: 12px;
2358
+ font-size: 12.5px;
1934
2359
  color: var(--ink-3);
1935
2360
  }
1936
2361
  .assistant__status--bad {
@@ -1940,8 +2365,12 @@ a.button {
1940
2365
  font-variant-numeric: tabular-nums;
1941
2366
  }
1942
2367
 
1943
- /* A spinner, for the turn while it works and for each call it is waiting on. */
2368
+ /*
2369
+ * A spinner, for the turn while it works and for each call it is waiting on;
2370
+ * and on the line a running run folds under, which is all of it that shows.
2371
+ */
1944
2372
  .assistant__status--working::after,
2373
+ .agent-run__list--working > summary::after,
1945
2374
  .assistant__step[data-state='running']::before {
1946
2375
  content: '';
1947
2376
  display: inline-block;
@@ -1949,11 +2378,12 @@ a.button {
1949
2378
  width: 9px;
1950
2379
  height: 9px;
1951
2380
  border-radius: 50%;
1952
- border: 1.5px solid var(--accent);
2381
+ border: 1.5px solid var(--ink-1);
1953
2382
  border-top-color: transparent;
1954
2383
  animation: assistant-spin 0.9s linear infinite;
1955
2384
  }
1956
- .assistant__status--working::after {
2385
+ .assistant__status--working::after,
2386
+ .agent-run__list--working > summary::after {
1957
2387
  margin-left: 6px;
1958
2388
  vertical-align: -1px;
1959
2389
  }
@@ -1964,6 +2394,7 @@ a.button {
1964
2394
  }
1965
2395
  @media (prefers-reduced-motion: reduce) {
1966
2396
  .assistant__status--working::after,
2397
+ .agent-run__list--working > summary::after,
1967
2398
  .assistant__step[data-state='running']::before {
1968
2399
  animation: none;
1969
2400
  }
@@ -1977,24 +2408,24 @@ a.button {
1977
2408
  margin-top: 4px;
1978
2409
  }
1979
2410
  .assistant__work > summary {
1980
- font-size: 12px;
2411
+ font-size: 12.5px;
1981
2412
  color: var(--ink-3);
1982
2413
  cursor: pointer;
1983
2414
  }
1984
2415
  .assistant__work > summary:hover {
1985
- color: var(--ink-2);
2416
+ color: var(--ink-1);
1986
2417
  }
1987
2418
  .assistant__took {
1988
2419
  margin: 4px 0 0;
1989
- font-size: 12px;
2420
+ font-size: 12.5px;
1990
2421
  color: var(--ink-3);
1991
2422
  }
1992
2423
  .assistant__steps {
1993
- margin: 5px 0 0;
2424
+ margin: 6px 0 0;
1994
2425
  padding: 0 0 0 10px;
1995
2426
  border-left: 2px solid var(--hairline);
1996
2427
  list-style: none;
1997
- font-size: 12px;
2428
+ font-size: 12.5px;
1998
2429
  line-height: 1.45;
1999
2430
  color: var(--ink-2);
2000
2431
  }
@@ -2031,19 +2462,47 @@ a.button {
2031
2462
  text-overflow: ellipsis;
2032
2463
  white-space: nowrap;
2033
2464
  }
2034
- .assistant__step-detail {
2465
+ .assistant__step-detail {
2466
+ min-width: 0;
2467
+ overflow: hidden;
2468
+ text-overflow: ellipsis;
2469
+ white-space: nowrap;
2470
+ font-family: var(--font-mono);
2471
+ font-size: 11.5px;
2472
+ color: var(--ink-3);
2473
+ }
2474
+ /* A run of calls between two things the agent said, folded to the one line that counts them. */
2475
+ .agent-run__calls > details {
2476
+ flex: 1 1 auto;
2035
2477
  min-width: 0;
2478
+ }
2479
+ .agent-run__calls summary {
2480
+ cursor: pointer;
2036
2481
  overflow: hidden;
2037
2482
  text-overflow: ellipsis;
2038
2483
  white-space: nowrap;
2039
- font-size: 11.5px;
2040
2484
  color: var(--ink-3);
2041
2485
  }
2042
- /* What it said on the way: its own words, set apart from the calls by having no mark. */
2486
+ .agent-run__calls summary:hover {
2487
+ color: var(--ink-1);
2488
+ }
2489
+ .agent-run__calls .agent-run__steps {
2490
+ margin-top: 4px;
2491
+ }
2492
+
2493
+ /* Between calls: composing, which no call records. Quieter than a call, since nothing has happened yet. */
2494
+ .assistant__step--waiting .assistant__step-text {
2495
+ font-style: italic;
2496
+ color: var(--ink-3);
2497
+ }
2498
+
2499
+ /* What it said on the way: its own words, in the reading face, set apart from the calls by having no mark. */
2043
2500
  .assistant__step--message {
2044
2501
  display: block;
2045
2502
  padding-left: 15px;
2503
+ font-family: var(--font-serif);
2046
2504
  font-style: italic;
2505
+ font-size: 13px;
2047
2506
  color: var(--ink-3);
2048
2507
  white-space: pre-line;
2049
2508
  overflow-wrap: anywhere;
@@ -2054,7 +2513,7 @@ a.button {
2054
2513
  display: flex;
2055
2514
  flex-wrap: wrap;
2056
2515
  gap: 6px;
2057
- margin-top: 6px;
2516
+ margin-top: 8px;
2058
2517
  }
2059
2518
 
2060
2519
  .assistant__quick {
@@ -2075,10 +2534,10 @@ a.button {
2075
2534
  padding: 8px 10px;
2076
2535
  border: 1px solid var(--border);
2077
2536
  border-radius: var(--radius-sm);
2078
- background: var(--page);
2537
+ background: var(--surface);
2079
2538
  color: var(--ink-1);
2080
2539
  font: inherit;
2081
- font-size: 13px;
2540
+ font-size: 13.5px;
2082
2541
  line-height: 1.4;
2083
2542
  resize: vertical;
2084
2543
  }
@@ -2092,12 +2551,15 @@ a.button {
2092
2551
  * The panel takes the side column: on Today it stands in for the agenda while it
2093
2552
  * is open, and on the boards it brings the column back. In the grid rather than
2094
2553
  * over it, so the list is never covered, and sticky like the agenda so a long
2095
- * list scrolls past a panel that stays put. Placed after the view rules above
2096
- * on purpose: they and these share a specificity, and the panel being open has
2554
+ * list scrolls past a panel that stays put. It is the one surface on the page
2555
+ * with an edge of its own, because it is the one thing that floats over the
2556
+ * sheet rather than being written on it. Placed after the view rules above on
2557
+ * purpose: they and these share a specificity, and the panel being open has
2097
2558
  * to win.
2098
2559
  */
2099
2560
  body[data-flyout='open'] .layout {
2100
2561
  grid-template-columns: minmax(0, 1fr) 420px;
2562
+ gap: 40px;
2101
2563
  }
2102
2564
  body[data-flyout='open'] .layout__side {
2103
2565
  display: none;
@@ -2112,8 +2574,8 @@ body[data-flyout='open'] .layout__side {
2112
2574
  max-height: calc(100vh - 32px);
2113
2575
  background: var(--surface);
2114
2576
  border: 1px solid var(--border);
2115
- border-radius: var(--radius);
2116
- box-shadow: var(--shadow);
2577
+ border-radius: 12px;
2578
+ box-shadow: var(--shadow-float);
2117
2579
  }
2118
2580
  .flyout[hidden] {
2119
2581
  display: none;
@@ -2123,7 +2585,7 @@ body[data-flyout='open'] .layout__side {
2123
2585
  display: grid;
2124
2586
  grid-template-columns: minmax(0, 1fr) auto;
2125
2587
  gap: 5px 10px;
2126
- padding: 14px 16px 13px;
2588
+ padding: 16px 18px 14px;
2127
2589
  border-bottom: 1px solid var(--hairline);
2128
2590
  }
2129
2591
  .flyout__where {
@@ -2131,7 +2593,7 @@ body[data-flyout='open'] .layout__side {
2131
2593
  flex-wrap: wrap;
2132
2594
  align-items: center;
2133
2595
  gap: 6px;
2134
- font-size: 12px;
2596
+ font-size: 12.5px;
2135
2597
  color: var(--ink-3);
2136
2598
  }
2137
2599
  .flyout__close {
@@ -2142,7 +2604,7 @@ body[data-flyout='open'] .layout__side {
2142
2604
  .flyout__title {
2143
2605
  grid-column: 1;
2144
2606
  margin: 0;
2145
- font-size: 15px;
2607
+ font-size: 15.5px;
2146
2608
  font-weight: 500;
2147
2609
  line-height: 1.4;
2148
2610
  color: var(--ink-1);
@@ -2154,11 +2616,11 @@ body[data-flyout='open'] .layout__side {
2154
2616
  }
2155
2617
  .flyout__title a:hover {
2156
2618
  text-decoration: underline;
2157
- text-decoration-color: var(--accent);
2619
+ text-decoration-color: var(--ink-3);
2158
2620
  }
2159
2621
 
2160
2622
  /*
2161
- * A ticket's status and park, laid out as on its card: the status at the left,
2623
+ * A ticket's status and park, laid out as on its row: the status at the left,
2162
2624
  * the park at the right, so each menu opens into the panel rather than out over
2163
2625
  * the list. Under the close button too, so the park lines up with it. A child
2164
2626
  * combinator, because the park menu's own Set button is a `.button` in here.
@@ -2178,17 +2640,20 @@ body[data-flyout='open'] .layout__side {
2178
2640
  flex: 1;
2179
2641
  min-height: 0;
2180
2642
  overflow-y: auto;
2181
- padding: 16px 16px 20px;
2643
+ padding: 18px 18px 22px;
2182
2644
  }
2183
2645
  /* The assistant's field and its canned asks, pinned under the body that scrolls. */
2184
2646
  .flyout__footer {
2185
2647
  flex: none;
2186
- padding: 12px 16px 14px;
2648
+ padding: 12px 18px 16px;
2187
2649
  border-top: 1px solid var(--hairline);
2188
2650
  }
2651
+ /* What the agent wrote under the row: the brief's own words, so the reading face. */
2189
2652
  .flyout__detail {
2190
- margin: 0 0 22px;
2191
- font-size: 13px;
2653
+ margin: 0 0 24px;
2654
+ font-family: var(--font-serif);
2655
+ font-size: 14px;
2656
+ line-height: 1.55;
2192
2657
  color: var(--ink-2);
2193
2658
  overflow-wrap: anywhere;
2194
2659
  }
@@ -2196,28 +2661,29 @@ body[data-flyout='open'] .layout__side {
2196
2661
  padding: 1px 4px;
2197
2662
  background: var(--surface-sunken);
2198
2663
  border-radius: 3px;
2199
- font-size: 0.92em;
2664
+ font-family: var(--font-mono);
2665
+ font-size: 0.9em;
2200
2666
  }
2201
2667
 
2202
2668
  .flyout__section + .flyout__section {
2203
- margin-top: 26px;
2669
+ margin-top: 28px;
2204
2670
  }
2205
2671
  .flyout__label {
2206
2672
  margin: 0 0 10px;
2207
- font-size: 11.5px;
2673
+ padding: 0 0 6px;
2674
+ border-bottom: 1px solid var(--hairline);
2675
+ font-size: 12.5px;
2208
2676
  font-weight: 600;
2209
- letter-spacing: 0.04em;
2210
- text-transform: uppercase;
2211
- color: var(--ink-3);
2677
+ color: var(--ink-2);
2212
2678
  }
2213
2679
 
2214
2680
  .flyout__notes {
2215
2681
  margin: 0 0 12px;
2216
- padding: 7px 10px;
2682
+ padding: 2px 0 2px 12px;
2217
2683
  border-left: 2px solid var(--hairline);
2218
- background: var(--surface-sunken);
2219
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
2220
- font-size: 12.5px;
2684
+ font-family: var(--font-serif);
2685
+ font-size: 13.5px;
2686
+ line-height: 1.5;
2221
2687
  color: var(--ink-2);
2222
2688
  }
2223
2689
  .flyout__note {
@@ -2228,12 +2694,13 @@ body[data-flyout='open'] .layout__side {
2228
2694
  }
2229
2695
  .flyout__when {
2230
2696
  color: var(--ink-3);
2697
+ font-family: var(--font);
2231
2698
  font-size: 11.5px;
2232
2699
  white-space: nowrap;
2233
2700
  }
2234
2701
  .flyout__empty {
2235
2702
  margin: 0 0 10px;
2236
- font-size: 12.5px;
2703
+ font-size: 13px;
2237
2704
  color: var(--ink-3);
2238
2705
  }
2239
2706
 
@@ -2255,10 +2722,10 @@ body[data-flyout='open'] .layout__side {
2255
2722
  padding: 0 10px;
2256
2723
  border: 1px solid var(--border);
2257
2724
  border-radius: var(--radius-sm);
2258
- background: var(--page);
2725
+ background: var(--surface);
2259
2726
  color: var(--ink-1);
2260
2727
  font: inherit;
2261
- font-size: 13px;
2728
+ font-size: 13.5px;
2262
2729
  }
2263
2730
  .flyout__submit {
2264
2731
  flex: none;
@@ -2277,7 +2744,7 @@ body[data-flyout='open'] .layout__side {
2277
2744
  z-index: 15;
2278
2745
  max-height: 80vh;
2279
2746
  border-bottom: 0;
2280
- border-radius: var(--radius) var(--radius) 0 0;
2747
+ border-radius: 12px 12px 0 0;
2281
2748
  }
2282
2749
  /* The sheet has the bottom, so a toast goes to the top rather than over its field. */
2283
2750
  body[data-flyout='open'] .toast {
@@ -2292,52 +2759,62 @@ body[data-flyout='open'] .layout__side {
2292
2759
  padding: 0;
2293
2760
  border: 0;
2294
2761
  background: none;
2295
- color: var(--accent);
2762
+ color: var(--ink-1);
2296
2763
  font: inherit;
2764
+ text-decoration: underline;
2765
+ text-decoration-color: var(--ink-3);
2766
+ text-underline-offset: 2px;
2297
2767
  cursor: pointer;
2298
2768
  }
2299
2769
  .link-button:hover {
2300
- text-decoration: underline;
2770
+ text-decoration-color: currentColor;
2301
2771
  }
2302
2772
  .objective__edit {
2303
- margin-left: 8px;
2304
- font-size: 11px;
2773
+ font-size: 12.5px;
2305
2774
  font-weight: 500;
2306
- letter-spacing: normal;
2307
- text-transform: none;
2775
+ color: var(--ink-3);
2776
+ text-decoration: none;
2777
+ }
2778
+ .objective__edit:hover {
2779
+ color: var(--ink-1);
2780
+ text-decoration: underline;
2308
2781
  }
2309
2782
 
2310
2783
  /* ---------- the first brief, after setup ---------- */
2311
2784
 
2312
2785
  /*
2313
- * Today between the setup screen and the first brief. Built from the
2314
- * objective's card, since it does the same job in its place: the first thing
2315
- * read, before anything else exists.
2786
+ * Today between the setup screen and the first brief. Set as the objective is,
2787
+ * since it does the same job in its place: the first thing read, before
2788
+ * anything else exists. On the paper, not the band: the band holds a morning's
2789
+ * masthead, and there is no morning yet.
2316
2790
  */
2317
2791
  .first-brief {
2318
- padding: 18px 20px;
2319
- background: var(--surface);
2320
- border: 1px solid var(--border);
2321
- border-left: 3px solid var(--accent);
2322
- border-radius: var(--radius);
2323
- box-shadow: var(--shadow);
2792
+ max-width: 60ch;
2793
+ padding: 10px 0 0;
2324
2794
  }
2325
2795
  .first-brief__title {
2326
- margin: 0 0 6px;
2327
- font-size: 18px;
2328
- letter-spacing: -0.01em;
2796
+ margin: 0 0 8px;
2797
+ font-family: var(--font-serif);
2798
+ font-size: 26px;
2799
+ font-weight: 500;
2800
+ line-height: 1.2;
2801
+ letter-spacing: -0.005em;
2329
2802
  }
2330
2803
  .first-brief__text {
2331
2804
  margin: 0;
2332
2805
  color: var(--ink-2);
2333
- font-size: 13.5px;
2334
- line-height: 1.5;
2806
+ font-size: 14.5px;
2807
+ line-height: 1.55;
2335
2808
  }
2336
2809
  .first-brief__actions {
2337
2810
  display: flex;
2338
2811
  flex-wrap: wrap;
2339
2812
  gap: 8px;
2340
- margin-top: 14px;
2813
+ margin-top: 18px;
2814
+ }
2815
+ .first-brief .button {
2816
+ padding: 7px 14px;
2817
+ font-size: 13.5px;
2341
2818
  }
2342
2819
 
2343
2820
  /* ---------- the setup screen ---------- */
@@ -2345,11 +2822,12 @@ body[data-flyout='open'] .layout__side {
2345
2822
  /*
2346
2823
  * The whole page while a new store is set up: one column, one question open at
2347
2824
  * a time, on a thread whose dots are the questions. Answered ones fold into a
2348
- * sentence; the open one is the only card. The buttons here are larger than the
2349
- * dashboard's: this page is read once, slowly, and each one is a decision.
2825
+ * sentence; the open one is the only card. The questions are set in the serif,
2826
+ * since they are read once and slowly, and the buttons here are larger than the
2827
+ * dashboard's: each one is a decision.
2350
2828
  */
2351
2829
  /* The page's own margins are the dashboard's; this one runs edge to edge. */
2352
- body[data-onboarding='true'] {
2830
+ body[data-onboarding='true'] #app {
2353
2831
  padding: 0;
2354
2832
  }
2355
2833
  .onboarding {
@@ -2363,14 +2841,13 @@ body[data-onboarding='true'] {
2363
2841
  display: flex;
2364
2842
  align-items: center;
2365
2843
  gap: 18px;
2366
- padding: 14px 24px;
2367
- background: var(--page);
2368
- border-bottom: 1px solid var(--hairline);
2844
+ padding: 14px 28px;
2845
+ background: var(--band);
2369
2846
  font-size: 13px;
2370
- color: var(--ink-2);
2847
+ color: var(--band-muted);
2371
2848
  }
2372
2849
  .onboarding__name {
2373
- color: var(--ink-1);
2850
+ color: var(--band-ink);
2374
2851
  font-weight: 600;
2375
2852
  font-size: 14px;
2376
2853
  }
@@ -2385,7 +2862,7 @@ body[data-onboarding='true'] {
2385
2862
  max-width: 220px;
2386
2863
  height: 4px;
2387
2864
  border-radius: 2px;
2388
- background: var(--hairline);
2865
+ background: rgba(255, 255, 255, 0.2);
2389
2866
  overflow: hidden;
2390
2867
  }
2391
2868
  .onboarding__track i {
@@ -2396,15 +2873,16 @@ body[data-onboarding='true'] {
2396
2873
  transition: width 0.3s ease;
2397
2874
  }
2398
2875
  .onboarding__column {
2399
- max-width: 600px;
2876
+ max-width: 640px;
2400
2877
  margin: 0 auto;
2401
- padding: 32px 24px 30vh;
2878
+ padding: 40px 24px 30vh;
2402
2879
  }
2403
2880
  .onboarding__lede {
2404
- margin: 0 0 24px;
2881
+ margin: 0 0 28px;
2405
2882
  padding-left: 30px;
2883
+ font-family: var(--font-serif);
2406
2884
  color: var(--ink-2);
2407
- font-size: 15px;
2885
+ font-size: 17px;
2408
2886
  line-height: 1.55;
2409
2887
  }
2410
2888
  .onboarding__thread {
@@ -2438,7 +2916,7 @@ body[data-onboarding='true'] {
2438
2916
  }
2439
2917
  .onboarding__dot--open {
2440
2918
  left: -30px;
2441
- top: 11px;
2919
+ top: 13px;
2442
2920
  width: 13px;
2443
2921
  height: 13px;
2444
2922
  background: var(--accent);
@@ -2450,7 +2928,7 @@ body[data-onboarding='true'] {
2450
2928
  width: 8px;
2451
2929
  height: 8px;
2452
2930
  background: var(--page);
2453
- border: 1.5px solid var(--accent);
2931
+ border: 1.5px solid var(--ink-1);
2454
2932
  }
2455
2933
  .onboarding__dot--later {
2456
2934
  border-color: var(--hairline);
@@ -2462,7 +2940,7 @@ body[data-onboarding='true'] {
2462
2940
  gap: 12px;
2463
2941
  padding: 5px 0;
2464
2942
  color: var(--ink-2);
2465
- font-size: 14px;
2943
+ font-size: 14.5px;
2466
2944
  line-height: 1.5;
2467
2945
  }
2468
2946
  .onboarding__done[data-status='later'] {
@@ -2488,22 +2966,24 @@ body[data-onboarding='true'] {
2488
2966
  cursor: pointer;
2489
2967
  }
2490
2968
  .onboarding__change:hover {
2491
- color: var(--accent);
2969
+ color: var(--ink-1);
2970
+ text-decoration: underline;
2492
2971
  }
2493
2972
  .onboarding__change:disabled {
2494
2973
  visibility: hidden;
2495
2974
  }
2496
2975
 
2497
2976
  .onboarding__card {
2498
- margin: 22px 0 28px;
2977
+ margin: 24px 0 30px;
2499
2978
  scroll-margin: 90px 0 120px;
2500
2979
  }
2501
2980
  .onboarding__card h2 {
2502
- margin: 0 0 10px;
2503
- font-size: 24px;
2981
+ margin: 0 0 12px;
2982
+ font-family: var(--font-serif);
2983
+ font-size: 27px;
2504
2984
  line-height: 1.2;
2505
- font-weight: 650;
2506
- letter-spacing: -0.01em;
2985
+ font-weight: 500;
2986
+ letter-spacing: -0.005em;
2507
2987
  text-wrap: balance;
2508
2988
  }
2509
2989
  .onboarding__card h2:focus {
@@ -2544,7 +3024,7 @@ body[data-onboarding='true'] {
2544
3024
  .onboarding__sparkle {
2545
3025
  flex: none;
2546
3026
  margin-top: 3px;
2547
- color: var(--accent);
3027
+ color: var(--accent-ink);
2548
3028
  }
2549
3029
  .onboarding__looking {
2550
3030
  margin: 0 0 16px;
@@ -2622,9 +3102,6 @@ body[data-onboarding='true'] {
2622
3102
  flex-wrap: wrap;
2623
3103
  gap: 16px;
2624
3104
  }
2625
- .onboarding__links a {
2626
- color: var(--accent);
2627
- }
2628
3105
  .onboarding__problem[data-blocking='false'] {
2629
3106
  margin: 0;
2630
3107
  border-left-color: var(--hairline);
@@ -2632,9 +3109,10 @@ body[data-onboarding='true'] {
2632
3109
  }
2633
3110
  .onboarding__problem pre {
2634
3111
  margin: 0 0 10px;
2635
- padding: 6px 10px;
3112
+ padding: 8px 10px;
2636
3113
  background: var(--surface-sunken);
2637
3114
  border-radius: var(--radius-sm);
3115
+ font-family: var(--font-mono);
2638
3116
  font-size: 13px;
2639
3117
  overflow-x: auto;
2640
3118
  }
@@ -2651,7 +3129,7 @@ body[data-onboarding='true'] {
2651
3129
  .onboarding__legend {
2652
3130
  margin-bottom: 8px;
2653
3131
  padding: 0;
2654
- color: var(--ink-3);
3132
+ color: var(--ink-2);
2655
3133
  font-size: 13px;
2656
3134
  font-weight: 600;
2657
3135
  }
@@ -2664,7 +3142,7 @@ body[data-onboarding='true'] {
2664
3142
  padding: 6px 13px;
2665
3143
  border: 1px solid var(--border);
2666
3144
  border-radius: 999px;
2667
- background: var(--surface);
3145
+ background: transparent;
2668
3146
  color: var(--ink-1);
2669
3147
  font: inherit;
2670
3148
  font-size: 14px;
@@ -2672,18 +3150,18 @@ body[data-onboarding='true'] {
2672
3150
  }
2673
3151
  .onboarding__pill:hover {
2674
3152
  border-color: var(--ink-3);
3153
+ background: var(--surface-sunken);
2675
3154
  }
2676
3155
  .onboarding__pill[aria-checked='true'] {
2677
- border-color: var(--accent);
2678
- background: var(--accent-wash);
2679
- color: var(--accent);
2680
- font-weight: 600;
3156
+ border-color: var(--band);
3157
+ background: var(--band);
3158
+ color: var(--band-ink);
3159
+ font-weight: 500;
2681
3160
  }
2682
3161
  .onboarding__list {
2683
3162
  background: var(--surface);
2684
3163
  border: 1px solid var(--border);
2685
3164
  border-radius: var(--radius);
2686
- box-shadow: var(--shadow);
2687
3165
  overflow: hidden;
2688
3166
  }
2689
3167
  .onboarding__group + .onboarding__group,
@@ -2733,15 +3211,15 @@ body[data-onboarding='true'] {
2733
3211
  border-radius: 50%;
2734
3212
  }
2735
3213
  .onboarding__option input:checked + .onboarding__box {
2736
- border-color: var(--accent);
2737
- background: var(--accent);
3214
+ border-color: var(--band);
3215
+ background: var(--band);
2738
3216
  }
2739
3217
  .onboarding__option input:checked + .onboarding__box[data-kind='check']::after {
2740
3218
  content: '';
2741
3219
  width: 9px;
2742
3220
  height: 5px;
2743
- border-left: 2px solid #fff;
2744
- border-bottom: 2px solid #fff;
3221
+ border-left: 2px solid var(--band-ink);
3222
+ border-bottom: 2px solid var(--band-ink);
2745
3223
  transform: translateY(-1px) rotate(-45deg);
2746
3224
  }
2747
3225
  .onboarding__option input:checked + .onboarding__box[data-kind='radio']::after {
@@ -2749,7 +3227,7 @@ body[data-onboarding='true'] {
2749
3227
  width: 6px;
2750
3228
  height: 6px;
2751
3229
  border-radius: 50%;
2752
- background: #fff;
3230
+ background: var(--band-ink);
2753
3231
  }
2754
3232
  .onboarding__option input:focus-visible + .onboarding__box {
2755
3233
  outline: 2px solid var(--focus-ring);
@@ -2778,11 +3256,17 @@ body[data-onboarding='true'] {
2778
3256
  padding: 8px 0;
2779
3257
  border: 0;
2780
3258
  background: none;
2781
- color: var(--accent);
3259
+ color: var(--ink-1);
2782
3260
  font: inherit;
2783
3261
  font-size: 14px;
3262
+ text-decoration: underline;
3263
+ text-decoration-color: var(--ink-3);
3264
+ text-underline-offset: 2px;
2784
3265
  cursor: pointer;
2785
3266
  }
3267
+ .onboarding__add-button:hover {
3268
+ text-decoration-color: currentColor;
3269
+ }
2786
3270
  .onboarding__pills .onboarding__add-button {
2787
3271
  padding: 6px 4px;
2788
3272
  }
@@ -2796,14 +3280,14 @@ body[data-onboarding='true'] {
2796
3280
  .onboarding__tell input {
2797
3281
  flex: 1;
2798
3282
  min-width: 0;
2799
- height: 34px;
3283
+ height: 36px;
2800
3284
  padding: 0 10px;
2801
3285
  border: 1px solid var(--border);
2802
3286
  border-radius: var(--radius-sm);
2803
3287
  background: var(--surface);
2804
3288
  color: var(--ink-1);
2805
3289
  font: inherit;
2806
- font-size: 14px;
3290
+ font-size: 14.5px;
2807
3291
  }
2808
3292
  .onboarding__fields {
2809
3293
  display: grid;
@@ -2858,7 +3342,7 @@ body[data-onboarding='true'] {
2858
3342
  font-size: 14px;
2859
3343
  }
2860
3344
  .onboarding__field-label {
2861
- font-size: 13px;
3345
+ font-size: 13.5px;
2862
3346
  font-weight: 500;
2863
3347
  color: var(--ink-2);
2864
3348
  }
@@ -2874,9 +3358,9 @@ body[data-onboarding='true'] {
2874
3358
  gap: 10px;
2875
3359
  }
2876
3360
  .onboarding .button {
2877
- padding: 8px 16px;
2878
- border-radius: 8px;
2879
- font-size: 14px;
3361
+ padding: 9px 16px;
3362
+ border-radius: var(--radius);
3363
+ font-size: 14.5px;
2880
3364
  font-weight: 550;
2881
3365
  }
2882
3366
  .onboarding .onboarding__quiet {
@@ -2886,6 +3370,7 @@ body[data-onboarding='true'] {
2886
3370
  }
2887
3371
  .onboarding .onboarding__quiet:hover {
2888
3372
  color: var(--ink-1);
3373
+ background: var(--surface-sunken);
2889
3374
  }
2890
3375
  .onboarding__tell {
2891
3376
  display: flex;
@@ -2917,6 +3402,9 @@ body[data-onboarding='true'] {
2917
3402
  color: var(--ink-2);
2918
3403
  font-size: 14px;
2919
3404
  }
3405
+ .onboarding__preview > summary:hover {
3406
+ color: var(--ink-1);
3407
+ }
2920
3408
  .onboarding__preview pre {
2921
3409
  max-height: 360px;
2922
3410
  margin: 10px 0 0;
@@ -2925,6 +3413,7 @@ body[data-onboarding='true'] {
2925
3413
  background: var(--surface);
2926
3414
  border: 1px solid var(--border);
2927
3415
  border-radius: var(--radius-sm);
3416
+ font-family: var(--font-mono);
2928
3417
  font-size: 12.5px;
2929
3418
  line-height: 1.5;
2930
3419
  white-space: pre-wrap;
@@ -2937,30 +3426,83 @@ body[data-onboarding='true'] {
2937
3426
 
2938
3427
  /* ---------- settings ---------- */
2939
3428
 
3429
+ /*
3430
+ * A column of groups, each a sheet titled in the serif, with an index beside
3431
+ * them that stays put as the page scrolls and says where on it you are. In a
3432
+ * group, each setting is a row: its name and what it does on the left, the
3433
+ * control on the right, a rule between rows.
3434
+ */
2940
3435
  .settings {
2941
3436
  display: grid;
2942
- gap: 16px;
2943
- max-width: 760px;
2944
- padding-bottom: 72px;
3437
+ grid-template-columns: minmax(0, 740px) 200px;
3438
+ column-gap: 44px;
3439
+ row-gap: 16px;
3440
+ max-width: 1000px;
3441
+ padding-bottom: 80px;
3442
+ }
3443
+ .settings > * {
3444
+ grid-column: 1;
2945
3445
  }
2946
3446
  .settings__head {
2947
3447
  display: flex;
2948
- align-items: center;
3448
+ align-items: baseline;
2949
3449
  justify-content: space-between;
3450
+ padding: 4px 2px 0;
3451
+ }
3452
+ .settings__nav {
3453
+ grid-column: 2;
3454
+ grid-row: 2 / span 40;
3455
+ position: sticky;
3456
+ top: 24px;
3457
+ align-self: start;
3458
+ display: grid;
3459
+ gap: 2px;
3460
+ padding-top: 4px;
3461
+ }
3462
+ .settings__nav a {
3463
+ display: block;
3464
+ padding: 5px 10px;
3465
+ border-left: 2px solid transparent;
3466
+ border-radius: 0 6px 6px 0;
3467
+ color: var(--ink-2);
3468
+ font-size: 13.5px;
3469
+ text-decoration: none;
3470
+ }
3471
+ .settings__nav a:hover {
3472
+ color: var(--ink-1);
3473
+ background: var(--surface-sunken);
3474
+ }
3475
+ .settings__nav a[aria-current='true'] {
3476
+ border-left-color: var(--accent);
3477
+ color: var(--ink-1);
3478
+ font-weight: 600;
3479
+ }
3480
+ @media (max-width: 1000px) {
3481
+ .settings {
3482
+ grid-template-columns: minmax(0, 1fr);
3483
+ }
3484
+ .settings__nav {
3485
+ display: none;
3486
+ }
2950
3487
  }
2951
3488
  .settings__title {
2952
3489
  margin: 0;
2953
- font-size: 18px;
3490
+ font-family: var(--font-serif);
3491
+ font-size: 26px;
3492
+ font-weight: 500;
3493
+ letter-spacing: -0.005em;
2954
3494
  }
2955
3495
  .settings__problem {
2956
3496
  margin: 0;
2957
3497
  padding: 10px 14px;
2958
- border: 1px solid var(--warning);
3498
+ border: 1px solid var(--border);
3499
+ border-left: 3px solid var(--warning);
2959
3500
  border-radius: var(--radius-sm);
2960
- font-size: 13px;
3501
+ background: var(--surface);
3502
+ font-size: 13.5px;
2961
3503
  }
2962
3504
  .settings-card {
2963
- padding: 16px 18px;
3505
+ padding: 18px 24px 6px;
2964
3506
  background: var(--surface);
2965
3507
  border: 1px solid var(--border);
2966
3508
  border-radius: var(--radius);
@@ -2968,55 +3510,148 @@ body[data-onboarding='true'] {
2968
3510
  scroll-margin-top: 16px;
2969
3511
  }
2970
3512
  .settings-card__title {
2971
- margin: 0 0 10px;
2972
- font-size: 15px;
3513
+ margin: 0 0 4px;
3514
+ font-family: var(--font-serif);
3515
+ font-size: 19px;
3516
+ font-weight: 500;
2973
3517
  }
2974
3518
  .settings-card__help {
2975
- margin: 0 0 12px;
3519
+ margin: 0 0 10px;
3520
+ max-width: 70ch;
2976
3521
  color: var(--ink-2);
2977
- font-size: 13px;
3522
+ font-size: 13.5px;
2978
3523
  line-height: 1.5;
2979
3524
  }
2980
3525
  .settings-card__warning {
2981
3526
  margin: 0 0 10px;
2982
3527
  color: var(--serious);
2983
- font-size: 13px;
3528
+ font-size: 13.5px;
2984
3529
  }
2985
3530
  .settings-card__more {
2986
- margin-top: 6px;
3531
+ margin: 0;
2987
3532
  }
2988
3533
  .settings-card__more > summary {
3534
+ padding: 12px 0;
3535
+ border-top: 1px solid var(--rule);
2989
3536
  cursor: pointer;
2990
3537
  color: var(--ink-2);
2991
- font-size: 13px;
2992
- padding: 4px 0;
3538
+ font-size: 13.5px;
2993
3539
  }
2994
- .settings-card__more[open] > summary {
2995
- margin-bottom: 10px;
3540
+ .settings-card__more > summary:hover {
3541
+ color: var(--ink-1);
2996
3542
  }
2997
3543
 
3544
+ /* One setting: name and help on the left, the control on the right. */
2998
3545
  .field {
2999
3546
  display: grid;
3000
- gap: 4px;
3001
- margin-bottom: 14px;
3547
+ grid-template-columns: minmax(0, 1fr) 300px;
3548
+ grid-template-areas:
3549
+ 'label control'
3550
+ 'help control'
3551
+ 'note control';
3552
+ column-gap: 28px;
3553
+ row-gap: 3px;
3554
+ align-items: start;
3555
+ margin: 0;
3556
+ padding: 14px 0;
3557
+ border-top: 1px solid var(--rule);
3002
3558
  }
3003
- .settings-card > .field:last-child,
3004
- .settings-card__more > .field:last-child {
3005
- margin-bottom: 0;
3559
+ .settings-card__title + .field,
3560
+ .settings-card__help + .field,
3561
+ .settings-card__warning + .field,
3562
+ .settings-card__more > .field:first-of-type {
3563
+ border-top: 0;
3006
3564
  }
3007
3565
  .field__label {
3008
- font-size: 13px;
3009
- font-weight: 500;
3566
+ grid-area: label;
3567
+ font-size: 14px;
3568
+ font-weight: 600;
3010
3569
  }
3011
3570
  .field__input {
3012
- height: 32px;
3571
+ grid-area: control;
3572
+ width: 100%;
3573
+ height: 34px;
3013
3574
  padding: 0 10px;
3014
3575
  border: 1px solid var(--border);
3015
3576
  border-radius: var(--radius-sm);
3016
3577
  background: var(--page);
3017
3578
  color: var(--ink-1);
3018
3579
  font: inherit;
3580
+ font-size: 13.5px;
3581
+ }
3582
+ select.field__input {
3583
+ appearance: none;
3584
+ padding-right: 30px;
3585
+ background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236e7484' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
3586
+ background-repeat: no-repeat;
3587
+ background-position: right 10px center;
3588
+ background-size: 14px;
3589
+ }
3590
+ @media (max-width: 600px) {
3591
+ .field {
3592
+ grid-template-columns: minmax(0, 1fr);
3593
+ grid-template-areas:
3594
+ 'label'
3595
+ 'help'
3596
+ 'note'
3597
+ 'control';
3598
+ }
3599
+ }
3600
+
3601
+ /*
3602
+ * A yes/no, or a short list: a segmented control of the real answers. The one
3603
+ * in force by default says "default" beside its name, so a setting never
3604
+ * touched never looks like a choice that was made.
3605
+ */
3606
+ .segmented {
3607
+ grid-area: control;
3608
+ display: inline-flex;
3609
+ justify-self: end;
3610
+ max-width: 100%;
3611
+ padding: 3px;
3612
+ background: var(--surface-sunken);
3613
+ border: 1px solid var(--hairline);
3614
+ border-radius: 999px;
3615
+ }
3616
+ .segmented__option {
3617
+ display: inline-flex;
3618
+ align-items: baseline;
3619
+ gap: 5px;
3620
+ padding: 4px 12px;
3621
+ border: 0;
3622
+ border-radius: 999px;
3623
+ background: none;
3624
+ color: var(--ink-2);
3625
+ font: inherit;
3019
3626
  font-size: 13px;
3627
+ font-weight: 500;
3628
+ white-space: nowrap;
3629
+ cursor: pointer;
3630
+ }
3631
+ .segmented__option small {
3632
+ font-size: 11.5px;
3633
+ color: var(--ink-3);
3634
+ }
3635
+ .segmented__option:hover {
3636
+ color: var(--ink-1);
3637
+ }
3638
+ .segmented__option[aria-checked='true'] {
3639
+ background: var(--band);
3640
+ color: var(--band-ink);
3641
+ }
3642
+ .segmented__option[aria-checked='true'] small {
3643
+ color: rgba(255, 255, 255, 0.7);
3644
+ }
3645
+ .segmented[aria-disabled='true'] {
3646
+ opacity: 0.55;
3647
+ }
3648
+ .segmented[aria-disabled='true'] .segmented__option {
3649
+ cursor: not-allowed;
3650
+ }
3651
+ @media (max-width: 600px) {
3652
+ .segmented {
3653
+ justify-self: start;
3654
+ }
3020
3655
  }
3021
3656
  .field__input:disabled {
3022
3657
  color: var(--ink-3);
@@ -3025,29 +3660,48 @@ body[data-onboarding='true'] {
3025
3660
  .field[data-changed='true'] .field__input {
3026
3661
  border-color: var(--accent);
3027
3662
  }
3663
+ .field[data-changed='true'] .segmented {
3664
+ border-color: var(--accent);
3665
+ }
3028
3666
  .field__help,
3029
3667
  .field__note {
3030
3668
  margin: 0;
3669
+ max-width: 70ch;
3031
3670
  color: var(--ink-3);
3032
- font-size: 12px;
3671
+ font-size: 12.5px;
3033
3672
  line-height: 1.45;
3034
3673
  }
3674
+ .field__help {
3675
+ grid-area: help;
3676
+ }
3035
3677
  .field__note {
3678
+ grid-area: note;
3036
3679
  color: var(--ink-2);
3037
3680
  }
3038
3681
 
3682
+ /* The objective's two fields read top to bottom: a sentence wants the width. */
3039
3683
  .objective-form {
3040
3684
  display: grid;
3041
3685
  gap: 2px;
3686
+ padding-top: 4px;
3687
+ }
3688
+ .objective-form .field {
3689
+ grid-template-columns: minmax(0, 1fr);
3690
+ grid-template-areas:
3691
+ 'label'
3692
+ 'control';
3693
+ padding: 8px 0 10px;
3042
3694
  }
3043
3695
  .objective-form__actions {
3044
3696
  display: flex;
3045
3697
  justify-content: flex-end;
3698
+ padding: 6px 0 12px;
3046
3699
  }
3047
3700
 
3048
3701
  .text-editor {
3049
3702
  display: grid;
3050
3703
  gap: 8px;
3704
+ padding-bottom: 14px;
3051
3705
  }
3052
3706
  .text-editor__area {
3053
3707
  width: 100%;
@@ -3057,7 +3711,7 @@ body[data-onboarding='true'] {
3057
3711
  border-radius: var(--radius-sm);
3058
3712
  background: var(--page);
3059
3713
  color: var(--ink-1);
3060
- font: 12.5px/1.5 ui-monospace, 'SF Mono', Menlo, monospace;
3714
+ font: 12.5px/1.5 var(--font-mono);
3061
3715
  resize: vertical;
3062
3716
  }
3063
3717
  .text-editor__bar {
@@ -3068,7 +3722,7 @@ body[data-onboarding='true'] {
3068
3722
  }
3069
3723
  .text-editor__status {
3070
3724
  color: var(--ink-3);
3071
- font-size: 12px;
3725
+ font-size: 12.5px;
3072
3726
  }
3073
3727
  .text-editor__conflict {
3074
3728
  display: flex;
@@ -3076,17 +3730,21 @@ body[data-onboarding='true'] {
3076
3730
  align-items: center;
3077
3731
  gap: 8px;
3078
3732
  padding: 8px 12px;
3079
- border: 1px solid var(--warning);
3733
+ border: 1px solid var(--border);
3734
+ border-left: 3px solid var(--warning);
3080
3735
  border-radius: var(--radius-sm);
3736
+ background: var(--page);
3081
3737
  }
3082
3738
  .text-editor__conflict p {
3083
3739
  flex: 1 1 100%;
3084
3740
  margin: 0;
3085
- font-size: 13px;
3741
+ font-size: 13.5px;
3086
3742
  }
3087
3743
 
3088
3744
  .calendar-picker {
3089
- margin: -4px 0 14px;
3745
+ margin: 0;
3746
+ padding: 12px 0;
3747
+ border-top: 1px solid var(--rule);
3090
3748
  }
3091
3749
  .calendar-picker__list {
3092
3750
  display: grid;
@@ -3095,7 +3753,7 @@ body[data-onboarding='true'] {
3095
3753
  margin: 10px 0 0;
3096
3754
  padding: 0;
3097
3755
  list-style: none;
3098
- font-size: 13px;
3756
+ font-size: 13.5px;
3099
3757
  }
3100
3758
  .calendar-picker__source {
3101
3759
  color: var(--ink-3);
@@ -3116,7 +3774,7 @@ body[data-onboarding='true'] {
3116
3774
  background: var(--surface);
3117
3775
  border: 1px solid var(--border);
3118
3776
  border-radius: var(--radius);
3119
- box-shadow: 0 6px 24px rgba(11, 11, 11, 0.14);
3777
+ box-shadow: var(--shadow-float);
3120
3778
  }
3121
3779
  .settings__bar[hidden] {
3122
3780
  display: none;
@@ -3124,7 +3782,7 @@ body[data-onboarding='true'] {
3124
3782
  .settings__bar-text {
3125
3783
  flex: 1;
3126
3784
  margin: 0;
3127
- font-size: 13px;
3785
+ font-size: 13.5px;
3128
3786
  color: var(--ink-2);
3129
3787
  }
3130
3788
  .settings__bar-text--error {