@sierragridteam/design-system 0.0.0-stage → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +17 -2
  2. package/assets/sierra-logo-full.png +0 -0
  3. package/assets/sierra-mark.png +0 -0
  4. package/package.json +36 -4
  5. package/src/components/Badge.astro +13 -0
  6. package/src/components/Button.astro +36 -0
  7. package/src/components/Callout.astro +17 -0
  8. package/src/components/Card.astro +33 -0
  9. package/src/components/CopyButton.astro +81 -0
  10. package/src/components/DataDiff.astro +50 -0
  11. package/src/components/DataRow.astro +23 -0
  12. package/src/components/DataStatus.astro +26 -0
  13. package/src/components/DataTable.astro +25 -0
  14. package/src/components/EmptyState.astro +17 -0
  15. package/src/components/Field.astro +25 -0
  16. package/src/components/FilterBar.astro +10 -0
  17. package/src/components/GeoJSONMap.astro +280 -0
  18. package/src/components/GeometryPreview.astro +11 -0
  19. package/src/components/Icon.astro +19 -0
  20. package/src/components/IconSprite.astro +68 -0
  21. package/src/components/IdentifierList.astro +54 -0
  22. package/src/components/Logo.astro +75 -0
  23. package/src/components/MapFrame.astro +25 -0
  24. package/src/components/MetricGrid.astro +35 -0
  25. package/src/components/PageHeader.astro +24 -0
  26. package/src/components/Select.astro +202 -0
  27. package/src/components/ValueTable.astro +32 -0
  28. package/src/lib/basemap-style.ts +269 -0
  29. package/src/lib/controls.ts +126 -0
  30. package/src/lib/data-values.ts +45 -0
  31. package/src/lib/dialog.ts +85 -0
  32. package/src/lib/dom.ts +68 -0
  33. package/src/lib/toast.ts +22 -0
  34. package/src/styles/base.css +165 -0
  35. package/src/styles/components.css +2235 -0
  36. package/src/styles/global.css +4 -0
  37. package/src/styles/shell.css +501 -0
  38. package/src/styles/tokens.css +172 -0
@@ -0,0 +1,4 @@
1
+ @import './tokens.css';
2
+ @import './base.css';
3
+ @import './components.css';
4
+ @import './shell.css';
@@ -0,0 +1,501 @@
1
+ /**
2
+ * App shell: sidebar + topbar + content. Desktop shows the sidebar; below
3
+ * 860px it becomes a drawer opened from the top bar.
4
+ */
5
+ .shell {
6
+ display: grid;
7
+ grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
8
+ min-height: 100dvh;
9
+ }
10
+
11
+ .sidebar {
12
+ position: sticky;
13
+ view-transition-name: sidebar;
14
+ top: 0;
15
+ align-self: start;
16
+ height: 100dvh;
17
+ display: flex;
18
+ flex-direction: column;
19
+ background: var(--surface-banner);
20
+ border-right: var(--border);
21
+ }
22
+
23
+ .sidebar__brand {
24
+ display: flex;
25
+ align-items: center;
26
+ min-height: var(--topbar-h);
27
+ padding: 0 var(--space-5);
28
+ border-bottom: var(--border);
29
+ }
30
+
31
+ .sidebar__nav {
32
+ flex: 1 1 auto;
33
+ padding: var(--space-4) var(--space-3);
34
+ overflow-y: auto;
35
+ }
36
+
37
+ .sidebar__group + .sidebar__group {
38
+ margin-top: var(--space-5);
39
+ }
40
+
41
+ .sidebar__group-label {
42
+ display: block;
43
+ padding: 0 var(--space-3);
44
+ margin-bottom: var(--space-2);
45
+ font-size: var(--fs-label);
46
+ font-weight: var(--fw-semibold);
47
+ letter-spacing: var(--tracking-label);
48
+ text-transform: uppercase;
49
+ color: var(--brand-brass-text);
50
+ }
51
+
52
+ .sidebar__list {
53
+ list-style: none;
54
+ margin: 0;
55
+ padding: 0;
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 2px;
59
+ }
60
+
61
+ .nav-link {
62
+ display: flex;
63
+ align-items: center;
64
+ gap: var(--space-3);
65
+ min-height: var(--control-h);
66
+ padding: 0 var(--space-3);
67
+ border-radius: var(--radius-sm);
68
+ font-size: var(--fs-ui);
69
+ font-weight: var(--fw-medium);
70
+ color: var(--ink-body);
71
+ text-decoration: none;
72
+ transition:
73
+ background-color var(--transition),
74
+ color var(--transition);
75
+ }
76
+
77
+ .nav-link .icon {
78
+ color: var(--ink-muted);
79
+ }
80
+
81
+ .nav-link:hover {
82
+ background: var(--surface-card);
83
+ color: var(--brand-green);
84
+ text-decoration: none;
85
+ }
86
+
87
+ .nav-link:hover .icon {
88
+ color: var(--brand-green);
89
+ }
90
+
91
+ .nav-link.is-active {
92
+ background: var(--brand-green-tint);
93
+ color: var(--brand-green);
94
+ box-shadow: inset 3px 0 0 var(--brand-green);
95
+ }
96
+
97
+ .nav-link.is-active .icon {
98
+ color: var(--brand-green);
99
+ }
100
+
101
+ .sidebar__footer {
102
+ padding: var(--space-3) var(--space-3);
103
+ border-top: var(--border);
104
+ }
105
+
106
+ /* Compact chip: 240px has to fit avatar, email, and the sign-out button. */
107
+ .sidebar__footer .avatar {
108
+ width: 28px;
109
+ height: 28px;
110
+ font-size: var(--fs-label-lg);
111
+ }
112
+
113
+ .sidebar__user {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: var(--space-1);
117
+ min-width: 0;
118
+ }
119
+
120
+ .sidebar__footer .user-chip {
121
+ flex: 1 1 auto;
122
+ min-width: 0;
123
+ gap: var(--space-2);
124
+ padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1);
125
+ border-radius: var(--radius-sm);
126
+ color: inherit;
127
+ text-decoration: none;
128
+ }
129
+
130
+ .sidebar__footer a.user-chip:hover {
131
+ background: var(--surface-card);
132
+ text-decoration: none;
133
+ }
134
+
135
+ /* Icon-only sign-out beside the chip; the label is the accessible name. */
136
+ .sidebar__signout {
137
+ flex: 0 0 auto;
138
+ display: inline-grid;
139
+ place-items: center;
140
+ width: var(--control-h-sm);
141
+ height: var(--control-h-sm);
142
+ border: 0;
143
+ border-radius: var(--radius-sm);
144
+ background: none;
145
+ color: var(--ink-muted);
146
+ transition:
147
+ background-color var(--transition),
148
+ color var(--transition);
149
+ }
150
+
151
+ .sidebar__signout:hover {
152
+ background: var(--surface-card);
153
+ color: var(--brand-green);
154
+ }
155
+
156
+ /* Top bar: only visible on narrow screens */
157
+ .topbar {
158
+ display: none;
159
+ view-transition-name: topbar;
160
+ position: sticky;
161
+ top: 0;
162
+ z-index: var(--z-topbar);
163
+ align-items: center;
164
+ gap: var(--space-3);
165
+ min-height: var(--topbar-h);
166
+ padding: 0 var(--gutter);
167
+ background: color-mix(in srgb, var(--surface-page) 92%, transparent);
168
+ backdrop-filter: saturate(1.1) blur(6px);
169
+ border-bottom: var(--border);
170
+ }
171
+
172
+ .topbar__toggle {
173
+ display: inline-flex;
174
+ align-items: center;
175
+ justify-content: center;
176
+ padding: var(--space-2);
177
+ margin-left: calc(var(--space-2) * -1);
178
+ background: none;
179
+ border: 0;
180
+ color: var(--ink-secondary);
181
+ }
182
+
183
+ .topbar__toggle:hover {
184
+ color: var(--brand-green);
185
+ }
186
+
187
+ .topbar__title {
188
+ font-family: var(--font-display);
189
+ font-size: var(--fs-lead);
190
+ font-weight: var(--fw-semibold);
191
+ letter-spacing: 0.04em;
192
+ color: var(--ink-strong);
193
+ }
194
+
195
+ .main {
196
+ min-width: 0;
197
+ view-transition-name: main;
198
+ padding: var(--space-7) var(--gutter) var(--space-10);
199
+ }
200
+
201
+ .main__inner {
202
+ max-width: var(--content-max);
203
+ margin-inline: auto;
204
+ }
205
+
206
+ .main__inner--narrow {
207
+ max-width: var(--content-narrow);
208
+ }
209
+
210
+ .scrim {
211
+ display: none;
212
+ position: fixed;
213
+ inset: 0;
214
+ z-index: var(--z-overlay);
215
+ background: rgb(22 39 30 / 40%);
216
+ }
217
+
218
+ @media (max-width: 860px) {
219
+ .shell {
220
+ grid-template-columns: minmax(0, 1fr);
221
+ }
222
+
223
+ .topbar {
224
+ display: flex;
225
+ }
226
+
227
+ .sidebar {
228
+ position: fixed;
229
+ top: 0;
230
+ left: 0;
231
+ z-index: var(--z-drawer);
232
+ width: min(var(--sidebar-w), 84vw);
233
+ transform: translateX(-100%);
234
+ transition: transform var(--transition-slow);
235
+ box-shadow: none;
236
+ }
237
+
238
+ .shell[data-drawer='open'] .sidebar {
239
+ transform: none;
240
+ box-shadow: var(--shadow-drawer);
241
+ }
242
+
243
+ .shell[data-drawer='open'] .scrim {
244
+ display: block;
245
+ }
246
+
247
+ .main {
248
+ padding-top: var(--space-5);
249
+ }
250
+ }
251
+
252
+ /* Auth layout: centred narrow card on the cool hero tint */
253
+ .auth {
254
+ min-height: 100dvh;
255
+ display: grid;
256
+ grid-template-rows: auto 1fr auto;
257
+ background: var(--surface-hero);
258
+ background-image:
259
+ linear-gradient(color-mix(in srgb, var(--brand-green) 4.5%, transparent) 1px, transparent 1px),
260
+ linear-gradient(
261
+ 90deg,
262
+ color-mix(in srgb, var(--brand-green) 4.5%, transparent) 1px,
263
+ transparent 1px
264
+ );
265
+ background-size: 52px 52px;
266
+ }
267
+
268
+ .auth__header {
269
+ display: flex;
270
+ justify-content: center;
271
+ padding: var(--space-7) var(--gutter) 0;
272
+ }
273
+
274
+ .auth__main {
275
+ display: grid;
276
+ place-items: center;
277
+ padding: var(--space-7) var(--gutter);
278
+ }
279
+
280
+ .auth__card {
281
+ width: 100%;
282
+ max-width: 420px;
283
+ padding: var(--space-7);
284
+ background: var(--surface-card);
285
+ border: var(--border);
286
+ border-radius: var(--radius);
287
+ }
288
+
289
+ .auth__card h1 {
290
+ margin-bottom: var(--space-2);
291
+ }
292
+
293
+ .auth__card > p {
294
+ color: var(--ink-secondary);
295
+ font-size: var(--fs-ui);
296
+ margin-bottom: var(--space-5);
297
+ }
298
+
299
+ .auth__footer {
300
+ padding: 0 var(--gutter) var(--space-6);
301
+ text-align: center;
302
+ font-size: var(--fs-small);
303
+ color: var(--ink-muted);
304
+ }
305
+
306
+ /* Boot screen: holds auth-dependent pages until the session is known (src/lib/boot.ts) */
307
+ html[data-boot='loading'] body > :not(.boot) {
308
+ visibility: hidden;
309
+ }
310
+
311
+ /* Dialogs are appended to <body> later and have their own entrance (components.css). */
312
+ html[data-boot='ready'] body > :not(.boot, .dialog) {
313
+ animation: boot-in var(--transition-slow) both;
314
+ }
315
+
316
+ .boot {
317
+ position: fixed;
318
+ inset: 0;
319
+ z-index: 100;
320
+ display: grid;
321
+ place-items: center;
322
+ padding: var(--gutter);
323
+ background: var(--surface-hero);
324
+ background-image:
325
+ linear-gradient(color-mix(in srgb, var(--brand-green) 4.5%, transparent) 1px, transparent 1px),
326
+ linear-gradient(
327
+ 90deg,
328
+ color-mix(in srgb, var(--brand-green) 4.5%, transparent) 1px,
329
+ transparent 1px
330
+ );
331
+ background-size: 52px 52px;
332
+ transition: opacity var(--transition-slow);
333
+ }
334
+
335
+ html[data-boot='ready'] .boot {
336
+ opacity: 0;
337
+ pointer-events: none;
338
+ }
339
+
340
+ .boot__inner {
341
+ display: flex;
342
+ flex-direction: column;
343
+ align-items: center;
344
+ gap: var(--space-5);
345
+ text-align: center;
346
+ }
347
+
348
+ /* A fast session never shows the loader; a slow one fades it in. */
349
+ [data-boot-working] {
350
+ animation: boot-in 400ms ease 180ms both;
351
+ }
352
+
353
+ .boot__mark {
354
+ height: 38px;
355
+ width: auto;
356
+ }
357
+
358
+ .boot__track {
359
+ position: relative;
360
+ width: 120px;
361
+ height: 2px;
362
+ overflow: hidden;
363
+ background: var(--line-soft);
364
+ border-radius: var(--radius-pill);
365
+ }
366
+
367
+ .boot__bar {
368
+ position: absolute;
369
+ inset: 0 auto 0 0;
370
+ width: 40%;
371
+ background: var(--brand-green);
372
+ border-radius: inherit;
373
+ animation: boot-sweep 1.3s cubic-bezier(0.65, 0, 0.35, 1) infinite;
374
+ }
375
+
376
+ .boot__hint {
377
+ margin: 0;
378
+ font-size: var(--fs-small);
379
+ color: var(--ink-muted);
380
+ animation: boot-in 400ms ease 6s both;
381
+ }
382
+
383
+ .boot__failed {
384
+ gap: var(--space-3);
385
+ max-width: 36ch;
386
+ }
387
+
388
+ .boot__title {
389
+ margin: 0;
390
+ font-family: var(--font-display);
391
+ font-size: var(--fs-h2);
392
+ line-height: var(--lh-heading);
393
+ color: var(--ink-strong);
394
+ }
395
+
396
+ .boot__message {
397
+ margin: 0 0 var(--space-3);
398
+ font-size: var(--fs-ui);
399
+ color: var(--ink-secondary);
400
+ }
401
+
402
+ /* Without JavaScript nothing would ever call reveal(); show the page as it is. */
403
+ @media (scripting: none) {
404
+ .boot {
405
+ display: none;
406
+ }
407
+
408
+ html[data-boot='loading'] body > :not(.boot) {
409
+ visibility: visible;
410
+ }
411
+ }
412
+
413
+ @keyframes boot-in {
414
+ from {
415
+ opacity: 0;
416
+ }
417
+ }
418
+
419
+ @keyframes boot-sweep {
420
+ from {
421
+ transform: translateX(-100%);
422
+ }
423
+ to {
424
+ transform: translateX(250%);
425
+ }
426
+ }
427
+
428
+ @media (prefers-reduced-motion: reduce) {
429
+ /* The global rule would stop the sweep after one pass; pulse gently instead. */
430
+ .boot__bar {
431
+ width: 100%;
432
+ animation: boot-pulse 1.6s ease-in-out infinite !important;
433
+ }
434
+ }
435
+
436
+ @keyframes boot-pulse {
437
+ 50% {
438
+ opacity: 0.35;
439
+ }
440
+ }
441
+
442
+ /* Client-side navigation (src/lib/navigation.ts). The sidebar, top bar, toasts and content
443
+ column are named view-transition groups (view-transition-name on each rule), so they leave
444
+ the page's crossfade: the shell stays put while the content swaps with a short fade and lift.
445
+ The names live here rather than in transition:name / transition:animate directives because
446
+ those emit an inline <style> the CSP hashes do not cover. */
447
+ ::view-transition-group(main) {
448
+ animation-duration: 0s;
449
+ }
450
+
451
+ ::view-transition-old(main) {
452
+ animation: content-out 90ms ease-in both;
453
+ }
454
+
455
+ ::view-transition-new(main) {
456
+ animation: content-in 220ms ease-out both;
457
+ }
458
+
459
+ @keyframes content-out {
460
+ to {
461
+ opacity: 0;
462
+ }
463
+ }
464
+
465
+ @keyframes content-in {
466
+ from {
467
+ opacity: 0;
468
+ transform: translateY(6px);
469
+ }
470
+ }
471
+
472
+ /* A thin sweep along the top while the next page is fetched; the delay keeps it off the
473
+ screen for the usual instant (prefetched) navigation. */
474
+ html[data-navigating] body::before {
475
+ content: '';
476
+ position: fixed;
477
+ top: 0;
478
+ left: 0;
479
+ z-index: var(--z-skiplink);
480
+ width: 25vw;
481
+ height: 2px;
482
+ background: var(--brand-green);
483
+ animation: nav-sweep 1.1s cubic-bezier(0.65, 0, 0.35, 1) 150ms infinite backwards;
484
+ }
485
+
486
+ @keyframes nav-sweep {
487
+ from {
488
+ transform: translateX(-100%);
489
+ }
490
+ to {
491
+ transform: translateX(400vw);
492
+ }
493
+ }
494
+
495
+ @media (prefers-reduced-motion: reduce) {
496
+ ::view-transition-group(*),
497
+ ::view-transition-old(*),
498
+ ::view-transition-new(*) {
499
+ animation: none !important;
500
+ }
501
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Design tokens — S.I.E.R.R.A Members.
3
+ *
4
+ * A derivative of the main site's "Civic Direction" system (sierragridteam.org,
5
+ * src/styles/tokens.css). Palette, typefaces, rules and status colours are
6
+ * inherited unchanged so the two sites read as one institution. Type roles,
7
+ * spacing, radii and layout are re-tuned for an application: denser, sans-serif
8
+ * body, sidebar shell. Rationale and the full comparison: docs/design-system.md.
9
+ *
10
+ * This is the ONLY file allowed to contain raw hex colours and raw px font
11
+ * sizes (stylelint enforces it). Everything else uses var(--…).
12
+ */
13
+
14
+ :root {
15
+ /* ---------------------------------------------------------------------- */
16
+ /* Surfaces — warm parchment neutrals (inherited) */
17
+ /* ---------------------------------------------------------------------- */
18
+ --surface-page: #f3efe4; /* app background */
19
+ --surface-card: #f6f2e7; /* cards, panels, table headers */
20
+ --surface-banner: #efe9da; /* sidebar, callouts, code, footer strips */
21
+ --surface-raised: #fdfcf7; /* inputs, hovered rows, popovers */
22
+ --surface-hero: #edefe7; /* cool tint — auth screens, empty states */
23
+ --surface-deep: #14281d; /* the one dark ground — admin badge, toasts */
24
+ --surface-deep-line: #2c4536;
25
+
26
+ /* ---------------------------------------------------------------------- */
27
+ /* Ink (inherited) */
28
+ /* ---------------------------------------------------------------------- */
29
+ --ink-strong: #16271e;
30
+ --ink-body: #3c453c;
31
+ --ink-secondary: #5a5e4f;
32
+ --ink-muted: #6f6750;
33
+ --ink-on-deep: #f1ece0;
34
+ --ink-on-deep-muted: #9db3a4;
35
+
36
+ /* ---------------------------------------------------------------------- */
37
+ /* Brand & signal (inherited) */
38
+ /* ---------------------------------------------------------------------- */
39
+ --brand-green: #1d5b3f; /* primary: actions, links, focus, active nav */
40
+ --brand-green-hover: #16472f;
41
+ --brand-green-tint: #e4ebe4; /* selected row / active nav ground */
42
+ --brand-brass: #b08a3e; /* rules, secondary outline, pending state */
43
+ --brand-brass-text: #785d20;
44
+ --brand-brass-tint: #f1e8d3;
45
+ --signal-orange: #c2410c; /* risk / destructive only */
46
+ --signal-orange-hover: #9a330a;
47
+ --signal-orange-text: #b03808;
48
+ --signal-orange-tint: #f6e2d6;
49
+
50
+ /* Status dots & badges */
51
+ --state-ok: #1d5b3f;
52
+ --state-elevated: #b08a3e;
53
+ --state-alarm: #c2410c;
54
+ --state-muted: #9a906f;
55
+
56
+ /* ---------------------------------------------------------------------- */
57
+ /* Lines (inherited — always warm tan, never grey) */
58
+ /* ---------------------------------------------------------------------- */
59
+ --line: #d8d0bd;
60
+ --line-soft: #e5ddca;
61
+ --line-control: #928869; /* ≥ 3:1 against inputs */
62
+ --border-w: 1px;
63
+ --border: var(--border-w) solid var(--line);
64
+ --border-soft: var(--border-w) solid var(--line-soft);
65
+
66
+ /* ---------------------------------------------------------------------- */
67
+ /* Typography — same faces, app roles */
68
+ /* ---------------------------------------------------------------------- */
69
+ --font-display:
70
+ "Newsreader Variable", "Newsreader", Georgia, "Times New Roman", serif;
71
+ --font-ui:
72
+ "IBM Plex Sans Variable", "IBM Plex Sans", system-ui, -apple-system,
73
+ sans-serif;
74
+ --font-mono:
75
+ "IBM Plex Mono", ui-monospace, "SF Mono", "Cascadia Code", monospace;
76
+
77
+ /* Serif is reserved for page titles and section headings. */
78
+ --fs-h1: clamp(1.625rem, 1.4rem + 1vw, 2rem); /* 26 → 32px */
79
+ --fs-h2: 1.375rem; /* 22px */
80
+ --fs-h3: 1rem; /* 16px, sans, semibold */
81
+ --fs-lead: 1.0625rem; /* 17px intro text */
82
+ --fs-body: 1rem; /* 16px — reading text, floor for prose */
83
+ --fs-ui: 0.875rem; /* 14px — controls, table cells, meta */
84
+ --fs-small: 0.8125rem; /* 13px — help text, timestamps */
85
+ --fs-label: 0.6875rem; /* 11px uppercase labels */
86
+ --fs-label-lg: 0.75rem; /* 12px */
87
+ --fs-stat: 1.75rem; /* 28px numbers */
88
+ --fs-code: 1.75rem; /* OTP entry */
89
+
90
+ --fw-regular: 400;
91
+ --fw-medium: 500;
92
+ --fw-semibold: 600;
93
+
94
+ --lh-heading: 1.15;
95
+ --lh-body: 1.55;
96
+ --lh-ui: 1.4;
97
+ --tracking-tight: -0.01em;
98
+ --tracking-label: 0.14em;
99
+ --tracking-kicker: 0.22em;
100
+
101
+ /* ---------------------------------------------------------------------- */
102
+ /* Geometry — the app diverges here: soft corners, 4px spacing grid */
103
+ /* ---------------------------------------------------------------------- */
104
+ --radius-sm: 2px; /* controls, badges */
105
+ --radius: 4px; /* cards, panels, rows */
106
+ --radius-pill: 999px;
107
+
108
+ --space-1: 4px;
109
+ --space-2: 8px;
110
+ --space-3: 12px;
111
+ --space-4: 16px;
112
+ --space-5: 20px;
113
+ --space-6: 24px;
114
+ --space-7: 32px;
115
+ --space-8: 40px;
116
+ --space-9: 48px;
117
+ --space-10: 64px;
118
+
119
+ --control-h: 36px; /* inputs, buttons, selects */
120
+ --control-h-sm: 28px;
121
+ --row-h: 48px; /* list rows */
122
+ --icon: 18px;
123
+ --icon-lg: 22px;
124
+
125
+ /* ---------------------------------------------------------------------- */
126
+ /* Layout — app shell */
127
+ /* ---------------------------------------------------------------------- */
128
+ --sidebar-w: 240px;
129
+ --topbar-h: 56px;
130
+ --content-max: 960px;
131
+ --content-narrow: 560px;
132
+ --dialog-w: 560px;
133
+ --dialog-w-wide: 760px;
134
+ --gutter: clamp(16px, 3vw, 32px);
135
+ --section-gap: var(--space-8);
136
+
137
+ --z-skiplink: 100;
138
+ --z-toast: 90;
139
+ --z-topbar: 50;
140
+ --z-drawer: 60;
141
+ --z-overlay: 40;
142
+
143
+ /* Shadows: none on cards; only floating things */
144
+ --shadow-overlay: 0 1px 0 var(--line);
145
+ --shadow-popover:
146
+ 0 6px 20px rgb(22 39 30 / 14%), 0 1px 3px rgb(22 39 30 / 10%);
147
+ --shadow-drawer: 0 12px 32px rgb(22 39 30 / 22%);
148
+ --backdrop: rgb(
149
+ 20 40 29 / 45%
150
+ ); /* behind modal dialogs: --surface-deep, translucent */
151
+
152
+ /* Motion */
153
+ --transition: 120ms ease;
154
+ --transition-slow: 200ms ease;
155
+ }
156
+
157
+ @media (prefers-reduced-motion: reduce) {
158
+ :root {
159
+ --transition: 0s;
160
+ --transition-slow: 0s;
161
+ }
162
+ }
163
+
164
+ /* Map ground: aligned with sierragridteam.org, independent of page layout. */
165
+ :root {
166
+ --map-water: #dde3da;
167
+ --map-road: #f8f6ef;
168
+ --map-road-casing: #ddd4bd;
169
+ --map-county-line: #c9c1a9;
170
+ --map-place: #9a906f;
171
+ --map-shield-text: #7d7459;
172
+ }