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

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,9 @@ 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
+ }
508
682
  /* What the agent said along the way, one fold per message, under its first line. */
509
683
  .agent-run__messages {
510
684
  display: flex;
@@ -517,7 +691,7 @@ body[data-view='tickets'] #brief-refresh {
517
691
  .agent-run__message {
518
692
  border: 1px solid var(--hairline);
519
693
  border-radius: var(--radius-sm);
520
- background: var(--surface-sunken);
694
+ background: var(--page);
521
695
  }
522
696
  .agent-run__message summary {
523
697
  padding: 6px 10px;
@@ -539,7 +713,9 @@ body[data-view='tickets'] #brief-refresh {
539
713
  display: inline;
540
714
  }
541
715
  .agent-run__message .assistant__reply {
716
+ margin: 0;
542
717
  padding: 0 10px 8px;
718
+ border-left: 0;
543
719
  }
544
720
  /*
545
721
  * A run's steps, the assistant's look: what it said in its own words between
@@ -550,8 +726,9 @@ body[data-view='tickets'] #brief-refresh {
550
726
  }
551
727
  .agent-run__said {
552
728
  margin: 6px 0;
553
- font-size: 12.5px;
554
- line-height: 1.45;
729
+ font-family: var(--font-serif);
730
+ font-size: 13.5px;
731
+ line-height: 1.5;
555
732
  color: var(--ink-1);
556
733
  overflow-wrap: anywhere;
557
734
  }
@@ -613,7 +790,7 @@ body[data-view='tickets'] #brief-refresh {
613
790
  padding: 7px 10px;
614
791
  border: 1px solid var(--hairline);
615
792
  border-radius: var(--radius-sm);
616
- background: var(--surface-sunken);
793
+ background: var(--page);
617
794
  text-align: left;
618
795
  font: inherit;
619
796
  color: var(--ink-2);
@@ -639,7 +816,7 @@ body[data-view='tickets'] #brief-refresh {
639
816
 
640
817
  /* Explanation, not status — so it borrows the accent, not one of the four state hues. */
641
818
  .banner--info {
642
- border-left: 3px solid var(--accent);
819
+ border-left-color: var(--accent);
643
820
  }
644
821
  .banner--info .banner__icon {
645
822
  color: var(--accent);
@@ -649,147 +826,275 @@ body[data-view='tickets'] #brief-refresh {
649
826
 
650
827
  .layout {
651
828
  display: grid;
652
- grid-template-columns: minmax(0, 1fr) 320px;
653
- gap: 24px;
829
+ grid-template-columns: minmax(0, 1fr) 300px;
830
+ gap: 48px;
654
831
  align-items: start;
655
- max-width: 1280px;
832
+ max-width: var(--page-width);
656
833
  margin: 0 auto;
657
834
  }
658
835
 
659
836
  @media (max-width: 900px) {
660
837
  .layout {
661
838
  grid-template-columns: minmax(0, 1fr);
839
+ gap: 32px;
662
840
  }
663
841
  .layout__side {
664
842
  order: -1;
665
843
  }
666
844
  }
667
845
 
668
- /* ---------- standing objective ---------- */
846
+ /* ---------- Today's masthead: the objective, the numbers, the note ---------- */
847
+
848
+ /*
849
+ * The rest of the morning's masthead, on the band with the date. Its band is
850
+ * its own pseudo-element (see `.band`), run up past the top of the page so it
851
+ * and the tabs' are one navy whatever sits between them, and it keeps a clear
852
+ * margin under the agent's note so the last line never sits on the edge.
853
+ */
854
+ .today__masthead {
855
+ position: relative;
856
+ padding: 2px 0 40px;
857
+ color: var(--band-ink);
858
+ }
859
+ .today__masthead::before {
860
+ top: -9999px;
861
+ }
669
862
 
670
863
  /*
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.
864
+ * A notice about the morning — the agent at work, a brief gone stale, a run
865
+ * that failed — is part of its masthead, so on Today it is drawn in the band's
866
+ * materials: the stats sheet's translucent white, the band's rule, its light
867
+ * ink. A sheet of paper laid on the band read as something from another page.
868
+ * The tone keeps its bar; the icons take the band's steps of red and amber.
869
+ */
870
+ body[data-view='today']:has(.today__masthead) .banner {
871
+ background: var(--band-sheet);
872
+ border-color: var(--band-rule);
873
+ color: #d9deea;
874
+ }
875
+ body[data-view='today']:has(.today__masthead) .banner--critical {
876
+ border-left-color: var(--band-critical);
877
+ }
878
+ body[data-view='today']:has(.today__masthead) .banner--critical .banner__icon {
879
+ color: var(--band-critical);
880
+ }
881
+ body[data-view='today']:has(.today__masthead) .banner--warning {
882
+ border-left-color: var(--warning);
883
+ }
884
+ body[data-view='today']:has(.today__masthead) .banner--info {
885
+ border-left-color: var(--accent);
886
+ }
887
+ body[data-view='today']:has(.today__masthead) .banner--link:hover {
888
+ background: rgba(255, 255, 255, 0.12);
889
+ }
890
+ body[data-view='today']:has(.today__masthead) .banner .button {
891
+ border-color: rgba(255, 255, 255, 0.28);
892
+ background: transparent;
893
+ color: var(--band-ink);
894
+ }
895
+ body[data-view='today']:has(.today__masthead) .banner .button:hover {
896
+ border-color: rgba(255, 255, 255, 0.5);
897
+ background: rgba(255, 255, 255, 0.1);
898
+ }
899
+ body[data-view='today']:has(.today__masthead) .banner a {
900
+ color: var(--band-ink);
901
+ }
902
+ body[data-view='today']:has(.today__masthead) .failure__facts {
903
+ color: var(--band-muted);
904
+ }
905
+ body[data-view='today']:has(.today__masthead) .failure__detail {
906
+ background: rgba(0, 0, 0, 0.28);
907
+ color: #d9deea;
908
+ }
909
+ .today__masthead + #sections {
910
+ margin-top: 30px;
911
+ }
912
+
913
+ /*
914
+ * The headline of the day-book: set in the serif, large, and without a box.
915
+ * Deliberately heavier than the agent's note below it. That one changes daily;
916
+ * this doesn't, and it should be the first thing read on the page.
673
917
  */
674
918
  .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);
919
+ margin: 4px 0 26px;
682
920
  }
683
921
 
684
922
  .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);
923
+ display: flex;
924
+ align-items: baseline;
925
+ gap: 10px;
926
+ margin: 0 0 6px;
927
+ font-size: 12.5px;
928
+ font-weight: 500;
929
+ color: var(--accent);
691
930
  }
692
931
 
693
932
  .objective__text {
694
933
  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);
934
+ max-width: 38ch;
935
+ font-family: var(--font-serif);
936
+ font-size: 24px;
937
+ font-weight: 500;
938
+ line-height: 1.25;
939
+ letter-spacing: -0.005em;
940
+ color: var(--band-ink);
941
+ text-wrap: pretty;
700
942
  }
701
943
 
702
944
  .objective__blocker {
703
- margin: 6px 0 0;
945
+ margin: 8px 0 0;
946
+ max-width: 70ch;
704
947
  font-size: 13.5px;
705
- color: var(--ink-2);
948
+ color: var(--band-muted);
706
949
  }
707
950
  .objective__blocker-label {
708
- color: var(--critical);
709
- font-weight: 500;
951
+ color: var(--band-critical);
952
+ font-weight: 600;
710
953
  }
711
954
 
712
955
  .objective__note {
713
956
  margin: 8px 0 0;
714
- font-size: 13px;
715
- color: var(--ink-3);
957
+ max-width: 70ch;
958
+ font-size: 13.5px;
959
+ color: var(--band-muted);
716
960
  }
717
961
 
718
- /* A reminder, not a headline: no accent, no shadow, nothing competing with the brief. */
962
+ /* A reminder, not a headline: nothing competing with the brief. */
719
963
  .objective--empty {
720
- padding: 10px 16px;
721
- background: transparent;
722
- border-style: dashed;
723
- border-left-width: 1px;
724
- box-shadow: none;
964
+ padding: 6px 0 6px 14px;
965
+ border-left: 2px dashed var(--band-rule);
966
+ }
967
+ .objective--empty .objective__label {
968
+ margin: 0;
969
+ font-size: 14px;
970
+ color: var(--band-ink);
725
971
  }
726
972
  .objective--empty .objective__note {
727
973
  margin-top: 2px;
728
974
  }
975
+ .objective--empty .link-button {
976
+ color: var(--band-ink);
977
+ }
978
+ .objective--empty code {
979
+ color: var(--band-ink);
980
+ }
729
981
 
730
982
  /* ---------- stat row ---------- */
731
983
 
984
+ /*
985
+ * The day's numbers on one sheet, each a figure with its name beneath and a
986
+ * rule between them, the way a planner's margin keeps its counts. One sheet
987
+ * rather than five tiles: the figures are read as a line, not compared as boxes.
988
+ */
732
989
  .stats {
733
- display: grid;
734
- grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
735
- gap: 12px;
736
- margin-bottom: 20px;
990
+ display: flex;
991
+ flex-wrap: wrap;
992
+ gap: 12px 0;
993
+ margin: 0;
994
+ padding: 14px 20px;
995
+ background: var(--band-sheet);
996
+ border: 1px solid var(--band-rule);
997
+ border-radius: var(--radius);
737
998
  }
738
999
 
739
1000
  .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);
1001
+ display: flex;
1002
+ flex-direction: column;
1003
+ flex: 1 1 120px;
1004
+ min-width: 0;
1005
+ padding: 0 20px;
1006
+ border-left: 1px solid var(--band-rule);
1007
+ }
1008
+ .stat:first-child {
1009
+ padding-left: 0;
1010
+ border-left: 0;
745
1011
  }
746
1012
  .stat__label {
747
- margin: 0;
748
- color: var(--ink-2);
749
- font-size: 12px;
1013
+ order: 2;
1014
+ margin: 2px 0 0;
1015
+ color: var(--band-muted);
1016
+ font-size: 12.5px;
1017
+ line-height: 1.35;
750
1018
  }
751
1019
  .stat__value {
752
- margin: 2px 0 0;
753
- font-size: 26px;
1020
+ order: 1;
1021
+ margin: 0;
1022
+ font-size: 22px;
754
1023
  font-weight: 600;
755
1024
  line-height: 1.15;
756
- letter-spacing: -0.02em;
1025
+ letter-spacing: -0.01em;
1026
+ font-variant-numeric: tabular-nums;
1027
+ white-space: nowrap; /* "5 h 15 min" is one figure, however narrow the column. */
1028
+ color: var(--band-ink);
757
1029
  }
758
1030
  .stat__value[data-tone='critical'] {
759
- color: var(--critical);
1031
+ color: var(--band-critical);
760
1032
  }
761
1033
  .stat__value[data-tone='good'] {
762
- color: var(--good-ink);
1034
+ color: var(--band-good);
763
1035
  }
764
1036
  .stat__footnote {
765
- margin: 3px 0 0;
766
- color: var(--ink-3);
767
- font-size: 11.5px;
1037
+ order: 3;
1038
+ margin: 4px 0 0;
1039
+ color: var(--band-muted);
1040
+ font-size: 12px;
768
1041
  line-height: 1.35;
769
- /* The last thing completed can be a full title; keep the tile from growing. */
1042
+ /* The last thing completed can be a full title; keep the line from growing. */
770
1043
  display: -webkit-box;
771
1044
  -webkit-line-clamp: 2;
772
1045
  -webkit-box-orient: vertical;
773
1046
  overflow: hidden;
774
1047
  }
775
1048
 
1049
+ /* Two to a line on a phone, the pairs ruled apart, rather than a ragged wrap. */
1050
+ @media (max-width: 600px) {
1051
+ .stats {
1052
+ display: grid;
1053
+ grid-template-columns: 1fr 1fr;
1054
+ gap: 14px 0;
1055
+ }
1056
+ .stat:nth-child(odd) {
1057
+ padding-left: 0;
1058
+ border-left: 0;
1059
+ }
1060
+ }
1061
+
1062
+ /*
1063
+ * The agent's one-line reading of the day, set as a note in the margin: the
1064
+ * serif's italic, against a rule. Yours above it is roman and heavy; this is
1065
+ * what it made of it. Anything bold in it steps back to roman, which is how
1066
+ * emphasis inside italic is made.
1067
+ */
776
1068
  .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;
1069
+ margin: 28px 0 0;
1070
+ padding: 2px 0 2px 16px;
1071
+ max-width: 64ch;
1072
+ border-left: 2px solid var(--accent);
1073
+ font-family: var(--font-serif);
1074
+ font-style: italic;
1075
+ font-size: 16px;
1076
+ line-height: 1.5;
1077
+ color: #c9d0e2;
1078
+ }
1079
+ .headline strong {
1080
+ font-style: normal;
1081
+ font-weight: 500;
1082
+ color: var(--band-ink);
1083
+ }
1084
+ .headline code {
1085
+ font-family: var(--font-mono);
1086
+ font-style: normal;
1087
+ font-size: 0.9em;
1088
+ color: var(--band-ink);
785
1089
  }
786
1090
 
787
1091
  /* ---------- sections ---------- */
788
1092
 
789
1093
  .section {
790
- margin-bottom: 22px;
1094
+ margin-bottom: 30px;
791
1095
  }
792
1096
 
1097
+ /* The heading stands on the paper above its sheet, naming what the sheet holds. */
793
1098
  .section__header {
794
1099
  display: flex;
795
1100
  align-items: baseline;
@@ -799,15 +1104,13 @@ body[data-view='tickets'] #brief-refresh {
799
1104
  }
800
1105
  .section__title {
801
1106
  margin: 0;
802
- font-size: 12px;
1107
+ font-size: 14px;
803
1108
  font-weight: 600;
804
- letter-spacing: 0.06em;
805
- text-transform: uppercase;
806
- color: var(--ink-2);
1109
+ color: var(--ink-1);
807
1110
  }
808
1111
  .section__count {
809
1112
  color: var(--ink-3);
810
- font-size: 12px;
1113
+ font-size: 12.5px;
811
1114
  font-variant-numeric: tabular-nums;
812
1115
  }
813
1116
  .section__dot {
@@ -818,40 +1121,52 @@ body[data-view='tickets'] #brief-refresh {
818
1121
  align-self: center;
819
1122
  }
820
1123
 
1124
+ /* A stack of cards with air between them; the heading stands on the paper above. */
821
1125
  .list {
822
1126
  list-style: none;
823
1127
  margin: 0;
824
1128
  padding: 0;
825
1129
  display: flex;
826
1130
  flex-direction: column;
827
- gap: 2px; /* the surface gap doing the separating, not a border */
1131
+ gap: 8px;
828
1132
  }
829
1133
 
830
1134
  /* ---------- item ---------- */
831
1135
 
1136
+ /*
1137
+ * A row is a card: its own sheet, with an edge, so where one ends and the next
1138
+ * begins is never in doubt. The one under the pointer darkens its edge, the
1139
+ * keyboard's cursor wears a ring, and the one the panel is open on carries a
1140
+ * bar on the edge the panel sits past.
1141
+ */
832
1142
  .item {
833
1143
  position: relative;
834
1144
  display: grid;
835
- grid-template-columns: auto minmax(0, 1fr);
836
- gap: 10px;
837
- padding: 11px 13px;
1145
+ grid-template-columns: 30px minmax(0, 1fr);
1146
+ gap: 0 8px;
1147
+ padding: 12px 14px 12px 8px;
838
1148
  background: var(--surface);
839
1149
  border: 1px solid var(--border);
840
1150
  border-radius: var(--radius);
841
1151
  box-shadow: var(--shadow);
1152
+ cursor: pointer; /* A click anywhere on the row opens the panel, and the cursor says so. */
842
1153
  scroll-margin: 90px;
843
1154
  }
1155
+ .item:hover {
1156
+ border-color: var(--ink-3);
1157
+ }
844
1158
  /*
845
1159
  * Two states used to share one look: selected and priority were both "accent
846
1160
  * border", so the ranked rows were indistinguishable from a keyboard cursor.
847
- * Selected is the quieter of the two.
1161
+ * The cursor is a ring; a rank is the numeral in the margin.
848
1162
  */
849
1163
  .item[data-selected='true'] {
850
- border-color: var(--ink-3);
851
- box-shadow: 0 0 0 1px var(--ink-3);
1164
+ border-color: var(--ink-2);
1165
+ box-shadow: 0 0 0 1px var(--ink-2);
852
1166
  }
853
- .item[data-priority='true'] {
854
- border-left: 3px solid var(--accent);
1167
+ .item[data-detail='true'] {
1168
+ border-color: var(--accent);
1169
+ box-shadow: inset -3px 0 0 var(--accent);
855
1170
  }
856
1171
  .item[data-status='done'] .item__title,
857
1172
  .item[data-status='dismissed'] .item__title {
@@ -863,18 +1178,44 @@ body[data-view='tickets'] #brief-refresh {
863
1178
  }
864
1179
 
865
1180
  .item__mark {
866
- padding-top: 4px;
1181
+ display: flex;
1182
+ justify-content: center;
1183
+ align-items: flex-start;
1184
+ padding-top: 6px;
867
1185
  }
868
1186
 
869
1187
  .item__dot {
870
- width: 9px;
871
- height: 9px;
1188
+ width: 8px;
1189
+ height: 8px;
872
1190
  border-radius: 50%;
873
1191
  display: block;
874
1192
  }
875
1193
 
1194
+ /*
1195
+ * A ranked row's number, in the margin where the dot would be. Drawn in the
1196
+ * serif at the title's cap height, so the three ranks read as a column down
1197
+ * the top of the page. The dot gives way: the source is named in text on the
1198
+ * line beneath, and the rank is what this row is for.
1199
+ */
1200
+ .item__mark[data-rank] {
1201
+ padding-top: 0;
1202
+ }
1203
+ .item__mark[data-rank]::before {
1204
+ content: attr(data-rank);
1205
+ font-family: var(--font-serif);
1206
+ font-size: 18px;
1207
+ font-weight: 500;
1208
+ line-height: 1.15;
1209
+ color: var(--accent-ink);
1210
+ font-variant-numeric: tabular-nums;
1211
+ }
1212
+ .item__mark[data-rank] .item__dot {
1213
+ display: none;
1214
+ }
1215
+
876
1216
  .item__body {
877
1217
  min-width: 0;
1218
+ max-width: 72ch;
878
1219
  }
879
1220
 
880
1221
  .item__title {
@@ -891,7 +1232,7 @@ body[data-view='tickets'] #brief-refresh {
891
1232
  }
892
1233
  .item__title a:hover {
893
1234
  text-decoration: underline;
894
- text-decoration-color: var(--accent);
1235
+ text-decoration-color: var(--ink-3);
895
1236
  }
896
1237
 
897
1238
  /*
@@ -909,9 +1250,9 @@ body[data-view='tickets'] #brief-refresh {
909
1250
  display: flex;
910
1251
  flex-wrap: wrap;
911
1252
  align-items: center;
912
- gap: 6px;
1253
+ gap: 4px 6px;
913
1254
  margin-top: 5px;
914
- font-size: 12px;
1255
+ font-size: 12.5px;
915
1256
  color: var(--ink-3);
916
1257
  }
917
1258
 
@@ -922,21 +1263,22 @@ body[data-view='tickets'] #brief-refresh {
922
1263
 
923
1264
  .item__detail {
924
1265
  margin: 6px 0 0;
925
- font-size: 13px;
1266
+ font-size: 13.5px;
1267
+ line-height: 1.5;
926
1268
  color: var(--ink-2);
927
1269
  overflow-wrap: anywhere;
928
1270
  }
929
1271
  /*
930
1272
  * 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.
1273
+ * the row says what to do about the pull request before it is opened.
932
1274
  */
933
1275
  .item__ahead {
934
1276
  display: -webkit-box;
935
- margin: 6px 0 0;
1277
+ margin: 7px 0 0;
936
1278
  padding: 4px 8px;
937
1279
  border-radius: var(--radius-sm);
938
1280
  background: var(--accent-wash);
939
- font-size: 12.5px;
1281
+ font-size: 13px;
940
1282
  color: var(--ink-1);
941
1283
  overflow: hidden;
942
1284
  overflow-wrap: anywhere;
@@ -950,7 +1292,7 @@ body[data-view='tickets'] #brief-refresh {
950
1292
  }
951
1293
  .item__ahead-mark {
952
1294
  margin-right: 6px;
953
- color: var(--accent);
1295
+ color: var(--accent-ink);
954
1296
  font-weight: 600;
955
1297
  }
956
1298
  .item__ahead[data-status='running'] .item__ahead-mark {
@@ -971,16 +1313,8 @@ body[data-view='tickets'] #brief-refresh {
971
1313
  padding: 1px 4px;
972
1314
  background: var(--surface-sunken);
973
1315
  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);
1316
+ font-family: var(--font-mono);
1317
+ font-size: 0.9em;
984
1318
  }
985
1319
 
986
1320
  /* pills */
@@ -997,16 +1331,9 @@ body[data-view='tickets'] #brief-refresh {
997
1331
  color: var(--ink-2);
998
1332
  white-space: nowrap;
999
1333
  }
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
1334
  .pill--objective {
1008
- border-color: var(--accent);
1009
- color: var(--accent);
1335
+ border-color: var(--accent-ink);
1336
+ color: var(--accent-ink);
1010
1337
  font-weight: 500;
1011
1338
  }
1012
1339
  .pill--overdue {
@@ -1034,10 +1361,14 @@ body[data-view='tickets'] #brief-refresh {
1034
1361
 
1035
1362
  /* actions */
1036
1363
 
1364
+ /*
1365
+ * The strip sits over the card's top right on the card's own white, so the
1366
+ * tail of a long title is covered rather than shown through it.
1367
+ */
1037
1368
  .item__actions {
1038
1369
  position: absolute;
1039
- top: 8px;
1040
- right: 10px;
1370
+ top: 9px;
1371
+ right: 12px;
1041
1372
  display: flex;
1042
1373
  gap: 4px;
1043
1374
  opacity: 0;
@@ -1053,43 +1384,69 @@ body[data-view='tickets'] #brief-refresh {
1053
1384
  @media (hover: none) {
1054
1385
  .item__actions {
1055
1386
  opacity: 1;
1387
+ background: transparent;
1388
+ }
1389
+ }
1390
+ /*
1391
+ * On a phone the title runs the whole width, so a strip laid over its end
1392
+ * covers the words. There it takes a line of its own under the row instead.
1393
+ */
1394
+ @media (max-width: 600px) {
1395
+ .item__actions,
1396
+ .item:hover .item__actions,
1397
+ .item[data-selected='true'] .item__actions,
1398
+ .item[data-detail='true'] .item__actions {
1399
+ position: static;
1400
+ grid-column: 2;
1401
+ margin-top: 8px;
1402
+ padding-left: 0;
1403
+ opacity: 1;
1404
+ background: transparent;
1056
1405
  }
1057
1406
  }
1058
1407
 
1059
1408
  .button {
1060
- padding: 3px 9px;
1409
+ padding: 4px 10px;
1061
1410
  border: 1px solid var(--border);
1062
1411
  border-radius: var(--radius-sm);
1063
1412
  background: var(--surface);
1064
- color: var(--ink-2);
1413
+ color: var(--ink-1);
1065
1414
  font: inherit;
1066
- font-size: 12px;
1415
+ font-size: 12.5px;
1416
+ font-weight: 500;
1417
+ line-height: 1.5;
1067
1418
  cursor: pointer;
1068
1419
  white-space: nowrap;
1069
1420
  }
1070
1421
  .button:hover {
1071
- color: var(--ink-1);
1072
- border-color: var(--ink-3);
1422
+ border-color: var(--ink-2);
1423
+ background: var(--surface-sunken);
1073
1424
  }
1074
1425
  .button--primary {
1075
- border-color: transparent;
1426
+ border-color: var(--accent);
1076
1427
  background: var(--accent);
1077
- color: #fff;
1428
+ color: var(--on-accent);
1078
1429
  }
1079
1430
  .button--primary:hover {
1080
- color: #fff;
1081
- filter: brightness(1.08);
1431
+ border-color: #c9841f;
1432
+ background: #c9841f;
1433
+ color: var(--on-accent);
1082
1434
  }
1083
1435
  /* Not yet: it reads as waiting, not as the next thing to press. */
1084
1436
  .button:disabled,
1085
1437
  .button:disabled:hover {
1086
1438
  opacity: 0.45;
1087
1439
  cursor: not-allowed;
1088
- filter: none;
1440
+ background: var(--surface);
1089
1441
  border-color: var(--border);
1442
+ color: var(--ink-1);
1443
+ }
1444
+ .button--primary:disabled,
1445
+ .button--primary:disabled:hover {
1446
+ background: var(--accent);
1447
+ border-color: var(--accent);
1448
+ color: var(--on-accent);
1090
1449
  }
1091
-
1092
- /* note composer */
1093
1450
 
1094
1451
  /* snooze menu */
1095
1452
 
@@ -1119,12 +1476,12 @@ body[data-view='tickets'] #brief-refresh {
1119
1476
  background: var(--surface);
1120
1477
  border: 1px solid var(--border);
1121
1478
  border-radius: var(--radius-sm);
1122
- box-shadow: 0 6px 24px rgba(11, 11, 11, 0.14);
1479
+ box-shadow: var(--shadow-float);
1123
1480
  }
1124
1481
  .menu button {
1125
1482
  display: block;
1126
1483
  width: 100%;
1127
- padding: 5px 9px;
1484
+ padding: 6px 9px;
1128
1485
  border: 0;
1129
1486
  border-radius: 4px;
1130
1487
  background: none;
@@ -1177,23 +1534,27 @@ body[data-view='tickets'] #brief-refresh {
1177
1534
 
1178
1535
  /* ---------- agenda ---------- */
1179
1536
 
1537
+ /*
1538
+ * The day's timeline, in the margin: a column of times, a rule running down
1539
+ * the day, a mark on it per event, and the red line of now crossing it. The
1540
+ * list is a sheet like the brief's, under a heading on the paper like theirs,
1541
+ * and sticky so the morning's meetings stay beside the afternoon's rows.
1542
+ */
1180
1543
  .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
1544
  position: sticky;
1187
1545
  top: 16px;
1188
1546
  }
1189
1547
 
1190
1548
  .agenda__title {
1191
- margin: 0 0 10px;
1192
- font-size: 12px;
1549
+ margin: 0 0 8px;
1550
+ padding: 0 2px;
1551
+ font-size: 14px;
1193
1552
  font-weight: 600;
1194
- letter-spacing: 0.06em;
1195
- text-transform: uppercase;
1196
- color: var(--ink-2);
1553
+ color: var(--ink-1);
1554
+ }
1555
+ /* Level with the masthead, the agenda's heading stands on the band. */
1556
+ body:has(.today__masthead) .agenda__title {
1557
+ color: var(--band-ink);
1197
1558
  }
1198
1559
 
1199
1560
  /*
@@ -1203,12 +1564,13 @@ body[data-view='tickets'] #brief-refresh {
1203
1564
  .agenda__note {
1204
1565
  margin: 0 0 10px;
1205
1566
  padding: 6px 8px;
1206
- border-radius: 6px;
1207
- font-size: 11px;
1567
+ border: 1px solid var(--border);
1568
+ border-left: 2px solid var(--ink-3);
1569
+ border-radius: var(--radius-sm);
1570
+ font-size: 11.5px;
1208
1571
  line-height: 1.4;
1209
1572
  color: var(--ink-2);
1210
- background: var(--surface-sunken);
1211
- border-left: 2px solid var(--ink-3);
1573
+ background: var(--surface);
1212
1574
  }
1213
1575
 
1214
1576
  /* Falling back to the brief is a louder thing than a merely stale read. */
@@ -1217,22 +1579,46 @@ body[data-view='tickets'] #brief-refresh {
1217
1579
  }
1218
1580
 
1219
1581
  .agenda__list {
1582
+ position: relative;
1220
1583
  list-style: none;
1221
1584
  margin: 0;
1222
- padding: 0;
1585
+ padding: 8px 14px;
1586
+ background: var(--surface);
1587
+ border: 1px solid var(--border);
1588
+ border-radius: var(--radius);
1589
+ box-shadow: var(--shadow);
1590
+ }
1591
+ /* The rule the day runs down, between the times and the names. */
1592
+ .agenda__list::before {
1593
+ content: '';
1594
+ position: absolute;
1595
+ top: 14px;
1596
+ bottom: 14px;
1597
+ left: 77px;
1598
+ width: 1px;
1599
+ background: var(--hairline);
1223
1600
  }
1224
1601
 
1225
1602
  .agenda__row {
1603
+ position: relative;
1226
1604
  display: grid;
1227
1605
  /* 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);
1606
+ grid-template-columns: 56px minmax(0, 1fr);
1607
+ gap: 16px;
1608
+ padding: 7px 0;
1232
1609
  font-size: 13px;
1233
1610
  }
1234
- .agenda__row:first-child {
1235
- border-top: 0;
1611
+ /* The event's mark on the rule, ringed in the sheet so the rule doesn't run through it. */
1612
+ .agenda__row::before {
1613
+ content: '';
1614
+ position: absolute;
1615
+ left: 60px;
1616
+ top: 13px;
1617
+ width: 7px;
1618
+ height: 7px;
1619
+ border-radius: 50%;
1620
+ background: var(--ink-2);
1621
+ box-shadow: 0 0 0 2px var(--surface);
1236
1622
  }
1237
1623
 
1238
1624
  .agenda__time {
@@ -1240,11 +1626,13 @@ body[data-view='tickets'] #brief-refresh {
1240
1626
  font-size: 12px;
1241
1627
  font-variant-numeric: tabular-nums; /* a column of times, so tabular is right here */
1242
1628
  white-space: nowrap;
1629
+ text-align: right;
1243
1630
  padding-top: 1px;
1244
1631
  }
1245
1632
 
1246
1633
  .agenda__name {
1247
1634
  color: var(--ink-1);
1635
+ line-height: 1.4;
1248
1636
  overflow-wrap: anywhere;
1249
1637
  }
1250
1638
  /* Event links take the row's ink so past events actually read as past. */
@@ -1254,12 +1642,15 @@ body[data-view='tickets'] #brief-refresh {
1254
1642
  }
1255
1643
  .agenda__name a:hover {
1256
1644
  text-decoration: underline;
1257
- text-decoration-color: var(--accent);
1645
+ text-decoration-color: var(--ink-3);
1258
1646
  }
1259
1647
  .agenda__row[data-past='true'] .agenda__name,
1260
1648
  .agenda__row[data-past='true'] .agenda__time {
1261
1649
  color: var(--ink-3);
1262
1650
  }
1651
+ .agenda__row[data-past='true']::before {
1652
+ background: var(--rule);
1653
+ }
1263
1654
 
1264
1655
  /*
1265
1656
  * An event that sits on the day without taking any of it: a delivery window, a
@@ -1267,11 +1658,15 @@ body[data-view='tickets'] #brief-refresh {
1267
1658
  * dimming, because being home for the delivery is the entire point of it being
1268
1659
  * on the agenda — a 14:30 slot that reads as already over is a worse mistake
1269
1660
  * than one that reads as a meeting. The row also says "marked free" in text,
1270
- * since ink is never the only cue here.
1661
+ * since ink is never the only cue here; its mark is hollow for the same reason.
1271
1662
  */
1272
1663
  .agenda__row[data-blocking='false'] .agenda__name {
1273
1664
  color: var(--ink-2);
1274
1665
  }
1666
+ .agenda__row[data-blocking='false']::before {
1667
+ background: var(--surface);
1668
+ box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 1.5px var(--ink-3);
1669
+ }
1275
1670
  .agenda__sub {
1276
1671
  display: block;
1277
1672
  color: var(--ink-3);
@@ -1282,10 +1677,16 @@ body[data-view='tickets'] #brief-refresh {
1282
1677
  color: var(--good-ink);
1283
1678
  font-weight: 500;
1284
1679
  }
1680
+ .agenda__row--free::before {
1681
+ background: var(--surface);
1682
+ box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 1.5px var(--good-ink);
1683
+ }
1285
1684
  .agenda__row--now {
1286
1685
  align-items: center;
1287
1686
  padding: 2px 0;
1288
- border-top: 0;
1687
+ }
1688
+ .agenda__row--now::before {
1689
+ display: none;
1289
1690
  }
1290
1691
  .agenda__now-label {
1291
1692
  color: var(--critical);
@@ -1293,36 +1694,40 @@ body[data-view='tickets'] #brief-refresh {
1293
1694
  font-weight: 600;
1294
1695
  font-variant-numeric: tabular-nums;
1295
1696
  white-space: nowrap;
1697
+ text-align: right;
1296
1698
  }
1699
+ /* Starts back across the rule, so now is seen to cut the day. */
1297
1700
  .agenda__now-line {
1298
1701
  height: 2px;
1702
+ margin-left: -14px;
1299
1703
  background: var(--critical);
1300
1704
  border-radius: 1px;
1301
1705
  }
1302
1706
 
1303
1707
  .empty {
1304
1708
  margin: 0;
1305
- padding: 18px 4px;
1709
+ padding: 16px 0;
1306
1710
  color: var(--ink-3);
1307
- font-size: 13.5px;
1308
- text-align: center;
1711
+ font-family: var(--font-serif);
1712
+ font-style: italic;
1713
+ font-size: 14.5px;
1309
1714
  }
1310
1715
 
1311
1716
  /* ---------- done drawer ---------- */
1312
1717
 
1313
1718
  .drawer {
1314
- margin-top: 8px;
1315
- border: 1px solid var(--border);
1316
- border-radius: var(--radius);
1317
- background: var(--surface);
1719
+ margin-top: 12px;
1318
1720
  }
1319
1721
  .drawer > summary {
1320
- padding: 9px 13px;
1722
+ padding: 10px 8px;
1321
1723
  cursor: pointer;
1322
1724
  color: var(--ink-2);
1323
1725
  font-size: 13px;
1324
1726
  list-style: none;
1325
1727
  }
1728
+ .drawer > summary:hover {
1729
+ color: var(--ink-1);
1730
+ }
1326
1731
  .drawer > summary::-webkit-details-marker {
1327
1732
  display: none;
1328
1733
  }
@@ -1334,10 +1739,7 @@ body[data-view='tickets'] #brief-refresh {
1334
1739
  content: '▾ ';
1335
1740
  }
1336
1741
  .drawer .list {
1337
- padding: 0 8px 8px;
1338
- }
1339
- .drawer .item {
1340
- box-shadow: none;
1742
+ padding: 0 0 8px;
1341
1743
  }
1342
1744
 
1343
1745
  /* ---------- toast ---------- */
@@ -1351,12 +1753,12 @@ body[data-view='tickets'] #brief-refresh {
1351
1753
  display: flex;
1352
1754
  align-items: center;
1353
1755
  gap: 12px;
1354
- padding: 9px 14px;
1756
+ padding: 9px 16px;
1355
1757
  background: var(--ink-1);
1356
1758
  color: var(--page);
1357
1759
  border-radius: 999px;
1358
1760
  font-size: 13px;
1359
- box-shadow: 0 6px 24px rgba(11, 11, 11, 0.25);
1761
+ box-shadow: 0 8px 28px rgba(0, 0, 0, 0.25);
1360
1762
  }
1361
1763
  .toast button {
1362
1764
  border: 0;
@@ -1365,6 +1767,7 @@ body[data-view='tickets'] #brief-refresh {
1365
1767
  font: inherit;
1366
1768
  font-weight: 600;
1367
1769
  text-decoration: underline;
1770
+ text-underline-offset: 2px;
1368
1771
  cursor: pointer;
1369
1772
  padding: 0;
1370
1773
  }
@@ -1372,24 +1775,27 @@ body[data-view='tickets'] #brief-refresh {
1372
1775
  /* ---------- help dialog ---------- */
1373
1776
 
1374
1777
  .help {
1375
- max-width: 420px;
1376
- padding: 22px;
1778
+ max-width: 440px;
1779
+ padding: 24px 26px;
1377
1780
  border: 1px solid var(--border);
1378
- border-radius: var(--radius);
1781
+ border-radius: 12px;
1379
1782
  background: var(--surface);
1380
1783
  color: var(--ink-1);
1784
+ box-shadow: var(--shadow-float);
1381
1785
  }
1382
1786
  .help::backdrop {
1383
- background: rgba(11, 11, 11, 0.4);
1787
+ background: rgba(10, 12, 20, 0.55);
1384
1788
  }
1385
1789
  .help h2 {
1386
- margin: 0 0 14px;
1387
- font-size: 16px;
1790
+ margin: 0 0 16px;
1791
+ font-family: var(--font-serif);
1792
+ font-size: 20px;
1793
+ font-weight: 500;
1388
1794
  }
1389
1795
  .help dl {
1390
- margin: 0 0 14px;
1796
+ margin: 0 0 16px;
1391
1797
  display: grid;
1392
- gap: 6px;
1798
+ gap: 7px;
1393
1799
  }
1394
1800
  .help dl > div {
1395
1801
  display: grid;
@@ -1405,8 +1811,9 @@ body[data-view='tickets'] #brief-refresh {
1405
1811
  color: var(--ink-2);
1406
1812
  }
1407
1813
  .help__note {
1408
- margin: 0 0 16px;
1814
+ margin: 0 0 18px;
1409
1815
  font-size: 13px;
1816
+ line-height: 1.5;
1410
1817
  color: var(--ink-3);
1411
1818
  }
1412
1819
  kbd {
@@ -1415,7 +1822,7 @@ kbd {
1415
1822
  border-bottom-width: 2px;
1416
1823
  border-radius: 4px;
1417
1824
  background: var(--surface-sunken);
1418
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1825
+ font-family: var(--font-mono);
1419
1826
  font-size: 11.5px;
1420
1827
  color: var(--ink-1);
1421
1828
  }
@@ -1429,38 +1836,38 @@ kbd {
1429
1836
  /* ---------- tabs ---------- */
1430
1837
 
1431
1838
  /*
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.
1839
+ * Three views, one page. Today is the brief; the boards are the live lists.
1840
+ * They're tabs rather than one long page because the brief is edited down to
1841
+ * a short list on purpose, and a wall of PRs beneath it would undo that.
1435
1842
  */
1436
1843
  .tabs {
1437
1844
  display: flex;
1438
- gap: 4px;
1439
- max-width: 1280px;
1440
- margin: -6px auto 14px;
1441
- border-bottom: 1px solid var(--hairline);
1845
+ gap: 2px;
1846
+ max-width: var(--page-width);
1847
+ margin: 0 auto 24px;
1848
+ border-bottom: 1px solid var(--band-rule);
1442
1849
  }
1443
1850
 
1444
1851
  .tab {
1445
1852
  display: inline-flex;
1446
1853
  align-items: center;
1447
1854
  gap: 7px;
1448
- padding: 7px 12px 9px;
1855
+ padding: 8px 12px 10px;
1449
1856
  margin-bottom: -1px;
1450
1857
  border: 0;
1451
1858
  border-bottom: 2px solid transparent;
1452
1859
  background: none;
1453
- color: var(--ink-2);
1860
+ color: var(--band-muted);
1454
1861
  font: inherit;
1455
- font-size: 13.5px;
1862
+ font-size: 14px;
1456
1863
  font-weight: 500;
1457
1864
  cursor: pointer;
1458
1865
  }
1459
1866
  .tab:hover {
1460
- color: var(--ink-1);
1867
+ color: var(--band-ink);
1461
1868
  }
1462
1869
  .tab[aria-selected='true'] {
1463
- color: var(--ink-1);
1870
+ color: var(--band-ink);
1464
1871
  border-bottom-color: var(--accent);
1465
1872
  }
1466
1873
 
@@ -1534,7 +1941,6 @@ body[data-view='settings'] .layout {
1534
1941
 
1535
1942
  /* ---------- the pull request board ---------- */
1536
1943
 
1537
-
1538
1944
  /* The line under a waiting-on-you row that says why. Reads as the row's detail. */
1539
1945
  .item__reason {
1540
1946
  margin: 6px 0 0;
@@ -1574,29 +1980,27 @@ body[data-view='settings'] .layout {
1574
1980
  /*
1575
1981
  * Two columns, by measurement rather than by taste: the rows were
1576
1982
  * 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
1983
+ * longest, so half of every row was empty and thirty of them came to 2527px of
1578
1984
  * scrolling. At 460px a column the same thirty fit in half that.
1579
1985
  *
1580
1986
  * 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
1987
+ * board whose rows disagree about height. A grid lays out in *rows*, so a
1988
+ * one-line row beside a row carrying a note gets the note's height reserved
1583
1989
  * 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
1990
+ * cannot reclaim the row, and one noted row on a real board cost about a
1585
1991
  * hundred pixels of nothing. A column flow has no rows to align against: each
1586
- * card starts where the one above it ended.
1992
+ * row starts where the one above it ended.
1587
1993
  *
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.
1994
+ * `break-inside: avoid` so a row is never split down the middle of a column.
1591
1995
  *
1592
1996
  * Never more than two, so the board keeps the shared page width and its edges
1593
1997
  * line up with the other tabs' however wide the display is. The 460px floor is
1594
1998
  * what drops it to one column on a narrow window rather than squeezing two.
1595
1999
  *
1596
2000
  * 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
2001
+ * toward balancing them. `.item__actions` stays inside its row, so it travels
2002
+ * with the row into its column and nothing notices. Anything that hangs below a
2003
+ * row must not be in here at all: the row menus once were, and were split
1600
2004
  * across both columns and pushed the next section down. They are popovers now.
1601
2005
  */
1602
2006
  #tickets .list {
@@ -1606,7 +2010,7 @@ body[data-view='settings'] .layout {
1606
2010
  }
1607
2011
  #tickets .list > .item {
1608
2012
  break-inside: avoid;
1609
- margin-bottom: 4px;
2013
+ margin-bottom: 8px;
1610
2014
  }
1611
2015
 
1612
2016
  /*
@@ -1617,13 +2021,14 @@ body[data-view='settings'] .layout {
1617
2021
  * column.
1618
2022
  */
1619
2023
  #tickets .item--ticket {
1620
- padding: 8px 11px;
2024
+ padding: 9px 14px 9px 8px;
1621
2025
  }
1622
2026
  #tickets .item__body {
1623
2027
  display: grid;
1624
2028
  grid-template-columns: 6rem minmax(0, 1fr);
1625
2029
  align-items: baseline;
1626
2030
  gap: 4px 9px;
2031
+ max-width: none;
1627
2032
  }
1628
2033
  #tickets .item__meta--status {
1629
2034
  grid-column: 1;
@@ -1633,7 +2038,7 @@ body[data-view='settings'] .layout {
1633
2038
  }
1634
2039
  /*
1635
2040
  * 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
2041
+ * absolutely positioned over the row's top right and opaque, so without this it
1637
2042
  * covers the tail of any summary long enough to reach it — on hover, and
1638
2043
  * permanently on the selected row, which is the row being read. Measured rather
1639
2044
  * than guessed: reserving the pull request board's three buttons cost 142px of
@@ -1662,10 +2067,8 @@ body[data-view='settings'] .layout {
1662
2067
  * The switch between the ticket tab's two views: what is out of sync, and what
1663
2068
  * you are working on. A segmented control rather than a second row of tabs, so it
1664
2069
  * 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
- /*
2070
+ * above are underlined words, and this is a pair of pills with one filled in.
2071
+ *
1669
2072
  * The switch and the key to the dots share a line: both describe the view
1670
2073
  * below rather than being part of it, and stacked they made a third tier under
1671
2074
  * the tabs, with the key hanging off the switch like a caption. The key goes
@@ -1677,7 +2080,7 @@ body[data-view='settings'] .layout {
1677
2080
  align-items: center;
1678
2081
  justify-content: space-between;
1679
2082
  gap: 8px 24px;
1680
- margin: 0 0 18px;
2083
+ margin: 0 0 22px;
1681
2084
  }
1682
2085
  .mode-switch {
1683
2086
  display: inline-flex;
@@ -1705,15 +2108,18 @@ body[data-view='settings'] .layout {
1705
2108
  color: var(--ink-1);
1706
2109
  }
1707
2110
  .mode-switch__option[aria-selected='true'] {
1708
- background: var(--surface);
1709
- color: var(--ink-1);
1710
- box-shadow: var(--shadow);
2111
+ background: var(--band);
2112
+ color: var(--band-ink);
1711
2113
  }
1712
2114
  .mode-switch__count {
1713
2115
  color: var(--ink-3);
1714
2116
  font-size: 12px;
1715
2117
  font-variant-numeric: tabular-nums;
1716
2118
  }
2119
+ .mode-switch__option[aria-selected='true'] .mode-switch__count {
2120
+ color: inherit;
2121
+ opacity: 0.7;
2122
+ }
1717
2123
 
1718
2124
  /*
1719
2125
  * On a Working on row whose ticket is also out of sync. The border is the due
@@ -1737,7 +2143,7 @@ body[data-view='settings'] .layout {
1737
2143
  gap: 4px 14px;
1738
2144
  /* A <p>, and its default margins made the switch's line taller whenever the key was on it. */
1739
2145
  margin: 0;
1740
- font-size: 12px;
2146
+ font-size: 12.5px;
1741
2147
  color: var(--ink-3);
1742
2148
  }
1743
2149
  .legend__entry {
@@ -1746,8 +2152,8 @@ body[data-view='settings'] .layout {
1746
2152
  gap: 6px;
1747
2153
  }
1748
2154
  .legend__dot {
1749
- width: 9px;
1750
- height: 9px;
2155
+ width: 8px;
2156
+ height: 8px;
1751
2157
  border-radius: 50%;
1752
2158
  display: block;
1753
2159
  }
@@ -1758,10 +2164,8 @@ body[data-view='settings'] .layout {
1758
2164
  * every single morning is one you stop reading by the end of the week.
1759
2165
  */
1760
2166
  .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);
2167
+ background: rgba(255, 255, 255, 0.14);
2168
+ color: var(--band-ink);
1765
2169
  }
1766
2170
 
1767
2171
  /*
@@ -1773,8 +2177,8 @@ body[data-view='settings'] .layout {
1773
2177
  * here" is actually worth knowing.
1774
2178
  */
1775
2179
  .court-hint {
1776
- margin: -6px 0 18px;
1777
- padding-left: 26px;
2180
+ margin: -10px 0 26px;
2181
+ padding: 0 8px;
1778
2182
  font-size: 12.5px;
1779
2183
  line-height: 1.5;
1780
2184
  color: var(--ink-3);
@@ -1800,8 +2204,8 @@ body[data-view='settings'] .layout {
1800
2204
 
1801
2205
  /*
1802
2206
  * 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.
2207
+ * right: the pill sits in the row's left gutter, so each menu opens toward the
2208
+ * middle of its own row.
1805
2209
  */
1806
2210
  .menu--status {
1807
2211
  right: auto;
@@ -1811,7 +2215,7 @@ body[data-view='settings'] .layout {
1811
2215
 
1812
2216
  /* The status the ticket claims — the row's own subject, so it carries weight. */
1813
2217
  .pill--status {
1814
- border-color: var(--hairline);
2218
+ border-color: var(--border);
1815
2219
  background: var(--surface-sunken);
1816
2220
  color: var(--ink-1);
1817
2221
  font-weight: 500;
@@ -1827,28 +2231,28 @@ a.button {
1827
2231
  /* ---------- the assistant ---------- */
1828
2232
 
1829
2233
  .pill--assistant {
1830
- color: var(--accent);
2234
+ color: var(--ink-1);
1831
2235
  background: var(--accent-wash);
2236
+ border-color: transparent;
1832
2237
  }
1833
2238
 
1834
2239
  /*
1835
- * ---------- the assistant ----------
1836
- *
1837
2240
  * 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.
2241
+ * the field is pinned in the panel's foot. What was asked is set in the sans,
2242
+ * as a row is; what came back is set in the serif, as the brief is — it is the
2243
+ * part written to be read.
1840
2244
  */
1841
2245
 
1842
2246
  .assistant__turns {
1843
2247
  display: flex;
1844
2248
  flex-direction: column;
1845
- gap: 12px;
2249
+ gap: 14px;
1846
2250
  margin-bottom: 14px;
1847
2251
  }
1848
2252
 
1849
2253
  .assistant__request {
1850
2254
  margin: 0;
1851
- font-size: 12.5px;
2255
+ font-size: 13px;
1852
2256
  color: var(--ink-2);
1853
2257
  }
1854
2258
  .assistant__request strong {
@@ -1856,17 +2260,16 @@ a.button {
1856
2260
  font-weight: 600;
1857
2261
  }
1858
2262
  .assistant__auto {
1859
- color: var(--accent);
2263
+ color: var(--ink-3);
1860
2264
  }
1861
2265
 
1862
2266
  .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;
2267
+ margin-top: 6px;
2268
+ padding: 2px 0 2px 12px;
2269
+ border-left: 2px solid var(--hairline);
2270
+ font-family: var(--font-serif);
2271
+ font-size: 14px;
2272
+ line-height: 1.55;
1870
2273
  color: var(--ink-1);
1871
2274
  overflow-wrap: anywhere;
1872
2275
  }
@@ -1874,7 +2277,7 @@ a.button {
1874
2277
  margin: 0;
1875
2278
  }
1876
2279
  .assistant__reply > * + * {
1877
- margin-top: 7px;
2280
+ margin-top: 8px;
1878
2281
  }
1879
2282
  .assistant__reply ul,
1880
2283
  .assistant__reply ol {
@@ -1884,14 +2287,17 @@ a.button {
1884
2287
  margin-top: 3px;
1885
2288
  }
1886
2289
  .assistant__reply pre {
1887
- padding: 7px 9px;
2290
+ padding: 8px 10px;
1888
2291
  border-radius: var(--radius-sm);
1889
2292
  background: var(--surface-sunken);
2293
+ font-family: var(--font-mono);
1890
2294
  font-size: 12px;
2295
+ line-height: 1.5;
1891
2296
  overflow-x: auto;
1892
2297
  white-space: pre-wrap;
1893
2298
  }
1894
2299
  .assistant__reply code {
2300
+ font-family: var(--font-mono);
1895
2301
  font-size: 12px;
1896
2302
  }
1897
2303
  .assistant__reply blockquote {
@@ -1920,6 +2326,7 @@ a.button {
1920
2326
  background: var(--surface);
1921
2327
  color: var(--ink-3);
1922
2328
  font: inherit;
2329
+ font-family: var(--font);
1923
2330
  font-size: 11px;
1924
2331
  cursor: pointer;
1925
2332
  }
@@ -1930,7 +2337,7 @@ a.button {
1930
2337
 
1931
2338
  .assistant__status {
1932
2339
  margin: 4px 0 0;
1933
- font-size: 12px;
2340
+ font-size: 12.5px;
1934
2341
  color: var(--ink-3);
1935
2342
  }
1936
2343
  .assistant__status--bad {
@@ -1949,7 +2356,7 @@ a.button {
1949
2356
  width: 9px;
1950
2357
  height: 9px;
1951
2358
  border-radius: 50%;
1952
- border: 1.5px solid var(--accent);
2359
+ border: 1.5px solid var(--ink-1);
1953
2360
  border-top-color: transparent;
1954
2361
  animation: assistant-spin 0.9s linear infinite;
1955
2362
  }
@@ -1977,24 +2384,24 @@ a.button {
1977
2384
  margin-top: 4px;
1978
2385
  }
1979
2386
  .assistant__work > summary {
1980
- font-size: 12px;
2387
+ font-size: 12.5px;
1981
2388
  color: var(--ink-3);
1982
2389
  cursor: pointer;
1983
2390
  }
1984
2391
  .assistant__work > summary:hover {
1985
- color: var(--ink-2);
2392
+ color: var(--ink-1);
1986
2393
  }
1987
2394
  .assistant__took {
1988
2395
  margin: 4px 0 0;
1989
- font-size: 12px;
2396
+ font-size: 12.5px;
1990
2397
  color: var(--ink-3);
1991
2398
  }
1992
2399
  .assistant__steps {
1993
- margin: 5px 0 0;
2400
+ margin: 6px 0 0;
1994
2401
  padding: 0 0 0 10px;
1995
2402
  border-left: 2px solid var(--hairline);
1996
2403
  list-style: none;
1997
- font-size: 12px;
2404
+ font-size: 12.5px;
1998
2405
  line-height: 1.45;
1999
2406
  color: var(--ink-2);
2000
2407
  }
@@ -2036,14 +2443,17 @@ a.button {
2036
2443
  overflow: hidden;
2037
2444
  text-overflow: ellipsis;
2038
2445
  white-space: nowrap;
2446
+ font-family: var(--font-mono);
2039
2447
  font-size: 11.5px;
2040
2448
  color: var(--ink-3);
2041
2449
  }
2042
- /* What it said on the way: its own words, set apart from the calls by having no mark. */
2450
+ /* What it said on the way: its own words, in the reading face, set apart from the calls by having no mark. */
2043
2451
  .assistant__step--message {
2044
2452
  display: block;
2045
2453
  padding-left: 15px;
2454
+ font-family: var(--font-serif);
2046
2455
  font-style: italic;
2456
+ font-size: 13px;
2047
2457
  color: var(--ink-3);
2048
2458
  white-space: pre-line;
2049
2459
  overflow-wrap: anywhere;
@@ -2054,7 +2464,7 @@ a.button {
2054
2464
  display: flex;
2055
2465
  flex-wrap: wrap;
2056
2466
  gap: 6px;
2057
- margin-top: 6px;
2467
+ margin-top: 8px;
2058
2468
  }
2059
2469
 
2060
2470
  .assistant__quick {
@@ -2075,10 +2485,10 @@ a.button {
2075
2485
  padding: 8px 10px;
2076
2486
  border: 1px solid var(--border);
2077
2487
  border-radius: var(--radius-sm);
2078
- background: var(--page);
2488
+ background: var(--surface);
2079
2489
  color: var(--ink-1);
2080
2490
  font: inherit;
2081
- font-size: 13px;
2491
+ font-size: 13.5px;
2082
2492
  line-height: 1.4;
2083
2493
  resize: vertical;
2084
2494
  }
@@ -2092,12 +2502,15 @@ a.button {
2092
2502
  * The panel takes the side column: on Today it stands in for the agenda while it
2093
2503
  * is open, and on the boards it brings the column back. In the grid rather than
2094
2504
  * 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
2505
+ * list scrolls past a panel that stays put. It is the one surface on the page
2506
+ * with an edge of its own, because it is the one thing that floats over the
2507
+ * sheet rather than being written on it. Placed after the view rules above on
2508
+ * purpose: they and these share a specificity, and the panel being open has
2097
2509
  * to win.
2098
2510
  */
2099
2511
  body[data-flyout='open'] .layout {
2100
2512
  grid-template-columns: minmax(0, 1fr) 420px;
2513
+ gap: 40px;
2101
2514
  }
2102
2515
  body[data-flyout='open'] .layout__side {
2103
2516
  display: none;
@@ -2112,8 +2525,8 @@ body[data-flyout='open'] .layout__side {
2112
2525
  max-height: calc(100vh - 32px);
2113
2526
  background: var(--surface);
2114
2527
  border: 1px solid var(--border);
2115
- border-radius: var(--radius);
2116
- box-shadow: var(--shadow);
2528
+ border-radius: 12px;
2529
+ box-shadow: var(--shadow-float);
2117
2530
  }
2118
2531
  .flyout[hidden] {
2119
2532
  display: none;
@@ -2123,7 +2536,7 @@ body[data-flyout='open'] .layout__side {
2123
2536
  display: grid;
2124
2537
  grid-template-columns: minmax(0, 1fr) auto;
2125
2538
  gap: 5px 10px;
2126
- padding: 14px 16px 13px;
2539
+ padding: 16px 18px 14px;
2127
2540
  border-bottom: 1px solid var(--hairline);
2128
2541
  }
2129
2542
  .flyout__where {
@@ -2131,7 +2544,7 @@ body[data-flyout='open'] .layout__side {
2131
2544
  flex-wrap: wrap;
2132
2545
  align-items: center;
2133
2546
  gap: 6px;
2134
- font-size: 12px;
2547
+ font-size: 12.5px;
2135
2548
  color: var(--ink-3);
2136
2549
  }
2137
2550
  .flyout__close {
@@ -2142,7 +2555,7 @@ body[data-flyout='open'] .layout__side {
2142
2555
  .flyout__title {
2143
2556
  grid-column: 1;
2144
2557
  margin: 0;
2145
- font-size: 15px;
2558
+ font-size: 15.5px;
2146
2559
  font-weight: 500;
2147
2560
  line-height: 1.4;
2148
2561
  color: var(--ink-1);
@@ -2154,11 +2567,11 @@ body[data-flyout='open'] .layout__side {
2154
2567
  }
2155
2568
  .flyout__title a:hover {
2156
2569
  text-decoration: underline;
2157
- text-decoration-color: var(--accent);
2570
+ text-decoration-color: var(--ink-3);
2158
2571
  }
2159
2572
 
2160
2573
  /*
2161
- * A ticket's status and park, laid out as on its card: the status at the left,
2574
+ * A ticket's status and park, laid out as on its row: the status at the left,
2162
2575
  * the park at the right, so each menu opens into the panel rather than out over
2163
2576
  * the list. Under the close button too, so the park lines up with it. A child
2164
2577
  * combinator, because the park menu's own Set button is a `.button` in here.
@@ -2178,17 +2591,20 @@ body[data-flyout='open'] .layout__side {
2178
2591
  flex: 1;
2179
2592
  min-height: 0;
2180
2593
  overflow-y: auto;
2181
- padding: 16px 16px 20px;
2594
+ padding: 18px 18px 22px;
2182
2595
  }
2183
2596
  /* The assistant's field and its canned asks, pinned under the body that scrolls. */
2184
2597
  .flyout__footer {
2185
2598
  flex: none;
2186
- padding: 12px 16px 14px;
2599
+ padding: 12px 18px 16px;
2187
2600
  border-top: 1px solid var(--hairline);
2188
2601
  }
2602
+ /* What the agent wrote under the row: the brief's own words, so the reading face. */
2189
2603
  .flyout__detail {
2190
- margin: 0 0 22px;
2191
- font-size: 13px;
2604
+ margin: 0 0 24px;
2605
+ font-family: var(--font-serif);
2606
+ font-size: 14px;
2607
+ line-height: 1.55;
2192
2608
  color: var(--ink-2);
2193
2609
  overflow-wrap: anywhere;
2194
2610
  }
@@ -2196,28 +2612,29 @@ body[data-flyout='open'] .layout__side {
2196
2612
  padding: 1px 4px;
2197
2613
  background: var(--surface-sunken);
2198
2614
  border-radius: 3px;
2199
- font-size: 0.92em;
2615
+ font-family: var(--font-mono);
2616
+ font-size: 0.9em;
2200
2617
  }
2201
2618
 
2202
2619
  .flyout__section + .flyout__section {
2203
- margin-top: 26px;
2620
+ margin-top: 28px;
2204
2621
  }
2205
2622
  .flyout__label {
2206
2623
  margin: 0 0 10px;
2207
- font-size: 11.5px;
2624
+ padding: 0 0 6px;
2625
+ border-bottom: 1px solid var(--hairline);
2626
+ font-size: 12.5px;
2208
2627
  font-weight: 600;
2209
- letter-spacing: 0.04em;
2210
- text-transform: uppercase;
2211
- color: var(--ink-3);
2628
+ color: var(--ink-2);
2212
2629
  }
2213
2630
 
2214
2631
  .flyout__notes {
2215
2632
  margin: 0 0 12px;
2216
- padding: 7px 10px;
2633
+ padding: 2px 0 2px 12px;
2217
2634
  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;
2635
+ font-family: var(--font-serif);
2636
+ font-size: 13.5px;
2637
+ line-height: 1.5;
2221
2638
  color: var(--ink-2);
2222
2639
  }
2223
2640
  .flyout__note {
@@ -2228,12 +2645,13 @@ body[data-flyout='open'] .layout__side {
2228
2645
  }
2229
2646
  .flyout__when {
2230
2647
  color: var(--ink-3);
2648
+ font-family: var(--font);
2231
2649
  font-size: 11.5px;
2232
2650
  white-space: nowrap;
2233
2651
  }
2234
2652
  .flyout__empty {
2235
2653
  margin: 0 0 10px;
2236
- font-size: 12.5px;
2654
+ font-size: 13px;
2237
2655
  color: var(--ink-3);
2238
2656
  }
2239
2657
 
@@ -2255,10 +2673,10 @@ body[data-flyout='open'] .layout__side {
2255
2673
  padding: 0 10px;
2256
2674
  border: 1px solid var(--border);
2257
2675
  border-radius: var(--radius-sm);
2258
- background: var(--page);
2676
+ background: var(--surface);
2259
2677
  color: var(--ink-1);
2260
2678
  font: inherit;
2261
- font-size: 13px;
2679
+ font-size: 13.5px;
2262
2680
  }
2263
2681
  .flyout__submit {
2264
2682
  flex: none;
@@ -2277,7 +2695,7 @@ body[data-flyout='open'] .layout__side {
2277
2695
  z-index: 15;
2278
2696
  max-height: 80vh;
2279
2697
  border-bottom: 0;
2280
- border-radius: var(--radius) var(--radius) 0 0;
2698
+ border-radius: 12px 12px 0 0;
2281
2699
  }
2282
2700
  /* The sheet has the bottom, so a toast goes to the top rather than over its field. */
2283
2701
  body[data-flyout='open'] .toast {
@@ -2292,52 +2710,62 @@ body[data-flyout='open'] .layout__side {
2292
2710
  padding: 0;
2293
2711
  border: 0;
2294
2712
  background: none;
2295
- color: var(--accent);
2713
+ color: var(--ink-1);
2296
2714
  font: inherit;
2715
+ text-decoration: underline;
2716
+ text-decoration-color: var(--ink-3);
2717
+ text-underline-offset: 2px;
2297
2718
  cursor: pointer;
2298
2719
  }
2299
2720
  .link-button:hover {
2300
- text-decoration: underline;
2721
+ text-decoration-color: currentColor;
2301
2722
  }
2302
2723
  .objective__edit {
2303
- margin-left: 8px;
2304
- font-size: 11px;
2724
+ font-size: 12.5px;
2305
2725
  font-weight: 500;
2306
- letter-spacing: normal;
2307
- text-transform: none;
2726
+ color: var(--ink-3);
2727
+ text-decoration: none;
2728
+ }
2729
+ .objective__edit:hover {
2730
+ color: var(--ink-1);
2731
+ text-decoration: underline;
2308
2732
  }
2309
2733
 
2310
2734
  /* ---------- the first brief, after setup ---------- */
2311
2735
 
2312
2736
  /*
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.
2737
+ * Today between the setup screen and the first brief. Set as the objective is,
2738
+ * since it does the same job in its place: the first thing read, before
2739
+ * anything else exists. On the paper, not the band: the band holds a morning's
2740
+ * masthead, and there is no morning yet.
2316
2741
  */
2317
2742
  .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);
2743
+ max-width: 60ch;
2744
+ padding: 10px 0 0;
2324
2745
  }
2325
2746
  .first-brief__title {
2326
- margin: 0 0 6px;
2327
- font-size: 18px;
2328
- letter-spacing: -0.01em;
2747
+ margin: 0 0 8px;
2748
+ font-family: var(--font-serif);
2749
+ font-size: 26px;
2750
+ font-weight: 500;
2751
+ line-height: 1.2;
2752
+ letter-spacing: -0.005em;
2329
2753
  }
2330
2754
  .first-brief__text {
2331
2755
  margin: 0;
2332
2756
  color: var(--ink-2);
2333
- font-size: 13.5px;
2334
- line-height: 1.5;
2757
+ font-size: 14.5px;
2758
+ line-height: 1.55;
2335
2759
  }
2336
2760
  .first-brief__actions {
2337
2761
  display: flex;
2338
2762
  flex-wrap: wrap;
2339
2763
  gap: 8px;
2340
- margin-top: 14px;
2764
+ margin-top: 18px;
2765
+ }
2766
+ .first-brief .button {
2767
+ padding: 7px 14px;
2768
+ font-size: 13.5px;
2341
2769
  }
2342
2770
 
2343
2771
  /* ---------- the setup screen ---------- */
@@ -2345,11 +2773,12 @@ body[data-flyout='open'] .layout__side {
2345
2773
  /*
2346
2774
  * The whole page while a new store is set up: one column, one question open at
2347
2775
  * 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.
2776
+ * sentence; the open one is the only card. The questions are set in the serif,
2777
+ * since they are read once and slowly, and the buttons here are larger than the
2778
+ * dashboard's: each one is a decision.
2350
2779
  */
2351
2780
  /* The page's own margins are the dashboard's; this one runs edge to edge. */
2352
- body[data-onboarding='true'] {
2781
+ body[data-onboarding='true'] #app {
2353
2782
  padding: 0;
2354
2783
  }
2355
2784
  .onboarding {
@@ -2363,14 +2792,13 @@ body[data-onboarding='true'] {
2363
2792
  display: flex;
2364
2793
  align-items: center;
2365
2794
  gap: 18px;
2366
- padding: 14px 24px;
2367
- background: var(--page);
2368
- border-bottom: 1px solid var(--hairline);
2795
+ padding: 14px 28px;
2796
+ background: var(--band);
2369
2797
  font-size: 13px;
2370
- color: var(--ink-2);
2798
+ color: var(--band-muted);
2371
2799
  }
2372
2800
  .onboarding__name {
2373
- color: var(--ink-1);
2801
+ color: var(--band-ink);
2374
2802
  font-weight: 600;
2375
2803
  font-size: 14px;
2376
2804
  }
@@ -2385,7 +2813,7 @@ body[data-onboarding='true'] {
2385
2813
  max-width: 220px;
2386
2814
  height: 4px;
2387
2815
  border-radius: 2px;
2388
- background: var(--hairline);
2816
+ background: rgba(255, 255, 255, 0.2);
2389
2817
  overflow: hidden;
2390
2818
  }
2391
2819
  .onboarding__track i {
@@ -2396,15 +2824,16 @@ body[data-onboarding='true'] {
2396
2824
  transition: width 0.3s ease;
2397
2825
  }
2398
2826
  .onboarding__column {
2399
- max-width: 600px;
2827
+ max-width: 640px;
2400
2828
  margin: 0 auto;
2401
- padding: 32px 24px 30vh;
2829
+ padding: 40px 24px 30vh;
2402
2830
  }
2403
2831
  .onboarding__lede {
2404
- margin: 0 0 24px;
2832
+ margin: 0 0 28px;
2405
2833
  padding-left: 30px;
2834
+ font-family: var(--font-serif);
2406
2835
  color: var(--ink-2);
2407
- font-size: 15px;
2836
+ font-size: 17px;
2408
2837
  line-height: 1.55;
2409
2838
  }
2410
2839
  .onboarding__thread {
@@ -2438,7 +2867,7 @@ body[data-onboarding='true'] {
2438
2867
  }
2439
2868
  .onboarding__dot--open {
2440
2869
  left: -30px;
2441
- top: 11px;
2870
+ top: 13px;
2442
2871
  width: 13px;
2443
2872
  height: 13px;
2444
2873
  background: var(--accent);
@@ -2450,7 +2879,7 @@ body[data-onboarding='true'] {
2450
2879
  width: 8px;
2451
2880
  height: 8px;
2452
2881
  background: var(--page);
2453
- border: 1.5px solid var(--accent);
2882
+ border: 1.5px solid var(--ink-1);
2454
2883
  }
2455
2884
  .onboarding__dot--later {
2456
2885
  border-color: var(--hairline);
@@ -2462,7 +2891,7 @@ body[data-onboarding='true'] {
2462
2891
  gap: 12px;
2463
2892
  padding: 5px 0;
2464
2893
  color: var(--ink-2);
2465
- font-size: 14px;
2894
+ font-size: 14.5px;
2466
2895
  line-height: 1.5;
2467
2896
  }
2468
2897
  .onboarding__done[data-status='later'] {
@@ -2488,22 +2917,24 @@ body[data-onboarding='true'] {
2488
2917
  cursor: pointer;
2489
2918
  }
2490
2919
  .onboarding__change:hover {
2491
- color: var(--accent);
2920
+ color: var(--ink-1);
2921
+ text-decoration: underline;
2492
2922
  }
2493
2923
  .onboarding__change:disabled {
2494
2924
  visibility: hidden;
2495
2925
  }
2496
2926
 
2497
2927
  .onboarding__card {
2498
- margin: 22px 0 28px;
2928
+ margin: 24px 0 30px;
2499
2929
  scroll-margin: 90px 0 120px;
2500
2930
  }
2501
2931
  .onboarding__card h2 {
2502
- margin: 0 0 10px;
2503
- font-size: 24px;
2932
+ margin: 0 0 12px;
2933
+ font-family: var(--font-serif);
2934
+ font-size: 27px;
2504
2935
  line-height: 1.2;
2505
- font-weight: 650;
2506
- letter-spacing: -0.01em;
2936
+ font-weight: 500;
2937
+ letter-spacing: -0.005em;
2507
2938
  text-wrap: balance;
2508
2939
  }
2509
2940
  .onboarding__card h2:focus {
@@ -2544,7 +2975,7 @@ body[data-onboarding='true'] {
2544
2975
  .onboarding__sparkle {
2545
2976
  flex: none;
2546
2977
  margin-top: 3px;
2547
- color: var(--accent);
2978
+ color: var(--accent-ink);
2548
2979
  }
2549
2980
  .onboarding__looking {
2550
2981
  margin: 0 0 16px;
@@ -2622,9 +3053,6 @@ body[data-onboarding='true'] {
2622
3053
  flex-wrap: wrap;
2623
3054
  gap: 16px;
2624
3055
  }
2625
- .onboarding__links a {
2626
- color: var(--accent);
2627
- }
2628
3056
  .onboarding__problem[data-blocking='false'] {
2629
3057
  margin: 0;
2630
3058
  border-left-color: var(--hairline);
@@ -2632,9 +3060,10 @@ body[data-onboarding='true'] {
2632
3060
  }
2633
3061
  .onboarding__problem pre {
2634
3062
  margin: 0 0 10px;
2635
- padding: 6px 10px;
3063
+ padding: 8px 10px;
2636
3064
  background: var(--surface-sunken);
2637
3065
  border-radius: var(--radius-sm);
3066
+ font-family: var(--font-mono);
2638
3067
  font-size: 13px;
2639
3068
  overflow-x: auto;
2640
3069
  }
@@ -2651,7 +3080,7 @@ body[data-onboarding='true'] {
2651
3080
  .onboarding__legend {
2652
3081
  margin-bottom: 8px;
2653
3082
  padding: 0;
2654
- color: var(--ink-3);
3083
+ color: var(--ink-2);
2655
3084
  font-size: 13px;
2656
3085
  font-weight: 600;
2657
3086
  }
@@ -2664,7 +3093,7 @@ body[data-onboarding='true'] {
2664
3093
  padding: 6px 13px;
2665
3094
  border: 1px solid var(--border);
2666
3095
  border-radius: 999px;
2667
- background: var(--surface);
3096
+ background: transparent;
2668
3097
  color: var(--ink-1);
2669
3098
  font: inherit;
2670
3099
  font-size: 14px;
@@ -2672,18 +3101,18 @@ body[data-onboarding='true'] {
2672
3101
  }
2673
3102
  .onboarding__pill:hover {
2674
3103
  border-color: var(--ink-3);
3104
+ background: var(--surface-sunken);
2675
3105
  }
2676
3106
  .onboarding__pill[aria-checked='true'] {
2677
- border-color: var(--accent);
2678
- background: var(--accent-wash);
2679
- color: var(--accent);
2680
- font-weight: 600;
3107
+ border-color: var(--band);
3108
+ background: var(--band);
3109
+ color: var(--band-ink);
3110
+ font-weight: 500;
2681
3111
  }
2682
3112
  .onboarding__list {
2683
3113
  background: var(--surface);
2684
3114
  border: 1px solid var(--border);
2685
3115
  border-radius: var(--radius);
2686
- box-shadow: var(--shadow);
2687
3116
  overflow: hidden;
2688
3117
  }
2689
3118
  .onboarding__group + .onboarding__group,
@@ -2733,15 +3162,15 @@ body[data-onboarding='true'] {
2733
3162
  border-radius: 50%;
2734
3163
  }
2735
3164
  .onboarding__option input:checked + .onboarding__box {
2736
- border-color: var(--accent);
2737
- background: var(--accent);
3165
+ border-color: var(--band);
3166
+ background: var(--band);
2738
3167
  }
2739
3168
  .onboarding__option input:checked + .onboarding__box[data-kind='check']::after {
2740
3169
  content: '';
2741
3170
  width: 9px;
2742
3171
  height: 5px;
2743
- border-left: 2px solid #fff;
2744
- border-bottom: 2px solid #fff;
3172
+ border-left: 2px solid var(--band-ink);
3173
+ border-bottom: 2px solid var(--band-ink);
2745
3174
  transform: translateY(-1px) rotate(-45deg);
2746
3175
  }
2747
3176
  .onboarding__option input:checked + .onboarding__box[data-kind='radio']::after {
@@ -2749,7 +3178,7 @@ body[data-onboarding='true'] {
2749
3178
  width: 6px;
2750
3179
  height: 6px;
2751
3180
  border-radius: 50%;
2752
- background: #fff;
3181
+ background: var(--band-ink);
2753
3182
  }
2754
3183
  .onboarding__option input:focus-visible + .onboarding__box {
2755
3184
  outline: 2px solid var(--focus-ring);
@@ -2778,11 +3207,17 @@ body[data-onboarding='true'] {
2778
3207
  padding: 8px 0;
2779
3208
  border: 0;
2780
3209
  background: none;
2781
- color: var(--accent);
3210
+ color: var(--ink-1);
2782
3211
  font: inherit;
2783
3212
  font-size: 14px;
3213
+ text-decoration: underline;
3214
+ text-decoration-color: var(--ink-3);
3215
+ text-underline-offset: 2px;
2784
3216
  cursor: pointer;
2785
3217
  }
3218
+ .onboarding__add-button:hover {
3219
+ text-decoration-color: currentColor;
3220
+ }
2786
3221
  .onboarding__pills .onboarding__add-button {
2787
3222
  padding: 6px 4px;
2788
3223
  }
@@ -2796,14 +3231,14 @@ body[data-onboarding='true'] {
2796
3231
  .onboarding__tell input {
2797
3232
  flex: 1;
2798
3233
  min-width: 0;
2799
- height: 34px;
3234
+ height: 36px;
2800
3235
  padding: 0 10px;
2801
3236
  border: 1px solid var(--border);
2802
3237
  border-radius: var(--radius-sm);
2803
3238
  background: var(--surface);
2804
3239
  color: var(--ink-1);
2805
3240
  font: inherit;
2806
- font-size: 14px;
3241
+ font-size: 14.5px;
2807
3242
  }
2808
3243
  .onboarding__fields {
2809
3244
  display: grid;
@@ -2858,7 +3293,7 @@ body[data-onboarding='true'] {
2858
3293
  font-size: 14px;
2859
3294
  }
2860
3295
  .onboarding__field-label {
2861
- font-size: 13px;
3296
+ font-size: 13.5px;
2862
3297
  font-weight: 500;
2863
3298
  color: var(--ink-2);
2864
3299
  }
@@ -2874,9 +3309,9 @@ body[data-onboarding='true'] {
2874
3309
  gap: 10px;
2875
3310
  }
2876
3311
  .onboarding .button {
2877
- padding: 8px 16px;
2878
- border-radius: 8px;
2879
- font-size: 14px;
3312
+ padding: 9px 16px;
3313
+ border-radius: var(--radius);
3314
+ font-size: 14.5px;
2880
3315
  font-weight: 550;
2881
3316
  }
2882
3317
  .onboarding .onboarding__quiet {
@@ -2886,6 +3321,7 @@ body[data-onboarding='true'] {
2886
3321
  }
2887
3322
  .onboarding .onboarding__quiet:hover {
2888
3323
  color: var(--ink-1);
3324
+ background: var(--surface-sunken);
2889
3325
  }
2890
3326
  .onboarding__tell {
2891
3327
  display: flex;
@@ -2917,6 +3353,9 @@ body[data-onboarding='true'] {
2917
3353
  color: var(--ink-2);
2918
3354
  font-size: 14px;
2919
3355
  }
3356
+ .onboarding__preview > summary:hover {
3357
+ color: var(--ink-1);
3358
+ }
2920
3359
  .onboarding__preview pre {
2921
3360
  max-height: 360px;
2922
3361
  margin: 10px 0 0;
@@ -2925,6 +3364,7 @@ body[data-onboarding='true'] {
2925
3364
  background: var(--surface);
2926
3365
  border: 1px solid var(--border);
2927
3366
  border-radius: var(--radius-sm);
3367
+ font-family: var(--font-mono);
2928
3368
  font-size: 12.5px;
2929
3369
  line-height: 1.5;
2930
3370
  white-space: pre-wrap;
@@ -2937,30 +3377,83 @@ body[data-onboarding='true'] {
2937
3377
 
2938
3378
  /* ---------- settings ---------- */
2939
3379
 
3380
+ /*
3381
+ * A column of groups, each a sheet titled in the serif, with an index beside
3382
+ * them that stays put as the page scrolls and says where on it you are. In a
3383
+ * group, each setting is a row: its name and what it does on the left, the
3384
+ * control on the right, a rule between rows.
3385
+ */
2940
3386
  .settings {
2941
3387
  display: grid;
2942
- gap: 16px;
2943
- max-width: 760px;
2944
- padding-bottom: 72px;
3388
+ grid-template-columns: minmax(0, 740px) 200px;
3389
+ column-gap: 44px;
3390
+ row-gap: 16px;
3391
+ max-width: 1000px;
3392
+ padding-bottom: 80px;
3393
+ }
3394
+ .settings > * {
3395
+ grid-column: 1;
2945
3396
  }
2946
3397
  .settings__head {
2947
3398
  display: flex;
2948
- align-items: center;
3399
+ align-items: baseline;
2949
3400
  justify-content: space-between;
3401
+ padding: 4px 2px 0;
3402
+ }
3403
+ .settings__nav {
3404
+ grid-column: 2;
3405
+ grid-row: 2 / span 40;
3406
+ position: sticky;
3407
+ top: 24px;
3408
+ align-self: start;
3409
+ display: grid;
3410
+ gap: 2px;
3411
+ padding-top: 4px;
3412
+ }
3413
+ .settings__nav a {
3414
+ display: block;
3415
+ padding: 5px 10px;
3416
+ border-left: 2px solid transparent;
3417
+ border-radius: 0 6px 6px 0;
3418
+ color: var(--ink-2);
3419
+ font-size: 13.5px;
3420
+ text-decoration: none;
3421
+ }
3422
+ .settings__nav a:hover {
3423
+ color: var(--ink-1);
3424
+ background: var(--surface-sunken);
3425
+ }
3426
+ .settings__nav a[aria-current='true'] {
3427
+ border-left-color: var(--accent);
3428
+ color: var(--ink-1);
3429
+ font-weight: 600;
3430
+ }
3431
+ @media (max-width: 1000px) {
3432
+ .settings {
3433
+ grid-template-columns: minmax(0, 1fr);
3434
+ }
3435
+ .settings__nav {
3436
+ display: none;
3437
+ }
2950
3438
  }
2951
3439
  .settings__title {
2952
3440
  margin: 0;
2953
- font-size: 18px;
3441
+ font-family: var(--font-serif);
3442
+ font-size: 26px;
3443
+ font-weight: 500;
3444
+ letter-spacing: -0.005em;
2954
3445
  }
2955
3446
  .settings__problem {
2956
3447
  margin: 0;
2957
3448
  padding: 10px 14px;
2958
- border: 1px solid var(--warning);
3449
+ border: 1px solid var(--border);
3450
+ border-left: 3px solid var(--warning);
2959
3451
  border-radius: var(--radius-sm);
2960
- font-size: 13px;
3452
+ background: var(--surface);
3453
+ font-size: 13.5px;
2961
3454
  }
2962
3455
  .settings-card {
2963
- padding: 16px 18px;
3456
+ padding: 18px 24px 6px;
2964
3457
  background: var(--surface);
2965
3458
  border: 1px solid var(--border);
2966
3459
  border-radius: var(--radius);
@@ -2968,55 +3461,148 @@ body[data-onboarding='true'] {
2968
3461
  scroll-margin-top: 16px;
2969
3462
  }
2970
3463
  .settings-card__title {
2971
- margin: 0 0 10px;
2972
- font-size: 15px;
3464
+ margin: 0 0 4px;
3465
+ font-family: var(--font-serif);
3466
+ font-size: 19px;
3467
+ font-weight: 500;
2973
3468
  }
2974
3469
  .settings-card__help {
2975
- margin: 0 0 12px;
3470
+ margin: 0 0 10px;
3471
+ max-width: 70ch;
2976
3472
  color: var(--ink-2);
2977
- font-size: 13px;
3473
+ font-size: 13.5px;
2978
3474
  line-height: 1.5;
2979
3475
  }
2980
3476
  .settings-card__warning {
2981
3477
  margin: 0 0 10px;
2982
3478
  color: var(--serious);
2983
- font-size: 13px;
3479
+ font-size: 13.5px;
2984
3480
  }
2985
3481
  .settings-card__more {
2986
- margin-top: 6px;
3482
+ margin: 0;
2987
3483
  }
2988
3484
  .settings-card__more > summary {
3485
+ padding: 12px 0;
3486
+ border-top: 1px solid var(--rule);
2989
3487
  cursor: pointer;
2990
3488
  color: var(--ink-2);
2991
- font-size: 13px;
2992
- padding: 4px 0;
3489
+ font-size: 13.5px;
2993
3490
  }
2994
- .settings-card__more[open] > summary {
2995
- margin-bottom: 10px;
3491
+ .settings-card__more > summary:hover {
3492
+ color: var(--ink-1);
2996
3493
  }
2997
3494
 
3495
+ /* One setting: name and help on the left, the control on the right. */
2998
3496
  .field {
2999
3497
  display: grid;
3000
- gap: 4px;
3001
- margin-bottom: 14px;
3498
+ grid-template-columns: minmax(0, 1fr) 300px;
3499
+ grid-template-areas:
3500
+ 'label control'
3501
+ 'help control'
3502
+ 'note control';
3503
+ column-gap: 28px;
3504
+ row-gap: 3px;
3505
+ align-items: start;
3506
+ margin: 0;
3507
+ padding: 14px 0;
3508
+ border-top: 1px solid var(--rule);
3002
3509
  }
3003
- .settings-card > .field:last-child,
3004
- .settings-card__more > .field:last-child {
3005
- margin-bottom: 0;
3510
+ .settings-card__title + .field,
3511
+ .settings-card__help + .field,
3512
+ .settings-card__warning + .field,
3513
+ .settings-card__more > .field:first-of-type {
3514
+ border-top: 0;
3006
3515
  }
3007
3516
  .field__label {
3008
- font-size: 13px;
3009
- font-weight: 500;
3517
+ grid-area: label;
3518
+ font-size: 14px;
3519
+ font-weight: 600;
3010
3520
  }
3011
3521
  .field__input {
3012
- height: 32px;
3522
+ grid-area: control;
3523
+ width: 100%;
3524
+ height: 34px;
3013
3525
  padding: 0 10px;
3014
3526
  border: 1px solid var(--border);
3015
3527
  border-radius: var(--radius-sm);
3016
3528
  background: var(--page);
3017
3529
  color: var(--ink-1);
3018
3530
  font: inherit;
3531
+ font-size: 13.5px;
3532
+ }
3533
+ select.field__input {
3534
+ appearance: none;
3535
+ padding-right: 30px;
3536
+ 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>");
3537
+ background-repeat: no-repeat;
3538
+ background-position: right 10px center;
3539
+ background-size: 14px;
3540
+ }
3541
+ @media (max-width: 600px) {
3542
+ .field {
3543
+ grid-template-columns: minmax(0, 1fr);
3544
+ grid-template-areas:
3545
+ 'label'
3546
+ 'help'
3547
+ 'note'
3548
+ 'control';
3549
+ }
3550
+ }
3551
+
3552
+ /*
3553
+ * A yes/no, or a short list: a segmented control of the real answers. The one
3554
+ * in force by default says "default" beside its name, so a setting never
3555
+ * touched never looks like a choice that was made.
3556
+ */
3557
+ .segmented {
3558
+ grid-area: control;
3559
+ display: inline-flex;
3560
+ justify-self: end;
3561
+ max-width: 100%;
3562
+ padding: 3px;
3563
+ background: var(--surface-sunken);
3564
+ border: 1px solid var(--hairline);
3565
+ border-radius: 999px;
3566
+ }
3567
+ .segmented__option {
3568
+ display: inline-flex;
3569
+ align-items: baseline;
3570
+ gap: 5px;
3571
+ padding: 4px 12px;
3572
+ border: 0;
3573
+ border-radius: 999px;
3574
+ background: none;
3575
+ color: var(--ink-2);
3576
+ font: inherit;
3019
3577
  font-size: 13px;
3578
+ font-weight: 500;
3579
+ white-space: nowrap;
3580
+ cursor: pointer;
3581
+ }
3582
+ .segmented__option small {
3583
+ font-size: 11.5px;
3584
+ color: var(--ink-3);
3585
+ }
3586
+ .segmented__option:hover {
3587
+ color: var(--ink-1);
3588
+ }
3589
+ .segmented__option[aria-checked='true'] {
3590
+ background: var(--band);
3591
+ color: var(--band-ink);
3592
+ }
3593
+ .segmented__option[aria-checked='true'] small {
3594
+ color: rgba(255, 255, 255, 0.7);
3595
+ }
3596
+ .segmented[aria-disabled='true'] {
3597
+ opacity: 0.55;
3598
+ }
3599
+ .segmented[aria-disabled='true'] .segmented__option {
3600
+ cursor: not-allowed;
3601
+ }
3602
+ @media (max-width: 600px) {
3603
+ .segmented {
3604
+ justify-self: start;
3605
+ }
3020
3606
  }
3021
3607
  .field__input:disabled {
3022
3608
  color: var(--ink-3);
@@ -3025,29 +3611,48 @@ body[data-onboarding='true'] {
3025
3611
  .field[data-changed='true'] .field__input {
3026
3612
  border-color: var(--accent);
3027
3613
  }
3614
+ .field[data-changed='true'] .segmented {
3615
+ border-color: var(--accent);
3616
+ }
3028
3617
  .field__help,
3029
3618
  .field__note {
3030
3619
  margin: 0;
3620
+ max-width: 70ch;
3031
3621
  color: var(--ink-3);
3032
- font-size: 12px;
3622
+ font-size: 12.5px;
3033
3623
  line-height: 1.45;
3034
3624
  }
3625
+ .field__help {
3626
+ grid-area: help;
3627
+ }
3035
3628
  .field__note {
3629
+ grid-area: note;
3036
3630
  color: var(--ink-2);
3037
3631
  }
3038
3632
 
3633
+ /* The objective's two fields read top to bottom: a sentence wants the width. */
3039
3634
  .objective-form {
3040
3635
  display: grid;
3041
3636
  gap: 2px;
3637
+ padding-top: 4px;
3638
+ }
3639
+ .objective-form .field {
3640
+ grid-template-columns: minmax(0, 1fr);
3641
+ grid-template-areas:
3642
+ 'label'
3643
+ 'control';
3644
+ padding: 8px 0 10px;
3042
3645
  }
3043
3646
  .objective-form__actions {
3044
3647
  display: flex;
3045
3648
  justify-content: flex-end;
3649
+ padding: 6px 0 12px;
3046
3650
  }
3047
3651
 
3048
3652
  .text-editor {
3049
3653
  display: grid;
3050
3654
  gap: 8px;
3655
+ padding-bottom: 14px;
3051
3656
  }
3052
3657
  .text-editor__area {
3053
3658
  width: 100%;
@@ -3057,7 +3662,7 @@ body[data-onboarding='true'] {
3057
3662
  border-radius: var(--radius-sm);
3058
3663
  background: var(--page);
3059
3664
  color: var(--ink-1);
3060
- font: 12.5px/1.5 ui-monospace, 'SF Mono', Menlo, monospace;
3665
+ font: 12.5px/1.5 var(--font-mono);
3061
3666
  resize: vertical;
3062
3667
  }
3063
3668
  .text-editor__bar {
@@ -3068,7 +3673,7 @@ body[data-onboarding='true'] {
3068
3673
  }
3069
3674
  .text-editor__status {
3070
3675
  color: var(--ink-3);
3071
- font-size: 12px;
3676
+ font-size: 12.5px;
3072
3677
  }
3073
3678
  .text-editor__conflict {
3074
3679
  display: flex;
@@ -3076,17 +3681,21 @@ body[data-onboarding='true'] {
3076
3681
  align-items: center;
3077
3682
  gap: 8px;
3078
3683
  padding: 8px 12px;
3079
- border: 1px solid var(--warning);
3684
+ border: 1px solid var(--border);
3685
+ border-left: 3px solid var(--warning);
3080
3686
  border-radius: var(--radius-sm);
3687
+ background: var(--page);
3081
3688
  }
3082
3689
  .text-editor__conflict p {
3083
3690
  flex: 1 1 100%;
3084
3691
  margin: 0;
3085
- font-size: 13px;
3692
+ font-size: 13.5px;
3086
3693
  }
3087
3694
 
3088
3695
  .calendar-picker {
3089
- margin: -4px 0 14px;
3696
+ margin: 0;
3697
+ padding: 12px 0;
3698
+ border-top: 1px solid var(--rule);
3090
3699
  }
3091
3700
  .calendar-picker__list {
3092
3701
  display: grid;
@@ -3095,7 +3704,7 @@ body[data-onboarding='true'] {
3095
3704
  margin: 10px 0 0;
3096
3705
  padding: 0;
3097
3706
  list-style: none;
3098
- font-size: 13px;
3707
+ font-size: 13.5px;
3099
3708
  }
3100
3709
  .calendar-picker__source {
3101
3710
  color: var(--ink-3);
@@ -3116,7 +3725,7 @@ body[data-onboarding='true'] {
3116
3725
  background: var(--surface);
3117
3726
  border: 1px solid var(--border);
3118
3727
  border-radius: var(--radius);
3119
- box-shadow: 0 6px 24px rgba(11, 11, 11, 0.14);
3728
+ box-shadow: var(--shadow-float);
3120
3729
  }
3121
3730
  .settings__bar[hidden] {
3122
3731
  display: none;
@@ -3124,7 +3733,7 @@ body[data-onboarding='true'] {
3124
3733
  .settings__bar-text {
3125
3734
  flex: 1;
3126
3735
  margin: 0;
3127
- font-size: 13px;
3736
+ font-size: 13.5px;
3128
3737
  color: var(--ink-2);
3129
3738
  }
3130
3739
  .settings__bar-text--error {