Skip to main content

max / goingson

233.4 KB · 9941 lines History Blame Raw
1 /* ============================================================================
2 GoingsOn — Neobrute Theme
3
4 Build new UI by COMPOSING the existing vocabulary, in this order of preference:
5
6 1. Use a UTILITY class for one-off adjustments (.mb-1, .mb-2, .flex-1,
7 .text-sm-secondary, .hidden)
8 2. Use a LAYOUT PRIMITIVE to position content (.row-flex + .row-flex-{2,3,4},
9 .row, .stack-{2,3,4})
10 3. Use a COMPONENT PRIMITIVE for a UI element (.card, .btn, .form-input,
11 .form-select, .modal, .badge,
12 .tag, .toggle-switch)
13 4. Extend a primitive with a modifier (.btn-primary, .btn-sm,
14 .form-select--compact,
15 .subtask-item--linked)
16 5. ONLY THEN consider a new class — and add it to the right
17 BAND below
18
19 A new class is a smell, not a goal. Before writing one:
20 • grep this file for the visual shape you want; almost everything is here
21 • check whether an existing primitive + modifier composes to your shape
22 • page-scoped rules under a feature class (`.day-plan .foo`) are a last
23 resort, not a first move
24
25 WHEN UTILITY-STACKING IS WRONG: A row of mixed-intent elements (one fills,
26 others size to content) belongs in a NAMED LAYOUT with an explicit
27 `grid-template-columns`, not in `.row-flex` + utilities. The utility form
28 encodes intent in browser flex-shrink math rather than in CSS that reads
29 as intent — especially fragile when the row contains a native `<select>`,
30 whose intrinsic-min-content sizing fights `flex: 1`. Smell test: if you
31 find yourself reaching for `.form-select--compact`, `style="width: auto;"`,
32 or `min-width: 0 !important` to make a row lay out right, the layout
33 itself wants a name. See `.email-filter-row`, `.contacts-filter-row`, and
34 `.work-hours-row` (all 2026-05-24) for the canonical form.
35
36 ----------------------------------------------------------------------------
37 FILE STRUCTURE — search by BAND name (uppercase anchors) to navigate.
38 Per-section titles use `=== N. Title ===` headers; numbered for stability,
39 not because order matters. Bands group related sections; cascade order is
40 load-bearing only inside the RESPONSIVE LAYERS and PRINT LAYERS bands.
41
42 BAND: FOUNDATIONS
43 1. Font Face
44 2. CSS Reset & Base
45 3. Design System Variables (Neobrute) — tokens (:root)
46 4. Utility Classes — shadow/hover/border,
47 layout, form sizing,
48 settings, subtask
49
50 BAND: APP SHELL & CHROME
51 5. Body & App Shell
52 6. Header
53 7. Tab Navigation
54 8. Main Content & Page Header
55
56 BAND: COMPONENT PRIMITIVES & WIDGETS
57 9. Buttons — .btn + variants/sizes
58 10. Quick Add Input
59 11. Cards
60 12. Tags & Badges
61 13. Data Table
62 14. Task Table & Rows
63 15. Due Date Badges
64 16. Events
65 17. Email List
66 18. Toast Notifications
67 19. Modals
68 20. Form Elements — .form-input,
69 .form-select, +
70 JS-rendered layout
71 utilities tail
72 21. Footer
73 22. Empty & Error States
74 23. Filter Bar
75
76 BAND: RESPONSIVE LAYER 1 (see RESPONSIVE STRATEGY)
77 24. Responsive - Large Screens & Tablet
78 25. Responsive - Mobile (768px, base pass)
79
80 BAND: A11Y, PAGINATION, FOCUS
81 26. Screen Reader & Accessibility
82 27. Pagination
83 28. Focus & Keyboard Accessibility
84
85 BAND: EMAIL READER
86 29. Source Email Link
87 30. Email Reader Mode
88
89 BAND: OVERLAYS
90 31. Dropdown Menus
91 32. Context Menus
92 33. Scrollbar Styling
93 34. Desktop App Styles (Loading, Skeleton, Spinner)
94
95 BAND: FEATURE SCREENS (A)
96 35. Project Dashboard 41. Settings
97 36. Task Badges 42. Snooze Options
98 37. Progress Bar 43. Bulk Selection
99 38. Day Plan View 44. Time Blocking
100 39. Timeline 45. App Layout
101 40. Unscheduled Tasks 46. Saved Views Sidebar
102 47. Contacts
103
104 BAND: PRINT LAYER 1 (see PRINT STRATEGY)
105 48. Print Styles (global)
106
107 BAND: WEEKLY REVIEW (V1 + V2 coexist)
108 49. Weekly Review (V1, still live)
109 50. Weekly Review V2 - Grid Layout
110 51. Weekly Review Transitions & Keyboard Navigation
111
112 BAND: PRINT LAYER 2
113 52. Weekly Review Print Styles
114
115 BAND: FEATURE SCREENS (B)
116 52b. Monthly Review 55. Toggle Switch
117 53. Import Wizard 56. Project Milestones
118 54. Plugin Manager (57 intentionally unused)
119
120 BAND: MOBILE LAYER (see RESPONSIVE STRATEGY)
121 58. Mobile Navigation (Nav Dot, Dial, Bottom Sheets)
122 59. Mobile Responsive (768px overrides, late pass)
123 60. Touch Device Hover Disable
124
125 BAND: FEATURE SCREENS (C)
126 61. Kanban Board 66. Timer Subview (Time tab pill)
127 62. Timer Widget 67. Task Overview
128 63. Focus Timer (Pomodoro) 68. Plan/Review Toggle Nudge Dot
129 64. Time Summary Panel 69. Finish & Review
130 65. Task Time Tracking UI 70. Calendar Views
131
132 BAND: SCOPED STYLESHEETS
133 Compose window (compose.html standalone Tauri window)
134
135 ----------------------------------------------------------------------------
136 EXISTING VOCABULARY — grep before inventing a new class.
137
138 UTILITIES
139 Layout .flex-1, .row, .row-flex + .row-flex-{2,3,4},
140 .stack-{2,3,4}, .mb-{1,2}
141 Text .text-sm-secondary, .text-xs-secondary, .text-center,
142 .text-left, .text-muted, .text-accent-red
143 Sizing .flex-1, .w-full
144 State .hidden, .is-selected, .is-active
145
146 LAYOUT PRIMITIVES
147 .row-flex (display:flex; align-items:center) + gap modifier .row-flex-N
148 .row (display:flex, no align) + gap modifier .row-flex-N
149 .stack (vertical) + gap modifier
150
151 COMPONENT PRIMITIVES
152 .btn + .btn-primary / -secondary / -danger / -sm
153 .card + .card--list-item / --shell / --muted (compact / container / info-panel)
154 .form-input + .form-input--ghost
155 .form-select + .form-select--compact / --ghost
156 .modal + .modal-overlay
157 .badge + variants ([data-color], --xs / --sm / --filled)
158 .tag + variants ([data-color])
159 .toggle-switch
160 .avatar + .avatar--sm / --lg / --unknown
161 .toast + variants
162 .pagination-controls
163 .filter-bar / .filter-select
164 .dropdown-menu / .context-menu
165 .empty-state
166
167 CONTROL MODIFIERS
168 Sizes: .btn-sm
169 Intents: .btn-primary / -secondary / -danger
170 Shapes: .form-select--compact / --ghost, .form-input--ghost
171
172 ----------------------------------------------------------------------------
173 UI MODE STRATEGY (do not casually merge)
174
175 UI mode is set ONCE at boot by index.html's inline script and exposed
176 as `<html class="ui-mode-desktop">` or `<html class="ui-mode-mobile">`.
177 Viewport width does NOT switch UI mode — desktop binaries stay desktop
178 even when the window is narrowed.
179
180 §25 Mobile (base pass) — early `.ui-mode-mobile` rules; applies before
181 feature CSS so feature rules can override.
182 §59 Mobile (late pass) — late `.ui-mode-mobile` rules; runs AFTER
183 feature CSS so it wins conflicts. Add new
184 mobile overrides here unless you need them
185 early.
186 §60 Touch hover disable — `@media (hover: none)`. INPUT-CAPABILITY axis,
187 not UI mode. Reserved for hover suppression
188 only. Never put visibility or layout rules
189 here — they belong under `.ui-mode-mobile`.
190
191 Intra-mode responsive: `@media (max-width: ...)` queries are allowed
192 INSIDE a UI mode (e.g. `.ui-mode-desktop` rules at narrow desktop
193 widths). Do not use a media query to switch BETWEEN UI modes.
194
195 PRINT STRATEGY
196 §48 Global print rules — early.
197 §52 Weekly Review print — placed after §49/§50 so V2 grid resets win.
198
199 ----------------------------------------------------------------------------
200 WEEKLY REVIEW V1 + V2 COEXISTENCE
201
202 §49 (V1: .weekly-review-content, .weekly-review-header, ...) and
203 §50 (V2: .review-grid, .review-card, ...) are BOTH live. weekly-review.js
204 and mobile.js still render V1 classes; the V2 grid is used by newer
205 review surfaces. Do not delete §49 until those JS render paths migrate.
206
207 ============================================================================ */
208
209 /* ===================================================================
210 1. Font Face
211 =================================================================== */
212 @font-face {
213 font-family: 'Reglo';
214 src: url('../fonts/Reglo-Bold.woff2') format('woff2');
215 font-weight: 700;
216 font-style: normal;
217 font-display: swap;
218 }
219
220 /* ===================================================================
221 2. CSS Reset & Base
222 =================================================================== */
223 *, *::before, *::after {
224 box-sizing: border-box;
225 margin: 0;
226 padding: 0;
227 }
228
229 /* ===================================================================
230 3. Design System Variables (Neobrute)
231 =================================================================== */
232 :root {
233 /* Day-plan timeline slot height (1 slot = 15 min). Mobile bumps this for fat-finger touch.
234 JS reads it via getComputedStyle so the height: in .timeline-slot stays in sync with
235 positioning math in day-planning-render.js / day-planning.js. */
236 --timeline-slot-h: 12px;
237
238 /* === NEOBRUTE DESIGN SYSTEM === */
239 /* Clean neobrutalism: bold borders, flat by default, offset shadows on actions + floats */
240
241 /* === INTENT LAYER (themeable) ===
242 Resolved intent tokens, applied at runtime by js/themes.js (setProperty
243 on :root). Defaults below are the "goingson" titular theme for first
244 paint; theme-common resolves every theme — including the derived states
245 (action-hover/active, selection, row-stripe, status surfaces) — so this
246 is one shared mapping across audiofiles / Balanced Breakfast / MNW. */
247 --surface-page: #E0E4FA;
248 --surface-raised: #FFFFFF;
249 --surface-sunken: #BAC2E6;
250 --surface-overlay: #CDD3F0;
251 --content: #000000;
252 --content-secondary: #2D2D2D;
253 --content-muted: #6B6B6B;
254 --content-on-action: #000000;
255 --action: #6196FF;
256 --action-hover: #70a6ff;
257 --danger: #DC3545;
258 --success: #5CB85C;
259 --warning: #F7D154;
260 --info: #17A2B8;
261 --border: #000000;
262 --border-strong: #000000;
263 --focus-ring: #6196ff;
264 --hover-surface: #bac2e6;
265 --category-one: #DC3545;
266 --category-two: #5CB85C;
267 --category-three: #6196FF;
268 --category-four: #F7D154;
269 --category-five: #7B68EE;
270 --category-six: #17A2B8;
271 --overlay: rgba(1, 1, 8, 0.5);
272
273 /* === APP-LOCAL (not theme intents) ===
274 GoingsOn's component CSS references the intent tokens above directly —
275 no brand aliases. Only the neobrute border width is app-local now;
276 overlay/scrim is a theme intent (theme-common 0.7.0). */
277 --border-width: 2px;
278 --border-width-sm: 2px;
279
280 /* Shadow offset scale (used by 3D action elements only) */
281 --shadow-offset-xs: 1px;
282 --shadow-offset-md: 3px;
283 --shadow-offset: 4px;
284 --shadow-offset-lg: 6px;
285 --shadow-offset-xl: 8px;
286
287 /* Neobrutalist shadows — actions + floats only */
288 --shadow-brutal-xs: var(--shadow-offset-xs) var(--shadow-offset-xs) 0 var(--border);
289 --shadow-brutal-md: var(--shadow-offset-md) var(--shadow-offset-md) 0 var(--border);
290 --shadow-brutal-lg: var(--shadow-offset-lg) var(--shadow-offset-lg) 0 var(--border);
291 --shadow-brutal-xl: var(--shadow-offset-xl) var(--shadow-offset-xl) 0 var(--border);
292
293 /* Border radius scale */
294 --radius-xs: 3px; /* Scrollbars, tiny elements */
295 --radius-sm: 5px; /* Buttons, inputs, small cards */
296 --radius-md: 5px; /* Cards, buttons — uniform */
297 --radius-lg: 10px; /* Modals, large panels */
298 --radius-xl: 20px; /* Pills, capsules */
299 --radius-full: 50%; /* Circles */
300
301 /* Layout widths */
302 --width-container: 1400px;
303 --width-modal: 560px;
304 --width-sidebar: 280px;
305
306 /* Spacing scale */
307 --space-1: 0.25rem;
308 --space-2: 0.5rem;
309 --space-3: 0.75rem;
310 --space-4: 1rem;
311 --space-5: 1.25rem;
312 --space-6: 1.5rem;
313
314 --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
315 --font-serif: Georgia, 'Times New Roman', serif;
316 --font-mono: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
317 --font-display: 'Reglo', var(--font-serif);
318
319 /* Semantic font aliases */
320 --font-heading: var(--font-sans);
321 --font-body: var(--font-sans);
322
323 /* Typography scale */
324 --font-size-xxs: 0.65rem; /* Tiny badges, indicators */
325 --font-size-xs: 0.7rem; /* Small badges, counts */
326 --font-size-sm: 0.75rem; /* Meta text, timestamps */
327 --font-size-md: 0.8rem; /* Table headers, compact UI */
328 --font-size-base: 0.875rem;/* Body text default */
329 --font-size-lg: 1rem; /* Emphasized body text */
330 --font-size-xl: 1.1rem; /* Subheadings */
331 --font-size-2xl: 1.25rem; /* Section titles */
332 --font-size-3xl: 1.5rem; /* Page titles */
333 --font-size-4xl: 1.75rem; /* Main headings */
334
335 /* Line height scale */
336 --line-height-tight: 1.25;
337 --line-height-normal: 1.5;
338 --line-height-relaxed: 1.75;
339
340 /* Transition timing */
341 --transition-fast: 0.1s;
342 --transition-normal: 0.15s;
343 --transition-slow: 0.3s;
344
345 /* Modal overlay — derived: mixes --text-primary into transparent. On a dark theme this
346 produces a *light* scrim, which is wrong; dark themes should override with their own
347 --overlay-color or this should be reworked to use a dedicated --scrim token. */
348 --overlay-color: color-mix(in srgb, var(--content) 60%, transparent);
349
350 }
351
352 html {
353 font-size: 16px;
354 }
355
356 /* ===================================================================
357 4. Utility Classes (Shadow, Hover, Border)
358 =================================================================== */
359 /* === LAYOUT UTILITIES === */
360 /* Compose: .row-flex + .row-flex-{2,3,4} for align-items:center rows.
361 .row for raw flex with no align. .flex-1 to grow a child. */
362 .flex-1 { flex: 1; }
363 .row { display: flex; }
364 .text-sm-secondary { font-size: 0.875rem; color: var(--content-secondary); }
365 .text-xs-secondary { font-size: 0.75rem; color: var(--content-secondary); }
366 .text-accent-red { color: var(--danger); }
367 .mb-1 { margin-bottom: 1rem; }
368 .mb-2 { margin-bottom: var(--space-2); }
369
370 /* === FORM SIZING UTILITIES === */
371 .form-select--compact { width: auto; min-width: 120px; }
372
373 /* === SETTINGS UTILITIES === */
374 .settings-divider { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 2px solid var(--border); }
375 .settings-heading { margin-bottom: 1rem; font-family: var(--font-heading); }
376 .settings-desc { font-size: 0.875rem; color: var(--content-secondary); margin-bottom: 1rem; }
377
378 /* === SUBTASK UTILITIES === */
379 /* .subtask-item is the base row; --linked is a modifier for subtasks that
380 reference another task (raised bg + accent border). Use both classes
381 together: <div class="subtask-item subtask-item--linked">. */
382 .subtask-item {
383 display: flex;
384 align-items: center;
385 gap: 0.5rem;
386 padding: 0.5rem;
387 background: var(--surface-overlay);
388 border-radius: 4px;
389 margin-bottom: 0.5rem;
390 }
391 .subtask-item--linked {
392 background: var(--surface-sunken);
393 border-left: var(--border-width) solid var(--action);
394 }
395 .subtask-checkbox { cursor: pointer; width: 18px; height: 18px; }
396 .subtask-checkbox-disabled { cursor: not-allowed; width: 18px; height: 18px; opacity: 0.5; }
397 .subtask-text-done { text-decoration: line-through; opacity: 0.6; }
398
399 /* ===================================================================
400 5. Body & App Shell
401 =================================================================== */
402 body {
403 font-family: var(--font-sans);
404 background-color: var(--surface-page);
405 color: var(--content);
406 line-height: 1.6;
407 height: 100vh;
408 overflow: hidden;
409 display: flex;
410 flex-direction: column;
411 }
412
413 /* Interactive chrome is not text. Buttons, tabs, nav, badges, and labels
414 shouldn't show a text selection on press-and-hold (notably the mobile
415 bottom tab bar, where a long-press otherwise highlights the label and
416 you have to dodge it). Content text — inputs, textareas, contenteditable,
417 and anything explicitly marked .selectable — stays selectable. */
418 .btn,
419 .tab,
420 .tab-label,
421 .tab-icon,
422 .tab-navigation,
423 .mobile-tab,
424 .mobile-tab-bar,
425 .mobile-tab-create,
426 .badge,
427 .tag,
428 .toggle-switch,
429 label,
430 button {
431 -webkit-user-select: none;
432 user-select: none;
433 }
434
435 input,
436 textarea,
437 [contenteditable="true"],
438 .selectable {
439 -webkit-user-select: text;
440 user-select: text;
441 }
442
443 /* ===================================================================
444 6. Header (desktop UI only)
445 The top app header is part of desktop layout. Mobile UI hides it
446 wholesale; rules below are scoped so they cannot leak in.
447 =================================================================== */
448 .ui-mode-desktop .app-header {
449 background: var(--surface-raised);
450 border-bottom: var(--border-width) solid var(--border);
451 padding: 0.75rem 1.5rem;
452 display: flex;
453 justify-content: space-between;
454 align-items: center;
455 }
456
457 .ui-mode-desktop .header-content {
458 display: flex;
459 align-items: center;
460 gap: 0.75rem;
461 }
462
463 .ui-mode-desktop .header-actions {
464 display: flex;
465 align-items: center;
466 gap: 0.5rem;
467 }
468
469 .ui-mode-desktop .app-title {
470 font-family: var(--font-display);
471 font-size: 1.75rem;
472 font-weight: 700;
473 color: var(--content);
474 letter-spacing: -0.02em;
475 }
476
477 .ui-mode-desktop .app-subtitle {
478 font-size: 0.875rem;
479 color: var(--content-muted);
480 font-weight: 500;
481 line-height: 1;
482 }
483
484 .mobile-view-title {
485 display: none;
486 }
487
488 /* ===================================================================
489 7. Tab Navigation (desktop UI only)
490 The top tab strip is desktop-only; mobile UI uses the bottom tab bar.
491 =================================================================== */
492 .ui-mode-desktop .tab-navigation {
493 display: flex;
494 justify-content: center;
495 gap: 0.5rem;
496 }
497
498 .ui-mode-desktop .tab {
499 display: flex;
500 align-items: center;
501 gap: 0.5rem;
502 padding: 0.75rem 1.25rem;
503 text-decoration: none;
504 color: var(--content);
505 background: var(--surface-raised);
506 border: var(--border-width) solid var(--border);
507 border-radius: var(--radius-md);
508 font-weight: 600;
509 transition: background-color 0.15s ease;
510 }
511
512 .ui-mode-desktop .tab:hover {
513 background: var(--surface-overlay);
514 }
515
516 .ui-mode-desktop .tab.active {
517 background-color: var(--action);
518 color: var(--content-on-action);
519 box-shadow: var(--shadow-brutal-xs);
520 }
521
522 .ui-mode-desktop .tab-icon {
523 font-size: 1.1rem;
524 }
525
526 .ui-mode-desktop .tab-label {
527 font-weight: 600;
528 font-size: 0.9rem;
529 }
530
531 .ui-mode-desktop .tab.tab-right {
532 margin-left: auto;
533 }
534
535 /* --- Tab Groups & Sub-Views (shared) --- */
536 .tab-group .subview.hidden {
537 display: none;
538 }
539
540 /* --- Pill Sub-Navigation (desktop UI only — mobile uses slide menu) --- */
541 .ui-mode-desktop .pill-nav {
542 display: flex;
543 align-items: center;
544 gap: var(--space-1);
545 padding: 0;
546 margin-bottom: 1rem;
547 min-height: 2rem;
548 }
549
550 .ui-mode-desktop .pill {
551 padding: var(--space-1) var(--space-3);
552 border-radius: var(--radius-xl);
553 border: var(--border-width-sm) solid var(--border);
554 background: var(--surface-raised);
555 font-family: var(--font-sans);
556 font-size: var(--font-size-sm);
557 font-weight: 600;
558 cursor: pointer;
559 transition: background-color var(--transition-fast);
560 }
561
562 .ui-mode-desktop .pill:hover {
563 background: var(--surface-sunken);
564 }
565
566 .ui-mode-desktop .pill.active {
567 background: var(--content);
568 color: var(--surface-raised);
569 border-color: var(--content);
570 box-shadow: var(--shadow-brutal-xs);
571 }
572
573 /* ===================================================================
574 8. Main Content & Page Header
575 =================================================================== */
576 .main-content {
577 flex: 1;
578 max-width: var(--width-container);
579 width: 100%;
580 margin: 0 auto;
581 padding: 1.5rem 1.75rem 2rem;
582 }
583
584 /* Page Header */
585 .page-header {
586 display: flex;
587 justify-content: space-between;
588 align-items: center;
589 gap: 0.5rem;
590 margin-bottom: 1rem;
591 }
592
593 .page-title {
594 font-family: var(--font-heading);
595 font-size: 1.75rem;
596 font-weight: 700;
597 color: var(--content);
598 }
599
600 /* --- Merged pill + page-header toolbar --- */
601 /* Tab groups use pills as view labels; page-header buttons float right on the same row */
602 .tab-group {
603 position: relative;
604 }
605
606 .tab-group > .subview > .page-header {
607 position: absolute;
608 top: 0;
609 right: 0;
610 margin: 0;
611 z-index: 1;
612 }
613
614 .tab-group .page-header .page-title {
615 display: none;
616 }
617
618 /* Special subviews that need their page-header in normal flow */
619 #project-dashboard-view > .page-header,
620 #day-plan-view > .page-header {
621 position: static;
622 margin-bottom: 1rem;
623 }
624
625 #project-dashboard-view .page-title {
626 display: block;
627 }
628
629 /* ===================================================================
630 9. Buttons
631 =================================================================== */
632 .btn {
633 display: inline-flex;
634 align-items: center;
635 justify-content: center;
636 gap: 0.5rem;
637 padding: 0.625rem 1.25rem;
638 border: var(--border-width) solid var(--border);
639 border-radius: var(--radius-sm);
640 font-size: 0.9rem;
641 font-weight: 600;
642 cursor: pointer;
643 transition: background-color 0.15s ease, transform 0.1s ease, box-shadow 0.1s ease;
644 text-decoration: none;
645 background: var(--surface-raised);
646 color: var(--content);
647 box-shadow: var(--shadow-brutal-xs);
648 }
649
650 .btn:hover {
651 background: var(--surface-overlay);
652 transform: translate(-1px, -1px);
653 box-shadow: var(--shadow-offset-md) var(--shadow-offset-md) 0 var(--border);
654 }
655
656 .btn:active {
657 background: var(--surface-sunken);
658 transform: translate(1px, 1px);
659 box-shadow: none;
660 }
661
662 .btn:disabled {
663 background: transparent;
664 color: var(--content-muted);
665 border-color: var(--content-muted);
666 cursor: not-allowed;
667 box-shadow: none;
668 }
669
670 .btn:disabled:hover {
671 background: transparent;
672 transform: none;
673 box-shadow: none;
674 }
675
676 .btn-primary {
677 background-color: var(--action);
678 color: var(--content-on-action);
679 }
680
681 .btn-primary:hover {
682 background-color: color-mix(in srgb, var(--action) 85%, black);
683 }
684
685 .btn-primary:active {
686 background-color: color-mix(in srgb, var(--action) 70%, black);
687 }
688
689 .btn-secondary {
690 background-color: var(--surface-overlay);
691 color: var(--content);
692 }
693
694 .btn-danger {
695 background-color: var(--danger);
696 color: var(--content-on-action);
697 }
698
699 .btn-danger:hover {
700 background-color: color-mix(in srgb, var(--danger) 85%, black);
701 }
702
703 .btn-danger:active {
704 background-color: color-mix(in srgb, var(--danger) 70%, black);
705 }
706
707 .btn-sm {
708 padding: 0.375rem 0.75rem;
709 font-size: 0.8rem;
710 }
711
712 /* ===================================================================
713 10. (vacated — Quick Add Input was deleted 2026-05-24; the modal at
714 keyboard.js:openQuickAddModal uses .form-input, not a bespoke
715 primitive. Section number kept for stable navigation.)
716 =================================================================== */
717
718 /* ===================================================================
719 11. Cards
720 =================================================================== */
721 .cards-grid {
722 display: grid;
723 grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
724 gap: 1.25rem;
725 }
726
727 .card {
728 background-color: var(--surface-raised);
729 border: var(--border-width) solid var(--border);
730 border-radius: var(--radius-md);
731 padding: 1.25rem;
732 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
733 transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
734 cursor: pointer;
735 }
736
737 .card:hover {
738 background-color: var(--surface-overlay);
739 transform: translate(-2px, -2px);
740 box-shadow: calc(var(--shadow-offset) + 2px) calc(var(--shadow-offset) + 2px) 0 var(--border);
741 }
742
743 /* Compact card for use in dense vertical lists (e.g. Project Dashboard).
744 Tighter padding, square corners, adds list spacing. */
745 .card--list-item {
746 padding: 0.75rem;
747 border-radius: 0;
748 margin-bottom: 0.5rem;
749 }
750
751 /* Container shell — keeps card chrome (border/radius/shadow) but strips
752 padding/cursor/hover and arranges children as a flex column. For list
753 wrappers like .email-list. */
754 .card--shell {
755 padding: 0;
756 cursor: default;
757 display: flex;
758 flex-direction: column;
759 overflow: hidden;
760 }
761 .card--shell:hover {
762 background-color: var(--surface-raised);
763 transform: none;
764 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
765 }
766
767 /* Muted info card — bg-secondary, no border/shadow/cursor/hover. For
768 small read-only info panels (contact info, summary stats). */
769 .card--muted {
770 background: var(--surface-overlay);
771 border: none;
772 box-shadow: none;
773 cursor: default;
774 }
775 .card--muted:hover {
776 background: var(--surface-overlay);
777 transform: none;
778 box-shadow: none;
779 }
780
781 /* Static card — keeps full card chrome (border/shadow/bg) but strips
782 cursor and hover animation. For read-only display cards (review
783 surfaces, monthly summary panels). */
784 .card--static {
785 cursor: default;
786 }
787 .card--static:hover {
788 background-color: var(--surface-raised);
789 transform: none;
790 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
791 }
792
793 .card-header {
794 display: flex;
795 justify-content: space-between;
796 align-items: flex-start;
797 margin-bottom: 0.75rem;
798 }
799
800 .card-title {
801 font-family: var(--font-heading);
802 font-size: 1.1rem;
803 font-weight: 700;
804 color: var(--content);
805 }
806
807 .card-description {
808 font-size: 0.9rem;
809 color: var(--content-secondary);
810 margin-bottom: 1rem;
811 }
812
813 .markdown-content {
814 font-size: 0.9rem;
815 color: var(--content-secondary);
816 line-height: 1.5;
817 }
818 .markdown-content p { margin: 0 0 0.5em 0; }
819 .markdown-content p:last-child { margin-bottom: 0; }
820 .markdown-content ul, .markdown-content ol { margin: 0 0 0.5em 1.5em; padding: 0; }
821 .markdown-content code { background: var(--surface-sunken); padding: 0.1em 0.3em; border-radius: 3px; font-size: 0.85em; }
822 .markdown-content pre { background: var(--surface-sunken); padding: 0.5em; border-radius: 4px; overflow-x: auto; margin: 0 0 0.5em 0; }
823 .markdown-content pre code { background: none; padding: 0; }
824 .markdown-content a { color: var(--action); }
825 .markdown-content blockquote { border-left: 3px solid var(--border); margin: 0 0 0.5em 0; padding-left: 0.75em; color: var(--content-secondary); }
826 .markdown-content h1, .markdown-content h2, .markdown-content h3 { margin: 0.5em 0 0.25em 0; font-size: 1em; font-weight: 600; color: var(--content); }
827 .markdown-content table { border-collapse: collapse; margin: 0.5em 0; }
828 .markdown-content th, .markdown-content td { border: 1px solid var(--border); padding: 0.25em 0.5em; }
829 .markdown-content img { max-width: 100%; }
830
831 .card-meta {
832 display: flex;
833 gap: 0.5rem;
834 flex-wrap: wrap;
835 }
836
837 /* ===================================================================
838 12. Tags & Badges
839 =================================================================== */
840
841 .tag, .badge {
842 display: inline-flex;
843 align-items: center;
844 padding: 0.25rem 0.625rem;
845 border: var(--border-width-sm) solid var(--border);
846 border-radius: var(--radius-sm);
847 font-size: 0.8125rem;
848 font-weight: 600;
849 background: var(--surface-raised);
850 color: var(--content);
851 }
852
853 /* Color variants using data attributes */
854 .badge[data-color="green"], .tag[data-color="green"] {
855 background-color: color-mix(in srgb, var(--category-two) 20%, var(--surface-raised));
856 border-color: var(--category-two);
857 }
858 .badge[data-color="yellow"], .tag[data-color="yellow"] {
859 background-color: color-mix(in srgb, var(--category-four) 20%, var(--surface-raised));
860 border-color: var(--category-four);
861 }
862 .badge[data-color="red"], .tag[data-color="red"] {
863 background-color: color-mix(in srgb, var(--category-one) 20%, var(--surface-raised));
864 border-color: var(--category-one);
865 }
866 .badge[data-color="cyan"], .tag[data-color="cyan"] {
867 background-color: color-mix(in srgb, var(--category-six) 20%, var(--surface-raised));
868 border-color: var(--category-six);
869 }
870 .badge[data-color="purple"], .tag[data-color="purple"] {
871 background-color: color-mix(in srgb, var(--category-five) 20%, var(--surface-raised));
872 border-color: var(--category-five);
873 }
874 .badge[data-color="muted"], .tag[data-color="muted"] {
875 background-color: var(--surface-sunken);
876 border-color: var(--content-muted);
877 }
878 .badge[data-color="blue"], .tag[data-color="blue"] {
879 background-color: color-mix(in srgb, var(--category-three) 20%, var(--surface-raised));
880 border-color: var(--category-three);
881 }
882
883 /* Size modifiers */
884 .badge--xs { padding: 0.1rem 0.5rem; font-size: 0.75rem; }
885 .badge--sm { padding: 0.15rem 0.55rem; font-size: 0.78rem; }
886
887 /* Filled intent — solid accent fill, no border. Pairs with data-color. */
888 .badge--filled { border: none; }
889 .badge--filled[data-color="green"] { background: var(--category-two); color: var(--content-on-action); }
890 .badge--filled[data-color="yellow"] { background: var(--category-four); color: var(--content); }
891 .badge--filled[data-color="red"] { background: var(--category-one); color: var(--content-on-action); }
892 .badge--filled[data-color="cyan"] { background: var(--category-six); color: var(--content-on-action); }
893 .badge--filled[data-color="purple"] { background: var(--category-five); color: var(--content-on-action); }
894 .badge--filled[data-color="blue"] { background: var(--category-three); color: var(--content-on-action); }
895 .badge--filled[data-color="muted"] { background: var(--surface-overlay); color: var(--content); }
896
897 /* Global keyboard-hint badge — small bordered mono pill used inline next
898 to labels ("Search ⌘K"). Relocated from §41 Settings 2026-05-24. */
899 .kbd-hint {
900 display: inline-block;
901 font-family: var(--font-mono, monospace);
902 font-size: 0.65rem;
903 font-weight: 600;
904 padding: 0.1rem 0.35rem;
905 margin-left: 0.35rem;
906 border: 1px solid currentColor;
907 border-radius: 3px;
908 opacity: 0.6;
909 vertical-align: middle;
910 line-height: 1;
911 }
912
913 /* Project status tag colors */
914 .tag.status-active {
915 background-color: color-mix(in srgb, var(--success) 20%, var(--surface-raised));
916 border-color: var(--success);
917 }
918 .tag.status-onhold, .tag.status-on_hold {
919 background-color: color-mix(in srgb, var(--warning) 20%, var(--surface-raised));
920 border-color: var(--warning);
921 }
922 .tag.status-archived {
923 background-color: var(--surface-sunken);
924 border-color: var(--content-muted);
925 }
926 .tag.status-inactive {
927 background-color: color-mix(in srgb, var(--danger) 20%, var(--surface-raised));
928 border-color: var(--danger);
929 }
930 .tag.status-completed {
931 background-color: color-mix(in srgb, var(--category-six) 20%, var(--surface-raised));
932 border-color: var(--category-six);
933 }
934
935 /* ===================================================================
936 13. Data Table
937 =================================================================== */
938 .data-table {
939 width: 100%;
940 border-collapse: separate;
941 border-spacing: 0;
942 background-color: var(--surface-raised);
943 border: var(--border-width) solid var(--border);
944 border-radius: var(--radius-md);
945 overflow: hidden;
946 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
947 }
948
949 .data-table th,
950 .data-table td {
951 padding: 1rem 1.25rem;
952 text-align: left;
953 border-bottom: 2px solid var(--border);
954 }
955
956 .data-table th {
957 background-color: var(--surface-overlay);
958 font-size: 0.8rem;
959 font-weight: 700;
960 text-transform: uppercase;
961 letter-spacing: 0.08em;
962 color: var(--content);
963 }
964
965 .data-table tbody tr {
966 transition: background-color 0.15s ease;
967 }
968
969 .data-table tbody tr:hover {
970 background-color: var(--surface-overlay);
971 }
972
973 .data-table tbody tr:last-child td {
974 border-bottom: none;
975 }
976
977 .data-table tbody tr.selected,
978 .data-table tbody tr.keyboard-selected {
979 background-color: color-mix(in srgb, var(--action) 25%, var(--surface-raised));
980 }
981
982 /* ===================================================================
983 14. Task Table & Rows
984 =================================================================== */
985 .task-table {
986 width: 100%;
987 background: var(--surface-raised);
988 border: var(--border-width) solid var(--border);
989 border-radius: var(--radius-lg);
990 overflow: hidden;
991 display: flex;
992 flex-direction: column;
993 flex: 1;
994 min-height: 0;
995 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
996 }
997
998 /* Task Grid Column Widths */
999 .task-header-row,
1000 .task-row {
1001 display: grid;
1002 /* Column floors keep every header label readable: the description column
1003 won't collapse below its "Description" label, and the priority column
1004 (a single-letter H/M/L body) is widened just enough to fit "Priority". */
1005 grid-template-columns: minmax(200px, 1fr) 140px 80px 110px 90px 100px 90px;
1006 align-items: center;
1007 gap: 0.75rem;
1008 }
1009
1010 /* Task Header Row */
1011 .task-header-row {
1012 background-color: var(--surface-overlay);
1013 border-bottom: 2px solid var(--border);
1014 padding: 0 1.25rem;
1015 }
1016
1017 .task-header-row .task-cell {
1018 padding: 0.75rem 0;
1019 font-size: 0.8rem;
1020 font-weight: 700;
1021 text-transform: uppercase;
1022 letter-spacing: 0.05em;
1023 color: var(--content);
1024 }
1025
1026 /* Task List Container - Virtual Scrolling */
1027 .task-list-container {
1028 flex: 1;
1029 min-height: 0;
1030 overflow-y: auto;
1031 position: relative;
1032 }
1033
1034 /* Task Row */
1035 .task-row {
1036 padding: 0.75rem 1.25rem;
1037 border-bottom: 1px solid var(--border);
1038 transition: background-color 0.15s ease, opacity 0.25s ease, transform 0.25s ease;
1039 cursor: pointer;
1040 }
1041
1042 .task-row-removing {
1043 opacity: 0;
1044 transform: translateX(20px);
1045 }
1046
1047 .task-row:hover {
1048 background-color: var(--surface-overlay);
1049 }
1050
1051 .task-row:last-child {
1052 border-bottom: none;
1053 }
1054
1055 .task-row.selected,
1056 .task-row.keyboard-selected {
1057 background-color: color-mix(in srgb, var(--action) 25%, var(--surface-raised));
1058 }
1059
1060 /* Task Cell Base */
1061 .task-cell {
1062 overflow: hidden;
1063 text-overflow: ellipsis;
1064 white-space: nowrap;
1065 min-width: 0; /* Allow grid items to shrink below content size */
1066 }
1067
1068 /* Task Actions Header */
1069 .task-actions-header {
1070 text-align: right;
1071 }
1072
1073 /* Event Table - extends .data-table */
1074 .event-table tbody tr {
1075 cursor: pointer;
1076 }
1077
1078 .task-description {
1079 font-weight: 600;
1080 /* Allow description to wrap and show badges on same line */
1081 white-space: normal;
1082 display: flex;
1083 flex-wrap: wrap;
1084 align-items: center;
1085 gap: 0.25rem 0.5rem;
1086 }
1087
1088 .task-description-text {
1089 /* Description text can truncate if very long */
1090 overflow: hidden;
1091 text-overflow: ellipsis;
1092 white-space: nowrap;
1093 max-width: 100%;
1094 }
1095
1096 .task-project {
1097 font-size: 0.85rem;
1098 color: var(--content-secondary);
1099 white-space: nowrap;
1100 }
1101
1102 /* Priority badges - centered in column */
1103 .priority-high,
1104 .priority-medium,
1105 .priority-low {
1106 display: inline-block;
1107 padding: 0.25rem 0.5rem;
1108 border-radius: var(--radius-xs);
1109 font-weight: 700;
1110 text-align: center;
1111 }
1112
1113 .priority-high {
1114 color: var(--danger);
1115 background: #fde8ea;
1116 background: color-mix(in srgb, var(--danger) 15%, var(--surface-raised));
1117 }
1118
1119 .priority-medium {
1120 color: var(--warning);
1121 background: #fef8e6;
1122 background: color-mix(in srgb, var(--warning) 15%, var(--surface-raised));
1123 }
1124
1125 .priority-low {
1126 color: var(--content-muted);
1127 background: var(--surface-overlay);
1128 }
1129
1130 /* Sortable column headers */
1131 .sortable {
1132 cursor: pointer;
1133 user-select: none;
1134 white-space: nowrap;
1135 }
1136
1137 .sortable:hover {
1138 background: var(--hover-surface);
1139 }
1140
1141 .sort-arrow {
1142 display: inline-block;
1143 width: 0.8em;
1144 margin-left: 0.25rem;
1145 opacity: 0.3;
1146 }
1147
1148 .sort-arrow::after {
1149 content: '\2195'; /* Up-down arrow */
1150 }
1151
1152 .sortable.sort-asc .sort-arrow::after {
1153 content: '\2191'; /* Up arrow */
1154 }
1155
1156 .sortable.sort-desc .sort-arrow::after {
1157 content: '\2193'; /* Down arrow */
1158 }
1159
1160 .sortable.sort-asc .sort-arrow,
1161 .sortable.sort-desc .sort-arrow {
1162 opacity: 1;
1163 }
1164
1165 /* Overdue task highlighting */
1166 .task-overdue .task-description-text {
1167 color: var(--danger);
1168 }
1169
1170 .task-overdue .task-due {
1171 color: var(--danger);
1172 font-weight: 600;
1173 }
1174
1175 .task-tags {
1176 display: flex;
1177 gap: 0.25rem;
1178 flex-wrap: wrap;
1179 }
1180
1181 .task-tag {
1182 background-color: var(--surface-sunken);
1183 color: var(--content);
1184 padding: 0.125rem 0.5rem;
1185 border-radius: var(--radius-xs);
1186 font-size: 0.75rem;
1187 font-weight: 600;
1188 border: 1px solid var(--border);
1189 }
1190
1191 .recurrence-icon {
1192 color: var(--category-five);
1193 font-size: 0.85rem;
1194 font-weight: 700;
1195 }
1196
1197 .annotation-badge {
1198 background-color: var(--warning);
1199 color: var(--content);
1200 padding: 0.125rem 0.5rem;
1201 border-radius: var(--radius-xs);
1202 font-size: 0.7rem;
1203 font-weight: 700;
1204 border: var(--border-width-sm) solid var(--border);
1205 }
1206
1207 .subtask-badge {
1208 background-color: var(--surface-overlay);
1209 color: var(--content);
1210 padding: 0.125rem 0.5rem;
1211 border-radius: var(--radius-xs);
1212 font-size: 0.7rem;
1213 font-weight: 700;
1214 border: var(--border-width-sm) solid var(--border);
1215 margin-left: 0.25rem;
1216 }
1217
1218 .task-pending { }
1219 .task-started {
1220 border-left: 4px solid var(--success);
1221 }
1222 .task-completed {
1223 opacity: 0.5;
1224 text-decoration: line-through;
1225 }
1226 .task-deleted { display: none; }
1227
1228 /* ===================================================================
1229 15. Due Date Badges
1230 =================================================================== */
1231 .due-overdue {
1232 color: var(--danger);
1233 font-weight: 700;
1234 background: #fde8ea; /* Fallback for browsers without color-mix() */
1235 background: color-mix(in srgb, var(--danger) 15%, var(--surface-raised));
1236 padding: 0.25rem 0.5rem;
1237 border-radius: var(--radius-xs);
1238 }
1239 .due-today {
1240 color: var(--warning);
1241 font-weight: 700;
1242 background: #fef8e6; /* Fallback for browsers without color-mix() */
1243 background: color-mix(in srgb, var(--warning) 15%, var(--surface-raised));
1244 padding: 0.25rem 0.5rem;
1245 border-radius: var(--radius-xs);
1246 }
1247 .due-soon { color: var(--content-secondary); }
1248 .due-future { color: var(--content-muted); }
1249
1250 /* ===================================================================
1251 16. Events
1252 =================================================================== */
1253 .events-list {
1254 display: flex;
1255 flex-direction: column;
1256 flex: 1;
1257 min-height: 0;
1258 gap: 1rem;
1259 }
1260
1261 /* Event Table - CSS Grid based for virtual scrolling */
1262 .event-table-virtual {
1263 width: 100%;
1264 background: var(--surface-raised);
1265 border: var(--border-width) solid var(--border);
1266 border-radius: var(--radius-lg);
1267 overflow: hidden;
1268 display: flex;
1269 flex-direction: column;
1270 flex: 1;
1271 min-height: 0;
1272 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
1273 }
1274
1275 /* Event Grid Column Widths */
1276 .event-header-row,
1277 .event-row-virtual {
1278 display: grid;
1279 grid-template-columns: 100px 80px 1fr 150px 40px;
1280 align-items: center;
1281 gap: 0.5rem;
1282 }
1283
1284 /* Event Header Row */
1285 .event-header-row {
1286 background-color: var(--surface-overlay);
1287 border-bottom: 2px solid var(--border);
1288 flex-shrink: 0;
1289 }
1290
1291 .event-header-row .event-cell {
1292 padding: 1rem 1.25rem;
1293 font-size: 0.8rem;
1294 font-weight: 700;
1295 text-transform: uppercase;
1296 letter-spacing: 0.05em;
1297 color: var(--content);
1298 }
1299
1300 /* Event List Container - Virtual Scrolling */
1301 .event-list-container {
1302 flex: 1;
1303 min-height: 0;
1304 overflow-y: auto;
1305 position: relative;
1306 }
1307
1308 /* Event Row */
1309 .event-row-virtual {
1310 padding: 0.75rem 1.25rem;
1311 border-bottom: 1px solid var(--border);
1312 transition: background-color 0.15s ease;
1313 cursor: pointer;
1314 }
1315
1316 .event-row-virtual:hover {
1317 background-color: var(--surface-overlay);
1318 }
1319
1320 .event-row-virtual:last-child {
1321 border-bottom: none;
1322 }
1323
1324 .event-row-virtual.event-past {
1325 opacity: 0.7;
1326 }
1327
1328 /* Event Cell Base */
1329 .event-cell {
1330 overflow: hidden;
1331 text-overflow: ellipsis;
1332 }
1333
1334 /* Event Table row styles - base in .data-table */
1335 .event-row {
1336 cursor: pointer;
1337 }
1338
1339 .event-cell-date {
1340 white-space: nowrap;
1341 }
1342
1343 .event-cell-date .event-date-num {
1344 font-weight: 700;
1345 font-size: 0.9rem;
1346 color: var(--content);
1347 margin-right: 0.5rem;
1348 }
1349
1350 .event-date-badge {
1351 display: inline-block;
1352 padding: 0.15rem 0.4rem;
1353 background: var(--success);
1354 color: var(--content-on-action);
1355 font-size: 0.7rem;
1356 font-weight: 700;
1357 text-transform: uppercase;
1358 border-radius: var(--radius-xs);
1359 margin-right: 0.5rem;
1360 }
1361
1362
1363 .event-cell-time {
1364 font-family: var(--font-mono);
1365 font-size: 0.85rem;
1366 color: var(--content-secondary);
1367 }
1368
1369 .event-cell-title {
1370 font-weight: 600;
1371 }
1372
1373 .event-cell-location {
1374 color: var(--content-secondary);
1375 font-size: 0.875rem;
1376 }
1377
1378 /* Event proximity-based badge colors */
1379 .event-date-badge.event-proximity-today {
1380 background: var(--success);
1381 }
1382 .event-date-badge.event-proximity-tomorrow {
1383 background: var(--warning);
1384 color: var(--content); /* Yellow needs dark text */
1385 }
1386 .event-date-badge.event-proximity-week {
1387 background: var(--category-six);
1388 }
1389 .event-date-badge.event-proximity-future {
1390 background: var(--action);
1391 }
1392 .event-date-badge.event-proximity-past {
1393 background: var(--content-muted);
1394 }
1395
1396 /* Past events - muted appearance */
1397 .event-row.event-past {
1398 opacity: 0.7;
1399 }
1400
1401 .no-upcoming-events {
1402 text-align: center;
1403 padding: 2rem;
1404 color: var(--content-secondary);
1405 font-style: italic;
1406 }
1407
1408 /* Past Events Collapsible Section */
1409 .past-events-section {
1410 margin-top: 0.5rem;
1411 }
1412
1413 .past-events-toggle {
1414 display: flex;
1415 align-items: center;
1416 gap: 0.75rem;
1417 padding: 0.75rem 1rem;
1418 background: var(--surface-overlay);
1419 border: var(--border-width-sm) solid var(--border);
1420 border-radius: var(--radius-sm);
1421 cursor: pointer;
1422 font-weight: 600;
1423 color: var(--content-secondary);
1424 transition: background-color 0.15s ease, color 0.15s ease;
1425 list-style: none;
1426 }
1427
1428 .past-events-toggle::-webkit-details-marker {
1429 display: none;
1430 }
1431
1432 .past-events-toggle::before {
1433 content: '';
1434 font-size: 0.7rem;
1435 transition: transform 0.15s ease;
1436 }
1437
1438 .past-events-section[open] .past-events-toggle::before {
1439 transform: rotate(90deg);
1440 }
1441
1442 .past-events-toggle:hover {
1443 background: var(--surface-sunken);
1444 color: var(--content);
1445 }
1446
1447 .past-events-label {
1448 flex: 1;
1449 }
1450
1451 .past-events-count {
1452 background: var(--content-muted);
1453 color: var(--content-on-action);
1454 font-size: 0.75rem;
1455 padding: 0.15rem 0.5rem;
1456 border-radius: var(--radius-sm);
1457 }
1458
1459 .past-events-section .event-table-past {
1460 margin-top: 0.75rem;
1461 opacity: 0.85;
1462 }
1463
1464 /* Past events container has fixed max height */
1465 .past-events-section .event-list-container {
1466 max-height: 300px;
1467 }
1468
1469 /* Recurring section reuses past-events-section styling but stays expanded by default
1470 and isn't dimmed. */
1471 #recurring-events-section .event-table-virtual {
1472 opacity: 1;
1473 margin-top: 0.75rem;
1474 }
1475 #recurring-events-section .event-list-container {
1476 max-height: 320px;
1477 }
1478 .event-row-virtual.event-recurring .event-recurrence-pattern {
1479 font-weight: 600;
1480 color: var(--action);
1481 }
1482
1483 /* Plain heading above the Upcoming list */
1484 .events-section-heading {
1485 margin: 1rem 0 0.5rem;
1486 font-size: 0.95rem;
1487 font-weight: 700;
1488 color: var(--content-secondary);
1489 text-transform: uppercase;
1490 letter-spacing: 0.05em;
1491 }
1492
1493 /* Legacy event styles kept for compatibility */
1494 .event-item {
1495 display: flex;
1496 gap: 1rem;
1497 padding: 1rem;
1498 background-color: var(--surface-raised);
1499 border: var(--border-width) solid var(--border);
1500 border-radius: var(--radius-md);
1501 transition: background-color 0.15s ease;
1502 cursor: pointer;
1503 }
1504
1505 .event-item:hover {
1506 background-color: var(--surface-overlay);
1507 }
1508
1509 .event-date {
1510 flex-shrink: 0;
1511 width: 80px;
1512 text-align: center;
1513 padding: 0.75rem;
1514 background-color: var(--success);
1515 border-radius: var(--radius-sm);
1516 color: var(--content-on-action);
1517 }
1518
1519 .event-date-day {
1520 font-size: 0.7rem;
1521 font-weight: 700;
1522 text-transform: uppercase;
1523 letter-spacing: 0.05em;
1524 }
1525
1526 .event-date-num {
1527 font-size: 1.5rem;
1528 font-weight: 700;
1529 }
1530
1531 .event-content {
1532 flex: 1;
1533 }
1534
1535 .event-title {
1536 font-family: var(--font-heading);
1537 font-weight: 700;
1538 font-size: 1.1rem;
1539 color: var(--content);
1540 margin-bottom: 0.25rem;
1541 }
1542
1543 .event-details {
1544 font-size: 0.875rem;
1545 color: var(--content-secondary);
1546 display: flex;
1547 gap: 1rem;
1548 }
1549
1550 .event-time, .event-location {
1551 display: flex;
1552 align-items: center;
1553 gap: 0.25rem;
1554 }
1555
1556 .event-project {
1557 margin-top: 0.5rem;
1558 }
1559
1560 /* ===================================================================
1561 17. Email List
1562 =================================================================== */
1563 /* Base chrome from .card.card--shell; only the flex sizing for the
1564 list panel remains here. */
1565 .email-list {
1566 flex: 1;
1567 min-height: 0;
1568 }
1569
1570 /* Email List Container for Virtual Scrolling */
1571 .email-list-container {
1572 flex: 1;
1573 min-height: 0;
1574 overflow-y: auto;
1575 position: relative;
1576 }
1577
1578 .email-item {
1579 display: flex;
1580 gap: 1rem;
1581 padding: 1rem;
1582 border-bottom: 2px solid var(--border);
1583 transition: background-color 0.15s ease;
1584 cursor: pointer;
1585 }
1586
1587 .email-item:last-child {
1588 border-bottom: none;
1589 }
1590
1591 .email-item:hover {
1592 background-color: var(--surface-overlay);
1593 }
1594
1595 .email-item.unread {
1596 background-color: color-mix(in srgb, var(--action) 20%, var(--surface-raised));
1597 border-left: 4px solid var(--action);
1598 }
1599
1600 .email-item.unread .email-subject {
1601 font-weight: 700;
1602 }
1603
1604 .email-item.unread .email-from {
1605 font-weight: 700;
1606 }
1607
1608 .email-item.outgoing {
1609 border-left: 4px solid var(--success);
1610 }
1611
1612 .email-checkbox {
1613 flex-shrink: 0;
1614 margin-top: 0.25rem;
1615 }
1616
1617 .email-content {
1618 flex: 1;
1619 min-width: 0;
1620 }
1621
1622 .email-header {
1623 display: flex;
1624 justify-content: space-between;
1625 margin-bottom: 0.25rem;
1626 align-items: center;
1627 gap: 0.5rem;
1628 }
1629
1630 /* Standalone — does not compose .badge. Smaller font, no border, centered
1631 min-width for thread counts. Audited 2026-05-21: composing .badge here
1632 would require overriding every declaration; net-zero dedup. */
1633 .thread-badge {
1634 background-color: var(--surface-sunken);
1635 color: var(--content-secondary);
1636 font-size: 0.7rem;
1637 font-weight: 600;
1638 padding: 0.1rem 0.4rem;
1639 border-radius: var(--radius-md);
1640 min-width: 1.25rem;
1641 text-align: center;
1642 }
1643
1644 .email-from {
1645 color: var(--content);
1646 font-size: 0.9rem;
1647 font-weight: 600;
1648 }
1649
1650 .email-date {
1651 color: var(--content-muted);
1652 font-size: 0.8rem;
1653 flex-shrink: 0;
1654 font-weight: 600;
1655 }
1656
1657 .email-subject {
1658 color: var(--content);
1659 font-size: 0.95rem;
1660 margin-bottom: 0.25rem;
1661 white-space: nowrap;
1662 overflow: hidden;
1663 text-overflow: ellipsis;
1664 }
1665
1666 .email-preview {
1667 color: var(--content-muted);
1668 font-size: 0.85rem;
1669 white-space: nowrap;
1670 overflow: hidden;
1671 text-overflow: ellipsis;
1672 }
1673
1674 /* ===================================================================
1675 18. Toast Notifications
1676 =================================================================== */
1677 @keyframes toastSlideIn {
1678 from {
1679 opacity: 0;
1680 transform: translateY(20px);
1681 }
1682 to {
1683 opacity: 1;
1684 transform: translateY(0);
1685 }
1686 }
1687
1688 .toast {
1689 position: fixed;
1690 bottom: var(--space-5);
1691 right: var(--space-5);
1692 padding: var(--space-3) var(--space-5);
1693 background: var(--surface-raised);
1694 color: var(--content);
1695 border: var(--border-width) solid var(--border);
1696 border-radius: var(--radius-md);
1697 box-shadow: var(--shadow-brutal-md);
1698 z-index: 2000;
1699 font-weight: 600;
1700 display: flex;
1701 align-items: center;
1702 gap: var(--space-3);
1703 animation: toastSlideIn 0.3s ease;
1704 }
1705
1706 .toast.toast-leaving {
1707 opacity: 0;
1708 transform: translateY(10px);
1709 transition: opacity 0.3s ease, transform 0.3s ease;
1710 }
1711
1712 .toast-info {
1713 background: var(--surface-raised);
1714 color: var(--content);
1715 }
1716
1717 .toast-success {
1718 background: var(--success);
1719 color: var(--content-on-action);
1720 }
1721
1722 .toast-error {
1723 background: var(--danger);
1724 color: var(--content-on-action);
1725 }
1726
1727 .toast-action {
1728 background: none;
1729 border: 1px solid currentColor;
1730 border-radius: var(--radius-sm);
1731 color: inherit;
1732 cursor: pointer;
1733 padding: 0.15rem 0.5rem;
1734 font-size: var(--font-size-sm);
1735 font-weight: 600;
1736 font-family: inherit;
1737 }
1738
1739 /* Undo Toast */
1740 .toast-undo {
1741 z-index: 10000;
1742 }
1743
1744 .undo-message {
1745 flex: 1;
1746 }
1747
1748 .undo-countdown {
1749 font-size: var(--font-size-sm);
1750 color: var(--content-muted);
1751 min-width: 2.5rem;
1752 text-align: right;
1753 }
1754
1755 /* ===================================================================
1756 19. Modals
1757 =================================================================== */
1758 @keyframes modalFadeIn {
1759 from {
1760 opacity: 0;
1761 }
1762 to {
1763 opacity: 1;
1764 }
1765 }
1766
1767 @keyframes modalSlideIn {
1768 from {
1769 opacity: 0;
1770 transform: translateY(-20px) scale(0.95);
1771 }
1772 to {
1773 opacity: 1;
1774 transform: translateY(0) scale(1);
1775 }
1776 }
1777
1778 @keyframes modalFadeOut {
1779 from {
1780 opacity: 1;
1781 }
1782 to {
1783 opacity: 0;
1784 }
1785 }
1786
1787 @keyframes modalSlideOut {
1788 from {
1789 opacity: 1;
1790 transform: translateY(0) scale(1);
1791 }
1792 to {
1793 opacity: 0;
1794 transform: translateY(-20px) scale(0.95);
1795 }
1796 }
1797
1798 .modal-overlay {
1799 position: fixed;
1800 top: 0;
1801 left: 0;
1802 right: 0;
1803 bottom: 0;
1804 background-color: var(--overlay);
1805 display: flex;
1806 align-items: center;
1807 justify-content: center;
1808 z-index: 1000;
1809 animation: modalFadeIn 0.15s ease-out;
1810 }
1811
1812 .modal-overlay.hidden {
1813 display: none;
1814 }
1815
1816 .modal-overlay.closing {
1817 animation: modalFadeOut 0.15s ease-in forwards;
1818 }
1819
1820 .modal-container {
1821 background-color: var(--surface-raised);
1822 border: var(--border-width) solid var(--border);
1823 border-radius: var(--radius-lg);
1824 box-shadow: var(--shadow-brutal-xl);
1825 max-width: var(--width-modal);
1826 width: 90%;
1827 /* dvh follows the visible viewport when mobile chrome / keyboard
1828 expand-collapse; subtract safe-area so the modal can't extend behind
1829 the iOS home indicator or notch even when the mobile branch below
1830 doesn't apply (e.g. iPad landscape > 768px). */
1831 max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 2rem);
1832 overflow: auto;
1833 animation: modalSlideIn 0.2s ease-out;
1834 }
1835
1836 .modal-container.modal-large {
1837 max-width: calc(100vw - 4rem);
1838 width: calc(100vw - 4rem);
1839 max-height: calc(100vh - 4rem);
1840 height: calc(100vh - 4rem);
1841 display: flex;
1842 flex-direction: column;
1843 }
1844
1845 .modal-container.modal-large .modal-content {
1846 flex: 1;
1847 overflow: auto;
1848 display: flex;
1849 flex-direction: column;
1850 }
1851
1852 .modal-overlay.closing .modal-container {
1853 animation: modalSlideOut 0.15s ease-in forwards;
1854 }
1855
1856 .modal-header {
1857 display: flex;
1858 justify-content: space-between;
1859 align-items: center;
1860 padding: 1rem 1.5rem;
1861 border-bottom: var(--border-width) solid var(--border);
1862 background: var(--surface-overlay);
1863 }
1864
1865 .modal-header h2, .modal-title {
1866 font-family: var(--font-heading);
1867 font-size: 1.25rem;
1868 font-weight: 700;
1869 }
1870
1871 .modal-close {
1872 background: var(--surface-raised);
1873 border: var(--border-width-sm) solid var(--border);
1874 border-radius: var(--radius-sm);
1875 font-size: 1.25rem;
1876 color: var(--content);
1877 cursor: pointer;
1878 line-height: 1;
1879 width: 36px;
1880 height: 36px;
1881 display: flex;
1882 align-items: center;
1883 justify-content: center;
1884 transition: background-color 0.15s ease;
1885 }
1886
1887 .modal-close:hover {
1888 background: var(--action);
1889 color: var(--content-on-action);
1890 }
1891
1892 .modal-content {
1893 padding: 1.5rem;
1894 }
1895
1896 /* Pin a form's action row to the bottom of the modal's scroll area so
1897 primary/cancel buttons stay visible even on short viewports. Without
1898 this, on small windows or iOS with the keyboard up the button row sits
1899 below the fold and looks cut off — there's no visible scrollbar on
1900 macOS by default so users don't realize they can scroll to it. */
1901 .modal-content > .form-actions:last-child,
1902 .modal-content form > .form-actions:last-child {
1903 position: sticky;
1904 bottom: 0;
1905 margin-top: 1.5rem;
1906 padding-top: 0.75rem;
1907 padding-bottom: 0.25rem;
1908 background: var(--surface-raised);
1909 border-top: var(--border-width-sm) solid var(--border);
1910 z-index: 1;
1911 }
1912
1913 /* ===================================================================
1914 20. Form Elements
1915 =================================================================== */
1916 .form-group {
1917 margin-bottom: 1.25rem;
1918 }
1919
1920 .form-more-toggle {
1921 display: block;
1922 background: none;
1923 border: none;
1924 cursor: pointer;
1925 font-size: 0.85rem;
1926 font-weight: 600;
1927 color: var(--action);
1928 padding: 0.25rem 0;
1929 margin-bottom: 0.75rem;
1930 }
1931
1932 .form-more-toggle::before {
1933 content: '+ ';
1934 }
1935
1936 .form-more-toggle.expanded::before {
1937 content: '- ';
1938 }
1939
1940 .form-extended-fields.hidden {
1941 display: none;
1942 }
1943
1944 .recurrence-weekday-label {
1945 display: inline-flex;
1946 align-items: center;
1947 gap: 0.25rem;
1948 padding: 0.25rem 0.5rem;
1949 font-size: 0.8rem;
1950 border: 1px solid var(--border);
1951 border-radius: var(--radius-sm);
1952 cursor: pointer;
1953 }
1954
1955 .recurrence-weekday-label:has(input:checked) {
1956 background: var(--action);
1957 color: var(--surface-page);
1958 border-color: var(--action);
1959 }
1960
1961 .recurrence-weekday-label input[type="checkbox"] {
1962 display: none;
1963 }
1964
1965 .recurrence-config .form-input,
1966 .recurrence-config .form-select {
1967 font-size: 0.85rem;
1968 padding: 0.25rem 0.5rem;
1969 }
1970
1971 .form-label {
1972 display: block;
1973 font-size: 0.9rem;
1974 font-weight: 700;
1975 color: var(--content);
1976 margin-bottom: 0.5rem;
1977 }
1978
1979 .form-input,
1980 .form-select,
1981 .form-textarea {
1982 width: 100%;
1983 padding: 0.75rem 1rem;
1984 border: var(--border-width-sm) solid var(--border);
1985 border-radius: var(--radius-sm);
1986 background-color: var(--surface-raised);
1987 color: var(--content);
1988 font-size: 1rem;
1989 box-shadow: none;
1990 }
1991
1992 .form-input:focus,
1993 .form-select:focus,
1994 .form-textarea:focus {
1995 outline: none;
1996 background-color: var(--surface-raised);
1997 box-shadow: 0 0 0 2px var(--action);
1998 }
1999
2000 .form-textarea {
2001 min-height: 100px;
2002 resize: vertical;
2003 }
2004
2005 /* Ghost variants — borderless / transparent inputs used in toolbar
2006 contexts (compose header rows). Strips chrome and reduces padding. */
2007 .form-input--ghost {
2008 background: transparent;
2009 border: none;
2010 padding: 0.5rem;
2011 font-size: 0.875rem;
2012 }
2013 .form-input--ghost:focus { background: transparent; box-shadow: none; }
2014 .form-select--ghost {
2015 background: var(--surface-page);
2016 padding: 0.5rem;
2017 font-size: 0.875rem;
2018 }
2019
2020 .form-actions {
2021 display: flex;
2022 justify-content: flex-end;
2023 gap: 0.75rem;
2024 margin-top: 1.5rem;
2025 }
2026
2027 /* Form Validation */
2028 .form-input[aria-invalid="true"],
2029 .form-select[aria-invalid="true"],
2030 .form-textarea[aria-invalid="true"] {
2031 border-color: var(--danger);
2032 box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 30%, transparent);
2033 }
2034
2035 .form-input[aria-invalid="true"]:focus,
2036 .form-select[aria-invalid="true"]:focus,
2037 .form-textarea[aria-invalid="true"]:focus {
2038 box-shadow: 0 0 0 2px var(--danger);
2039 }
2040
2041 .form-error {
2042 color: var(--danger);
2043 font-size: 0.8rem;
2044 font-weight: 600;
2045 margin-top: 0.25rem;
2046 display: none;
2047 }
2048
2049 .form-error.visible {
2050 display: block;
2051 }
2052
2053 .form-hint {
2054 font-size: var(--font-size-sm);
2055 color: var(--content-secondary);
2056 margin-top: var(--space-1);
2057 }
2058
2059 .form-hint--preview {
2060 color: var(--action);
2061 }
2062
2063 .form-checkbox-label {
2064 display: flex;
2065 align-items: center;
2066 gap: var(--space-2);
2067 cursor: pointer;
2068 }
2069
2070 .empty-state-action {
2071 margin-top: var(--space-3);
2072 }
2073
2074 /* ===================================================================
2075 Layout utility classes (used by JS-rendered markup)
2076 =================================================================== */
2077 .stack {
2078 display: flex;
2079 flex-direction: column;
2080 }
2081 .stack-2 { gap: var(--space-2); }
2082 .stack-3 { gap: var(--space-3); }
2083 .stack-4 { gap: var(--space-4); }
2084
2085 .row-flex {
2086 display: flex;
2087 align-items: center;
2088 }
2089 .row-flex-2 { gap: var(--space-2); }
2090 .row-flex-3 { gap: var(--space-3); }
2091 .row-flex-4 { gap: var(--space-4); }
2092
2093 .text-center { text-align: center; }
2094 .text-left { text-align: left; }
2095 .w-full { width: 100%; }
2096 .text-muted { color: var(--content-muted); }
2097 .text-secondary { color: var(--content-secondary); }
2098 .text-danger { color: var(--danger); }
2099 .text-sm { font-size: var(--font-size-sm); }
2100 .text-xs { font-size: var(--font-size-xs, 0.75rem); }
2101
2102 .section-divider {
2103 border-top: var(--border-width-sm) solid var(--border);
2104 padding-top: var(--space-4);
2105 margin-top: var(--space-4);
2106 }
2107
2108 /* Sync dashboard primitives */
2109 .sync-status-row {
2110 display: flex;
2111 align-items: center;
2112 gap: var(--space-3);
2113 margin-bottom: var(--space-5);
2114 }
2115 .sync-status-dot {
2116 width: 10px;
2117 height: 10px;
2118 border-radius: var(--radius-full);
2119 background: var(--success);
2120 display: inline-block;
2121 }
2122 .sync-stats-grid {
2123 display: grid;
2124 grid-template-columns: 1fr 1fr;
2125 gap: var(--space-4);
2126 margin-bottom: var(--space-5);
2127 }
2128 .sync-stat {
2129 padding: var(--space-3);
2130 background: var(--surface-overlay);
2131 border-radius: var(--radius-md);
2132 }
2133 .sync-stat-label {
2134 font-size: var(--font-size-sm);
2135 color: var(--content-muted);
2136 margin-bottom: var(--space-1);
2137 }
2138 .sync-stat-value {
2139 font-size: var(--font-size-md, 0.9rem);
2140 }
2141 .sync-encryption-error {
2142 color: var(--danger);
2143 font-size: var(--font-size-sm);
2144 margin-top: var(--space-2);
2145 display: none;
2146 }
2147 .sync-encryption-error.visible {
2148 display: block;
2149 }
2150 .sync-section-actions {
2151 margin-bottom: var(--space-5);
2152 }
2153 .sync-banner {
2154 padding: var(--space-3);
2155 background: var(--surface-overlay);
2156 border-radius: var(--radius-md);
2157 margin-bottom: var(--space-4);
2158 font-size: var(--font-size-sm);
2159 color: var(--content-secondary);
2160 }
2161 .sync-banner--warning {
2162 background: var(--surface-overlay);
2163 border: 1px solid var(--border);
2164 padding: var(--space-4);
2165 }
2166 .sync-empty {
2167 padding: var(--space-5) 0;
2168 }
2169 .sync-empty-message {
2170 margin-bottom: var(--space-5);
2171 }
2172 .sync-hint {
2173 margin-bottom: var(--space-4);
2174 }
2175 .sync-status-label {
2176 font-weight: 500;
2177 }
2178 .sync-account-row {
2179 display: flex;
2180 align-items: baseline;
2181 gap: var(--space-3);
2182 margin-bottom: var(--space-5);
2183 font-size: var(--font-size-sm);
2184 }
2185 .sync-account-label {
2186 color: var(--content-muted);
2187 }
2188 .sync-account-value {
2189 color: var(--content);
2190 }
2191 .sync-account-username {
2192 color: var(--content-muted);
2193 }
2194 .sync-banner-title {
2195 font-weight: 500;
2196 margin: 0 0 var(--space-3) 0;
2197 }
2198 .sync-banner-body {
2199 margin: 0 0 var(--space-2) 0;
2200 font-size: var(--font-size-sm);
2201 color: var(--content-secondary);
2202 }
2203 .sync-banner-tier-line {
2204 margin: 0 0 var(--space-4) 0;
2205 font-size: var(--font-size-sm);
2206 color: var(--content-secondary);
2207 }
2208 .sync-banner-actions {
2209 display: flex;
2210 gap: var(--space-2);
2211 align-items: center;
2212 }
2213
2214 /* Backup / data settings primitives */
2215 .settings-subheading {
2216 margin-bottom: var(--space-3);
2217 font-size: var(--font-size-md, 0.9rem);
2218 }
2219 .settings-desc-block {
2220 font-size: var(--font-size-sm);
2221 color: var(--content-secondary);
2222 margin-bottom: var(--space-4);
2223 }
2224 .settings-actions-row {
2225 display: flex;
2226 flex-wrap: wrap;
2227 gap: var(--space-3);
2228 margin-bottom: var(--space-4);
2229 }
2230 .settings-actions-row--center {
2231 align-items: center;
2232 flex-wrap: nowrap;
2233 margin-top: var(--space-3);
2234 }
2235 .settings-status-text {
2236 font-size: var(--font-size-sm);
2237 color: var(--content-secondary);
2238 }
2239 /* Preference row — label/description on the left, control (toggle, button) on the right. */
2240 .settings-toggle-row {
2241 display: flex;
2242 justify-content: space-between;
2243 align-items: center;
2244 gap: var(--space-3);
2245 margin: var(--space-3) 0;
2246 }
2247 .settings-toggle-row > div { flex: 1; }
2248 .settings-toggle-row .settings-desc { margin-bottom: 0; }
2249 .settings-section-block {
2250 padding-top: var(--space-4);
2251 border-top: var(--border-width-sm) solid var(--border);
2252 }
2253 .form-hint--spaced {
2254 margin-top: var(--space-2);
2255 }
2256 .empty-italic {
2257 color: var(--content-secondary);
2258 font-style: italic;
2259 }
2260
2261 .form-grid-2 {
2262 display: grid;
2263 grid-template-columns: 1fr 1fr;
2264 gap: var(--space-4);
2265 }
2266
2267 /* Email account list / detail primitives */
2268 .email-detect-status {
2269 font-size: var(--font-size-sm);
2270 color: var(--content-secondary);
2271 margin-top: var(--space-1);
2272 }
2273 .email-detect-note {
2274 font-size: var(--font-size-sm);
2275 margin-top: var(--space-2);
2276 padding: var(--space-3) var(--space-3);
2277 background: var(--surface-sunken);
2278 border-left: 3px solid var(--action);
2279 border-radius: var(--radius-sm);
2280 line-height: var(--line-height-normal);
2281 }
2282 .account-row {
2283 padding: var(--space-3);
2284 background: var(--surface-overlay);
2285 border-radius: var(--radius-sm);
2286 margin-bottom: var(--space-2);
2287 }
2288 .account-row-header {
2289 display: flex;
2290 justify-content: space-between;
2291 align-items: flex-start;
2292 }
2293 .account-row-name {
2294 font-weight: 600;
2295 }
2296 .account-row-meta {
2297 font-size: var(--font-size-sm);
2298 color: var(--content-secondary);
2299 }
2300 .account-row-sync {
2301 font-size: var(--font-size-sm);
2302 color: var(--content-secondary);
2303 }
2304 .account-row-provider-badge {
2305 font-size: var(--font-size-xs, 0.7rem);
2306 padding: 0.125rem 0.375rem;
2307 background: var(--action);
2308 color: var(--content-on-action);
2309 border-radius: var(--radius-xs);
2310 margin-left: var(--space-2);
2311 }
2312 .test-conn-result {
2313 padding: var(--space-2);
2314 background: var(--surface-overlay);
2315 border-radius: var(--radius-sm);
2316 margin-bottom: var(--space-2);
2317 }
2318 .test-conn-result--success { color: var(--success); }
2319 .test-conn-result--error { color: var(--danger); }
2320
2321 .folder-list {
2322 max-height: 150px;
2323 overflow-y: auto;
2324 background: var(--surface-overlay);
2325 padding: var(--space-2);
2326 border-radius: var(--radius-sm);
2327 font-family: var(--font-mono);
2328 font-size: var(--font-size-sm);
2329 }
2330 .folder-list-meta {
2331 font-size: var(--font-size-sm);
2332 color: var(--content-secondary);
2333 margin-top: var(--space-2);
2334 }
2335 .error-pre {
2336 background: var(--surface-overlay);
2337 padding: var(--space-2);
2338 border-radius: var(--radius-sm);
2339 font-family: var(--font-mono);
2340 font-size: var(--font-size-sm);
2341 white-space: pre-wrap;
2342 max-height: 150px;
2343 overflow-y: auto;
2344 }
2345 .test-conn-section {
2346 border-top: var(--border-width-sm) solid var(--border);
2347 margin: var(--space-4) 0;
2348 padding-top: var(--space-4);
2349 }
2350 .oauth-waiting {
2351 text-align: center;
2352 padding: var(--space-5);
2353 }
2354 .oauth-waiting-title {
2355 font-size: var(--font-size-lg, 1.25rem);
2356 margin-bottom: var(--space-4);
2357 }
2358 .oauth-waiting-body {
2359 color: var(--content-secondary);
2360 margin-bottom: var(--space-5);
2361 }
2362 .oauth-waiting-spinner {
2363 margin: 0 auto var(--space-5);
2364 }
2365
2366 .contact-card-header { gap: var(--space-3); }
2367 .contact-card-body { flex: 1; min-width: 0; }
2368 .contact-detail-header {
2369 display: flex;
2370 align-items: center;
2371 gap: var(--space-4);
2372 margin-bottom: var(--space-5);
2373 }
2374 .contact-detail-name { margin: 0; }
2375 .contact-detail-tags { margin-bottom: var(--space-4); }
2376
2377 .form-actions--spaced { margin-top: var(--space-5); }
2378
2379 .milestones-empty {
2380 color: var(--content-muted);
2381 font-size: var(--font-size-sm);
2382 margin-bottom: var(--space-4);
2383 }
2384
2385 .bulk-modal-prompt {
2386 color: var(--content-secondary);
2387 margin-bottom: var(--space-2);
2388 }
2389 .bulk-modal-prompt--wide {
2390 margin-bottom: var(--space-3);
2391 }
2392 /* Marker class kept for .ui-mode-mobile padding override only. Base styling: .btn.btn-sm + .w-full.text-left. */
2393 .bulk-modal-scroll {
2394 max-height: 300px;
2395 overflow-y: auto;
2396 display: flex;
2397 flex-direction: column;
2398 gap: var(--space-1);
2399 }
2400 .bulk-priority-row {
2401 display: flex;
2402 gap: var(--space-2);
2403 }
2404
2405 .snooze-hint {
2406 font-size: var(--font-size-sm);
2407 color: var(--content-secondary);
2408 margin: 0 0 var(--space-3) 0;
2409 }
2410
2411 .time-tracking-empty {
2412 color: var(--content-secondary);
2413 padding: var(--space-4) 0;
2414 }
2415
2416 .backups-empty {
2417 color: var(--content-secondary);
2418 font-style: italic;
2419 }
2420 .backup-item {
2421 display: flex;
2422 align-items: center;
2423 justify-content: space-between;
2424 padding: var(--space-3);
2425 border: 1px solid var(--border);
2426 border-radius: var(--radius-md);
2427 margin-bottom: var(--space-2);
2428 }
2429 .backup-item-meta {
2430 font-size: var(--font-size-sm);
2431 color: var(--content-secondary);
2432 }
2433 .export-desc {
2434 font-size: var(--font-size-sm);
2435 color: var(--content-secondary);
2436 margin-bottom: var(--space-5);
2437 }
2438 .export-note {
2439 margin-top: var(--space-4);
2440 padding: var(--space-3);
2441 background: var(--surface-overlay);
2442 border-radius: var(--radius-sm);
2443 }
2444 .export-note-text {
2445 font-size: var(--font-size-sm);
2446 color: var(--content-secondary);
2447 margin: 0;
2448 }
2449
2450 .paint-time-preview {
2451 font-weight: 600;
2452 color: var(--action);
2453 margin-bottom: var(--space-2);
2454 }
2455
2456 .recurrence-config {
2457 display: none;
2458 margin-top: var(--space-2);
2459 padding: var(--space-2);
2460 border: 1px solid var(--border);
2461 border-radius: var(--radius-sm);
2462 }
2463 .recurrence-config:not(.hidden) {
2464 display: block;
2465 }
2466 .recurrence-preview {
2467 font-size: var(--font-size-sm);
2468 color: var(--action);
2469 font-weight: 600;
2470 margin-bottom: var(--space-2);
2471 }
2472 .recurrence-sublabel {
2473 font-size: var(--font-size-xs, 0.75rem);
2474 }
2475 .recurrence-unit {
2476 font-size: var(--font-size-sm);
2477 }
2478 .recurrence-day-label {
2479 display: flex;
2480 align-items: center;
2481 gap: var(--space-2);
2482 font-size: var(--font-size-sm);
2483 }
2484 .recurrence-nth-toggle {
2485 font-size: var(--font-size-sm);
2486 margin: var(--space-1) 0;
2487 }
2488 .recurrence-row { margin-bottom: var(--space-2); }
2489 .recurrence-row.recurrence-hidden { display: none; }
2490 .recurrence-interval-row {
2491 display: flex;
2492 align-items: center;
2493 gap: var(--space-2);
2494 }
2495 .recurrence-num { width: 4rem; }
2496 .recurrence-weekdays {
2497 display: flex;
2498 gap: var(--space-1);
2499 flex-wrap: wrap;
2500 }
2501 .recurrence-monthly {
2502 margin-bottom: 0;
2503 }
2504 .recurrence-monthly.recurrence-hidden { display: none; }
2505 .recurrence-monthly-stack {
2506 display: flex;
2507 flex-direction: column;
2508 gap: var(--space-2);
2509 }
2510 .recurrence-monthly-week { width: auto; }
2511
2512 .confirm-message-wrap { margin-bottom: var(--space-5); }
2513 .confirm-message {
2514 color: var(--content-secondary);
2515 line-height: var(--line-height-normal);
2516 }
2517 .review-intro {
2518 color: var(--content-secondary);
2519 font-size: var(--font-size-sm);
2520 margin: 0 0 var(--space-4);
2521 }
2522 .review-intro--weekly {
2523 margin: var(--space-2) 0 var(--space-4);
2524 }
2525 .no-events-day {
2526 color: var(--content-secondary);
2527 }
2528 .loading--error { color: var(--danger); }
2529 .project-dashboard-desc {
2530 color: var(--content-secondary);
2531 margin-bottom: var(--space-4);
2532 }
2533
2534 /* Pending-key hint (top-level "go to" prompt) */
2535 .pending-key-hint {
2536 position: fixed;
2537 bottom: var(--space-5);
2538 left: 50%;
2539 transform: translateX(-50%);
2540 padding: var(--space-2) var(--space-4);
2541 background: var(--surface-raised);
2542 color: var(--content);
2543 border: var(--border-width) solid var(--border);
2544 border-radius: var(--radius-md);
2545 box-shadow: var(--shadow-brutal-md);
2546 z-index: 10000;
2547 font-size: var(--font-size-sm);
2548 white-space: nowrap;
2549 animation: toastSlideIn 0.15s ease;
2550 }
2551 .pending-key-hint-label { opacity: 0.7; }
2552 .pending-key-hint kbd {
2553 background: var(--surface-overlay);
2554 border: 1px solid var(--border);
2555 border-radius: var(--radius-xs);
2556 padding: 0.125rem 0.4rem;
2557 font-family: inherit;
2558 font-size: var(--font-size-sm);
2559 }
2560
2561 /* Keyboard shortcuts overlay */
2562 .shortcuts-overlay {
2563 position: fixed;
2564 top: 0; left: 0; right: 0; bottom: 0;
2565 background: var(--overlay);
2566 display: flex;
2567 align-items: center;
2568 justify-content: center;
2569 z-index: 3000;
2570 }
2571 .shortcuts-overlay-panel {
2572 background: var(--surface-raised);
2573 border-radius: var(--radius-md);
2574 padding: var(--space-5);
2575 max-width: 600px;
2576 max-height: 80vh;
2577 overflow-y: auto;
2578 }
2579 .shortcuts-title {
2580 margin-top: 0;
2581 margin-bottom: var(--space-4);
2582 border-bottom: 1px solid var(--border);
2583 padding-bottom: var(--space-2);
2584 }
2585 .shortcuts-grid {
2586 display: grid;
2587 grid-template-columns: 1fr 1fr;
2588 gap: var(--space-5);
2589 }
2590 .shortcuts-group-heading {
2591 color: var(--content-secondary);
2592 font-size: var(--font-size-sm);
2593 margin-bottom: var(--space-2);
2594 }
2595 .shortcuts-group-heading + .shortcut-row {
2596 margin-top: 0;
2597 }
2598 .shortcuts-group-heading-spaced {
2599 color: var(--content-secondary);
2600 font-size: var(--font-size-sm);
2601 margin-bottom: var(--space-2);
2602 margin-top: var(--space-3);
2603 }
2604 .shortcuts-close {
2605 margin-top: var(--space-5);
2606 text-align: center;
2607 }
2608 .shortcut-row {
2609 display: flex;
2610 align-items: center;
2611 gap: var(--space-2);
2612 margin-bottom: var(--space-2);
2613 }
2614 .shortcut-row kbd {
2615 background: var(--surface-overlay);
2616 border: 1px solid var(--border);
2617 border-radius: var(--radius-xs);
2618 padding: 0.25rem 0.5rem;
2619 font-family: inherit;
2620 font-size: var(--font-size-sm);
2621 min-width: 1.5rem;
2622 text-align: center;
2623 }
2624 .shortcut-row span {
2625 color: var(--content-secondary);
2626 font-size: var(--font-size-sm);
2627 margin-left: auto;
2628 }
2629
2630 .quick-add-syntax {
2631 font-size: var(--font-size-sm);
2632 color: var(--content-secondary);
2633 margin-top: var(--space-2);
2634 line-height: var(--line-height-relaxed);
2635 }
2636 .quick-add-syntax > span { margin-right: var(--space-3); }
2637 .quick-add-syntax kbd {
2638 font-size: 0.7rem;
2639 padding: 0.1rem 0.3rem;
2640 border: 1px solid var(--border);
2641 border-radius: var(--radius-xs);
2642 background: var(--surface-overlay);
2643 }
2644
2645 .virtual-scroller-wrapper {
2646 position: relative;
2647 width: 100%;
2648 }
2649 .virtual-scroller-spacer {
2650 height: 0;
2651 width: 100%;
2652 }
2653
2654 /* Generic helpers used by JS-rendered markup */
2655 .meta-text {
2656 font-size: var(--font-size-sm);
2657 color: var(--content-muted);
2658 }
2659 .meta-text--secondary {
2660 color: var(--content-secondary);
2661 }
2662 .subtasks-empty {
2663 color: var(--content-secondary);
2664 text-align: center;
2665 padding: var(--space-4);
2666 }
2667 .subtask-linked-tag {
2668 color: var(--action);
2669 font-size: var(--font-size-sm);
2670 }
2671 .task-actions-bar {
2672 display: flex;
2673 flex-wrap: wrap;
2674 gap: var(--space-2);
2675 margin-top: var(--space-4);
2676 padding-top: var(--space-3);
2677 border-top: 1px solid var(--border);
2678 }
2679 .error-state--padded {
2680 padding: var(--space-4);
2681 }
2682 .event-cell--shrink {
2683 flex: 0 0 auto;
2684 padding-right: 0;
2685 }
2686 .empty-state-content {
2687 /* empty-state already has padding/center; this is a placeholder if more nesting needed */
2688 }
2689
2690 .hr-soft {
2691 border: none;
2692 border-top: 1px solid var(--border);
2693 margin: var(--space-2) 0;
2694 }
2695
2696 .card-badge--success {
2697 background: var(--success);
2698 color: var(--content-on-action);
2699 }
2700 .card-badge--warning { background: var(--warning); }
2701 .card-badge--info {
2702 background: var(--action);
2703 color: var(--content-on-action);
2704 }
2705 .card-badge--danger {
2706 background: var(--danger);
2707 color: var(--content-on-action);
2708 }
2709 .card-badge--neutral { background: var(--surface-overlay); }
2710
2711 .empty-italic--muted {
2712 color: var(--content-muted);
2713 font-style: italic;
2714 }
2715
2716 .review-history-block {
2717 margin-top: var(--space-5);
2718 padding-top: var(--space-4);
2719 border-top: 1px dashed var(--border);
2720 }
2721 .review-history-heading {
2722 font-size: var(--font-size-sm);
2723 color: var(--content-muted);
2724 margin-bottom: var(--space-3);
2725 }
2726
2727 /* Email detail / list primitives */
2728 .email-attachment-row {
2729 display: flex;
2730 align-items: center;
2731 gap: var(--space-2);
2732 padding: 0.375rem 0;
2733 }
2734 .email-attachment-size {
2735 font-size: var(--font-size-sm);
2736 color: var(--content-muted);
2737 flex-shrink: 0;
2738 }
2739 .email-attachments-block {
2740 margin-bottom: var(--space-3);
2741 padding: var(--space-2) var(--space-3);
2742 background: var(--surface-overlay);
2743 border-radius: var(--radius-sm);
2744 border: 1px solid var(--border);
2745 }
2746 .email-attachments-heading {
2747 font-size: var(--font-size-sm);
2748 font-weight: 600;
2749 color: var(--content-secondary);
2750 margin-bottom: var(--space-1);
2751 }
2752 .email-thread-count {
2753 color: var(--content-muted);
2754 font-size: var(--font-size-sm);
2755 }
2756 .email-subject-line {
2757 font-weight: 600;
2758 font-size: 1.1rem;
2759 }
2760 .email-meta-line {
2761 font-size: var(--font-size-sm);
2762 color: var(--content-secondary);
2763 margin-top: var(--space-1);
2764 }
2765 .email-snoozed-tag { color: var(--warning); }
2766 .email-actions-bar {
2767 border-top: 1px solid var(--border);
2768 padding-top: var(--space-4);
2769 margin-top: auto;
2770 }
2771 .email-attachment-tag {
2772 margin-right: var(--space-2);
2773 }
2774 .email-draft-item {
2775 cursor: pointer;
2776 padding: var(--space-3);
2777 }
2778 .email-draft-meta {
2779 font-size: var(--font-size-sm);
2780 color: var(--content-secondary);
2781 }
2782 .label-existing-line {
2783 font-size: var(--font-size-sm);
2784 color: var(--content-secondary);
2785 margin-top: var(--space-1);
2786 }
2787 .search-no-results {
2788 padding: var(--space-5);
2789 text-align: center;
2790 color: var(--content-secondary);
2791 }
2792 .email-attachment-name {
2793 flex: 1;
2794 min-width: 0;
2795 }
2796 .email-draft-subject { font-weight: 500; }
2797
2798 /* Compose form fields — shared between the desktop compose.html window
2799 and the in-app modal (Phase 7 Tier 6 #3 stage 3). The composeForm.buildFieldsHtml
2800 helper emits markup using these classes; both surfaces render the same
2801 HTML so spacing/typography stays unified. Window-only chrome
2802 (.compose-toolbar, .status-bar, .save-contact-bar, .reply-indicator)
2803 still lives in compose.html since it has no modal analogue yet.
2804
2805 NOTE on naming: .header-row / .header-label refer to the compose
2806 form's "header fields" (To, Cc, Subject), NOT the app header. Don't
2807 rename without grepping composeForm.buildFieldsHtml. The input/select
2808 inside each row use .form-input--ghost / .form-select--ghost. */
2809 .header-row {
2810 display: flex;
2811 align-items: center;
2812 padding: 0.75rem 1rem;
2813 border-bottom: 1px solid var(--border);
2814 gap: 0.5rem;
2815 }
2816 .header-row--tight {
2817 padding: 0.25rem 1rem;
2818 }
2819 .header-label {
2820 width: 80px;
2821 color: var(--content-secondary);
2822 font-size: 0.875rem;
2823 flex-shrink: 0;
2824 }
2825 .autocomplete-wrapper {
2826 position: relative;
2827 flex: 1;
2828 background: transparent;
2829 border-radius: var(--radius-sm);
2830 }
2831 .autocomplete-wrapper:focus-within {
2832 background: var(--surface-overlay);
2833 }
2834 .body-container {
2835 flex: 1;
2836 display: flex;
2837 flex-direction: column;
2838 overflow: hidden;
2839 }
2840 .body-textarea {
2841 flex: 1;
2842 min-height: 12rem;
2843 background: var(--surface-raised);
2844 border: none;
2845 color: var(--content);
2846 font-size: 0.9375rem;
2847 font-family: inherit;
2848 padding: 1rem;
2849 resize: vertical;
2850 outline: none;
2851 line-height: 1.6;
2852 }
2853 .body-textarea::placeholder { color: var(--content-muted); }
2854 /* Reply indicator — shared between compose.html's toolbar (where it
2855 benefits from align-self:center inside a flex row) and the in-app
2856 compose modal (where it's just an inline label above the form). */
2857 .reply-indicator {
2858 display: none;
2859 color: var(--content-secondary);
2860 font-size: 0.8125rem;
2861 align-self: center;
2862 }
2863
2864 /* Attachment list — rendered into #attachments-bar by composeForm. */
2865 .compose-attachments {
2866 padding: 0.5rem 1rem;
2867 border-top: 1px solid var(--border);
2868 background: var(--surface-overlay);
2869 font-size: 0.8125rem;
2870 }
2871 /* Compose with `row-flex row-flex-2` for the row. */
2872 .compose-attachment-item {
2873 padding: 0.25rem 0;
2874 }
2875 .compose-attachment-name {
2876 flex: 1;
2877 overflow: hidden;
2878 text-overflow: ellipsis;
2879 white-space: nowrap;
2880 }
2881 .compose-attachment-size {
2882 color: var(--content-muted);
2883 flex-shrink: 0;
2884 }
2885 .compose-attachment-remove {
2886 background: none;
2887 border: none;
2888 color: var(--danger);
2889 cursor: pointer;
2890 font-size: 1rem;
2891 padding: 0 0.25rem;
2892 }
2893 .compose-attachment-total {
2894 display: flex;
2895 gap: var(--space-2);
2896 align-items: baseline;
2897 padding-top: var(--space-2);
2898 margin-top: var(--space-1);
2899 font-size: var(--font-size-sm);
2900 color: var(--content-muted);
2901 border-top: 1px dashed var(--border);
2902 }
2903 .compose-attachment-total.over-warn { color: var(--warning); }
2904 .compose-attachment-total.over-cap { color: var(--danger); }
2905 .compose-attachment-warn { font-style: italic; }
2906
2907 /* About section (Settings → About) */
2908 .about-info-list {
2909 display: grid;
2910 grid-template-columns: max-content 1fr;
2911 column-gap: var(--space-4);
2912 row-gap: var(--space-2);
2913 margin: var(--space-4) 0;
2914 font-size: var(--font-size-sm);
2915 }
2916 .about-info-list dt {
2917 font-weight: 600;
2918 color: var(--content-secondary);
2919 }
2920 .about-info-list dd {
2921 margin: 0;
2922 font-family: var(--font-mono);
2923 }
2924 .about-updater-note {
2925 margin-top: var(--space-4);
2926 }
2927
2928 /* Filter-bar result count (Phase 7 Tier 2 #9) */
2929 .filter-count {
2930 font-size: var(--font-size-sm);
2931 color: var(--content-muted);
2932 margin-right: var(--space-2);
2933 white-space: nowrap;
2934 }
2935 .filter-count--capped {
2936 color: var(--warning);
2937 font-weight: 600;
2938 }
2939
2940 /* Hide the List / Board toggle in mobile UI. Kanban drag-drop has no touch
2941 fallback (Phase 6 #1) — showing the toggle would expose a broken feature.
2942 Keyed off UI mode rather than `hover: none` so a desktop touch laptop
2943 with a working mouse still gets the toggle. Re-enable when touch-drag lands. */
2944 .ui-mode-mobile #task-view-toggle { display: none; }
2945
2946 /* Phase 7 Tier 3 #11 — swipe peek-labels.
2947 Injected into a row on touch start, removed on touch end. Show the action
2948 that will fire when the user releases past threshold. */
2949 .swipe-peek {
2950 position: absolute;
2951 top: 0;
2952 bottom: 0;
2953 display: flex;
2954 align-items: center;
2955 padding: 0 var(--space-3);
2956 font-size: var(--font-size-sm);
2957 font-weight: 600;
2958 color: var(--content-on-action);
2959 pointer-events: none;
2960 opacity: 0;
2961 transition: opacity 0.1s linear;
2962 z-index: 0;
2963 }
2964 /* Right-swipe reveals what was hidden to the LEFT of the row */
2965 .swipe-peek--right {
2966 left: 0;
2967 background: var(--action);
2968 justify-content: flex-start;
2969 }
2970 .swipe-peek--left {
2971 right: 0;
2972 background: var(--action);
2973 justify-content: flex-end;
2974 }
2975 .swipe-peek--success { background: var(--success); }
2976 .swipe-peek--warn { background: var(--warning); color: var(--content); }
2977 .swipe-peek--danger { background: var(--danger); }
2978 .swipe-peek--ready {
2979 /* Stronger visual cue at the action threshold */
2980 box-shadow: inset 0 0 0 2px var(--content-on-action);
2981 }
2982 /* Ensure rows with peek labels behave as containing block + clip content */
2983 .task-row,
2984 .email-item,
2985 .event-row-virtual {
2986 position: relative;
2987 overflow: hidden;
2988 }
2989
2990 .attachment-item {
2991 display: flex;
2992 align-items: center;
2993 gap: var(--space-3);
2994 padding: var(--space-2) 0;
2995 border-bottom: 1px solid var(--border);
2996 }
2997 .attachment-icon { font-size: 1.2rem; }
2998 .attachment-meta {
2999 font-size: var(--font-size-sm);
3000 color: var(--content-muted);
3001 }
3002 .attachment-sync-warning {
3003 font-size: var(--font-size-sm);
3004 color: var(--content-muted);
3005 }
3006 .attachment-info { flex: 1; min-width: 0; }
3007 .attachment-filename {
3008 font-weight: 500;
3009 overflow: hidden;
3010 text-overflow: ellipsis;
3011 white-space: nowrap;
3012 }
3013 .attachment-actions {
3014 display: flex;
3015 gap: var(--space-1);
3016 }
3017 .attachment-attach-row { margin-top: var(--space-4); }
3018
3019 .link-task-item {
3020 display: flex;
3021 align-items: center;
3022 gap: var(--space-2);
3023 padding: var(--space-2);
3024 background: var(--surface-overlay);
3025 border-radius: var(--radius-sm);
3026 margin-bottom: var(--space-2);
3027 cursor: pointer;
3028 }
3029 .link-task-item:hover { background: var(--surface-sunken); }
3030 .link-task-project {
3031 font-size: var(--font-size-sm);
3032 color: var(--content-secondary);
3033 }
3034 .link-task-prompt {
3035 color: var(--content-secondary);
3036 margin-bottom: var(--space-4);
3037 }
3038 .link-task-desc { flex: 1; }
3039 .link-task-list {
3040 max-height: 400px;
3041 overflow-y: auto;
3042 }
3043 .form-actions--top-spaced { margin-top: var(--space-4); }
3044
3045 /* About + Welcome modals */
3046 .about-panel {
3047 text-align: center;
3048 padding: var(--space-4);
3049 }
3050 .about-title {
3051 font-family: var(--font-display);
3052 margin-bottom: var(--space-4);
3053 }
3054 .about-tagline {
3055 color: var(--content-secondary);
3056 margin-bottom: var(--space-2);
3057 }
3058 .about-version {
3059 color: var(--content-muted);
3060 font-size: var(--font-size-sm);
3061 }
3062
3063 .welcome-panel { line-height: var(--line-height-relaxed); }
3064 .welcome-intro {
3065 color: var(--content-secondary);
3066 margin-bottom: var(--space-4);
3067 }
3068 .welcome-section { margin-bottom: var(--space-4); }
3069 .welcome-subhead {
3070 font-size: var(--font-size-md, 0.9rem);
3071 margin-bottom: var(--space-2);
3072 }
3073 .welcome-subhead--tight { margin-bottom: var(--space-1); }
3074 .welcome-step-stack {
3075 display: flex;
3076 flex-direction: column;
3077 gap: var(--space-2);
3078 }
3079 .welcome-tabs-list {
3080 color: var(--content-secondary);
3081 font-size: var(--font-size-sm);
3082 padding-left: var(--space-4);
3083 margin: 0;
3084 }
3085
3086 /* "What's New" after-update dialog */
3087 .whats-new-panel { line-height: var(--line-height-relaxed); }
3088 .whats-new-group {
3089 font-size: var(--font-size-md, 0.9rem);
3090 margin: var(--space-3) 0 var(--space-1);
3091 }
3092 .whats-new-group:first-child { margin-top: 0; }
3093 .whats-new-list {
3094 color: var(--content-secondary);
3095 font-size: var(--font-size-sm);
3096 padding-left: var(--space-4);
3097 margin: 0;
3098 }
3099 .whats-new-text {
3100 color: var(--content-secondary);
3101 margin-bottom: var(--space-2);
3102 }
3103
3104 .review-more-line {
3105 color: var(--content-muted);
3106 font-size: var(--font-size-sm);
3107 margin-top: var(--space-2);
3108 }
3109
3110 .modal-attachments {
3111 font-size: var(--font-size-sm);
3112 margin-top: var(--space-1);
3113 }
3114
3115 .account-row-info {
3116 flex: 1;
3117 }
3118 .account-row-actions {
3119 display: flex;
3120 align-items: center;
3121 gap: var(--space-2);
3122 margin-bottom: var(--space-2);
3123 }
3124 .account-row-quick {
3125 display: flex;
3126 gap: var(--space-2);
3127 }
3128 .account-row-quick .btn {
3129 flex: 1;
3130 }
3131 .account-list {
3132 margin-bottom: var(--space-4);
3133 max-height: 400px;
3134 overflow-y: auto;
3135 }
3136 .form-actions-spacer { flex: 1; }
3137 .oauth-block {
3138 margin-bottom: var(--space-5);
3139 }
3140 .oauth-block-title {
3141 font-weight: 500;
3142 margin-bottom: var(--space-3);
3143 }
3144 .oauth-buttons {
3145 display: flex;
3146 flex-wrap: wrap;
3147 gap: var(--space-2);
3148 }
3149 .oauth-buttons .btn {
3150 flex: 1;
3151 min-width: 120px;
3152 }
3153 .oauth-helptext {
3154 font-size: var(--font-size-sm);
3155 color: var(--content-secondary);
3156 margin-top: var(--space-2);
3157 }
3158 .imap-block-divider {
3159 border-top: var(--border-width-sm) solid var(--border);
3160 margin: var(--space-4) 0;
3161 padding-top: var(--space-4);
3162 }
3163 .imap-block-title {
3164 font-weight: 500;
3165 margin-bottom: var(--space-3);
3166 }
3167 .test-conn-results {
3168 margin-bottom: var(--space-4);
3169 }
3170 .sync-results {
3171 margin-bottom: var(--space-4);
3172 }
3173 .sync-result-banner {
3174 padding: var(--space-3);
3175 background: var(--surface-overlay);
3176 border-radius: var(--radius-sm);
3177 margin-bottom: var(--space-2);
3178 }
3179 .sync-result-grid {
3180 display: grid;
3181 grid-template-columns: 1fr 1fr;
3182 gap: var(--space-2);
3183 margin-bottom: var(--space-2);
3184 }
3185 .sync-result-tile {
3186 padding: var(--space-2);
3187 background: var(--surface-overlay);
3188 border-radius: var(--radius-sm);
3189 }
3190
3191 /* ===================================================================
3192 21. Footer
3193 =================================================================== */
3194 .app-footer {
3195 background-color: var(--surface-raised);
3196 border-top: var(--border-width) solid var(--border);
3197 padding: 0.75rem 1.5rem;
3198 }
3199
3200 .footer-content {
3201 max-width: var(--width-container);
3202 margin: 0 auto;
3203 display: flex;
3204 justify-content: space-between;
3205 align-items: center;
3206 }
3207
3208 /* Desktop UI only — keyboard hints aren't meaningful in mobile UI. */
3209 .ui-mode-desktop .keyboard-hints {
3210 display: flex;
3211 gap: 1rem;
3212 font-size: 0.8rem;
3213 color: var(--content-muted);
3214 }
3215
3216 kbd {
3217 display: inline-block;
3218 padding: 0.2rem 0.5rem;
3219 background-color: var(--surface-overlay);
3220 border: var(--border-width-sm) solid var(--border);
3221 border-radius: var(--radius-xs);
3222 font-family: var(--font-mono);
3223 font-size: 0.75rem;
3224 font-weight: 700;
3225 }
3226
3227 .welcome-hint {
3228 color: var(--content-secondary);
3229 font-size: var(--font-size-sm);
3230 margin-bottom: var(--space-2);
3231 }
3232
3233 .version {
3234 font-size: 0.75rem;
3235 color: var(--content-muted);
3236 font-weight: 600;
3237 }
3238
3239 /* ===================================================================
3240 22. Empty & Error States
3241 =================================================================== */
3242 .empty-state {
3243 text-align: center;
3244 padding: 3rem;
3245 color: var(--content-secondary);
3246 }
3247
3248 .empty-state--compact {
3249 padding: 2rem 1rem;
3250 font-size: var(--font-size-sm);
3251 }
3252
3253 .empty-state--dashboard {
3254 padding: 2rem 1rem;
3255 }
3256
3257 .empty-state--error {
3258 color: var(--danger);
3259 }
3260
3261 .empty-state-icon {
3262 display: flex;
3263 justify-content: center;
3264 margin-bottom: var(--space-3);
3265 color: var(--content-muted);
3266 }
3267
3268 .empty-state-icon svg {
3269 width: 2.75rem;
3270 height: 2.75rem;
3271 }
3272
3273 .empty-state--compact .empty-state-icon svg,
3274 .empty-state--dashboard .empty-state-icon svg {
3275 width: 2rem;
3276 height: 2rem;
3277 }
3278
3279 .empty-state-text {
3280 font-size: 1.1rem;
3281 font-weight: 600;
3282 margin-bottom: 1rem;
3283 }
3284
3285 /* In compact/dashboard columns the empty copy is a quiet placeholder, not a headline. */
3286 .empty-state--compact .empty-state-text,
3287 .empty-state--dashboard .empty-state-text {
3288 font-size: var(--font-size-sm);
3289 font-weight: 500;
3290 margin-bottom: var(--space-2);
3291 }
3292
3293 .error-state {
3294 text-align: center;
3295 padding: 2rem;
3296 color: var(--danger);
3297 background: color-mix(in srgb, var(--danger) 10%, var(--surface-raised));
3298 border: var(--border-width-sm) solid var(--danger);
3299 border-radius: var(--radius-sm);
3300 font-weight: 600;
3301 }
3302
3303 /* View states */
3304 .view {
3305 display: block;
3306 }
3307
3308 .view.hidden {
3309 display: none;
3310 }
3311
3312 /* ===================================================================
3313 23. Filter Bar
3314 =================================================================== */
3315 .filter-bar {
3316 display: flex;
3317 flex-wrap: wrap;
3318 gap: 0.75rem;
3319 margin-bottom: 1.5rem;
3320 padding: 1rem;
3321 background-color: var(--surface-raised);
3322 border: var(--border-width) solid var(--border);
3323 border-radius: var(--radius-md);
3324 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
3325 }
3326
3327 .filter-group {
3328 display: flex;
3329 align-items: center;
3330 gap: 0.5rem;
3331 }
3332
3333 .filter-label {
3334 font-size: 0.8rem;
3335 font-weight: 700;
3336 color: var(--content-secondary);
3337 text-transform: uppercase;
3338 letter-spacing: 0.05em;
3339 }
3340
3341 .filter-select {
3342 padding: 0.5rem 0.75rem;
3343 border: var(--border-width-sm) solid var(--border);
3344 border-radius: var(--radius-sm);
3345 background-color: var(--surface-raised);
3346 color: var(--content);
3347 font-size: 0.875rem;
3348 font-weight: 600;
3349 }
3350
3351 .filter-select:focus {
3352 outline: none;
3353 background-color: var(--action);
3354 color: var(--content-on-action);
3355 }
3356
3357 .filter-checkbox {
3358 display: flex;
3359 align-items: center;
3360 gap: 0.4rem;
3361 font-size: 0.875rem;
3362 font-weight: 600;
3363 color: var(--content);
3364 cursor: pointer;
3365 }
3366
3367 .filter-checkbox input[type="checkbox"] {
3368 width: 1rem;
3369 height: 1rem;
3370 cursor: pointer;
3371 }
3372
3373 .btn-link {
3374 background: none;
3375 border: none;
3376 box-shadow: none;
3377 color: var(--content-secondary);
3378 font-size: 0.875rem;
3379 cursor: pointer;
3380 text-decoration: underline;
3381 padding: 0.5rem;
3382 }
3383
3384 .btn-link:hover {
3385 box-shadow: none;
3386 transform: none;
3387 color: var(--content);
3388 }
3389
3390 /* ===================================================================
3391 24. Responsive - Large Screens & Tablet
3392 =================================================================== */
3393
3394 /* Wide desktop — intra-desktop responsive (only desktop UI gets these). */
3395 @media (min-width: 1400px) {
3396 .ui-mode-desktop .main-content {
3397 max-width: none;
3398 }
3399
3400 .ui-mode-desktop .cards-grid {
3401 grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
3402 }
3403
3404 .ui-mode-desktop .project-dashboard-grid {
3405 gap: 2rem;
3406 }
3407
3408 .ui-mode-desktop .day-plan-sidebar {
3409 width: 320px;
3410 }
3411
3412 .ui-mode-desktop .modal-container {
3413 max-width: 640px;
3414 }
3415 }
3416
3417 /* Tablet — intra-desktop responsive (desktop UI on narrow desktops/iPads).
3418 Scoped to .ui-mode-desktop so it never affects mobile UI. */
3419 @media (max-width: 1024px) {
3420 .ui-mode-desktop .saved-views-sidebar {
3421 width: 180px;
3422 }
3423
3424 .ui-mode-desktop .day-plan-sidebar {
3425 width: 240px;
3426 }
3427
3428 .ui-mode-desktop .project-dashboard-grid {
3429 grid-template-columns: 1fr 1fr;
3430 gap: 1rem;
3431 }
3432
3433 .ui-mode-desktop .project-dashboard-grid .dashboard-column:last-child {
3434 grid-column: span 2;
3435 }
3436
3437 .ui-mode-desktop .filter-bar {
3438 flex-wrap: wrap;
3439 }
3440
3441 .ui-mode-desktop .filter-actions {
3442 width: 100%;
3443 justify-content: flex-end;
3444 margin-top: 0.5rem;
3445 }
3446 }
3447
3448 /* ===================================================================
3449 25. Responsive - Mobile (768px)
3450 =================================================================== */
3451 .ui-mode-mobile .tab-navigation {
3452 flex-wrap: wrap;
3453 gap: 0.5rem;
3454 }
3455
3456 .ui-mode-mobile .tab {
3457 flex: 1 1 auto;
3458 min-width: calc(33% - 0.5rem);
3459 justify-content: center;
3460 padding: 0.625rem 0.75rem;
3461 }
3462
3463 .ui-mode-mobile .tab-label {
3464 display: none;
3465 }
3466
3467 .ui-mode-mobile .tab-icon {
3468 font-size: 1.25rem;
3469 }
3470
3471 .ui-mode-mobile .kbd-hint {
3472 display: none;
3473 }
3474
3475 .ui-mode-mobile .cards-grid {
3476 grid-template-columns: 1fr;
3477 }
3478
3479 .ui-mode-mobile .task-table {
3480 font-size: 0.85rem;
3481 }
3482
3483 /* Hide recurrence, progress, and actions columns on mobile */
3484 .ui-mode-mobile .task-header-row,
3485 .ui-mode-mobile .task-row {
3486 grid-template-columns: 1fr 80px 40px 80px;
3487 }
3488
3489 .ui-mode-mobile .task-header-row .task-cell:nth-child(n+5),
3490 .ui-mode-mobile .task-row .task-cell:nth-child(n+5) {
3491 display: none;
3492 }
3493
3494 .ui-mode-mobile .filter-bar {
3495 flex-direction: column;
3496 }
3497
3498 .ui-mode-mobile .keyboard-hints {
3499 display: none;
3500 }
3501
3502 .ui-mode-mobile .page-title {
3503 font-size: 1.5rem;
3504 }
3505
3506 .ui-mode-mobile .saved-views-sidebar {
3507 display: none;
3508 }
3509
3510 .ui-mode-mobile .day-plan-content {
3511 flex-direction: column;
3512 }
3513
3514 .ui-mode-mobile .day-plan-sidebar {
3515 width: 100%;
3516 max-height: 200px;
3517 }
3518
3519 .ui-mode-mobile .project-dashboard-grid {
3520 grid-template-columns: 1fr;
3521 }
3522
3523 .ui-mode-mobile .project-dashboard-grid .dashboard-column:last-child {
3524 grid-column: span 1;
3525 }
3526
3527 .ui-mode-mobile .modal-container {
3528 width: 95%;
3529 max-height: 95vh;
3530 }
3531
3532 .ui-mode-mobile .bulk-actions-bar {
3533 flex-wrap: wrap;
3534 }
3535
3536 .ui-mode-mobile .bulk-select-all {
3537 width: 100%;
3538 margin-top: 0.5rem;
3539 }
3540
3541
3542 /* ===================================================================
3543 26. Screen Reader & Accessibility
3544 =================================================================== */
3545 .sr-only {
3546 position: absolute;
3547 width: 1px;
3548 height: 1px;
3549 padding: 0;
3550 margin: -1px;
3551 overflow: hidden;
3552 clip: rect(0, 0, 0, 0);
3553 white-space: nowrap;
3554 border: 0;
3555 }
3556
3557 /* ===================================================================
3558 27. Pagination
3559 =================================================================== */
3560 .pagination-controls {
3561 display: flex;
3562 align-items: center;
3563 justify-content: center;
3564 gap: 1rem;
3565 padding: 1rem;
3566 margin-top: 1rem;
3567 background: var(--surface-raised);
3568 border: var(--border-width) solid var(--border);
3569 border-radius: var(--radius-md);
3570 }
3571
3572 .pagination-info {
3573 font-weight: 600;
3574 color: var(--content-secondary);
3575 font-size: 0.9rem;
3576 }
3577
3578 .pagination-controls .btn:disabled {
3579 opacity: 0.5;
3580 cursor: not-allowed;
3581 }
3582
3583 /* ===================================================================
3584 28. Focus & Keyboard Accessibility
3585 =================================================================== */
3586 .tab:focus-visible,
3587 .btn:focus-visible,
3588 .form-input:focus-visible,
3589 .form-select:focus-visible,
3590 .form-textarea:focus-visible,
3591 .card:focus-visible,
3592 .email-item:focus-visible,
3593 .task-row:focus-visible,
3594 .event-row-virtual:focus-visible,
3595 .saved-view-item:focus-visible,
3596 .filter-select:focus-visible,
3597 .modal-close:focus-visible,
3598 .snooze-option:focus-visible,
3599 .unscheduled-task:focus-visible,
3600 .timeline-item:focus-visible,
3601 .card:focus-visible {
3602 outline: 3px solid var(--action);
3603 outline-offset: 2px;
3604 }
3605
3606 /* Ensure clickable table rows can receive focus */
3607 .task-row-clickable,
3608 .event-row {
3609 cursor: pointer;
3610 }
3611
3612 /* Skip link for keyboard navigation */
3613 .skip-link {
3614 position: absolute;
3615 top: -100px;
3616 left: 0;
3617 background: var(--action);
3618 color: var(--content-on-action);
3619 padding: 0.75rem 1.5rem;
3620 z-index: 9999;
3621 font-weight: 700;
3622 border: var(--border-width) solid var(--border);
3623 text-decoration: none;
3624 }
3625
3626 .skip-link:focus {
3627 top: 0;
3628 }
3629
3630 /* ===================================================================
3631 29. Source Email Link
3632 =================================================================== */
3633 .source-email-link {
3634 padding: 0.75rem;
3635 background: var(--surface-overlay);
3636 border-radius: var(--radius-sm);
3637 border-left: 4px solid var(--action);
3638 }
3639
3640 /* ===================================================================
3641 30. Email Reader Mode
3642 =================================================================== */
3643
3644 /* Thread message container */
3645 .thread-message {
3646 margin-bottom: 1rem;
3647 padding: 0.75rem;
3648 background: var(--surface-overlay);
3649 border-radius: var(--radius-sm);
3650 }
3651
3652 .thread-message-latest {
3653 border-left: 3px solid var(--action);
3654 }
3655
3656 .thread-message-header {
3657 display: flex;
3658 justify-content: space-between;
3659 margin-bottom: 0.5rem;
3660 font-size: 0.8rem;
3661 color: var(--content-secondary);
3662 }
3663
3664 .thread-message-from {
3665 font-weight: 700;
3666 }
3667
3668 /* Reader mode body styling */
3669 .email-reader-body {
3670 white-space: pre-wrap;
3671 font-size: 0.9rem;
3672 line-height: 1.6;
3673 color: var(--content);
3674 word-wrap: break-word;
3675 overflow-wrap: break-word;
3676 }
3677
3678 /* Links extracted from HTML emails - shown as [url] */
3679 .email-reader-body .email-link {
3680 color: var(--action);
3681 text-decoration: underline;
3682 cursor: pointer;
3683 word-break: break-all;
3684 }
3685
3686 .email-reader-body .email-link:hover {
3687 color: var(--category-six);
3688 }
3689
3690 /* Bullet points from list items */
3691 .email-reader-body {
3692 /* Ensure bullet points align nicely */
3693 }
3694
3695 /* Horizontal rule separators */
3696 .email-reader-body hr {
3697 border: none;
3698 border-top: 2px solid var(--border);
3699 margin: 1rem 0;
3700 }
3701
3702 /* Quote blocks if detected */
3703 .email-reader-quote {
3704 border-left: 3px solid var(--content-muted);
3705 padding-left: 1rem;
3706 margin: 0.5rem 0;
3707 color: var(--content-secondary);
3708 font-style: italic;
3709 }
3710
3711 /* Collapsible quoted text */
3712 .email-quote-toggle {
3713 display: inline-block;
3714 color: var(--content-muted);
3715 font-size: 0.8125rem;
3716 cursor: pointer;
3717 padding: 0.25rem 0;
3718 user-select: none;
3719 }
3720
3721 .email-quote-toggle:hover {
3722 color: var(--action);
3723 }
3724
3725 .email-quote-block {
3726 border-left: 3px solid var(--content-muted);
3727 padding-left: 1rem;
3728 margin: 0.25rem 0 0.5rem;
3729 color: var(--content-secondary);
3730 }
3731
3732 .email-quote-block.hidden {
3733 display: none;
3734 }
3735
3736 /* Email address autocomplete. Shares bg/border/shadow with .dropdown-menu
3737 but uses a different positioning model (parent-relative, shown by default
3738 with max-height) — kept separate intentionally. */
3739 .autocomplete-dropdown {
3740 background: var(--surface-raised);
3741 border: 1px solid var(--border);
3742 border-radius: var(--radius-sm);
3743 box-shadow: var(--shadow-brutal-md);
3744 z-index: 100;
3745 max-height: 200px;
3746 overflow-y: auto;
3747 }
3748
3749 .autocomplete-item {
3750 padding: 0.5rem 0.75rem;
3751 cursor: pointer;
3752 font-size: 0.875rem;
3753 }
3754
3755 .autocomplete-item:hover,
3756 .autocomplete-item.active {
3757 background: var(--surface-overlay);
3758 }
3759
3760 .autocomplete-name {
3761 font-weight: 500;
3762 }
3763
3764 .autocomplete-email {
3765 color: var(--content-secondary);
3766 margin-left: 0.25rem;
3767 }
3768
3769 /* Email reader container for large modal */
3770 .email-reader-container {
3771 display: flex;
3772 flex-direction: column;
3773 height: 100%;
3774 min-height: 0;
3775 }
3776
3777 .email-reader-header {
3778 margin-bottom: 1rem;
3779 padding-bottom: 0.75rem;
3780 border-bottom: 1px solid var(--border);
3781 }
3782
3783 /* Email sender contact card. Compose with `row-flex row-flex-2` for the row. */
3784 .email-sender-contact {
3785 margin-top: 0.5rem;
3786 padding: 0.4rem 0.5rem;
3787 background: var(--surface-sunken);
3788 border-radius: 4px;
3789 }
3790
3791 .email-sender-info {
3792 display: flex;
3793 flex-direction: column;
3794 flex: 1;
3795 min-width: 0;
3796 }
3797
3798 .email-sender-name {
3799 font-weight: 600;
3800 font-size: 0.85rem;
3801 }
3802
3803 .email-sender-company {
3804 font-size: 0.75rem;
3805 color: var(--content-secondary);
3806 }
3807
3808 .email-reader-thread {
3809 flex: 1;
3810 overflow-y: auto;
3811 margin-bottom: 1rem;
3812 min-height: 0;
3813 }
3814
3815 /* ===================================================================
3816 31. Dropdown Menus
3817 =================================================================== */
3818 .dropdown {
3819 position: relative;
3820 display: inline-block;
3821 }
3822
3823 .dropdown-menu {
3824 display: none;
3825 position: absolute;
3826 bottom: 100%;
3827 left: 0;
3828 margin-bottom: 0.25rem;
3829 background: var(--surface-raised);
3830 border: var(--border-width) solid var(--border);
3831 border-radius: var(--radius-md);
3832 box-shadow: var(--shadow-brutal-md);
3833 min-width: 160px;
3834 z-index: 100;
3835 }
3836
3837 .dropdown-menu.show {
3838 display: block;
3839 }
3840
3841 .dropdown-item {
3842 display: block;
3843 width: 100%;
3844 padding: 0.5rem 1rem;
3845 text-align: left;
3846 background: none;
3847 border: none;
3848 cursor: pointer;
3849 font-size: 0.875rem;
3850 color: var(--content);
3851 }
3852
3853 .dropdown-item:hover {
3854 background: var(--surface-overlay);
3855 }
3856
3857 .dropdown-item:first-child {
3858 border-radius: var(--radius-md) var(--radius-md) 0 0;
3859 }
3860
3861 .dropdown-item:last-child {
3862 border-radius: 0 0 var(--radius-md) var(--radius-md);
3863 }
3864
3865 /* ===================================================================
3866 32. Context Menus
3867 =================================================================== */
3868
3869 .context-menu {
3870 position: fixed;
3871 z-index: 10000;
3872 min-width: 180px;
3873 max-width: 280px;
3874 background: var(--surface-raised);
3875 border: var(--border-width) solid var(--border);
3876 border-radius: var(--radius-sm);
3877 box-shadow: var(--shadow-brutal-lg);
3878 padding: 0.25rem 0;
3879 display: none;
3880 }
3881
3882 .context-menu.visible {
3883 display: block;
3884 }
3885
3886 .context-menu-item {
3887 display: flex;
3888 align-items: center;
3889 gap: 0.75rem;
3890 padding: 0.5rem 1rem;
3891 font-size: 0.875rem;
3892 font-weight: 500;
3893 color: var(--content);
3894 cursor: pointer;
3895 border: none;
3896 background: none;
3897 width: 100%;
3898 text-align: left;
3899 transition: background 0.1s;
3900 }
3901
3902 .context-menu-item:hover,
3903 .context-menu-item:focus {
3904 background: var(--action);
3905 color: var(--content-on-action);
3906 outline: none;
3907 }
3908
3909 .context-menu-item:focus-visible {
3910 outline: 2px solid var(--action);
3911 outline-offset: -2px;
3912 }
3913
3914 .context-menu-header {
3915 font-size: 0.7rem;
3916 font-weight: 700;
3917 color: var(--content-secondary);
3918 text-transform: uppercase;
3919 letter-spacing: 0.05em;
3920 padding: 0.5rem 1rem 0.25rem;
3921 }
3922
3923 .context-menu-item-icon {
3924 width: 1.25rem;
3925 text-align: center;
3926 flex-shrink: 0;
3927 }
3928
3929 .context-menu-item-label {
3930 flex: 1;
3931 }
3932
3933 .context-menu-item-subtitle {
3934 display: block;
3935 font-size: 0.7rem;
3936 color: var(--content-secondary);
3937 font-weight: normal;
3938 }
3939
3940 .context-menu-item-shortcut {
3941 font-size: 0.75rem;
3942 color: var(--content-muted);
3943 font-family: var(--font-mono);
3944 }
3945
3946 .context-menu-item--danger {
3947 color: var(--danger);
3948 }
3949
3950 .context-menu-item--danger:hover {
3951 background: var(--danger);
3952 color: var(--content-on-action);
3953 }
3954
3955 .context-menu-separator {
3956 height: 2px;
3957 background: var(--border);
3958 margin: 0.25rem 0.5rem;
3959 }
3960
3961 /* Keyboard hint in context menu */
3962 .context-menu-hint {
3963 padding: 0.35rem 1rem;
3964 font-size: 0.7rem;
3965 color: var(--content-muted);
3966 border-top: 1px solid var(--border);
3967 margin-top: 0.25rem;
3968 }
3969
3970 /* ===================================================================
3971 33. Scrollbar Styling
3972 =================================================================== */
3973 ::-webkit-scrollbar {
3974 width: 12px;
3975 height: 12px;
3976 }
3977
3978 ::-webkit-scrollbar-track {
3979 background: var(--surface-overlay);
3980 border-left: 2px solid var(--border);
3981 }
3982
3983 ::-webkit-scrollbar-thumb {
3984 background: var(--content-muted);
3985 border: var(--border-width-sm) solid var(--border);
3986 border-radius: var(--radius-sm);
3987 }
3988
3989 ::-webkit-scrollbar-thumb:hover {
3990 background: var(--content-secondary);
3991 }
3992
3993 /* ===================================================================
3994 34. Desktop App Styles (Loading, Skeleton, Spinner)
3995 =================================================================== */
3996
3997 /* Loading state */
3998 .loading {
3999 display: flex;
4000 justify-content: center;
4001 align-items: center;
4002 height: 200px;
4003 color: var(--content-secondary);
4004 font-family: var(--font-heading);
4005 }
4006
4007 /* Skeleton shimmer loading placeholders */
4008 .skeleton-shimmer {
4009 display: flex;
4010 flex-direction: column;
4011 gap: 1rem;
4012 padding: 1rem;
4013 }
4014
4015 .skeleton-shimmer .skeleton-row {
4016 display: flex;
4017 align-items: center;
4018 gap: 0.75rem;
4019 padding: 0.75rem;
4020 background: var(--surface-raised);
4021 border-radius: var(--radius-md);
4022 border: var(--border-width) solid var(--border);
4023 }
4024
4025 .skeleton-shimmer .skeleton-avatar {
4026 width: 36px;
4027 height: 36px;
4028 border-radius: var(--radius-full);
4029 background: linear-gradient(90deg, var(--surface-overlay) 25%, var(--surface-sunken) 50%, var(--surface-overlay) 75%);
4030 background-size: 200% 100%;
4031 animation: skeleton-pulse 1.5s ease-in-out infinite;
4032 flex-shrink: 0;
4033 }
4034
4035 .skeleton-shimmer .skeleton-lines {
4036 flex: 1;
4037 display: flex;
4038 flex-direction: column;
4039 gap: 0.4rem;
4040 }
4041
4042 .skeleton-shimmer .skeleton-line {
4043 height: 0.75rem;
4044 border-radius: var(--radius-sm);
4045 background: linear-gradient(90deg, var(--surface-overlay) 25%, var(--surface-sunken) 50%, var(--surface-overlay) 75%);
4046 background-size: 200% 100%;
4047 animation: skeleton-pulse 1.5s ease-in-out infinite;
4048 }
4049
4050 .skeleton-shimmer .skeleton-line.short { width: 40%; }
4051 .skeleton-shimmer .skeleton-line.medium { width: 65%; }
4052 .skeleton-shimmer .skeleton-line.long { width: 90%; }
4053
4054 @keyframes skeleton-pulse {
4055 0% { background-position: 200% 0; }
4056 100% { background-position: -200% 0; }
4057 }
4058
4059 /* Spinner animation */
4060 @keyframes spin {
4061 0% { transform: rotate(0deg); }
4062 100% { transform: rotate(360deg); }
4063 }
4064
4065 .spinner {
4066 display: inline-block;
4067 width: 1em;
4068 height: 1em;
4069 border: 2px solid currentColor;
4070 border-top-color: transparent;
4071 border-radius: var(--radius-full);
4072 animation: spin 0.8s linear infinite;
4073 }
4074
4075 /* Button loading state */
4076 .btn-loading {
4077 position: relative;
4078 pointer-events: none;
4079 opacity: 0.8;
4080 }
4081
4082 .btn-loading .btn-text {
4083 visibility: hidden;
4084 }
4085
4086 .btn-loading::after {
4087 content: '';
4088 position: absolute;
4089 left: 50%;
4090 top: 50%;
4091 width: 1em;
4092 height: 1em;
4093 margin-left: -0.5em;
4094 margin-top: -0.5em;
4095 border: 2px solid currentColor;
4096 border-top-color: transparent;
4097 border-radius: var(--radius-full);
4098 animation: spin 0.8s linear infinite;
4099 }
4100
4101 .hidden { display: none !important; }
4102
4103 /* ===================================================================
4104 35. Project Dashboard
4105 =================================================================== */
4106 .project-dashboard-grid {
4107 display: grid;
4108 grid-template-columns: repeat(3, 1fr);
4109 gap: 1.5rem;
4110 flex: 1;
4111 min-height: 0;
4112 }
4113
4114 .dashboard-column {
4115 background: var(--surface-raised);
4116 border: var(--border-width) solid var(--border);
4117 padding: 1rem;
4118 display: flex;
4119 flex-direction: column;
4120 overflow: hidden;
4121 }
4122
4123 .dashboard-column-header {
4124 display: flex;
4125 justify-content: space-between;
4126 align-items: center;
4127 margin-bottom: 1rem;
4128 padding-bottom: 0.5rem;
4129 border-bottom: 2px solid var(--border);
4130 }
4131
4132 .dashboard-column-header h3 {
4133 margin: 0;
4134 font-size: 1rem;
4135 font-family: var(--font-heading);
4136 font-weight: 700;
4137 }
4138
4139 .dashboard-list {
4140 flex: 1;
4141 overflow-y: auto;
4142 }
4143
4144 /* Dashboard list items compose .card + .card--list-item (see Cards section).
4145 .dashboard-item-title / -meta are page-scoped sub-element classes. */
4146 .dashboard-item-title {
4147 font-weight: 600;
4148 margin-bottom: 0.25rem;
4149 }
4150
4151 .dashboard-item-meta {
4152 font-size: 0.75rem;
4153 color: var(--content-secondary);
4154 }
4155
4156 /* ===================================================================
4157 36. Task Badges
4158 =================================================================== */
4159 .task-badges {
4160 display: flex;
4161 gap: 0.25rem;
4162 margin-top: 0.25rem;
4163 }
4164
4165 .task-badge {
4166 font-size: 0.65rem;
4167 padding: 0.15rem 0.4rem;
4168 border: var(--border-width-sm) solid var(--border);
4169 background: var(--surface-overlay);
4170 color: var(--content);
4171 font-weight: 600;
4172 }
4173
4174 .task-badge.has-items {
4175 background: var(--action);
4176 color: var(--content-on-action);
4177 }
4178
4179 .task-badge.recurrence {
4180 background: var(--category-five);
4181 color: var(--content-on-action);
4182 }
4183
4184 /* Status-token indicator dot (task row) + commits-manager rows.
4185 Colour rolls a task's tokens up at a glance: neutral (no tokens),
4186 pending/amber (e.g. a commit not pushed), complete/green (all pushed). */
4187 .token-dot {
4188 -webkit-appearance: none;
4189 appearance: none;
4190 display: inline-block;
4191 width: 0.6rem;
4192 height: 0.6rem;
4193 padding: 0;
4194 line-height: 0;
4195 border-radius: 50%;
4196 border: var(--border-width-sm) solid var(--border);
4197 background: var(--content-muted);
4198 cursor: pointer;
4199 vertical-align: middle;
4200 flex: none;
4201 }
4202
4203 .token-dot--neutral {
4204 background: transparent;
4205 border-color: var(--content-muted);
4206 opacity: 0.5;
4207 }
4208
4209 .token-dot--pending {
4210 background: var(--warning);
4211 }
4212
4213 .token-dot--complete {
4214 background: var(--success);
4215 }
4216
4217 .token-dot:focus-visible {
4218 outline: var(--border-width-sm) solid var(--focus-ring);
4219 outline-offset: 2px;
4220 }
4221
4222 .token-item {
4223 display: flex;
4224 align-items: center;
4225 gap: 0.4rem;
4226 padding: 0.35rem 0;
4227 border-bottom: var(--border-width-sm) solid var(--border);
4228 }
4229
4230 .token-item .token-dot {
4231 cursor: default;
4232 }
4233
4234 .token-ref {
4235 font-family: var(--font-mono);
4236 font-size: 0.8rem;
4237 word-break: break-all;
4238 }
4239
4240 .token-ref--primary {
4241 font-weight: 700;
4242 }
4243
4244 .token-primary-tag {
4245 font-family: inherit;
4246 font-size: 0.6rem;
4247 text-transform: uppercase;
4248 letter-spacing: 0.03em;
4249 padding: 0.05rem 0.3rem;
4250 border: var(--border-width-sm) solid var(--border);
4251 background: var(--success);
4252 color: var(--content-on-action);
4253 }
4254
4255 /* Clickable task rows */
4256 .task-row-clickable {
4257 cursor: pointer;
4258 transition: background 0.1s;
4259 }
4260
4261 .task-row-clickable:hover {
4262 background: var(--surface-overlay);
4263 }
4264
4265 /* ===================================================================
4266 37. Progress Bar
4267 =================================================================== */
4268 .task-progress {
4269 /* Width controlled by grid, not explicit value */
4270 }
4271
4272 .progress-bar-container {
4273 width: 100%;
4274 height: 10px;
4275 background: var(--surface-overlay);
4276 border: var(--border-width-sm) solid var(--border);
4277 overflow: hidden;
4278 }
4279
4280 .progress-bar {
4281 height: 100%;
4282 background: var(--success);
4283 transition: width 0.3s ease;
4284 }
4285
4286 .no-subtasks {
4287 color: var(--content-secondary);
4288 font-size: 0.875rem;
4289 }
4290
4291 /* ===================================================================
4292 38. Day Plan View
4293 =================================================================== */
4294 #day-plan-view {
4295 display: flex;
4296 flex-direction: column;
4297 flex: 1;
4298 min-height: 0;
4299 }
4300
4301 #day-plan-view .page-header {
4302 flex-shrink: 0;
4303 }
4304
4305 .day-plan-nav {
4306 display: flex;
4307 align-items: center;
4308 gap: 0.5rem;
4309 }
4310
4311 .day-plan-date-picker {
4312 padding: 0.5rem;
4313 background: var(--surface-raised);
4314 border: var(--border-width) solid var(--border);
4315 border-radius: var(--radius-sm);
4316 color: var(--content);
4317 font-family: var(--font-body);
4318 }
4319
4320 .day-plan-date-display {
4321 font-size: 1.25rem;
4322 font-weight: 700;
4323 margin-left: 1rem;
4324 font-family: var(--font-heading);
4325 line-height: 1;
4326 }
4327
4328 .day-plan-content {
4329 flex: 1;
4330 min-height: 0;
4331 display: flex;
4332 gap: 1.5rem;
4333 }
4334
4335 .day-plan-main {
4336 flex: 1;
4337 min-height: 0;
4338 display: flex;
4339 flex-direction: column;
4340 background: var(--surface-raised);
4341 border: var(--border-width) solid var(--border);
4342 border-radius: var(--radius-md);
4343 overflow: hidden;
4344 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
4345 }
4346
4347 .day-plan-sidebar {
4348 width: 280px;
4349 flex-shrink: 0;
4350 display: flex;
4351 flex-direction: column;
4352 background: var(--surface-raised);
4353 border: var(--border-width) solid var(--border);
4354 border-radius: var(--radius-md);
4355 overflow: hidden;
4356 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
4357 }
4358
4359 .sidebar-header {
4360 padding: 1rem;
4361 border-bottom: 2px solid var(--border);
4362 flex-shrink: 0;
4363 }
4364
4365 .sidebar-header h3 {
4366 margin: 0;
4367 font-size: 1rem;
4368 font-family: var(--font-heading);
4369 font-weight: 700;
4370 }
4371
4372 .sidebar-task-list {
4373 flex: 1;
4374 overflow-y: auto;
4375 padding: 0.75rem;
4376 display: flex;
4377 flex-direction: column;
4378 gap: 0.5rem;
4379 }
4380
4381 /* ===================================================================
4382 39. Timeline
4383 =================================================================== */
4384 .timeline-container {
4385 flex: 1;
4386 min-height: 0;
4387 overflow-y: auto;
4388 overflow-x: hidden;
4389 }
4390
4391 .timeline-scroll-area {
4392 position: relative;
4393 padding: 0.5rem 1rem 3rem 0.5rem;
4394 min-height: min-content;
4395 }
4396
4397 #timeline-slots {
4398 position: relative;
4399 }
4400
4401 #timeline-items {
4402 position: absolute;
4403 top: 0.5rem;
4404 left: 0.5rem;
4405 right: 1rem;
4406 bottom: 0;
4407 pointer-events: none;
4408 }
4409
4410 #timeline-items .timeline-item {
4411 pointer-events: auto;
4412 }
4413
4414 .timeline-slot {
4415 display: grid;
4416 grid-template-columns: 50px 1fr;
4417 height: var(--timeline-slot-h, 12px);
4418 position: relative;
4419 }
4420
4421 .timeline-slot.hour-start .timeline-slot-area {
4422 border-top: 1px dashed color-mix(in srgb, var(--border) 50%, transparent);
4423 }
4424
4425 .timeline-time {
4426 font-size: 0.7rem;
4427 color: var(--content-secondary);
4428 padding-right: 0.5rem;
4429 text-align: right;
4430 font-weight: 500;
4431 transform: translateY(-0.5em);
4432 }
4433
4434 .timeline-hint {
4435 text-align: center;
4436 color: var(--content-secondary);
4437 font-size: 0.85rem;
4438 font-weight: 600;
4439 margin: 0 0 0.5rem;
4440 padding: 0.35rem 0.75rem;
4441 background: var(--surface-overlay);
4442 border-radius: var(--radius-sm);
4443 }
4444
4445 .timeline-slot-area {
4446 position: relative;
4447 cursor: grab;
4448 }
4449
4450 .timeline-slot-area:hover {
4451 background: var(--surface-overlay);
4452 }
4453
4454 .timeline-item {
4455 position: absolute;
4456 left: 60px;
4457 right: 10px;
4458 border: var(--border-width) solid var(--border);
4459 border-radius: var(--radius-sm);
4460 padding: 0.25rem 0.5rem;
4461 overflow: hidden;
4462 cursor: grab;
4463 z-index: 10;
4464 transition: opacity 0.15s ease, box-shadow 0.15s ease;
4465 }
4466
4467 .timeline-item.task {
4468 background: var(--success);
4469 color: var(--content);
4470 }
4471
4472 .timeline-item.event {
4473 background: var(--action);
4474 color: var(--content-on-action);
4475 }
4476
4477 .timeline-item.block {
4478 opacity: 0.85;
4479 }
4480
4481 .timeline-item.block-free_time {
4482 background: var(--category-six);
4483 color: var(--content);
4484 }
4485
4486 .timeline-item.block-personal {
4487 background: var(--warning);
4488 color: var(--content);
4489 }
4490
4491 .timeline-item.block-vacation {
4492 background: var(--category-five);
4493 color: var(--content-on-action);
4494 }
4495
4496 .timeline-item.block-focus {
4497 background: var(--danger);
4498 color: var(--content-on-action);
4499 }
4500
4501 .timeline-item.conflict {
4502 box-shadow: 0 0 0 3px var(--danger);
4503 }
4504
4505 .timeline-item.selected {
4506 box-shadow: 0 0 0 3px var(--surface-raised), 0 0 0 6px var(--action);
4507 }
4508
4509 .timeline-item-title {
4510 font-weight: 600;
4511 font-size: 0.75rem;
4512 line-height: 1.2;
4513 white-space: nowrap;
4514 overflow: hidden;
4515 text-overflow: ellipsis;
4516 }
4517
4518 .timeline-item-meta {
4519 font-size: 0.65rem;
4520 opacity: 0.85;
4521 line-height: 1.1;
4522 }
4523
4524 .timeline-current-time {
4525 position: absolute;
4526 left: 50px;
4527 right: 0;
4528 height: 2px;
4529 background: var(--danger);
4530 z-index: 20;
4531 pointer-events: none;
4532 }
4533
4534 .timeline-current-time::before {
4535 content: '';
4536 position: absolute;
4537 left: -4px;
4538 top: -3px;
4539 width: 8px;
4540 height: 8px;
4541 background: var(--danger);
4542 border-radius: var(--radius-full);
4543 }
4544
4545 /* Timeline Painting */
4546 .timeline-paint-preview {
4547 position: absolute;
4548 left: 70px;
4549 right: 10px;
4550 background: var(--action);
4551 opacity: 0.4;
4552 border: var(--border-width-sm) dashed var(--border);
4553 border-radius: var(--radius-sm);
4554 z-index: 5;
4555 pointer-events: none;
4556 }
4557
4558 .timeline-item.dragging {
4559 cursor: grabbing;
4560 opacity: 0.8;
4561 z-index: 100;
4562 box-shadow: var(--shadow-brutal-md, 4px 4px 0 var(--border));
4563 }
4564
4565 .timeline-container.is-painting {
4566 cursor: crosshair;
4567 user-select: none;
4568 }
4569
4570 .timeline-container.is-painting .timeline-slot-area {
4571 pointer-events: none;
4572 }
4573
4574 /* ===================================================================
4575 40. Unscheduled Tasks
4576 =================================================================== */
4577 .unscheduled-task {
4578 padding: 0.75rem;
4579 background: var(--surface-raised);
4580 border: var(--border-width-sm) solid var(--border);
4581 border-left: 6px solid var(--success);
4582 border-radius: var(--radius-sm);
4583 cursor: grab;
4584 transition: background-color 0.1s;
4585 }
4586
4587 .unscheduled-task:hover {
4588 background: var(--surface-overlay);
4589 }
4590
4591
4592 .unscheduled-task.priority-high {
4593 border-left-color: var(--danger);
4594 }
4595
4596 .unscheduled-task.priority-medium {
4597 border-left-color: var(--warning);
4598 }
4599
4600 .unscheduled-task.priority-low {
4601 border-left-color: var(--success);
4602 }
4603
4604 .unscheduled-task-title {
4605 font-weight: 600;
4606 margin-bottom: 0.25rem;
4607 white-space: nowrap;
4608 overflow: hidden;
4609 text-overflow: ellipsis;
4610 }
4611
4612 .unscheduled-task-meta {
4613 font-size: 0.75rem;
4614 color: var(--content-secondary);
4615 }
4616
4617 .empty-unscheduled {
4618 text-align: center;
4619 color: var(--content-secondary);
4620 padding: 2rem 1rem;
4621 }
4622
4623 /* ===================================================================
4624 41. Settings
4625 =================================================================== */
4626 /* Marker class on the header `?` button. Extends .btn with mono font and
4627 a fixed min-width so the single-character glyph stays centered. Mobile
4628 touch passes hide it (see §59 + body.is-touch rule below). */
4629 .shortcut-hint-btn {
4630 font-family: var(--font-mono, monospace);
4631 font-weight: 700;
4632 min-width: 2rem;
4633 padding: 0.5rem;
4634 }
4635
4636 .settings-section h3 {
4637 font-size: 1rem;
4638 color: var(--content);
4639 }
4640
4641 .settings-section .form-hint {
4642 font-size: 0.75rem;
4643 color: var(--content-secondary);
4644 }
4645
4646 /* Settings Overlay (Phase 7 Tier 6 — settings as modeless drawer) -----
4647 The settings panel now floats above whichever view the user came from,
4648 so theme/notification/account changes can be previewed against the
4649 actual app rather than a stand-alone settings page. Card is centered
4650 and keeps the original sidebar+content layout intact. */
4651 .settings-overlay {
4652 position: fixed;
4653 inset: 0;
4654 z-index: 70;
4655 display: flex;
4656 align-items: center;
4657 justify-content: center;
4658 padding: var(--space-4);
4659 }
4660 .settings-overlay.hidden {
4661 display: none;
4662 }
4663 .settings-overlay-backdrop {
4664 position: absolute;
4665 inset: 0;
4666 background: rgba(0, 0, 0, 0.35);
4667 }
4668 .settings-overlay-card {
4669 position: relative;
4670 background: var(--surface-page);
4671 border: 1px solid var(--border);
4672 border-radius: var(--radius-lg, 8px);
4673 box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
4674 width: min(960px, 100%);
4675 height: min(720px, 100%);
4676 max-height: calc(100vh - 2 * var(--space-4));
4677 overflow: hidden;
4678 display: flex;
4679 flex-direction: column;
4680 }
4681 .settings-overlay-card.hidden {
4682 display: none;
4683 }
4684 /* Duplicate of .sr-only (§26) deleted 2026-05-21; use .sr-only. */
4685 .ui-mode-mobile .settings-overlay { padding: 0; }
4686 .ui-mode-mobile .settings-overlay-card {
4687 width: 100%;
4688 height: 100%;
4689 max-height: 100%;
4690 border-radius: 0;
4691 border: none;
4692 }
4693
4694
4695 /* Settings Page Layout */
4696 .settings-page-layout {
4697 display: flex;
4698 min-height: 100%;
4699 }
4700
4701 .settings-sidebar {
4702 width: 200px;
4703 flex-shrink: 0;
4704 border-right: 1px solid var(--border);
4705 padding: 1.5rem 0;
4706 display: flex;
4707 flex-direction: column;
4708 gap: 0.25rem;
4709 }
4710
4711 .settings-nav-items {
4712 display: flex;
4713 flex-direction: column;
4714 gap: 0.125rem;
4715 }
4716
4717 .settings-nav-item {
4718 background: none;
4719 border: none;
4720 text-align: left;
4721 padding: 0.5rem 1.25rem;
4722 font-size: 0.875rem;
4723 color: var(--content-secondary);
4724 cursor: pointer;
4725 border-radius: 0;
4726 border-left: 2px solid transparent;
4727 }
4728 .settings-nav-item:hover { background: var(--hover-surface); color: var(--content); }
4729 .settings-nav-item.active {
4730 color: var(--content);
4731 font-weight: 600;
4732 border-left-color: var(--action);
4733 background: var(--surface-overlay);
4734 }
4735
4736 .settings-content {
4737 flex: 1;
4738 padding: 1.5rem 2rem;
4739 max-width: 640px;
4740 overflow-y: auto;
4741 }
4742
4743 /* Contact Dashboard */
4744 .contact-header-card {
4745 display: flex;
4746 align-items: center;
4747 gap: 1.25rem;
4748 margin-bottom: 1.5rem;
4749 }
4750
4751
4752 /* Base chrome from .card.card--muted; only feature-specific spacing
4753 (gap, margin, tighter padding) remains here. */
4754 .contact-info-section {
4755 display: flex;
4756 flex-direction: column;
4757 gap: 0.375rem;
4758 margin-bottom: 1.5rem;
4759 padding: 1rem;
4760 }
4761
4762 .contact-info-item {
4763 font-size: 0.875rem;
4764 }
4765
4766 .contact-dashboard-summary {
4767 display: flex;
4768 gap: 1.5rem;
4769 margin-bottom: 1.5rem;
4770 }
4771
4772 .contact-summary-stat {
4773 display: flex;
4774 flex-direction: column;
4775 align-items: center;
4776 padding: 0.75rem 1.25rem;
4777 background: var(--surface-overlay);
4778 border-radius: var(--radius-md);
4779 min-width: 80px;
4780 }
4781
4782 .contact-summary-count {
4783 font-size: 1.5rem;
4784 font-weight: 700;
4785 color: var(--content);
4786 }
4787
4788 .contact-summary-label {
4789 font-size: 0.75rem;
4790 color: var(--content-secondary);
4791 margin-top: 0.25rem;
4792 }
4793
4794 .contact-timeline {
4795 display: flex;
4796 flex-direction: column;
4797 gap: 0.25rem;
4798 }
4799
4800 /* Compose with `row-flex row-flex-3` for the row. */
4801 .contact-timeline-item {
4802 padding: 0.5rem 0.75rem;
4803 border-radius: var(--radius-sm);
4804 cursor: pointer;
4805 font-size: 0.875rem;
4806 }
4807
4808 .contact-timeline-item:hover {
4809 background: var(--hover-surface);
4810 }
4811
4812 .contact-timeline-icon {
4813 flex-shrink: 0;
4814 width: 2rem;
4815 text-align: center;
4816 font-size: 0.8rem;
4817 }
4818
4819 .contact-timeline-title {
4820 flex: 1;
4821 overflow: hidden;
4822 text-overflow: ellipsis;
4823 white-space: nowrap;
4824 }
4825
4826 .contact-timeline-date {
4827 flex-shrink: 0;
4828 font-size: 0.75rem;
4829 color: var(--content-secondary);
4830 }
4831
4832 /* Address Highlight Mirror */
4833 .address-highlight-mirror {
4834 position: absolute;
4835 top: 0;
4836 left: 0;
4837 right: 0;
4838 bottom: 0;
4839 pointer-events: none;
4840 white-space: nowrap;
4841 overflow: hidden;
4842 z-index: 0;
4843 display: flex;
4844 align-items: center;
4845 }
4846
4847 .addr-malformed { color: var(--danger); }
4848 .addr-contact { color: var(--action); }
4849 .addr-verified { color: var(--success); }
4850 .addr-ghost { color: var(--content-muted); opacity: 0.5; }
4851
4852 /* Sync Status Indicator */
4853 /* Compose with `row-flex row-flex-2` for the row. */
4854 .sync-indicator {
4855 background: none;
4856 border: none;
4857 cursor: pointer;
4858 padding: 0.25rem 0.5rem;
4859 border-radius: var(--radius-sm);
4860 transition: background var(--transition-fast);
4861 }
4862 .sync-indicator:hover { background: var(--hover-surface); }
4863 .sync-dot {
4864 width: 8px;
4865 height: 8px;
4866 border-radius: var(--radius-full);
4867 background: var(--content-muted);
4868 transition: background var(--transition-slow);
4869 flex-shrink: 0;
4870 }
4871 .sync-dot.connected { background: var(--success); }
4872 .sync-dot.syncing { background: var(--info); animation: sync-pulse 1s infinite; }
4873 .sync-dot.warn { background: var(--warning); border-radius: 0; transform: rotate(45deg); }
4874 .sync-dot.error { background: var(--danger); border-radius: 0; }
4875
4876 /* Status label — always shown at desktop widths so color isn't the sole signal.
4877 Hidden on narrow widths to save space; hover still surfaces the title attr. */
4878 .sync-label {
4879 font-size: var(--font-size-sm);
4880 color: var(--content-secondary);
4881 white-space: nowrap;
4882 }
4883 /* Sync label hides in mobile UI; desktop keeps it at any width. */
4884 .ui-mode-mobile .sync-label { display: none; }
4885 @keyframes sync-pulse {
4886 0%, 100% { opacity: 1; }
4887 50% { opacity: 0.4; }
4888 }
4889
4890 /* ===================================================================
4891 42. Snooze Options
4892 =================================================================== */
4893 .snooze-options {
4894 display: flex;
4895 flex-direction: column;
4896 gap: 0.5rem;
4897 }
4898
4899 .snooze-option {
4900 display: flex;
4901 justify-content: space-between;
4902 align-items: center;
4903 padding: 0.75rem 1rem;
4904 background: var(--surface-overlay);
4905 border: var(--border-width-sm) solid var(--border);
4906 color: var(--content);
4907 cursor: pointer;
4908 transition: background-color 0.1s;
4909 text-align: left;
4910 width: 100%;
4911 }
4912
4913 .snooze-option:hover {
4914 background: var(--action);
4915 color: var(--content-on-action);
4916 }
4917
4918 .snooze-option-label {
4919 font-weight: 600;
4920 }
4921
4922 .snooze-option-time {
4923 font-size: 0.75rem;
4924 color: var(--content-secondary);
4925 }
4926
4927 .snooze-option:hover .snooze-option-time {
4928 color: var(--content-on-action);
4929 }
4930
4931 .snooze-custom {
4932 margin-top: 0.5rem;
4933 padding-top: 0.5rem;
4934 border-top: 2px solid var(--border);
4935 }
4936
4937 .snooze-badge {
4938 display: inline-block;
4939 font-size: 0.65rem;
4940 padding: 0.15rem 0.4rem;
4941 border: var(--border-width-sm) solid var(--border);
4942 background: var(--warning);
4943 color: var(--content);
4944 font-weight: 700;
4945 margin-top: 0.25rem;
4946 }
4947
4948 .contact-badge {
4949 display: inline-block;
4950 font-size: 0.65rem;
4951 padding: 0.15rem 0.4rem;
4952 border: var(--border-width-sm) solid var(--border);
4953 background: var(--action);
4954 color: var(--surface-page);
4955 font-weight: 700;
4956 margin-top: 0.25rem;
4957 }
4958
4959 /* ===================================================================
4960 43. Bulk Selection
4961 =================================================================== */
4962 .bulk-checkbox {
4963 width: 18px;
4964 height: 18px;
4965 cursor: pointer;
4966 accent-color: var(--action);
4967 border: var(--border-width-sm) solid var(--border);
4968 }
4969
4970 .task-actions-cell {
4971 text-align: right;
4972 white-space: nowrap;
4973 display: flex;
4974 align-items: center;
4975 justify-content: flex-end;
4976 gap: 0.5rem;
4977 }
4978
4979 .task-actions-cell .bulk-checkbox {
4980 margin-right: 0.5rem;
4981 }
4982
4983 /* Kebab menu button — extends .btn-icon with hover-reveal + bigger font. */
4984 .kebab-btn {
4985 font-size: 1.1rem;
4986 padding: 0.2rem 0.4rem;
4987 border-radius: var(--radius-sm);
4988 color: var(--content-secondary);
4989 opacity: 0;
4990 transition: opacity 0.15s ease;
4991 }
4992
4993 .task-row:hover .kebab-btn,
4994 .task-row:focus-within .kebab-btn,
4995 .email-item:hover .kebab-btn,
4996 .email-item:focus-within .kebab-btn,
4997 .event-row-virtual:hover .kebab-btn,
4998 .event-row-virtual:focus-within .kebab-btn {
4999 opacity: 1;
5000 }
5001
5002 .kebab-btn:hover {
5003 background: var(--hover-surface);
5004 }
5005
5006 .task-recurrence {
5007 font-size: 0.85rem;
5008 color: var(--content-secondary);
5009 }
5010
5011 .task-due {
5012 white-space: nowrap;
5013 }
5014
5015 .bulk-actions-bar {
5016 display: flex;
5017 align-items: center;
5018 gap: 0.5rem;
5019 padding: 0.75rem 1rem;
5020 background: var(--action);
5021 color: var(--content-on-action);
5022 border: var(--border-width) solid var(--border);
5023 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
5024 margin-bottom: 1rem;
5025 }
5026
5027 .bulk-actions-bar.hidden {
5028 display: none;
5029 }
5030
5031 .bulk-count {
5032 font-weight: 700;
5033 margin-right: 1rem;
5034 font-family: var(--font-heading);
5035 }
5036
5037 .bulk-actions-bar .btn {
5038 background: var(--surface-raised);
5039 border: var(--border-width-sm) solid var(--border);
5040 color: var(--content);
5041 }
5042
5043 .bulk-actions-bar .btn:hover {
5044 background: var(--surface-overlay);
5045 }
5046
5047 .bulk-select-all {
5048 margin-left: auto;
5049 }
5050
5051 .email-checkbox-cell {
5052 padding: 0.75rem 0.5rem;
5053 display: flex;
5054 align-items: center;
5055 }
5056
5057 .email-item-with-checkbox {
5058 display: flex;
5059 align-items: flex-start;
5060 }
5061
5062 .email-item-with-checkbox .email-content {
5063 flex: 1;
5064 }
5065
5066 /* ===================================================================
5067 44. Time Blocking
5068 =================================================================== */
5069 .time-block-form {
5070 display: flex;
5071 flex-direction: column;
5072 gap: 1rem;
5073 }
5074
5075 .time-block-quick-options {
5076 display: grid;
5077 grid-template-columns: repeat(3, 1fr);
5078 gap: 0.5rem;
5079 }
5080
5081 /* Selected state for quick-pick time slots. Base styling comes from .btn.btn-sm.btn-secondary. */
5082 .time-block-quick-btn.selected {
5083 background: var(--action);
5084 color: var(--content-on-action);
5085 box-shadow: inset 0 0 0 2px var(--border);
5086 }
5087
5088 .duration-presets {
5089 display: flex;
5090 gap: 0.5rem;
5091 flex-wrap: wrap;
5092 }
5093
5094 .duration-preset {
5095 padding: 0.35rem 0.75rem;
5096 background: var(--surface-overlay);
5097 border: var(--border-width-sm) solid var(--border);
5098 color: var(--content);
5099 cursor: pointer;
5100 font-size: 0.75rem;
5101 font-weight: 600;
5102 transition: background-color 0.1s;
5103 }
5104
5105 .duration-preset:hover {
5106 background: var(--surface-sunken);
5107 }
5108
5109 .duration-preset.selected {
5110 background: var(--action);
5111 color: var(--content-on-action);
5112 }
5113
5114 .conflict-warning {
5115 padding: 0.75rem;
5116 background: var(--danger);
5117 border: var(--border-width) solid var(--border);
5118 color: var(--content-on-action);
5119 font-size: 0.875rem;
5120 font-weight: 600;
5121 margin-top: 0.5rem;
5122 }
5123
5124 /* ===================================================================
5125 45. App Layout
5126 =================================================================== */
5127 .app-body {
5128 display: flex;
5129 flex: 1;
5130 min-height: 0;
5131 overflow: hidden;
5132 }
5133
5134 /* Adjust main content to work with sidebar */
5135 .app-body .main-content {
5136 flex: 1;
5137 min-width: 0;
5138 display: flex;
5139 flex-direction: column;
5140 overflow-x: visible;
5141 overflow-y: auto;
5142 }
5143
5144 /* All views fill available space */
5145 #tasks-view,
5146 #events-view,
5147 #projects-view,
5148 #emails-view {
5149 padding-bottom: 2.5rem;
5150 }
5151
5152 /* Task view fills available height */
5153 #tasks-view {
5154 display: flex;
5155 flex-direction: column;
5156 flex: 1;
5157 min-height: 0;
5158 }
5159
5160 #tasks-view .page-header,
5161 #tasks-view .bulk-actions-bar,
5162 #tasks-view .filter-bar {
5163 flex-shrink: 0;
5164 }
5165
5166 /* Events view fills available height */
5167 #events-view {
5168 display: flex;
5169 flex-direction: column;
5170 flex: 1;
5171 min-height: 0;
5172 }
5173
5174 #events-view .page-header {
5175 flex-shrink: 0;
5176 }
5177
5178 /* Emails view fills available height */
5179 #emails-view {
5180 display: flex;
5181 flex-direction: column;
5182 flex: 1;
5183 min-height: 0;
5184 }
5185
5186 /* Email filter row: search input flexes; selects + count are content-sized.
5187 Grid columns make the geometry explicit and immune to <select> intrinsic
5188 min-content shenanigans that flex layout exposes. */
5189 .email-filter-row {
5190 display: grid;
5191 grid-template-columns: minmax(0, 1fr) auto auto auto;
5192 gap: var(--space-2);
5193 align-items: center;
5194 }
5195 .email-filter-row > .form-input,
5196 .email-filter-row > .form-select {
5197 width: 100%;
5198 min-width: 0;
5199 }
5200 .email-filter-row > .form-select {
5201 width: 9rem;
5202 }
5203
5204 /* Contacts filter row: same shape as .email-filter-row (search fills,
5205 filter sizes to content, action button sizes to content). Tag filter
5206 uses .filter-select rather than .form-select, but the layout rule is
5207 identical. */
5208 .contacts-filter-row {
5209 display: grid;
5210 grid-template-columns: minmax(0, 1fr) auto auto;
5211 gap: var(--space-2);
5212 align-items: center;
5213 }
5214 .contacts-filter-row > .form-input {
5215 width: 100%;
5216 min-width: 0;
5217 }
5218 .contacts-filter-row > .filter-select {
5219 width: 9rem;
5220 min-width: 0;
5221 }
5222
5223 /* Work-hours row in Settings: two small selects with a "to" label
5224 between. Same lens as .email-filter-row — selects size to their
5225 short content; the grid columns express the intent explicitly. */
5226 .work-hours-row {
5227 display: grid;
5228 grid-template-columns: auto auto auto;
5229 gap: var(--space-2);
5230 align-items: center;
5231 }
5232 .work-hours-row > .form-select {
5233 width: auto;
5234 }
5235
5236 #emails-view .page-header,
5237 #emails-view .bulk-actions-bar {
5238 flex-shrink: 0;
5239 }
5240
5241 /* ===================================================================
5242 46. Saved Views Sidebar (desktop UI only — hidden on mobile)
5243 =================================================================== */
5244 .ui-mode-desktop .saved-views-sidebar {
5245 width: 200px;
5246 flex-shrink: 0;
5247 background: var(--surface-raised);
5248 border-right: var(--border-width) solid var(--border);
5249 display: flex;
5250 flex-direction: column;
5251 overflow: hidden;
5252 }
5253
5254 .sidebar-section {
5255 display: flex;
5256 flex-direction: column;
5257 flex: 1;
5258 min-height: 0;
5259 }
5260
5261 .sidebar-section-header {
5262 display: flex;
5263 justify-content: space-between;
5264 align-items: center;
5265 padding: 0.75rem 1rem;
5266 font-size: 0.75rem;
5267 font-weight: 700;
5268 text-transform: uppercase;
5269 letter-spacing: 0.05em;
5270 color: var(--content-secondary);
5271 border-bottom: 2px solid var(--border);
5272 background: var(--surface-overlay);
5273 }
5274
5275 .btn-icon {
5276 background: none;
5277 border: none;
5278 color: var(--content-muted);
5279 cursor: pointer;
5280 padding: 0.25rem;
5281 font-size: 0.875rem;
5282 line-height: 1;
5283 }
5284
5285 .btn-icon:hover {
5286 color: var(--content);
5287 }
5288
5289 .pinned-views-list {
5290 flex: 1;
5291 overflow-y: auto;
5292 padding: 0.5rem;
5293 }
5294
5295 .sidebar-empty {
5296 text-align: center;
5297 padding: 1.5rem 0.5rem;
5298 color: var(--content-muted);
5299 font-size: 0.8rem;
5300 }
5301
5302 .saved-view-item {
5303 display: flex;
5304 align-items: center;
5305 gap: 0.5rem;
5306 padding: 0.5rem 0.75rem;
5307 margin-bottom: 0.5rem;
5308 background: var(--surface-raised);
5309 border: var(--border-width-sm) solid var(--border);
5310 border-radius: var(--radius-sm);
5311 cursor: pointer;
5312 font-size: 0.85rem;
5313 font-weight: 600;
5314 color: var(--content);
5315 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
5316 transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease, color 0.15s ease;
5317 }
5318
5319 .saved-view-item:hover {
5320 background: var(--action);
5321 color: var(--content-on-action);
5322 }
5323
5324 .saved-view-item.active {
5325 background: var(--action);
5326 color: var(--content-on-action);
5327 box-shadow: inset 0 0 0 2px var(--border);
5328 }
5329
5330 .saved-view-item .view-icon {
5331 font-size: 0.75rem;
5332 }
5333
5334 .saved-view-item .view-name {
5335 flex: 1;
5336 white-space: nowrap;
5337 overflow: hidden;
5338 text-overflow: ellipsis;
5339 }
5340
5341 .saved-view-item .view-actions {
5342 opacity: 0;
5343 transition: opacity 0.1s;
5344 }
5345
5346 .saved-view-item:hover .view-actions {
5347 opacity: 1;
5348 }
5349
5350 /* Filter actions in filter bar */
5351 .filter-actions {
5352 display: flex;
5353 gap: 0.5rem;
5354 margin-left: auto;
5355 }
5356
5357 /* ===================================================================
5358 47. Contacts
5359 =================================================================== */
5360 /* Avatar primitive — circular badge with initials. Default 40px with
5361 border; size + unknown modifiers compose. */
5362 .avatar {
5363 width: 40px;
5364 height: 40px;
5365 min-width: 40px;
5366 border-radius: 50%;
5367 background-color: var(--action);
5368 color: var(--content-on-action);
5369 display: flex;
5370 align-items: center;
5371 justify-content: center;
5372 font-weight: 700;
5373 font-size: 0.85rem;
5374 font-family: var(--font-heading);
5375 border: var(--border-width-sm) solid var(--border);
5376 flex-shrink: 0;
5377 }
5378 .avatar--sm { width: 32px; height: 32px; min-width: 32px; font-size: 0.75rem; border: none; }
5379 .avatar--lg { width: 60px; height: 60px; min-width: 60px; font-size: 1.2rem; }
5380 .avatar--unknown { background: var(--surface-overlay); color: var(--content-secondary); }
5381
5382 .contact-card .card-header {
5383 display: flex;
5384 align-items: center;
5385 }
5386
5387 .contact-nickname {
5388 display: block;
5389 font-size: 0.85rem;
5390 color: var(--content-secondary);
5391 font-style: italic;
5392 }
5393
5394 .contact-company {
5395 display: block;
5396 font-size: 0.85rem;
5397 color: var(--content-secondary);
5398 }
5399
5400 .contact-email {
5401 font-size: 0.85rem;
5402 color: var(--content-secondary);
5403 }
5404
5405 .contact-detail .detail-row {
5406 margin-bottom: 0.5rem;
5407 font-size: 0.9rem;
5408 }
5409
5410 .contact-detail .contact-info-section {
5411 margin-bottom: 1rem;
5412 padding-bottom: 1rem;
5413 border-bottom: 1px solid var(--surface-sunken);
5414 }
5415
5416 .contact-detail .contact-notes {
5417 margin-bottom: 1.5rem;
5418 }
5419
5420 .contact-detail .contact-notes p {
5421 margin-top: 0.25rem;
5422 white-space: pre-wrap;
5423 color: var(--content-secondary);
5424 }
5425
5426 .sub-collection {
5427 margin-bottom: 1.25rem;
5428 }
5429
5430 .sub-collection-header {
5431 display: flex;
5432 justify-content: space-between;
5433 align-items: center;
5434 margin-bottom: 0.5rem;
5435 }
5436
5437 .sub-collection-header h4 {
5438 margin: 0;
5439 font-size: 0.95rem;
5440 font-weight: 600;
5441 }
5442
5443 .sub-item {
5444 display: flex;
5445 justify-content: space-between;
5446 align-items: center;
5447 padding: 0.4rem 0;
5448 border-bottom: 1px solid var(--surface-sunken);
5449 font-size: 0.9rem;
5450 }
5451
5452 .sub-item:last-child {
5453 border-bottom: none;
5454 }
5455
5456 .sub-empty {
5457 font-size: 0.85rem;
5458 color: var(--content-secondary);
5459 font-style: italic;
5460 padding: 0.25rem 0;
5461 }
5462
5463 /* Edit form sub-collection summaries */
5464 .edit-sub-collections {
5465 border-top: 1px solid var(--border);
5466 padding-top: 1rem;
5467 margin-bottom: 0.5rem;
5468 }
5469
5470 .edit-sub-section {
5471 margin-bottom: 0.75rem;
5472 }
5473
5474 .edit-sub-header {
5475 display: flex;
5476 justify-content: space-between;
5477 align-items: center;
5478 margin-bottom: 0.25rem;
5479 }
5480
5481 .sub-item-compact {
5482 font-size: 0.85rem;
5483 color: var(--content-secondary);
5484 padding: 0.125rem 0;
5485 display: flex;
5486 align-items: center;
5487 gap: var(--space-2);
5488 justify-content: space-between;
5489 }
5490 .sub-item-actions {
5491 display: inline-flex;
5492 gap: var(--space-1);
5493 flex-shrink: 0;
5494 }
5495 .reminder-options {
5496 display: flex;
5497 flex-wrap: wrap;
5498 gap: var(--space-2) var(--space-4);
5499 margin-top: var(--space-2);
5500 }
5501 .reminder-option {
5502 display: inline-flex;
5503 align-items: center;
5504 gap: var(--space-2);
5505 font-size: var(--font-size-sm);
5506 color: var(--content-secondary);
5507 cursor: pointer;
5508 }
5509
5510 /* Task detail drawer (Phase 7 Tier 6) ---------------------------------
5511 Right-anchored slide-in overlay so users can scan the list and read
5512 one task's full detail without losing list scroll position. Falls back
5513 to a full-screen sheet on narrow viewports. */
5514 .task-drawer {
5515 position: fixed;
5516 top: 0;
5517 right: 0;
5518 bottom: 0;
5519 width: min(480px, 100vw);
5520 background: var(--surface-page);
5521 border-left: 1px solid var(--border);
5522 box-shadow: -4px 0 18px rgba(0, 0, 0, 0.18);
5523 transform: translateX(100%);
5524 transition: transform 180ms ease-out;
5525 z-index: 60;
5526 display: flex;
5527 flex-direction: column;
5528 overflow: hidden;
5529 }
5530 .task-drawer.visible {
5531 transform: translateX(0);
5532 }
5533 .task-drawer-header {
5534 display: flex;
5535 align-items: center;
5536 gap: var(--space-3);
5537 padding: var(--space-3) var(--space-4);
5538 border-bottom: 1px solid var(--border);
5539 background: var(--surface-overlay);
5540 flex-shrink: 0;
5541 }
5542 .task-drawer-title {
5543 flex: 1;
5544 margin: 0;
5545 font-size: var(--font-size-lg, 1.05rem);
5546 font-weight: 500;
5547 overflow: hidden;
5548 text-overflow: ellipsis;
5549 white-space: nowrap;
5550 }
5551 .task-drawer-close {
5552 flex-shrink: 0;
5553 }
5554 .task-drawer-actions {
5555 display: flex;
5556 gap: var(--space-2);
5557 flex-shrink: 0;
5558 }
5559 .task-drawer-content {
5560 flex: 1;
5561 overflow-y: auto;
5562 padding: var(--space-4);
5563 }
5564 /* Mark the row whose task is currently open in the drawer. */
5565 .task-row--active {
5566 background: var(--surface-overlay);
5567 box-shadow: inset 3px 0 0 var(--action);
5568 }
5569 .ui-mode-mobile .task-drawer {
5570 width: 100vw;
5571 border-left: none;
5572 }
5573
5574
5575 /* ===================================================================
5576 48. Print Styles (global + weekly review)
5577 ===================================================================
5578 All `@media print` rules live here. Weekly-review-specific print
5579 styles consolidated from former §52 on 2026-05-24. */
5580 @media print {
5581 /* ----- Global chrome ----- */
5582
5583 /* Hide navigation and interactive elements */
5584 .sidebar,
5585 .header,
5586 .tabs,
5587 .tab-nav,
5588 .filter-bar,
5589 .pagination,
5590 .btn,
5591 .modal-overlay,
5592 .toast,
5593 .context-menu,
5594 .keyboard-hints,
5595 .review-actions-grid,
5596 .focus-section .btn,
5597 .focus-slot .btn,
5598 .tab-badge,
5599 .tab-status-dot,
5600 .card-badge,
5601 .virtual-scroller-spacer {
5602 display: none !important;
5603 }
5604
5605 /* Reset body + main content to full width */
5606 body {
5607 background: white;
5608 color: black;
5609 }
5610
5611 .main-content,
5612 .weekly-review-content {
5613 margin: 0;
5614 padding: 0;
5615 max-width: 100%;
5616 width: 100%;
5617 }
5618
5619 .view {
5620 padding: 0;
5621 }
5622
5623 /* Ensure text is readable */
5624 a {
5625 color: black;
5626 text-decoration: underline;
5627 }
5628
5629 /* ----- Tables ----- */
5630
5631 .data-table,
5632 .task-table {
5633 border: 1px solid #333;
5634 box-shadow: none;
5635 }
5636
5637 .data-table {
5638 page-break-inside: avoid;
5639 }
5640
5641 .data-table th,
5642 .data-table td {
5643 border: 1px solid #ccc;
5644 padding: 0.5rem;
5645 display: table-cell !important;
5646 }
5647
5648 .data-table tbody tr:hover,
5649 .task-row:hover {
5650 background: none;
5651 }
5652
5653 .task-list-container {
5654 height: auto !important;
5655 overflow: visible !important;
5656 }
5657
5658 .task-header-row,
5659 .task-row {
5660 grid-template-columns: 1fr 100px 40px 80px 60px 80px 60px !important;
5661 }
5662
5663 .task-header-row .task-cell,
5664 .task-row .task-cell {
5665 display: block !important;
5666 border: 1px solid #ccc;
5667 padding: 0.25rem 0.5rem;
5668 }
5669
5670 .view-header {
5671 page-break-after: avoid;
5672 }
5673
5674 /* ----- Weekly review ----- */
5675
5676 /* Reset backgrounds for print */
5677 body,
5678 .weekly-review-content,
5679 .review-card,
5680 .focus-slot,
5681 .reflection-prompt,
5682 .project-health,
5683 .event-item {
5684 background: white !important;
5685 color: black !important;
5686 -webkit-print-color-adjust: exact;
5687 print-color-adjust: exact;
5688 }
5689
5690 /* Print-friendly card chrome */
5691 .review-card {
5692 border: 1px solid #ccc !important;
5693 box-shadow: none !important;
5694 page-break-inside: avoid;
5695 margin-bottom: 1rem;
5696 }
5697
5698 .focus-slot {
5699 border: 1px solid #999 !important;
5700 }
5701
5702 .focus-slot.primary {
5703 border: 2px solid #f7d154 !important;
5704 background: #fffbea !important;
5705 }
5706
5707 /* Two-column print layout */
5708 .review-grid {
5709 display: block !important;
5710 }
5711
5712 .review-card {
5713 display: inline-block;
5714 vertical-align: top;
5715 width: 48%;
5716 margin-right: 2%;
5717 }
5718
5719 .focus-section.full-width,
5720 .reflection-section,
5721 .week-timeline,
5722 .week-timeline-events {
5723 width: 100% !important;
5724 display: block !important;
5725 }
5726
5727 /* Print header */
5728 .weekly-review-header {
5729 border-bottom: 2px solid #333;
5730 padding-bottom: 1rem;
5731 margin-bottom: 1.5rem;
5732 }
5733
5734 .week-dates {
5735 font-size: 1.5rem;
5736 font-weight: bold;
5737 }
5738
5739 /* Timeline dots print in color */
5740 .day-dot {
5741 -webkit-print-color-adjust: exact;
5742 print-color-adjust: exact;
5743 }
5744
5745 .day-dot.completed {
5746 background: #5cb85c !important;
5747 }
5748
5749 .day-dot.event {
5750 background: #9b59b6 !important;
5751 }
5752
5753 .day-dot.overdue {
5754 background: #d9534f !important;
5755 }
5756
5757 /* Project health colors */
5758 .project-health {
5759 border-left: 4px solid #337ab7 !important;
5760 }
5761
5762 .project-health.warning {
5763 border-left-color: #f7d154 !important;
5764 }
5765
5766 .project-health.danger {
5767 border-left-color: #d9534f !important;
5768 }
5769
5770 /* Focus grid for print */
5771 .focus-grid {
5772 display: flex !important;
5773 gap: 1rem;
5774 }
5775
5776 .focus-slot {
5777 flex: 1;
5778 }
5779
5780 /* Reflection prompts */
5781 .reflection-prompts {
5782 display: flex !important;
5783 gap: 1rem;
5784 }
5785
5786 .reflection-prompt {
5787 flex: 1;
5788 }
5789
5790 .prompt-input {
5791 border: 1px solid #ccc !important;
5792 min-height: 80px;
5793 }
5794
5795 /* Page break hints */
5796 .focus-section {
5797 page-break-before: auto;
5798 }
5799
5800 .reflection-section {
5801 page-break-before: always;
5802 }
5803 }
5804
5805 /* ===================================================================
5806 49. Weekly Review — chrome around the V2 grid + tab indicators
5807 ===================================================================
5808 The V1 grid layout (stat cards, review sections, focus toggle, notes
5809 textarea, etc.) was removed 2026-05-24 after V2 took over rendering
5810 in `weekly-review-render.js`. What remains here is the outer chrome
5811 (header, status pill, focus background gradient) still composed by
5812 `weekly-review.js`, plus tab indicators (`.tab-badge`,
5813 `.tab-status-dot`) consumed by tab nav + events.js. */
5814
5815 .weekly-review-content {
5816 max-width: 900px;
5817 margin: 0 auto;
5818 padding: 1rem;
5819 }
5820
5821 .weekly-review-header {
5822 display: flex;
5823 justify-content: space-between;
5824 align-items: center;
5825 margin-bottom: 1.5rem;
5826 padding-bottom: 1rem;
5827 border-bottom: var(--border-width-sm) solid var(--border);
5828 }
5829
5830 .week-dates {
5831 font-family: var(--font-heading);
5832 font-size: 1.25rem;
5833 font-weight: 700;
5834 color: var(--content);
5835 }
5836
5837 .review-status {
5838 padding: 0.25rem 0.75rem;
5839 border-radius: var(--radius-xs);
5840 font-size: 0.875rem;
5841 font-weight: 600;
5842 border: var(--border-width-sm) solid var(--border);
5843 }
5844
5845 .review-status.completed {
5846 background: var(--success);
5847 color: var(--content-on-action);
5848 }
5849
5850 .review-status.pending {
5851 background: var(--warning);
5852 color: var(--content);
5853 }
5854
5855 .review-status.unreviewed {
5856 background: var(--surface-overlay);
5857 color: var(--content-muted);
5858 }
5859
5860 /* Event time pill — used in the week timeline + finish-review timeline event list. */
5861 .event-time {
5862 font-size: 0.875rem;
5863 font-weight: 600;
5864 color: var(--content-muted);
5865 min-width: 80px;
5866 }
5867
5868 /* Focus section background — applied on top of the .card.card--static.review-card
5869 composition for the focus scope card in the V2 grid. */
5870 .focus-section {
5871 background: linear-gradient(135deg, var(--surface-raised) 0%, color-mix(in srgb, var(--warning) 15%, var(--surface-raised)) 100%);
5872 }
5873
5874 /* Tab Badge (for nudge) */
5875 .tab-badge {
5876 display: inline-block;
5877 width: 8px;
5878 height: 8px;
5879 background: var(--danger);
5880 border-radius: var(--radius-full);
5881 margin-left: 0.5rem;
5882 vertical-align: middle;
5883 animation: pulse-badge 2s infinite;
5884 }
5885
5886 @keyframes pulse-badge {
5887 0%, 100% {
5888 opacity: 1;
5889 transform: scale(1);
5890 }
5891 50% {
5892 opacity: 0.6;
5893 transform: scale(0.8);
5894 }
5895 }
5896
5897 .tab-status-dot {
5898 width: 8px;
5899 height: 8px;
5900 border-radius: 50%;
5901 display: inline-block;
5902 margin-left: 0.5rem;
5903 vertical-align: middle;
5904 transition: background-color 0.3s ease;
5905 }
5906 .tab-status-dot.status-none { display: none; }
5907 .tab-status-dot.status-green { background-color: var(--success); }
5908 .tab-status-dot.status-yellow { background-color: var(--warning); animation: pulse-badge 2s ease-in-out infinite; }
5909 .tab-status-dot.status-red { background-color: var(--danger); animation: pulse-badge 1.5s ease-in-out infinite; }
5910
5911 /* ===================================================================
5912 50. Weekly Review V2 - Grid Layout
5913 =================================================================== */
5914
5915 /* Main Grid Layout */
5916 .review-grid {
5917 display: grid;
5918 grid-template-columns: 1fr 1fr;
5919 gap: 1.5rem;
5920 max-width: 1200px;
5921 margin: 0 auto;
5922 }
5923
5924 /* Review Cards — marker class for review-specific scoping. Callsites compose
5925 `.card .card--static .review-card`; chrome inherits from .card. Only the
5926 padding bump (+0.25rem) and the review-scoped descendants live here. */
5927 .review-card {
5928 padding: 1.5rem;
5929 }
5930
5931 .review-card .card-header {
5932 align-items: center;
5933 padding-bottom: 0.75rem;
5934 border-bottom: var(--border-width-sm) solid var(--surface-overlay);
5935 }
5936
5937 .review-card .card-title {
5938 display: flex;
5939 align-items: center;
5940 gap: 0.5rem;
5941 }
5942
5943 .review-card .card-icon {
5944 font-size: 1.25rem;
5945 }
5946
5947 .review-card .card-badge {
5948 font-size: 0.8rem;
5949 padding: 0.25rem 0.75rem;
5950 border-radius: var(--radius-md);
5951 font-weight: 600;
5952 }
5953
5954 /* Week Timeline - spans full width */
5955 .week-timeline {
5956 grid-column: 1 / -1;
5957 }
5958
5959 .timeline-visual {
5960 display: flex;
5961 gap: 0.5rem;
5962 margin-top: 1rem;
5963 }
5964
5965 .timeline-day {
5966 flex: 1;
5967 text-align: center;
5968 padding: 0.75rem 0.5rem;
5969 background: var(--surface-overlay);
5970 border-radius: var(--radius-md);
5971 border: 1px solid var(--border);
5972 position: relative;
5973 }
5974
5975 .timeline-day.today {
5976 background: var(--action);
5977 color: var(--content-on-action);
5978 border-width: 2px;
5979 font-weight: 700;
5980 }
5981
5982 .timeline-day.past {
5983 opacity: 0.7;
5984 }
5985
5986 .timeline-day.future {
5987 background: var(--surface-raised);
5988 }
5989
5990 .timeline-day .day-name {
5991 font-size: 0.7rem;
5992 font-weight: 600;
5993 text-transform: uppercase;
5994 color: var(--content-muted);
5995 }
5996
5997 .timeline-day .day-number {
5998 font-size: 1.1rem;
5999 font-weight: 700;
6000 }
6001
6002 .day-dots {
6003 display: flex;
6004 justify-content: center;
6005 gap: 3px;
6006 margin-top: 0.5rem;
6007 min-height: 8px;
6008 }
6009
6010 .day-dot {
6011 width: 8px;
6012 height: 8px;
6013 border-radius: var(--radius-full);
6014 }
6015
6016 .day-dot.task { background: var(--action); }
6017 .day-dot.event { background: var(--category-five); }
6018 .day-dot.completed { background: var(--success); }
6019 .day-dot.overdue { background: var(--danger); }
6020 .day-dot.vacation-off {
6021 background: var(--content-muted);
6022 opacity: 0.5;
6023 width: 12px;
6024 height: 4px;
6025 border-radius: 2px;
6026 }
6027
6028 /* Day Events (inline on timeline strip) */
6029 .day-events {
6030 display: flex;
6031 flex-direction: column;
6032 gap: 2px;
6033 margin-top: 0.5rem;
6034 text-align: left;
6035 }
6036
6037 .day-event {
6038 font-size: 0.6rem;
6039 line-height: 1.3;
6040 padding: 1px 4px;
6041 border-left: 2px solid var(--category-five);
6042 white-space: nowrap;
6043 overflow: hidden;
6044 text-overflow: ellipsis;
6045 color: var(--content-secondary);
6046 }
6047
6048 .day-event .event-time {
6049 font-size: 0.55rem;
6050 font-weight: 600;
6051 color: var(--category-five);
6052 margin-right: 2px;
6053 min-width: auto;
6054 }
6055
6056 .day-event-more {
6057 font-size: 0.55rem;
6058 color: var(--content-muted);
6059 padding: 1px 4px;
6060 font-style: italic;
6061 }
6062
6063 /* Week's Events Card (below timeline) */
6064 .week-timeline-events {
6065 grid-column: 1 / -1;
6066 }
6067
6068 .timeline-events-day {
6069 margin-bottom: 0.75rem;
6070 }
6071
6072 .timeline-events-day:last-child {
6073 margin-bottom: 0;
6074 }
6075
6076 .timeline-events-day-label {
6077 font-family: var(--font-heading);
6078 font-size: 0.8rem;
6079 font-weight: 700;
6080 color: var(--content-secondary);
6081 margin-bottom: 0.25rem;
6082 text-transform: uppercase;
6083 }
6084
6085 /* Vacation Day Toggles */
6086 .vacation-toggles-section {
6087 margin-top: 1rem;
6088 padding-top: 1rem;
6089 border-top: 2px solid var(--border);
6090 }
6091
6092 .vacation-toggles-section h3 {
6093 margin: 0 0 0.75rem 0;
6094 font-size: 0.9rem;
6095 font-family: var(--font-heading);
6096 font-weight: 700;
6097 }
6098
6099 .vacation-toggles {
6100 display: flex;
6101 gap: 0.5rem;
6102 }
6103
6104 .vacation-toggle {
6105 width: 2.5rem;
6106 height: 2.5rem;
6107 border-radius: var(--radius-sm);
6108 border: var(--border-width) solid var(--border);
6109 background: var(--surface-overlay);
6110 font-family: var(--font-heading);
6111 font-weight: 700;
6112 font-size: 0.8rem;
6113 cursor: pointer;
6114 transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
6115 display: flex;
6116 align-items: center;
6117 justify-content: center;
6118 }
6119
6120 .vacation-toggle:hover {
6121 background: var(--hover-surface);
6122 }
6123
6124 .vacation-toggle.active {
6125 background: var(--category-five);
6126 color: var(--content-on-action);
6127 border-color: var(--category-five);
6128 }
6129
6130 /* Vacation Timeline Day */
6131 .timeline-day.vacation {
6132 opacity: 0.5;
6133 }
6134
6135 .timeline-day.vacation .day-name {
6136 text-decoration: line-through;
6137 }
6138
6139 /* Vacation Day Banner (Day Plan) */
6140 .vacation-day-banner {
6141 text-align: center;
6142 padding: 0.5rem 1rem;
6143 background: color-mix(in srgb, var(--category-five) 15%, var(--surface-overlay));
6144 border: var(--border-width-sm) solid var(--category-five);
6145 border-radius: var(--radius-sm);
6146 font-family: var(--font-heading);
6147 font-weight: 700;
6148 font-size: 0.85rem;
6149 color: var(--category-five);
6150 margin-bottom: 0.75rem;
6151 }
6152
6153 /* Stats Row */
6154 .stats-row {
6155 display: flex;
6156 gap: 1rem;
6157 margin-bottom: 1rem;
6158 }
6159
6160 .stat-box {
6161 flex: 1;
6162 text-align: center;
6163 padding: 1rem;
6164 background: var(--surface-overlay);
6165 border-radius: var(--radius-md);
6166 }
6167
6168 .stat-box .stat-number {
6169 font-family: var(--font-heading);
6170 font-size: 2rem;
6171 font-weight: 800;
6172 line-height: 1;
6173 }
6174
6175 .stat-box .stat-number.green { color: var(--success); }
6176 .stat-box .stat-number.red { color: var(--danger); }
6177 .stat-box .stat-number.blue { color: var(--action); }
6178 .stat-box .stat-number.purple { color: var(--category-five); }
6179
6180 .stat-box .stat-label {
6181 font-size: 0.75rem;
6182 text-transform: uppercase;
6183 color: var(--content-muted);
6184 font-weight: 600;
6185 margin-top: 0.25rem;
6186 }
6187
6188 /* Task Lists in Review Cards */
6189 .task-list {
6190 list-style: none;
6191 max-height: 200px;
6192 overflow-y: auto;
6193 }
6194
6195 .task-item {
6196 display: flex;
6197 align-items: center;
6198 gap: 0.75rem;
6199 padding: 0.75rem;
6200 margin-bottom: 0.5rem;
6201 background: var(--surface-overlay);
6202 border-radius: var(--radius-md);
6203 cursor: pointer;
6204 transition: background-color var(--transition-normal);
6205 }
6206
6207 .task-item:hover {
6208 background: var(--action);
6209 color: var(--content-on-action);
6210 }
6211
6212 .task-item.completed {
6213 opacity: 0.6;
6214 text-decoration: line-through;
6215 }
6216
6217 .task-checkbox {
6218 width: 20px;
6219 height: 20px;
6220 border: 2px solid var(--border);
6221 border-radius: var(--radius-xs);
6222 display: flex;
6223 align-items: center;
6224 justify-content: center;
6225 flex-shrink: 0;
6226 }
6227
6228 .task-checkbox.checked {
6229 background: var(--success);
6230 color: var(--content-on-action);
6231 }
6232
6233 .task-text {
6234 flex: 1;
6235 font-size: 0.9rem;
6236 }
6237
6238 .task-project {
6239 font-size: 0.75rem;
6240 padding: 0.2rem 0.5rem;
6241 background: var(--surface-raised);
6242 border-radius: var(--radius-xs);
6243 color: var(--content-muted);
6244 }
6245
6246 .task-due {
6247 font-size: 0.75rem;
6248 color: var(--content-muted);
6249 }
6250
6251 .task-due.overdue {
6252 color: var(--danger);
6253 font-weight: 600;
6254 }
6255
6256 /* Focus Section - spans full width */
6257 .focus-section.full-width {
6258 grid-column: 1 / -1;
6259 }
6260
6261 /* Shared scope-slot frame — used by Week's Focus card and Month's Goals card.
6262 View-specific styling layers on top (e.g. `.focus-slot.primary`, `.scope-slot.done`). */
6263 .scope-slots {
6264 display: grid;
6265 grid-template-columns: 1fr 1fr 1fr;
6266 gap: 1rem;
6267 margin-top: 1rem;
6268 }
6269
6270 .scope-slot {
6271 padding: 1.25rem;
6272 background: var(--surface-overlay);
6273 border: 2px dashed var(--border);
6274 border-radius: var(--radius-md);
6275 min-height: 100px;
6276 display: flex;
6277 flex-direction: column;
6278 gap: 0.5rem;
6279 transition: background 0.15s, border-color 0.15s;
6280 }
6281
6282 .scope-slot.filled {
6283 border-style: solid;
6284 background: var(--surface-raised);
6285 }
6286
6287 .scope-slot.empty {
6288 cursor: pointer;
6289 }
6290
6291 .scope-slot.empty:hover {
6292 border-color: var(--action);
6293 background: var(--surface-sunken);
6294 }
6295
6296 .scope-slot-label {
6297 font-size: 0.7rem;
6298 text-transform: uppercase;
6299 letter-spacing: 0.05em;
6300 color: var(--content-muted);
6301 font-weight: 600;
6302 }
6303
6304 .scope-slot-title {
6305 font-weight: 600;
6306 font-size: 0.95rem;
6307 }
6308
6309 .scope-slot-meta {
6310 font-size: 0.8rem;
6311 color: var(--content-secondary);
6312 }
6313
6314 .scope-slot-empty {
6315 color: var(--content-muted);
6316 font-style: italic;
6317 font-size: 0.9rem;
6318 }
6319
6320 /* Focus-specific overlay: primary-priority highlight */
6321 .focus-slot.primary {
6322 border-color: var(--warning);
6323 background: linear-gradient(135deg, var(--surface-raised) 0%, color-mix(in srgb, var(--warning) 10%, var(--surface-raised)) 100%);
6324 }
6325
6326 /* Legacy aliases — keep so existing JS selectors and styles still apply.
6327 New code should use the .scope-slot* classes. */
6328 .focus-grid { /* alias of .scope-slots */ }
6329 .focus-slot { /* alias of .scope-slot */ }
6330 .focus-label { /* alias of .scope-slot-label */ }
6331 .focus-task { /* alias of .scope-slot-title */ }
6332 .focus-meta { /* alias of .scope-slot-meta */ }
6333 .focus-empty { /* alias of .scope-slot-empty */ }
6334
6335 /* Projects Health */
6336 .projects-grid {
6337 display: grid;
6338 grid-template-columns: repeat(3, 1fr);
6339 gap: 0.75rem;
6340 margin-top: 0.5rem;
6341 }
6342
6343 .project-health {
6344 padding: 0.75rem;
6345 background: var(--surface-overlay);
6346 border-radius: var(--radius-md);
6347 border-left: 4px solid var(--action);
6348 }
6349
6350 .project-health.warning {
6351 border-left-color: var(--warning);
6352 }
6353
6354 .project-health.danger {
6355 border-left-color: var(--danger);
6356 }
6357
6358 .project-name {
6359 font-weight: 600;
6360 font-size: 0.85rem;
6361 margin-bottom: 0.25rem;
6362 }
6363
6364 .project-stats {
6365 font-size: 0.75rem;
6366 color: var(--content-muted);
6367 }
6368
6369 /* Reflection Section */
6370 .reflection-section {
6371 grid-column: 1 / -1;
6372 }
6373
6374 .reflection-prompts {
6375 display: grid;
6376 grid-template-columns: 1fr 1fr;
6377 gap: 1rem;
6378 margin-top: 1rem;
6379 }
6380
6381 .reflection-prompt {
6382 padding: 1rem;
6383 background: var(--surface-overlay);
6384 border-radius: var(--radius-md);
6385 }
6386
6387 .prompt-label {
6388 font-size: 0.8rem;
6389 font-weight: 600;
6390 color: var(--content-secondary);
6391 margin-bottom: 0.5rem;
6392 }
6393
6394 .prompt-input,
6395 .reflection-textarea {
6396 width: 100%;
6397 padding: 0.75rem;
6398 border: var(--border-width-sm) solid var(--border);
6399 border-radius: var(--radius-md);
6400 font-size: 0.9rem;
6401 font-family: inherit;
6402 resize: none;
6403 background: var(--surface-raised);
6404 }
6405
6406 .prompt-input:focus,
6407 .reflection-textarea:focus {
6408 outline: none;
6409 border-color: var(--action);
6410 }
6411
6412 /* Review Actions in Grid */
6413 .review-actions-grid {
6414 grid-column: 1 / -1;
6415 display: flex;
6416 justify-content: flex-end;
6417 gap: 1rem;
6418 padding-top: 1rem;
6419 }
6420
6421 /* Event items */
6422 .event-item {
6423 display: flex;
6424 align-items: center;
6425 gap: 0.75rem;
6426 padding: 0.75rem;
6427 margin-bottom: 0.5rem;
6428 background: var(--surface-overlay);
6429 border-radius: var(--radius-md);
6430 border-left: 3px solid var(--category-five);
6431 }
6432
6433 .event-item .event-time {
6434 font-size: 0.8rem;
6435 font-weight: 600;
6436 color: var(--category-five);
6437 min-width: 100px;
6438 }
6439
6440 .event-item .event-title {
6441 flex: 1;
6442 font-size: 0.9rem;
6443 }
6444
6445 /* Accomplishment celebration */
6446 .accomplishment-highlight {
6447 background: linear-gradient(135deg, color-mix(in srgb, var(--success) 10%, var(--surface-raised)) 0%, color-mix(in srgb, var(--success) 5%, var(--surface-raised)) 100%);
6448 border: 2px solid var(--success);
6449 padding: 1rem;
6450 border-radius: var(--radius-md);
6451 margin-bottom: 1rem;
6452 display: flex;
6453 align-items: center;
6454 gap: 1rem;
6455 }
6456
6457 .accomplishment-icon {
6458 font-size: 2rem;
6459 }
6460
6461 .accomplishment-text {
6462 font-size: 1rem;
6463 }
6464
6465 .accomplishment-text strong {
6466 color: var(--success);
6467 }
6468
6469 /* Scrollbar styling for task lists */
6470 .task-list::-webkit-scrollbar {
6471 width: 6px;
6472 }
6473
6474 .task-list::-webkit-scrollbar-track {
6475 background: var(--surface-overlay);
6476 border-radius: var(--radius-xs);
6477 }
6478
6479 .task-list::-webkit-scrollbar-thumb {
6480 background: var(--border);
6481 border-radius: var(--radius-xs);
6482 }
6483
6484 /* Weekly Review Grid in mobile UI — collapse to single column. */
6485 .ui-mode-mobile .review-grid {
6486 grid-template-columns: 1fr;
6487 }
6488
6489 .ui-mode-mobile .week-timeline,
6490 .ui-mode-mobile .week-timeline-events,
6491 .ui-mode-mobile .focus-section.full-width,
6492 .ui-mode-mobile .reflection-section {
6493 grid-column: 1;
6494 }
6495
6496 .ui-mode-mobile .focus-grid {
6497 grid-template-columns: 1fr;
6498 }
6499
6500 .ui-mode-mobile .reflection-prompts {
6501 grid-template-columns: 1fr;
6502 }
6503
6504 .ui-mode-mobile .projects-grid {
6505 grid-template-columns: 1fr 1fr;
6506 }
6507
6508 /* Weekly Review extras — mobile UI: stack stat cards and project grid. */
6509 .ui-mode-mobile .stat-cards {
6510 flex-direction: column;
6511 }
6512
6513 .ui-mode-mobile .stat-card {
6514 max-width: none;
6515 }
6516
6517 .ui-mode-mobile .week-info {
6518 flex-direction: column;
6519 align-items: flex-start;
6520 gap: 0.5rem;
6521 }
6522
6523 .ui-mode-mobile .projects-grid {
6524 grid-template-columns: 1fr;
6525 }
6526
6527 /* ===================================================================
6528 51. Weekly Review Transitions & Keyboard Navigation
6529 =================================================================== */
6530
6531 /* Smooth transitions for focus slots */
6532 .focus-slot {
6533 transition: background-color 0.2s ease-out, border-color 0.2s ease-out;
6534 }
6535
6536 .focus-slot.filled {
6537 animation: focusSlotFill 0.3s ease-out;
6538 }
6539
6540 @keyframes focusSlotFill {
6541 0% {
6542 transform: scale(0.95);
6543 opacity: 0.7;
6544 }
6545 100% {
6546 transform: scale(1);
6547 opacity: 1;
6548 }
6549 }
6550
6551 /* Keyboard focus states */
6552 .focus-slot:focus-within,
6553 .focus-slot:focus {
6554 outline: 2px solid var(--action);
6555 outline-offset: 2px;
6556 }
6557
6558 .focus-slot[tabindex]:focus {
6559 outline: 2px solid var(--action);
6560 outline-offset: 2px;
6561 }
6562
6563 /* Suggested task buttons transitions */
6564 .focus-section .btn {
6565 transition: transform 0.15s ease-out, opacity 0.15s ease-out;
6566 }
6567
6568 .focus-section .btn:active {
6569 transform: scale(0.97);
6570 }
6571
6572 /* §52 vacated 2026-05-24 — weekly-review print styles consolidated into §48. */
6573
6574
6575 /* ===================================================================
6576 52b. Monthly Review
6577 =================================================================== */
6578
6579 .monthly-review-nav,
6580 .weekly-review-nav {
6581 display: flex;
6582 align-items: center;
6583 gap: 0.5rem;
6584 }
6585
6586 .weekly-review-nav .week-dates {
6587 font-family: var(--font-heading);
6588 font-size: 1.25rem;
6589 font-weight: 700;
6590 color: var(--content);
6591 margin-left: 0.5rem;
6592 }
6593
6594 .monthly-review-month-display {
6595 font-family: var(--font-heading);
6596 font-size: 1.25rem;
6597 font-weight: 700;
6598 color: var(--content);
6599 margin-left: 0.5rem;
6600 }
6601
6602 .monthly-review-content {
6603 max-width: 900px;
6604 margin: 0 auto;
6605 padding: 1rem;
6606 }
6607
6608 /* Heat Map Calendar */
6609 .month-heatmap {
6610 margin-bottom: 1.5rem;
6611 border: var(--border-width-sm) solid var(--border);
6612 border-radius: var(--radius-md);
6613 padding: 1rem;
6614 background: var(--surface-overlay);
6615 }
6616
6617 .month-heatmap-header {
6618 display: grid;
6619 grid-template-columns: repeat(7, 1fr);
6620 text-align: center;
6621 margin-bottom: 0.5rem;
6622 }
6623
6624 .month-heatmap-day-header {
6625 font-family: var(--font-heading);
6626 font-size: 0.75rem;
6627 font-weight: 600;
6628 color: var(--content-secondary);
6629 text-transform: uppercase;
6630 }
6631
6632 .month-heatmap-grid {
6633 display: grid;
6634 grid-template-columns: repeat(7, 1fr);
6635 gap: 3px;
6636 }
6637
6638 .month-heatmap-cell {
6639 aspect-ratio: 1;
6640 display: flex;
6641 flex-direction: column;
6642 align-items: center;
6643 justify-content: center;
6644 border-radius: var(--radius-xs);
6645 cursor: pointer;
6646 transition: transform 0.1s ease;
6647 border: var(--border-width-sm) solid transparent;
6648 position: relative;
6649 min-height: 40px;
6650 }
6651
6652 .month-heatmap-cell:not(.empty):hover {
6653 transform: scale(1.1);
6654 border-color: var(--border);
6655 z-index: 1;
6656 }
6657
6658 .month-heatmap-cell.empty {
6659 cursor: default;
6660 background: transparent;
6661 }
6662
6663 .month-heatmap-cell.intensity-0 { background: var(--surface-page); }
6664 .month-heatmap-cell.intensity-1 { background: color-mix(in srgb, var(--success) 20%, var(--surface-page)); }
6665 .month-heatmap-cell.intensity-2 { background: color-mix(in srgb, var(--success) 40%, var(--surface-page)); }
6666 .month-heatmap-cell.intensity-3 { background: color-mix(in srgb, var(--success) 60%, var(--surface-page)); }
6667
6668 .month-heatmap-cell.vacation {
6669 background: var(--surface-sunken);
6670 opacity: 0.6;
6671 }
6672
6673 .month-heatmap-cell.today {
6674 border-color: var(--action);
6675 border-width: 2px;
6676 }
6677
6678 .month-heatmap-cell.past.intensity-0 {
6679 background: var(--surface-sunken);
6680 }
6681
6682 .month-heatmap-day-number {
6683 font-family: var(--font-heading);
6684 font-size: 0.8rem;
6685 font-weight: 600;
6686 color: var(--content);
6687 }
6688
6689 .month-heatmap-dots {
6690 display: flex;
6691 gap: 2px;
6692 margin-top: 2px;
6693 }
6694
6695 .month-dot {
6696 font-size: 0.6rem;
6697 font-weight: 700;
6698 border-radius: var(--radius-xs);
6699 padding: 0 3px;
6700 line-height: 1.3;
6701 }
6702
6703 .month-dot.completed { color: var(--success); }
6704 .month-dot.event { color: var(--category-five); }
6705
6706 /* Cards Grid */
6707 .monthly-review-cards {
6708 display: grid;
6709 grid-template-columns: 1fr 1fr;
6710 gap: 1rem;
6711 }
6712
6713 .review-card.month-stats-card {
6714 grid-column: span 1;
6715 }
6716
6717 .review-card.month-goals-card {
6718 margin-bottom: 1rem;
6719 }
6720
6721 .review-card.month-pulse-card,
6722 .review-card.month-patterns-card {
6723 grid-column: span 1;
6724 }
6725
6726 .review-card.month-reflection-card {
6727 grid-column: 1 / -1;
6728 }
6729
6730 .review-card-title {
6731 font-family: var(--font-heading);
6732 font-size: 1rem;
6733 font-weight: 700;
6734 margin-bottom: 0.75rem;
6735 color: var(--content);
6736 }
6737
6738 /* Stats */
6739 .month-stats-grid {
6740 display: grid;
6741 grid-template-columns: 1fr 1fr;
6742 gap: 0.5rem;
6743 }
6744
6745 .month-stat-item {
6746 display: flex;
6747 flex-direction: column;
6748 align-items: center;
6749 padding: 0.5rem;
6750 border-radius: var(--radius-xs);
6751 background: var(--surface-page);
6752 border: var(--border-width-sm) solid var(--border);
6753 }
6754
6755 .month-stat-value {
6756 font-family: var(--font-heading);
6757 font-size: 1.5rem;
6758 font-weight: 700;
6759 color: var(--content);
6760 }
6761
6762 .month-stat-label {
6763 font-size: 0.75rem;
6764 color: var(--content-secondary);
6765 text-transform: uppercase;
6766 font-weight: 600;
6767 }
6768
6769 .month-stats-highlights {
6770 display: flex;
6771 gap: 1rem;
6772 margin-top: 0.5rem;
6773 justify-content: center;
6774 }
6775
6776 .stat-highlight {
6777 font-size: 0.8rem;
6778 color: var(--content-secondary);
6779 }
6780
6781 /* Project Pulse */
6782 .month-pulse-list {
6783 display: flex;
6784 flex-direction: column;
6785 gap: 0.5rem;
6786 }
6787
6788 .month-pulse-item {
6789 display: flex;
6790 align-items: center;
6791 gap: 0.5rem;
6792 padding: 0.5rem;
6793 border-radius: var(--radius-xs);
6794 background: var(--surface-page);
6795 border: var(--border-width-sm) solid var(--border);
6796 }
6797
6798 .pulse-name {
6799 font-weight: 600;
6800 flex: 1;
6801 font-size: 0.875rem;
6802 }
6803
6804 .pulse-stats {
6805 font-size: 0.75rem;
6806 color: var(--content-secondary);
6807 }
6808
6809 .pulse-arrow {
6810 font-size: 1rem;
6811 font-weight: 700;
6812 }
6813
6814 .month-pulse-item.positive .pulse-arrow { color: var(--success); }
6815 .month-pulse-item.negative .pulse-arrow { color: var(--danger); }
6816 .month-pulse-item.neutral .pulse-arrow { color: var(--content-secondary); }
6817
6818 /* Goals — scope-slot frame is shared with Focus; goal-specific bits below.
6819 .month-goals-list is now just a hook for legacy selectors; layout comes from .scope-slots. */
6820 .month-goals-list { /* layout inherited from .scope-slots */ }
6821
6822 .month-goal-body {
6823 display: flex;
6824 align-items: center;
6825 gap: 0.5rem;
6826 flex: 1;
6827 }
6828
6829 .month-goal-item.done {
6830 opacity: 0.7;
6831 }
6832
6833 .month-goal-item.done .month-goal-text {
6834 text-decoration: line-through;
6835 }
6836
6837 .month-goal-item.abandoned {
6838 opacity: 0.5;
6839 }
6840
6841 .month-goal-item.abandoned .month-goal-text {
6842 text-decoration: line-through;
6843 }
6844
6845 /* Extends .btn-icon with bigger font, fixed width, and parent-driven color overrides. */
6846 .month-goal-status-btn {
6847 font-size: 1rem;
6848 padding: 0;
6849 color: var(--content-secondary);
6850 width: 24px;
6851 text-align: center;
6852 }
6853
6854 .month-goal-item.done .month-goal-status-btn { color: var(--success); }
6855 .month-goal-item.abandoned .month-goal-status-btn { color: var(--danger); }
6856
6857 .month-goal-text {
6858 flex: 1;
6859 font-size: 0.875rem;
6860 }
6861
6862 /* Extends .btn-icon with hover-reveal opacity and tertiary color. */
6863 .month-goal-delete-btn {
6864 color: var(--content-muted);
6865 padding: 0 4px;
6866 font-size: 0.75rem;
6867 opacity: 0;
6868 transition: opacity 0.15s;
6869 }
6870
6871 .month-goal-item:hover .month-goal-delete-btn {
6872 opacity: 1;
6873 }
6874
6875 .month-goal-placeholder {
6876 color: var(--content-muted);
6877 font-size: 0.875rem;
6878 }
6879
6880 /* Reflection */
6881 .month-reflection-fields {
6882 display: flex;
6883 flex-direction: column;
6884 gap: 0.5rem;
6885 }
6886
6887 .month-reflection-label {
6888 font-size: 0.875rem;
6889 font-weight: 600;
6890 color: var(--content-secondary);
6891 }
6892
6893 .month-reflection-textarea {
6894 width: 100%;
6895 padding: 0.5rem;
6896 border: var(--border-width-sm) solid var(--border);
6897 border-radius: var(--radius-xs);
6898 background: var(--surface-page);
6899 color: var(--content);
6900 font-family: var(--font-body);
6901 font-size: 0.875rem;
6902 resize: vertical;
6903 }
6904
6905 .month-reflection-textarea:focus {
6906 outline: 2px solid var(--action);
6907 outline-offset: -1px;
6908 }
6909
6910 /* Patterns */
6911 .month-patterns-list {
6912 list-style: none;
6913 padding: 0;
6914 margin: 0;
6915 display: flex;
6916 flex-direction: column;
6917 gap: 0.5rem;
6918 }
6919
6920 .month-pattern-item {
6921 font-size: 0.875rem;
6922 color: var(--content-secondary);
6923 padding: 0.5rem;
6924 background: var(--surface-page);
6925 border-radius: var(--radius-xs);
6926 border: var(--border-width-sm) solid var(--border);
6927 }
6928
6929 /* Monthly Review in mobile UI — collapse to single column, denser heatmap. */
6930 .ui-mode-mobile .monthly-review-cards {
6931 grid-template-columns: 1fr;
6932 }
6933
6934 .ui-mode-mobile .review-card.month-stats-card,
6935 .ui-mode-mobile .review-card.month-goals-card,
6936 .ui-mode-mobile .review-card.month-pulse-card,
6937 .ui-mode-mobile .review-card.month-patterns-card {
6938 grid-column: span 1;
6939 }
6940
6941 .ui-mode-mobile .month-heatmap-cell {
6942 min-height: 32px;
6943 }
6944
6945 .ui-mode-mobile .month-heatmap-day-number {
6946 font-size: 0.7rem;
6947 }
6948
6949 .ui-mode-mobile .month-heatmap-dots {
6950 display: none;
6951 }
6952
6953 /* ===================================================================
6954 53. Import Wizard
6955 =================================================================== */
6956 .import-wizard {
6957 display: flex;
6958 flex-direction: column;
6959 gap: 1.5rem;
6960 }
6961
6962 .import-step {
6963 padding: 1rem;
6964 background: var(--surface-overlay);
6965 border: var(--border-width) solid var(--border);
6966 border-radius: var(--radius-md);
6967 }
6968
6969 .import-step h3 {
6970 margin: 0 0 1rem 0;
6971 font-size: var(--font-size-md);
6972 font-weight: 600;
6973 }
6974
6975 .plugin-selector {
6976 display: grid;
6977 grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
6978 gap: 0.75rem;
6979 }
6980
6981 .plugin-option {
6982 display: flex;
6983 flex-direction: column;
6984 align-items: flex-start;
6985 padding: 0.75rem 1rem;
6986 background: var(--surface-raised);
6987 border: var(--border-width) solid var(--border);
6988 border-radius: var(--radius-sm);
6989 cursor: pointer;
6990 text-align: left;
6991 transition: border-color var(--transition-fast), background var(--transition-fast);
6992 }
6993
6994 .plugin-option:hover {
6995 border-color: var(--action);
6996 background: var(--hover-surface);
6997 }
6998
6999 .plugin-option.selected {
7000 border-color: var(--action);
7001 background: color-mix(in srgb, var(--action) 10%, var(--surface-raised));
7002 box-shadow: 0 0 0 2px color-mix(in srgb, var(--action) 30%, transparent);
7003 }
7004
7005 .plugin-option .plugin-name {
7006 font-weight: 600;
7007 margin-bottom: 0.25rem;
7008 }
7009
7010 .plugin-option .plugin-meta {
7011 display: flex;
7012 gap: 0.5rem;
7013 font-size: var(--font-size-sm);
7014 color: var(--content-muted);
7015 margin-bottom: 0.25rem;
7016 }
7017
7018 .plugin-option .plugin-extensions {
7019 color: var(--category-six);
7020 }
7021
7022 .plugin-option .plugin-types {
7023 color: var(--content-secondary);
7024 }
7025
7026 .plugin-option .plugin-description {
7027 font-size: var(--font-size-sm);
7028 color: var(--content-secondary);
7029 line-height: 1.4;
7030 }
7031
7032 .file-selector {
7033 display: flex;
7034 align-items: center;
7035 gap: 1rem;
7036 }
7037
7038 .selected-file-name {
7039 color: var(--content-secondary);
7040 font-family: monospace;
7041 font-size: var(--font-size-sm);
7042 }
7043
7044 .import-preview-container {
7045 min-height: 100px;
7046 }
7047
7048 .import-preview-table-wrapper {
7049 max-height: 300px;
7050 overflow: auto;
7051 border: 1px solid var(--border);
7052 border-radius: var(--radius-sm);
7053 }
7054
7055 .import-preview-table {
7056 font-size: var(--font-size-sm);
7057 margin: 0;
7058 }
7059
7060 .import-preview-table th {
7061 position: sticky;
7062 top: 0;
7063 background: var(--surface-overlay);
7064 z-index: 1;
7065 }
7066
7067 .import-preview-table td {
7068 max-width: 200px;
7069 overflow: hidden;
7070 text-overflow: ellipsis;
7071 white-space: nowrap;
7072 }
7073
7074 .import-summary {
7075 margin: 0 0 0.75rem 0;
7076 color: var(--content);
7077 }
7078
7079 .import-more {
7080 margin: 0.5rem 0 0 0;
7081 color: var(--content-muted);
7082 font-style: italic;
7083 font-size: var(--font-size-sm);
7084 }
7085
7086 .import-empty,
7087 .import-error {
7088 padding: 2rem;
7089 text-align: center;
7090 color: var(--content-muted);
7091 }
7092
7093 .import-error {
7094 color: var(--danger);
7095 }
7096
7097 .import-warnings {
7098 margin-top: 1rem;
7099 padding: 0.75rem;
7100 background: color-mix(in srgb, var(--warning) 10%, var(--surface-raised));
7101 border: 1px solid var(--warning);
7102 border-radius: var(--radius-sm);
7103 font-size: var(--font-size-sm);
7104 }
7105
7106 .import-warnings ul {
7107 margin: 0.5rem 0 0 1.25rem;
7108 padding: 0;
7109 }
7110
7111 .import-warnings li {
7112 margin-bottom: 0.25rem;
7113 }
7114
7115 .import-external-types {
7116 display: flex;
7117 gap: 1rem;
7118 margin-bottom: 1.5rem;
7119 }
7120
7121 .import-type-card {
7122 flex: 1;
7123 display: flex;
7124 flex-direction: column;
7125 align-items: center;
7126 gap: 0.5rem;
7127 padding: 1.5rem 1rem;
7128 background: var(--surface-raised);
7129 border: 2px solid var(--border);
7130 border-radius: var(--radius-md);
7131 cursor: pointer;
7132 transition: border-color 0.15s, background 0.15s;
7133 }
7134
7135 .import-type-card:hover {
7136 border-color: var(--action);
7137 background: var(--surface-overlay);
7138 }
7139
7140 .import-type-icon {
7141 font-size: 2rem;
7142 }
7143
7144 .import-type-label {
7145 font-weight: 600;
7146 color: var(--content);
7147 }
7148
7149 .import-type-desc {
7150 font-size: var(--font-size-sm);
7151 color: var(--content-muted);
7152 }
7153
7154 /* ===================================================================
7155 54. Plugin Manager
7156 =================================================================== */
7157 .plugin-list {
7158 display: flex;
7159 flex-direction: column;
7160 gap: 0.75rem;
7161 }
7162
7163 .plugin-item {
7164 display: flex;
7165 justify-content: space-between;
7166 align-items: center;
7167 padding: 1rem;
7168 background: var(--surface-raised);
7169 border: var(--border-width) solid var(--border);
7170 border-radius: var(--radius-md);
7171 }
7172
7173 .plugin-item .plugin-info {
7174 flex: 1;
7175 }
7176
7177 .plugin-item .plugin-name {
7178 font-weight: 600;
7179 }
7180
7181 .plugin-item .plugin-version {
7182 color: var(--content-muted);
7183 font-size: var(--font-size-sm);
7184 margin-left: 0.5rem;
7185 }
7186
7187 .plugin-item .plugin-description {
7188 margin: 0.25rem 0;
7189 color: var(--content-secondary);
7190 font-size: var(--font-size-sm);
7191 }
7192
7193 .plugin-item .plugin-extensions {
7194 font-size: var(--font-size-xs);
7195 color: var(--content-muted);
7196 }
7197
7198 .plugin-item .plugin-actions {
7199 margin-left: 1rem;
7200 }
7201
7202 /* ===================================================================
7203 55. Toggle Switch
7204 =================================================================== */
7205 .toggle-switch {
7206 position: relative;
7207 display: inline-block;
7208 width: 44px;
7209 height: 24px;
7210 }
7211
7212 .toggle-switch input {
7213 opacity: 0;
7214 width: 0;
7215 height: 0;
7216 }
7217
7218 .toggle-slider {
7219 position: absolute;
7220 cursor: pointer;
7221 top: 0;
7222 left: 0;
7223 right: 0;
7224 bottom: 0;
7225 background-color: var(--surface-sunken);
7226 border: 2px solid var(--border);
7227 border-radius: var(--radius-xl);
7228 transition: background-color var(--transition-fast), border-color var(--transition-fast);
7229 }
7230
7231 .toggle-slider:before {
7232 position: absolute;
7233 content: "";
7234 height: 16px;
7235 width: 16px;
7236 left: 2px;
7237 bottom: 2px;
7238 background-color: var(--content-muted);
7239 border-radius: var(--radius-full);
7240 transition: transform var(--transition-fast), background-color var(--transition-fast);
7241 }
7242
7243 .toggle-switch input:checked + .toggle-slider {
7244 background-color: var(--action);
7245 border-color: var(--action);
7246 }
7247
7248 .toggle-switch input:checked + .toggle-slider:before {
7249 transform: translateX(20px);
7250 background-color: var(--surface-raised);
7251 }
7252
7253 .toggle-switch input:focus + .toggle-slider {
7254 box-shadow: 0 0 0 2px color-mix(in srgb, var(--action) 30%, transparent);
7255 }
7256
7257 /* ===================================================================
7258 56. Project Milestones
7259 =================================================================== */
7260 .milestones-section {
7261 margin-bottom: 1.5rem;
7262 }
7263
7264 .milestones-header {
7265 display: flex;
7266 justify-content: space-between;
7267 align-items: center;
7268 margin-bottom: 1rem;
7269 padding-bottom: 0.5rem;
7270 border-bottom: 2px solid var(--border);
7271 }
7272
7273 .milestones-header h3 {
7274 margin: 0;
7275 font-size: 1rem;
7276 font-family: var(--font-heading);
7277 font-weight: 700;
7278 }
7279
7280 .milestone-card {
7281 background: var(--surface-raised);
7282 border: var(--border-width) solid var(--border);
7283 border-radius: var(--radius-md);
7284 padding: 1rem;
7285 margin-bottom: 0.75rem;
7286 transition: background-color 0.1s;
7287 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
7288 }
7289
7290 .milestone-card:hover {
7291 background: var(--surface-overlay);
7292 }
7293
7294 .milestone-card-header {
7295 display: flex;
7296 justify-content: space-between;
7297 align-items: flex-start;
7298 margin-bottom: 0.5rem;
7299 }
7300
7301 .milestone-card-header h4 {
7302 margin: 0;
7303 font-size: 0.95rem;
7304 font-family: var(--font-heading);
7305 font-weight: 700;
7306 }
7307
7308 .milestone-card-header .milestone-status {
7309 font-size: 0.7rem;
7310 font-weight: 700;
7311 text-transform: uppercase;
7312 padding: 0.15rem 0.4rem;
7313 border-radius: var(--radius-sm);
7314 background: var(--surface-overlay);
7315 color: var(--content-muted);
7316 }
7317
7318 .milestone-card-header .milestone-status.completed {
7319 background: color-mix(in srgb, var(--success) 15%, var(--surface-overlay));
7320 color: var(--success);
7321 }
7322
7323 .milestone-meta {
7324 display: flex;
7325 gap: 1rem;
7326 font-size: 0.8rem;
7327 color: var(--content-muted);
7328 margin-bottom: 0.5rem;
7329 }
7330
7331 .milestone-progress {
7332 height: 6px;
7333 background: var(--surface-overlay);
7334 border-radius: var(--radius-full);
7335 overflow: hidden;
7336 border: var(--border-width-sm) solid var(--border);
7337 }
7338
7339 .milestone-progress-fill {
7340 height: 100%;
7341 background: var(--success);
7342 border-radius: var(--radius-full);
7343 transition: width var(--transition-fast);
7344 }
7345
7346 .milestone-actions {
7347 display: flex;
7348 gap: 0.5rem;
7349 margin-top: 0.5rem;
7350 }
7351
7352 .milestone-actions button {
7353 font-size: 0.75rem;
7354 padding: 0.2rem 0.5rem;
7355 background: var(--surface-overlay);
7356 border: var(--border-width-sm) solid var(--border);
7357 border-radius: var(--radius-sm);
7358 cursor: pointer;
7359 color: var(--content-secondary);
7360 transition: background var(--transition-fast);
7361 }
7362
7363 .milestone-actions button:hover {
7364 background: var(--hover-surface);
7365 }
7366
7367 .milestone-actions button.danger:hover {
7368 background: color-mix(in srgb, var(--danger) 15%, var(--surface-overlay));
7369 color: var(--danger);
7370 }
7371
7372 button.milestone-reorder-btn.btn {
7373 font-size: 0.65rem;
7374 padding: 0.15rem 0.35rem;
7375 line-height: 1;
7376 min-width: 1.5rem;
7377 text-align: center;
7378 }
7379
7380 .milestones-completed-section {
7381 margin-top: 0.75rem;
7382 }
7383
7384 .milestones-completed-toggle {
7385 font-size: 0.8rem;
7386 color: var(--content-secondary);
7387 padding: 0.25rem 0;
7388 }
7389
7390 .milestone-card-summary {
7391 padding: 0.5rem 0.75rem;
7392 opacity: 0.7;
7393 }
7394
7395 .milestone-card-summary .milestone-info {
7396 display: flex;
7397 align-items: center;
7398 gap: 0.5rem;
7399 }
7400
7401 .milestone-complete-badge {
7402 font-size: 0.7rem;
7403 font-weight: 700;
7404 padding: 0.1rem 0.4rem;
7405 border-radius: var(--radius-sm);
7406 background: color-mix(in srgb, var(--success) 15%, var(--surface-overlay));
7407 color: var(--success);
7408 }
7409
7410 /* ===================================================================
7411 58. Mobile Navigation (Nav Dot, Dial, Bottom Sheets)
7412 =================================================================== */
7413
7414 /* --- Mobile Tab Bar (hidden on desktop, shown <=768px) --- */
7415 .mobile-tab-bar {
7416 display: none;
7417 position: fixed;
7418 bottom: 0;
7419 left: 0;
7420 right: 0;
7421 z-index: 1100;
7422 background: var(--surface-raised);
7423 border-top: var(--border-width) solid var(--border);
7424 padding-bottom: env(safe-area-inset-bottom, 0px);
7425 height: calc(52px + env(safe-area-inset-bottom, 0px));
7426 }
7427
7428 .mobile-tab {
7429 flex: 1;
7430 display: flex;
7431 align-items: center;
7432 justify-content: center;
7433 height: 52px;
7434 background: none;
7435 border: none;
7436 color: var(--content-muted);
7437 font-size: 0.7rem;
7438 font-weight: 700;
7439 font-family: var(--font-sans);
7440 text-transform: uppercase;
7441 letter-spacing: 0.05em;
7442 cursor: pointer;
7443 -webkit-tap-highlight-color: transparent;
7444 transition: color 0.15s ease;
7445 }
7446
7447 .mobile-tab.active {
7448 color: var(--action);
7449 }
7450
7451 .mobile-tab:active {
7452 background: var(--surface-overlay);
7453 }
7454
7455 .mobile-tab-create {
7456 font-size: 1.4rem;
7457 font-weight: 400;
7458 color: var(--success);
7459 letter-spacing: 0;
7460 text-transform: none;
7461 }
7462
7463 /* --- Tab Long-press Slide Menu ---
7464 Anchored above a mobile tab. JS sets left/bottom inline. Origin is
7465 bottom-center so the scale-in reads as "growing up out of the tab". */
7466 .mobile-tab-slide-menu {
7467 position: fixed;
7468 z-index: 1102;
7469 min-width: 140px;
7470 background: var(--surface-raised);
7471 border: var(--border-width) solid var(--border);
7472 border-radius: var(--radius-md);
7473 box-shadow: var(--shadow-brutal-md);
7474 padding: 0.25rem;
7475 display: flex;
7476 flex-direction: column;
7477 opacity: 0;
7478 transform: scale(0.92);
7479 transform-origin: 50% 100%;
7480 transition: opacity 120ms ease-out, transform 120ms ease-out;
7481 }
7482
7483 .mobile-tab-slide-menu.is-open {
7484 opacity: 1;
7485 transform: scale(1);
7486 }
7487
7488 .mobile-tab-slide-item {
7489 padding: 0.7rem 0.9rem;
7490 min-height: 44px;
7491 display: flex;
7492 align-items: center;
7493 justify-content: center;
7494 font-size: var(--font-size-sm);
7495 font-weight: 700;
7496 text-transform: uppercase;
7497 letter-spacing: 0.05em;
7498 color: var(--content);
7499 border-radius: var(--radius-sm);
7500 transition: background 80ms ease, transform 80ms ease;
7501 }
7502
7503 .mobile-tab-slide-item.is-highlighted {
7504 background: var(--action);
7505 color: var(--content-on-action);
7506 transform: scale(1.03);
7507 }
7508
7509 /* --- Action Bottom Sheet --- */
7510 .action-sheet {
7511 position: fixed;
7512 inset: 0;
7513 z-index: 10001;
7514 display: flex;
7515 flex-direction: column;
7516 justify-content: flex-end;
7517 }
7518
7519 .action-sheet.hidden {
7520 display: none;
7521 }
7522
7523 .action-sheet-backdrop {
7524 position: absolute;
7525 inset: 0;
7526 background: rgba(0, 0, 0, 0.4);
7527 }
7528
7529 .action-sheet-container {
7530 position: relative;
7531 background: var(--surface-raised);
7532 border-top: var(--border-width) solid var(--border);
7533 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
7534 padding: 0.5rem 1rem calc(0.5rem + env(safe-area-inset-bottom, 0px));
7535 max-height: 60vh;
7536 overflow-y: auto;
7537 animation: sheetSlideUp 0.25s ease-out;
7538 }
7539
7540 .action-sheet-handle {
7541 width: 36px;
7542 height: 4px;
7543 border-radius: 2px;
7544 background: var(--content-muted);
7545 margin: 0 auto 0.75rem;
7546 opacity: 0.4;
7547 }
7548
7549 .action-sheet-content button {
7550 display: flex;
7551 align-items: center;
7552 gap: 0.75rem;
7553 width: 100%;
7554 padding: 0.875rem 0.5rem;
7555 background: none;
7556 border: none;
7557 border-bottom: 1px solid var(--surface-overlay);
7558 font-size: var(--font-size-base);
7559 font-weight: 600;
7560 color: var(--content);
7561 text-align: left;
7562 cursor: pointer;
7563 }
7564
7565 .action-sheet-content button:last-child {
7566 border-bottom: none;
7567 }
7568
7569 .action-sheet-content button:active {
7570 background: var(--surface-overlay);
7571 }
7572
7573 .action-sheet-content button.danger {
7574 color: var(--danger);
7575 }
7576
7577 .action-sheet-cancel {
7578 display: block;
7579 width: 100%;
7580 padding: 0.875rem;
7581 margin-top: 0.5rem;
7582 background: var(--surface-overlay);
7583 border: var(--border-width-sm) solid var(--border);
7584 border-radius: var(--radius-md);
7585 font-size: var(--font-size-base);
7586 font-weight: 700;
7587 color: var(--content);
7588 text-align: center;
7589 cursor: pointer;
7590 }
7591
7592 .action-sheet-cancel:active {
7593 background: var(--surface-sunken);
7594 }
7595
7596 /* --- Modal Drag Handle (mobile swipe-to-dismiss) --- */
7597 .modal-drag-handle {
7598 display: none;
7599 width: 36px;
7600 height: 4px;
7601 border-radius: 2px;
7602 background: var(--content-muted);
7603 margin: 0.5rem auto 0;
7604 opacity: 0.4;
7605 }
7606
7607 /* --- Mobile Sort Dropdown (replaces clickable column headers) --- */
7608 .mobile-sort-bar {
7609 display: none;
7610 gap: 0.5rem;
7611 padding: 0.5rem 0;
7612 align-items: center;
7613 }
7614
7615 .mobile-sort-bar select {
7616 flex: 1;
7617 font-size: var(--font-size-sm);
7618 }
7619
7620 /* --- Mobile Filter Toggle --- */
7621 .mobile-filter-toggle {
7622 display: none;
7623 }
7624
7625 /* --- Swipe Action Layer --- */
7626 .swipe-actions-container {
7627 position: relative;
7628 overflow: hidden;
7629 }
7630
7631 .swipe-actions-bg {
7632 position: absolute;
7633 top: 0;
7634 bottom: 0;
7635 display: flex;
7636 align-items: center;
7637 padding: 0 1rem;
7638 font-weight: 700;
7639 font-size: var(--font-size-sm);
7640 color: var(--content-on-action);
7641 }
7642
7643 .swipe-actions-bg.swipe-left {
7644 right: 0;
7645 background: var(--success);
7646 }
7647
7648 .swipe-actions-bg.swipe-right {
7649 left: 0;
7650 background: var(--danger);
7651 }
7652
7653 .swipe-content {
7654 position: relative;
7655 background: var(--surface-raised);
7656 transition: transform 0.15s ease;
7657 }
7658
7659 /* --- Pull to Refresh --- */
7660 .pull-to-refresh-indicator {
7661 display: none;
7662 text-align: center;
7663 padding: 0.75rem;
7664 font-size: var(--font-size-sm);
7665 color: var(--content-muted);
7666 font-weight: 600;
7667 }
7668
7669 .pull-to-refresh-indicator.visible {
7670 display: block;
7671 }
7672
7673 /* --- Event Date Group Headers (mobile) --- */
7674 .event-date-group-header {
7675 display: none;
7676 }
7677
7678 /* --- Day Plan Collapsible Sidebar (mobile) --- */
7679 .day-plan-sidebar-toggle {
7680 display: none;
7681 }
7682
7683 @keyframes sheetSlideUp {
7684 from { transform: translateY(100%); }
7685 to { transform: translateY(0); }
7686 }
7687
7688 @keyframes sheetSlideDown {
7689 from { transform: translateY(0); }
7690 to { transform: translateY(100%); }
7691 }
7692
7693 @keyframes dialFadeIn {
7694 from { opacity: 0; }
7695 to { opacity: 1; }
7696 }
7697
7698 /* ===================================================================
7699 59. Mobile Responsive (768px overrides)
7700 =================================================================== */
7701
7702 /* --- Safe area padding + room for mobile tab bar --- */
7703 html.ui-mode-mobile, .ui-mode-mobile body {
7704 overflow-x: hidden;
7705 max-width: 100vw;
7706 touch-action: pan-y;
7707 overscroll-behavior-x: none;
7708 }
7709 .ui-mode-mobile body {
7710 padding-top: env(safe-area-inset-top, 0px);
7711 padding-bottom: calc(52px + env(safe-area-inset-bottom, 0px));
7712 padding-left: env(safe-area-inset-left, 0px);
7713 padding-right: env(safe-area-inset-right, 0px);
7714 }
7715 /* Fixed-position UI must extend edge-to-edge under the notch in landscape */
7716 .ui-mode-mobile .mobile-tab-bar,
7717 .ui-mode-mobile .timer-widget {
7718 padding-left: env(safe-area-inset-left, 0px);
7719 padding-right: env(safe-area-inset-right, 0px);
7720 }
7721
7722 .ui-mode-mobile .mobile-tab-bar {
7723 display: flex;
7724 }
7725
7726 /* --- Hide desktop tab navigation --- */
7727 .ui-mode-mobile .tab-navigation {
7728 display: none !important;
7729 }
7730
7731 .ui-mode-mobile .app-header {
7732 display: none;
7733 }
7734
7735 /* Pill nav is replaced on mobile by the bottom tab bar's long-press
7736 slide menu — hide the in-page sub-tab strip. */
7737 .ui-mode-mobile .pill-nav {
7738 display: none;
7739 }
7740
7741 /* === Mobile toolbar grids ===
7742 Toolbar rows become equal-column grids on mobile so children share
7743 the row predictably (no orphans, no ragged wrapping). Search inputs
7744 always span the full grid row. */
7745 .ui-mode-mobile #emails-view > div.row-flex.mb-2,
7746 .ui-mode-mobile #tasks-view .page-header > .row-flex,
7747 .ui-mode-mobile #tasks-view .mobile-sort-bar,
7748 .ui-mode-mobile #contacts-view .page-header > .row-flex {
7749 display: grid;
7750 grid-auto-flow: row;
7751 grid-template-columns: repeat(2, 1fr);
7752 gap: var(--space-2);
7753 align-items: center;
7754 }
7755
7756 /* Tasks page-header: Quick Add + New Task are hidden on mobile (see
7757 .mobile-hide / .btn-primary rules), so only the view-toggle remains
7758 and takes the full row. */
7759 .ui-mode-mobile #tasks-view .page-header > .row-flex {
7760 grid-template-columns: 1fr;
7761 }
7762
7763 /* Mobile-hide utility: marker class on controls that don't belong in
7764 the mobile layout (Drafts, Quick Add). Surfaced elsewhere instead
7765 (slide menu, bottom bar). */
7766 .ui-mode-mobile .mobile-hide {
7767 display: none !important;
7768 }
7769
7770 /* Status badges in the day/week/month page-headers are informational
7771 and visible inside their respective review subviews anyway. */
7772 .ui-mode-mobile #day-review-status-badge,
7773 .ui-mode-mobile #week-review-status-badge,
7774 .ui-mode-mobile #month-review-status-badge {
7775 display: none !important;
7776 }
7777
7778 /* Day-plan timeline: drag-paint and its hint don't apply on mobile —
7779 tap-to-add is the touch path. Suppress the hover affordance and
7780 grab cursor too. */
7781 .ui-mode-mobile #day-plan-view .timeline-hint {
7782 display: none;
7783 }
7784 .ui-mode-mobile #day-plan-view .timeline-slot-area {
7785 cursor: default;
7786 }
7787 .ui-mode-mobile #day-plan-view .timeline-slot-area:hover {
7788 background: transparent;
7789 }
7790
7791 /* Day-plan nav: keep ← Today → + date input on one row when there's
7792 width; wrap the date input below only if the row would overflow.
7793 The inline date-display span is redundant with the date input. */
7794 .ui-mode-mobile #day-plan-view .day-plan-nav {
7795 display: flex;
7796 flex-wrap: wrap;
7797 column-gap: var(--space-2);
7798 row-gap: var(--space-3);
7799 align-items: center;
7800 }
7801 /* Restore per-button borders/radii — the desktop segmented-strip rule
7802 (no right border, square corners) doesn't apply here on mobile. */
7803 .ui-mode-mobile #day-plan-view .day-plan-nav .btn {
7804 flex: 0 0 auto;
7805 border-radius: var(--radius-sm);
7806 border-right-width: var(--border-width);
7807 }
7808 .ui-mode-mobile #day-plan-view .day-plan-nav .day-plan-date-picker {
7809 flex: 1 1 120px;
7810 min-width: 0;
7811 }
7812 .ui-mode-mobile #day-plan-view .day-plan-date-display {
7813 display: none;
7814 }
7815
7816 /* Search inputs always span the full grid row. */
7817 .ui-mode-mobile #email-search,
7818 .ui-mode-mobile #contacts-search {
7819 grid-column: 1 / -1;
7820 width: 100%;
7821 min-width: 0;
7822 }
7823
7824 /* The email-count span ("48 threads") is inside the grid row — hide
7825 on mobile; will get a tidier home in layer-2 trims. */
7826 .ui-mode-mobile #email-count {
7827 display: none;
7828 }
7829
7830 /* Inside the new grid cells, undo the segmented-button styling (no
7831 right border, square corners) inherited from the desktop page-header
7832 rule — grid already gives equal sizing. */
7833 .ui-mode-mobile #tasks-view .page-header > .row-flex .btn,
7834 .ui-mode-mobile #contacts-view .page-header > .row-flex .btn {
7835 border-radius: var(--radius-sm);
7836 border-right-width: var(--border-width);
7837 }
7838
7839 /* View-toggle inside the tasks grid should fill its cell. */
7840 .ui-mode-mobile #tasks-view .page-header .view-toggle {
7841 display: flex;
7842 width: 100%;
7843 }
7844 .ui-mode-mobile #tasks-view .page-header .view-toggle .view-toggle-btn {
7845 flex: 1 1 0;
7846 }
7847
7848 /* Undo absolute positioning on mobile — page-header buttons are hidden anyway */
7849 .ui-mode-mobile .tab-group > .subview > .page-header {
7850 position: static;
7851 }
7852
7853 /* --- Main content adjustments --- */
7854 .ui-mode-mobile .main-content {
7855 padding: 0.75rem;
7856 }
7857
7858 .ui-mode-mobile .page-header {
7859 flex-wrap: wrap;
7860 gap: 0.5rem;
7861 }
7862
7863 .ui-mode-mobile .page-header .btn-primary {
7864 display: none;
7865 }
7866
7867 .ui-mode-mobile .page-title {
7868 display: none;
7869 }
7870
7871 /* Compact toolbar buttons: collapse into a single segmented block so the
7872 button text has more room without crowding the row. Stretch each segment
7873 to share row width so the block reads as one unified control. */
7874 .ui-mode-mobile .page-header > div,
7875 .ui-mode-mobile #emails-view .page-header > div,
7876 .ui-mode-mobile #contacts-view .page-header > div {
7877 gap: 0 !important;
7878 flex-wrap: wrap;
7879 }
7880 .ui-mode-mobile .page-header > div .btn,
7881 .ui-mode-mobile #emails-view .page-header > div .btn,
7882 .ui-mode-mobile #contacts-view .page-header > div .btn,
7883 .ui-mode-mobile .bulk-actions-bar .btn {
7884 flex: 1 1 0;
7885 min-width: 0;
7886 padding: 0.4rem 0.5rem;
7887 font-size: 0.75rem;
7888 border-radius: 0;
7889 border-right-width: 0;
7890 white-space: nowrap;
7891 }
7892 .ui-mode-mobile .page-header > div .btn:first-child,
7893 .ui-mode-mobile #emails-view .page-header > div .btn:first-child,
7894 .ui-mode-mobile #contacts-view .page-header > div .btn:first-child,
7895 .ui-mode-mobile .bulk-actions-bar .btn:first-of-type {
7896 border-top-left-radius: var(--radius-sm);
7897 border-bottom-left-radius: var(--radius-sm);
7898 }
7899 /* Right-cap the visually-last button. `.btn-primary` (Compose) is hidden
7900 on mobile via display:none but stays in the DOM, so `:last-child` would
7901 pick the hidden one. Cover both: actual last child, or the button
7902 immediately before a hidden primary. */
7903 .ui-mode-mobile .page-header > div .btn:last-child,
7904 .ui-mode-mobile .page-header > div .btn:has(+ .btn-primary),
7905 .ui-mode-mobile #emails-view .page-header > div .btn:last-child,
7906 .ui-mode-mobile #emails-view .page-header > div .btn:has(+ .btn-primary),
7907 .ui-mode-mobile #contacts-view .page-header > div .btn:last-child,
7908 .ui-mode-mobile #contacts-view .page-header > div .btn:has(+ .btn-primary) {
7909 border-top-right-radius: var(--radius-sm);
7910 border-bottom-right-radius: var(--radius-sm);
7911 border-right-width: var(--border-width);
7912 }
7913 /* Bulk-actions: 4 contiguous buttons form a block; bulk-select-all is
7914 pushed right by margin-left:auto so it stays standalone. */
7915 .ui-mode-mobile .bulk-actions-bar {
7916 gap: 0;
7917 }
7918 .ui-mode-mobile .bulk-actions-bar .bulk-count {
7919 margin-right: 0.5rem;
7920 }
7921 .ui-mode-mobile .bulk-actions-bar .btn:not(.bulk-select-all) + .bulk-select-all {
7922 border-right-width: var(--border-width);
7923 border-radius: var(--radius-sm);
7924 }
7925 .ui-mode-mobile .bulk-actions-bar .btn:not(.bulk-select-all):nth-last-of-type(2) {
7926 border-top-right-radius: var(--radius-sm);
7927 border-bottom-right-radius: var(--radius-sm);
7928 border-right-width: var(--border-width);
7929 }
7930 .ui-mode-mobile .bulk-select-all {
7931 margin-left: auto;
7932 }
7933
7934 /* Email filter row: let selects shrink and wrap instead of forcing 120px. */
7935 .ui-mode-mobile #emails-view .form-select[id^="email-"] {
7936 min-width: 0 !important;
7937 flex: 1;
7938 }
7939
7940 /* Compact form controls. Keep font-size at 1rem (16px) — iOS Safari/WKWebView
7941 auto-zooms when a focused input is below 16px. Only shave padding. */
7942 .ui-mode-mobile .form-input,
7943 .ui-mode-mobile .form-select,
7944 .ui-mode-mobile .form-textarea {
7945 padding: 0.45rem 0.65rem;
7946 }
7947 .ui-mode-mobile .form-textarea {
7948 min-height: 72px;
7949 }
7950 .ui-mode-mobile .form-group {
7951 margin-bottom: 0.75rem;
7952 }
7953 .ui-mode-mobile .form-label {
7954 margin-bottom: 0.25rem;
7955 }
7956 .ui-mode-mobile .form-actions {
7957 gap: 0.5rem;
7958 margin-top: 1rem;
7959 }
7960 .ui-mode-mobile .quick-add-input {
7961 padding: 0.55rem 0.75rem;
7962 }
7963 .ui-mode-mobile .quick-add {
7964 gap: 0.5rem;
7965 margin-bottom: 1rem;
7966 }
7967
7968 /* Snooze + bulk-modal option rows (date/snooze pickers) — tighten the
7969 generous stacked-row padding so more options fit above the keyboard. */
7970 .ui-mode-mobile .snooze-option,
7971 .ui-mode-mobile .bulk-modal-option-btn {
7972 padding: 0.55rem 0.75rem;
7973 }
7974 .ui-mode-mobile .snooze-options {
7975 gap: 0.35rem;
7976 }
7977
7978 /* Modal chrome: trim header + content padding so date/snooze/compose
7979 modals reclaim ~24px of vertical room above the keyboard. */
7980 .ui-mode-mobile .modal-header {
7981 padding: 0.6rem 0.9rem;
7982 }
7983 .ui-mode-mobile .modal-header h2, .ui-mode-mobile .modal-title {
7984 font-size: 1.05rem;
7985 }
7986 .ui-mode-mobile .modal-content {
7987 padding: 0.9rem;
7988 }
7989 .ui-mode-mobile .modal-content > .form-actions:last-child,
7990 .ui-mode-mobile .modal-content form > .form-actions:last-child {
7991 margin-top: 0.9rem;
7992 padding-top: 0.5rem;
7993 }
7994
7995 /* --- Modal → Bottom Sheet --- */
7996 /* Lift the entire overlay above the mobile tab bar so bottom-sheet modals
7997 and their content aren't clipped behind it. */
7998 .ui-mode-mobile .modal-overlay {
7999 align-items: flex-end;
8000 bottom: calc(52px + env(safe-area-inset-bottom, 0px));
8001 }
8002
8003 .ui-mode-mobile .modal-container {
8004 width: 100% !important;
8005 max-width: 100% !important;
8006 max-height: calc(100vh - 52px - env(safe-area-inset-bottom, 0px) - env(safe-area-inset-top, 0px));
8007 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
8008 margin: 0;
8009 border-bottom: none;
8010 padding-bottom: 0;
8011 }
8012
8013 .ui-mode-mobile .modal-container.modal-large {
8014 max-width: 100% !important;
8015 width: 100% !important;
8016 max-height: calc(100vh - 52px - env(safe-area-inset-bottom, 0px) - env(safe-area-inset-top, 0px));
8017 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
8018 }
8019
8020 .ui-mode-mobile .modal-drag-handle {
8021 display: block;
8022 }
8023
8024 .ui-mode-mobile .modal-header {
8025 padding: 0.75rem 1rem;
8026 }
8027
8028 .ui-mode-mobile .modal-content {
8029 padding: 1rem;
8030 }
8031
8032 /* Mobile uses different modal animations (slide up/down from bottom rather
8033 than fade-and-scale). @keyframes can't be scoped — defined globally under
8034 distinct names and applied via animation-name override below. */
8035 @keyframes modalSlideInMobile {
8036 from { transform: translateY(100%); }
8037 to { transform: translateY(0); }
8038 }
8039
8040 @keyframes modalSlideOutMobile {
8041 from { transform: translateY(0); }
8042 to { transform: translateY(100%); }
8043 }
8044
8045 .ui-mode-mobile .modal-container {
8046 animation-name: modalSlideInMobile;
8047 }
8048 .ui-mode-mobile .modal-overlay.closing .modal-container {
8049 animation-name: modalSlideOutMobile;
8050 }
8051
8052 /* --- Toast repositioning for mobile --- */
8053 .ui-mode-mobile .toast,
8054 .ui-mode-mobile .toast-undo {
8055 bottom: calc(env(safe-area-inset-bottom, 0px) + 4.5rem) !important;
8056 left: 1rem !important;
8057 right: 1rem !important;
8058 max-width: none !important;
8059 }
8060
8061 /* --- Task View: Card Reflow --- */
8062 .ui-mode-mobile .task-table {
8063 border: none;
8064 box-shadow: none;
8065 background: transparent;
8066 }
8067
8068 .ui-mode-mobile .task-header-row {
8069 display: none !important;
8070 }
8071
8072 .ui-mode-mobile .task-row {
8073 display: flex !important;
8074 flex-direction: column;
8075 gap: 0.25rem;
8076 padding: 0.75rem 1rem;
8077 margin-bottom: 0.5rem;
8078 background: var(--surface-raised);
8079 border: var(--border-width-sm) solid var(--border);
8080 border-radius: var(--radius-md);
8081 border-left: 4px solid var(--content-muted);
8082 }
8083
8084 .ui-mode-mobile .task-row.task-pending { border-left-color: var(--content-muted); }
8085 .ui-mode-mobile .task-row .task-cell.priority-h ~ .task-cell:first-child,
8086 .ui-mode-mobile .task-row:has(.priority-h) { border-left-color: var(--danger); }
8087 .ui-mode-mobile .task-row:has(.priority-m) { border-left-color: var(--warning); }
8088 .ui-mode-mobile .task-row:has(.priority-l) { border-left-color: var(--content-muted); }
8089
8090 .ui-mode-mobile .task-row .task-cell {
8091 display: flex !important;
8092 overflow: visible;
8093 padding: 0;
8094 }
8095
8096 .ui-mode-mobile .task-cell.task-description {
8097 font-weight: 600;
8098 font-size: var(--font-size-base);
8099 }
8100
8101 .ui-mode-mobile .task-cell.task-project,
8102 .ui-mode-mobile .task-cell.task-due {
8103 font-size: var(--font-size-sm);
8104 color: var(--content-secondary);
8105 }
8106
8107 /* Show project and due inline */
8108 .ui-mode-mobile .task-row .task-cell.task-project::before {
8109 content: none;
8110 }
8111
8112 /* Hide priority letter (shown via left border color), recurrence, progress columns */
8113 .ui-mode-mobile .task-row .task-cell:nth-child(3),
8114 .ui-mode-mobile .task-cell.task-recurrence,
8115 .ui-mode-mobile .task-cell.task-progress {
8116 display: none !important;
8117 }
8118
8119 /* Task meta row: project + due side-by-side */
8120 .ui-mode-mobile .task-cell.task-project {
8121 order: 2;
8122 }
8123 .ui-mode-mobile .task-cell.task-due {
8124 order: 3;
8125 }
8126 .ui-mode-mobile .task-cell.task-description {
8127 order: 1;
8128 }
8129 .ui-mode-mobile .task-cell.task-actions-cell {
8130 order: 4;
8131 justify-content: flex-end;
8132 }
8133
8134 /* Show subtask progress inline if present */
8135 .ui-mode-mobile .task-cell.task-progress:has(.progress-bar-container) {
8136 display: flex !important;
8137 order: 5;
8138 }
8139
8140 .ui-mode-mobile .task-actions-cell .bulk-checkbox {
8141 display: none;
8142 }
8143
8144 .ui-mode-mobile .kebab-btn {
8145 opacity: 1;
8146 }
8147
8148 /* --- Mobile Sort & Filter --- */
8149 .ui-mode-mobile .mobile-sort-bar {
8150 display: flex;
8151 }
8152
8153 .ui-mode-mobile .mobile-filter-toggle {
8154 display: inline-flex;
8155 align-items: center;
8156 gap: 0.25rem;
8157 padding: 0.5rem 0.75rem;
8158 background: var(--surface-raised);
8159 border: var(--border-width-sm) solid var(--border);
8160 border-radius: var(--radius-sm);
8161 font-size: var(--font-size-sm);
8162 font-weight: 600;
8163 cursor: pointer;
8164 }
8165
8166 .ui-mode-mobile .filter-bar {
8167 display: none !important;
8168 }
8169
8170 .ui-mode-mobile .filter-bar.mobile-visible {
8171 display: flex !important;
8172 flex-direction: column;
8173 position: fixed;
8174 bottom: calc(52px + env(safe-area-inset-bottom, 0px));
8175 left: 0;
8176 right: 0;
8177 background: var(--surface-raised);
8178 border-top: var(--border-width) solid var(--border);
8179 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
8180 padding: 1rem;
8181 z-index: 1050;
8182 box-shadow: 0 -4px 12px rgba(0,0,0,0.1);
8183 }
8184
8185 /* --- Events View: List Reflow --- */
8186 .ui-mode-mobile .event-header-row {
8187 display: none !important;
8188 }
8189
8190 .ui-mode-mobile .event-row-virtual {
8191 display: flex !important;
8192 flex-direction: column;
8193 gap: 0.125rem;
8194 padding: 0.75rem 1rem;
8195 border-bottom: 1px solid var(--surface-overlay);
8196 }
8197
8198 .ui-mode-mobile .event-cell-date {
8199 font-weight: 700;
8200 font-size: var(--font-size-sm);
8201 color: var(--content-secondary);
8202 }
8203
8204 .ui-mode-mobile .event-cell-time {
8205 font-size: var(--font-size-sm);
8206 color: var(--content-muted);
8207 }
8208
8209 .ui-mode-mobile .event-cell-title {
8210 font-weight: 600;
8211 font-size: var(--font-size-base);
8212 }
8213
8214 .ui-mode-mobile .event-cell-location {
8215 font-size: var(--font-size-sm);
8216 color: var(--content-secondary);
8217 }
8218
8219 .ui-mode-mobile .event-date-group-header {
8220 display: flex;
8221 position: sticky;
8222 top: 0;
8223 z-index: 5;
8224 padding: 0.5rem 1rem;
8225 background: var(--surface-overlay);
8226 font-weight: 700;
8227 font-size: var(--font-size-sm);
8228 text-transform: uppercase;
8229 letter-spacing: 0.05em;
8230 color: var(--content);
8231 border-bottom: var(--border-width-sm) solid var(--border);
8232 }
8233
8234 /* --- Emails: Tighter mobile layout --- */
8235 .ui-mode-mobile .email-item {
8236 padding: 0.625rem 0.75rem;
8237 }
8238
8239 .ui-mode-mobile .email-from {
8240 font-size: var(--font-size-sm);
8241 }
8242
8243 .ui-mode-mobile .email-subject {
8244 font-size: var(--font-size-base);
8245 }
8246
8247 .ui-mode-mobile .email-preview {
8248 display: none;
8249 }
8250
8251 .ui-mode-mobile .email-date {
8252 font-size: var(--font-size-xs);
8253 }
8254
8255 .ui-mode-mobile .email-item .bulk-checkbox {
8256 display: none;
8257 }
8258
8259 /* --- Day Plan --- */
8260 .ui-mode-mobile .day-plan-content {
8261 flex-direction: column;
8262 }
8263
8264 .ui-mode-mobile .day-plan-sidebar {
8265 width: 100%;
8266 max-height: none;
8267 border-top: var(--border-width-sm) solid var(--border);
8268 order: 2;
8269 }
8270
8271 .ui-mode-mobile .day-plan-sidebar.collapsed .sidebar-task-list {
8272 display: none;
8273 }
8274
8275 .ui-mode-mobile .day-plan-sidebar-toggle {
8276 display: flex;
8277 align-items: center;
8278 justify-content: space-between;
8279 width: 100%;
8280 padding: 0.625rem 0.75rem;
8281 background: var(--surface-overlay);
8282 border: none;
8283 border-bottom: 1px solid var(--border);
8284 font-size: var(--font-size-sm);
8285 font-weight: 700;
8286 cursor: pointer;
8287 color: var(--content);
8288 }
8289
8290 .ui-mode-mobile .day-plan-main {
8291 order: 1;
8292 }
8293
8294 .ui-mode-mobile .day-plan-nav {
8295 flex-wrap: wrap;
8296 gap: 0.25rem;
8297 }
8298
8299 /* --- Weekly Review --- */
8300 .ui-mode-mobile .weekly-review-content {
8301 padding: 0;
8302 }
8303
8304 /* --- Monthly Review --- */
8305 .ui-mode-mobile .monthly-review-content {
8306 padding: 0;
8307 }
8308
8309 /* --- Review textareas: auto-grow friendly --- */
8310 .ui-mode-mobile .month-reflection-textarea,
8311 .ui-mode-mobile .prompt-input {
8312 resize: none;
8313 overflow: hidden;
8314 }
8315
8316 .ui-mode-mobile .monthly-review-nav {
8317 flex-wrap: wrap;
8318 gap: 0.25rem;
8319 }
8320
8321 .ui-mode-mobile .monthly-review-month-display {
8322 font-size: 1rem;
8323 }
8324
8325 /* --- Day Summary Sheet --- */
8326 .ui-mode-mobile .day-summary-sheet {
8327 padding: 0.5rem 0;
8328 }
8329
8330 .ui-mode-mobile .day-summary-date {
8331 font-size: 1rem;
8332 font-weight: 700;
8333 margin-bottom: 0.75rem;
8334 color: var(--content);
8335 }
8336
8337 .ui-mode-mobile .day-summary-stats {
8338 display: flex;
8339 gap: 0.5rem;
8340 margin-bottom: 1rem;
8341 }
8342
8343 .ui-mode-mobile .day-summary-chip {
8344 padding: 0.25rem 0.75rem;
8345 background: var(--surface-overlay);
8346 border-radius: var(--radius-sm);
8347 font-size: var(--font-size-sm);
8348 font-weight: 600;
8349 color: var(--content-secondary);
8350 }
8351
8352 .ui-mode-mobile .day-summary-list {
8353 list-style: none;
8354 padding: 0;
8355 margin: 0 0 1rem 0;
8356 }
8357
8358 .ui-mode-mobile .day-summary-item {
8359 padding: 0.5rem 0;
8360 border-bottom: 1px solid var(--surface-overlay);
8361 font-size: var(--font-size-sm);
8362 color: var(--content);
8363 }
8364
8365 .ui-mode-mobile .day-summary-time {
8366 font-weight: 600;
8367 color: var(--content-secondary);
8368 margin-right: 0.5rem;
8369 }
8370
8371 .ui-mode-mobile .day-summary-more {
8372 color: var(--content-muted);
8373 font-style: italic;
8374 }
8375
8376 .ui-mode-mobile .day-summary-empty {
8377 color: var(--content-muted);
8378 font-size: var(--font-size-sm);
8379 margin: 0.5rem 0 1rem;
8380 }
8381
8382 .ui-mode-mobile .day-summary-go-btn {
8383 width: 100%;
8384 margin-top: 0.5rem;
8385 }
8386
8387 /* --- Bulk Actions --- */
8388 .ui-mode-mobile .bulk-actions-bar {
8389 position: fixed;
8390 bottom: calc(52px + env(safe-area-inset-bottom, 0px));
8391 left: 0;
8392 right: 0;
8393 z-index: 1050;
8394 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
8395 box-shadow: 0 -4px 12px rgba(0,0,0,0.15);
8396 }
8397
8398 /* --- Pagination --- */
8399 .ui-mode-mobile .pagination-controls {
8400 padding: 0.5rem;
8401 }
8402
8403 .ui-mode-mobile .pagination-controls .btn {
8404 padding: 0.5rem 0.75rem;
8405 font-size: var(--font-size-sm);
8406 }
8407
8408
8409 /* ===================================================================
8410 60. Touch Device Hover Disable
8411 =================================================================== */
8412
8413 @media (hover: none) {
8414 .task-row:hover {
8415 background-color: transparent;
8416 }
8417
8418 .task-row-clickable:hover {
8419 background: transparent;
8420 }
8421
8422 .event-row-virtual:hover {
8423 background-color: transparent;
8424 }
8425
8426 .email-item:hover {
8427 background-color: transparent;
8428 }
8429
8430 .card:hover {
8431 background-color: var(--surface-raised);
8432 transform: none;
8433 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
8434 }
8435
8436 .btn:hover {
8437 background: var(--surface-raised);
8438 }
8439
8440 .btn-primary:hover {
8441 background-color: var(--action);
8442 }
8443
8444 .btn-danger:hover {
8445 background-color: var(--danger);
8446 }
8447
8448 .card:hover {
8449 background-color: var(--surface-raised);
8450 transform: none;
8451 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
8452 }
8453
8454 .kanban-card:hover {
8455 background: var(--surface-raised);
8456 transform: none;
8457 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
8458 }
8459
8460 .saved-view-item:hover {
8461 background: var(--surface-raised);
8462 color: var(--content);
8463 transform: none;
8464 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
8465 }
8466
8467 .context-menu-item:hover {
8468 background: transparent;
8469 color: var(--content);
8470 }
8471
8472 .modal-close:hover {
8473 background: var(--surface-raised);
8474 color: var(--content);
8475 }
8476
8477 .month-heatmap-cell:hover {
8478 background: transparent;
8479 transform: none;
8480 }
8481
8482 /* Row-action kebabs are hover-revealed on desktop; on touch always show them */
8483 .task-row .kebab-btn,
8484 .email-item .kebab-btn,
8485 .event-row-virtual .kebab-btn {
8486 opacity: 1;
8487 }
8488
8489 /* No physical keyboard on touch — hide the `?` shortcuts entry points */
8490 .shortcut-hint-btn {
8491 display: none;
8492 }
8493
8494 /* Stack the time-block picker and presets vertically; enforce 44px touch targets */
8495 .time-block-quick-options {
8496 grid-template-columns: 1fr;
8497 }
8498 .time-block-quick-btn,
8499 .duration-preset {
8500 min-height: 44px;
8501 padding: 0.75rem;
8502 font-size: 1rem;
8503 }
8504 }
8505
8506 /* Touch-device body class (set by touch.js) — equivalent guards for browsers
8507 that report (hover: hover) but are still touch-first (e.g. some Chromebooks). */
8508 body.is-touch .task-row .kebab-btn,
8509 body.is-touch .email-item .kebab-btn,
8510 body.is-touch .event-row-virtual .kebab-btn {
8511 opacity: 1;
8512 }
8513 body.is-touch .shortcut-hint-btn {
8514 display: none;
8515 }
8516
8517 /* ===================================================================
8518 61. Kanban Board
8519 =================================================================== */
8520
8521 /* View Toggle */
8522 .view-toggle {
8523 display: flex;
8524 gap: 0;
8525 margin-left: auto;
8526 }
8527
8528 .view-toggle-btn {
8529 padding: 0.35rem 0.75rem;
8530 border: var(--border-width-sm) solid var(--border);
8531 background: var(--surface-overlay);
8532 font-family: var(--font-body);
8533 font-size: var(--font-size-md);
8534 cursor: pointer;
8535 transition: background var(--transition-fast), box-shadow var(--transition-fast);
8536 }
8537
8538 .view-toggle-btn.active {
8539 background: var(--surface-raised);
8540 font-weight: 600;
8541 }
8542
8543 .view-toggle-btn:first-child { border-radius: var(--radius-xs) 0 0 var(--radius-xs); }
8544 .view-toggle-btn:last-child { border-radius: 0 var(--radius-xs) var(--radius-xs) 0; border-left: none; }
8545
8546 /* Kanban Board */
8547 .kanban-board {
8548 display: grid;
8549 grid-template-columns: repeat(3, 1fr);
8550 gap: 1rem;
8551 padding: 0.5rem 0;
8552 min-height: 400px;
8553 }
8554
8555 .kanban-column {
8556 background: var(--surface-raised);
8557 border: var(--border-width) solid var(--border);
8558 display: flex;
8559 flex-direction: column;
8560 min-height: 300px;
8561 max-height: calc(100vh - 200px);
8562 }
8563
8564 .kanban-column-header {
8565 padding: 0.75rem 1rem;
8566 border-bottom: 2px solid var(--border);
8567 font-family: var(--font-heading);
8568 font-weight: 700;
8569 display: flex;
8570 justify-content: space-between;
8571 align-items: center;
8572 }
8573
8574 .kanban-column-count {
8575 font-family: var(--font-body);
8576 font-size: var(--font-size-sm);
8577 color: var(--content-secondary);
8578 }
8579
8580 .kanban-column-body {
8581 flex: 1;
8582 overflow-y: auto;
8583 padding: 0.5rem;
8584 display: flex;
8585 flex-direction: column;
8586 gap: 0.5rem;
8587 }
8588
8589 .kanban-column.drag-over {
8590 background-color: var(--surface-sunken);
8591 }
8592
8593 /* Kanban Cards — marker class for kanban-specific scoping. Callsites compose
8594 `.card .kanban-card`; chrome + hover transform inherit from .card. Deltas:
8595 thinner border, square corners, tighter padding, grab cursor, priority
8596 left-border hook. */
8597 .kanban-card {
8598 padding: 0.75rem;
8599 border-width: var(--border-width-sm);
8600 border-radius: 0;
8601 cursor: grab;
8602 border-left: 4px solid transparent;
8603 }
8604
8605 .kanban-card.dragging { opacity: 0.5; cursor: grabbing; }
8606 .kanban-card.priority-high { border-left-color: var(--danger); }
8607 .kanban-card.priority-medium { border-left-color: var(--warning); }
8608 .kanban-card.priority-low { border-left-color: var(--success); }
8609
8610 .kanban-card-title { font-weight: 600; margin-bottom: 0.25rem; }
8611 .kanban-card-meta { font-size: var(--font-size-sm); color: var(--content-secondary); display: flex; gap: 0.5rem; flex-wrap: wrap; }
8612 .kanban-card-due.overdue { color: var(--danger); font-weight: 600; }
8613
8614 .progress-bar-mini { height: 3px; background: var(--surface-sunken); border-radius: 2px; margin-top: 0.5rem; }
8615 .progress-bar-mini .progress-fill { height: 100%; background: var(--success); border-radius: 2px; }
8616
8617 /* Kanban Responsive */
8618 .ui-mode-mobile .kanban-board { grid-template-columns: 1fr; }
8619 .ui-mode-mobile .kanban-column { max-height: none; }
8620
8621
8622 /* ===================================================================
8623 62. Timer Widget (Floating Bottom Bar)
8624 =================================================================== */
8625
8626 .timer-widget {
8627 position: fixed;
8628 bottom: 0;
8629 left: 0;
8630 right: 0;
8631 z-index: 900;
8632 background: var(--surface-page);
8633 border-top: var(--border-width) solid var(--border);
8634 box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
8635 padding: 0.5rem 1rem;
8636 transition: transform 0.2s ease;
8637 }
8638
8639 .timer-widget.hidden {
8640 transform: translateY(100%);
8641 pointer-events: none;
8642 }
8643
8644 .timer-widget-inner {
8645 display: flex;
8646 align-items: center;
8647 gap: 1rem;
8648 max-width: 800px;
8649 margin: 0 auto;
8650 }
8651
8652 .timer-task-name {
8653 flex: 1;
8654 font-weight: 600;
8655 overflow: hidden;
8656 text-overflow: ellipsis;
8657 white-space: nowrap;
8658 }
8659
8660 .timer-elapsed {
8661 font-family: var(--font-mono, monospace);
8662 font-size: 1.125rem;
8663 font-weight: 700;
8664 color: var(--action);
8665 min-width: 5rem;
8666 text-align: center;
8667 }
8668
8669 .timer-actions {
8670 display: flex;
8671 gap: 0.5rem;
8672 }
8673
8674 /* ===================================================================
8675 63. Focus Timer (Pomodoro Overlay)
8676 =================================================================== */
8677
8678 .focus-overlay {
8679 position: fixed;
8680 inset: 0;
8681 z-index: 1000;
8682 background: var(--surface-page);
8683 display: flex;
8684 align-items: center;
8685 justify-content: center;
8686 transition: opacity 0.3s ease;
8687 }
8688
8689 .focus-overlay.hidden {
8690 opacity: 0;
8691 pointer-events: none;
8692 }
8693
8694 .focus-overlay-content {
8695 text-align: center;
8696 max-width: 400px;
8697 width: 100%;
8698 padding: 2rem;
8699 }
8700
8701 .focus-header {
8702 display: flex;
8703 align-items: center;
8704 justify-content: space-between;
8705 margin-bottom: 2rem;
8706 }
8707
8708 .focus-label {
8709 font-family: var(--font-heading);
8710 font-size: 1.25rem;
8711 font-weight: 700;
8712 }
8713
8714 .focus-presets {
8715 display: flex;
8716 gap: 0.5rem;
8717 }
8718
8719 .focus-preset-btn.active {
8720 background: var(--action);
8721 color: var(--surface-page);
8722 border-color: var(--action);
8723 }
8724
8725 .focus-countdown {
8726 font-family: var(--font-mono, monospace);
8727 font-size: 4rem;
8728 font-weight: 700;
8729 line-height: 1;
8730 margin-bottom: 1.5rem;
8731 color: var(--content);
8732 }
8733
8734 .focus-progress-bar {
8735 height: 6px;
8736 background: var(--surface-sunken);
8737 border-radius: 3px;
8738 margin-bottom: 1.5rem;
8739 overflow: hidden;
8740 }
8741
8742 .focus-progress-fill {
8743 height: 100%;
8744 background: var(--action);
8745 border-radius: 3px;
8746 transition: width 1s linear;
8747 }
8748
8749 .focus-task-name {
8750 color: var(--content-secondary);
8751 margin-bottom: 2rem;
8752 font-size: 0.9rem;
8753 }
8754
8755 .focus-actions {
8756 display: flex;
8757 gap: 1rem;
8758 justify-content: center;
8759 }
8760
8761 /* ===================================================================
8762 64. Time Summary Panel (Day View)
8763 =================================================================== */
8764
8765 .time-summary-section {
8766 margin-bottom: 1rem;
8767 }
8768
8769 .time-summary-toggle {
8770 display: flex;
8771 align-items: center;
8772 gap: 0.5rem;
8773 width: 100%;
8774 padding: 0.5rem;
8775 background: none;
8776 border: none;
8777 font-family: var(--font-heading);
8778 font-size: 0.875rem;
8779 font-weight: 700;
8780 color: var(--content);
8781 cursor: pointer;
8782 text-align: left;
8783 }
8784
8785 .time-summary-toggle:hover {
8786 color: var(--action);
8787 }
8788
8789 .time-summary-toggle-icon {
8790 font-size: 0.625rem;
8791 transition: transform 0.15s ease;
8792 }
8793
8794 .time-summary-body {
8795 padding: 0.5rem;
8796 overflow: hidden;
8797 transition: max-height 0.2s ease;
8798 max-height: 500px;
8799 }
8800
8801 .time-summary-body.collapsed {
8802 max-height: 0;
8803 padding: 0 0.5rem;
8804 }
8805
8806 .time-summary-today {
8807 display: flex;
8808 justify-content: space-between;
8809 align-items: center;
8810 padding: 0.5rem 0;
8811 border-bottom: 1px solid var(--border);
8812 margin-bottom: 0.5rem;
8813 }
8814
8815 .time-summary-today-label {
8816 font-weight: 600;
8817 font-size: 0.875rem;
8818 }
8819
8820 .time-summary-today-value {
8821 font-family: var(--font-mono, monospace);
8822 font-weight: 700;
8823 font-size: 1rem;
8824 color: var(--action);
8825 }
8826
8827 .time-summary-week-header {
8828 font-size: 0.75rem;
8829 font-weight: 700;
8830 text-transform: uppercase;
8831 letter-spacing: 0.05em;
8832 color: var(--content-secondary);
8833 margin-bottom: 0.5rem;
8834 }
8835
8836 .time-summary-project {
8837 margin-bottom: 0.5rem;
8838 }
8839
8840 .time-summary-project-info {
8841 display: flex;
8842 justify-content: space-between;
8843 align-items: center;
8844 font-size: 0.8125rem;
8845 margin-bottom: 0.25rem;
8846 }
8847
8848 .time-summary-project-name {
8849 color: var(--content);
8850 overflow: hidden;
8851 text-overflow: ellipsis;
8852 white-space: nowrap;
8853 flex: 1;
8854 }
8855
8856 .time-summary-project-time {
8857 font-family: var(--font-mono, monospace);
8858 font-weight: 600;
8859 font-size: 0.75rem;
8860 color: var(--content-secondary);
8861 margin-left: 0.5rem;
8862 flex-shrink: 0;
8863 }
8864
8865 .time-summary-bar {
8866 height: 4px;
8867 background: var(--surface-sunken);
8868 border-radius: 2px;
8869 overflow: hidden;
8870 }
8871
8872 .time-summary-bar-fill {
8873 height: 100%;
8874 background: var(--action);
8875 border-radius: 2px;
8876 }
8877
8878 /* ===================================================================
8879 65. Task Time Tracking UI
8880 =================================================================== */
8881
8882 /* Inline action buttons in day sidebar unscheduled tasks */
8883 .unscheduled-task-actions {
8884 display: flex;
8885 gap: 0.25rem;
8886 margin-top: 0.375rem;
8887 }
8888
8889 .unscheduled-task-actions .btn {
8890 font-size: 0.7rem;
8891 padding: 0.125rem 0.375rem;
8892 min-height: auto;
8893 line-height: 1.4;
8894 }
8895
8896 /* Compact time badge in task rows */
8897 .task-time-badge {
8898 display: inline-block;
8899 font-family: var(--font-mono, monospace);
8900 font-size: 0.7rem;
8901 font-weight: 600;
8902 color: var(--content-secondary);
8903 background: var(--surface-overlay);
8904 border: var(--border-width-sm) solid var(--border);
8905 border-radius: var(--radius-sm);
8906 padding: 0.05rem 0.35rem;
8907 margin-left: 0.375rem;
8908 vertical-align: middle;
8909 white-space: nowrap;
8910 }
8911
8912 .task-time-badge.over-estimate {
8913 color: var(--danger);
8914 border-color: var(--danger);
8915 }
8916
8917 /* Play icon for started tasks — entry point into time tracking */
8918 .task-started-icon {
8919 display: inline-block;
8920 width: 0;
8921 height: 0;
8922 border-style: solid;
8923 border-width: 5px 0 5px 8px;
8924 border-color: transparent transparent transparent var(--success);
8925 margin-right: 0.375rem;
8926 vertical-align: middle;
8927 cursor: pointer;
8928 opacity: 0.8;
8929 flex-shrink: 0;
8930 }
8931 .task-started-icon:hover {
8932 opacity: 1;
8933 }
8934
8935 /* Pulsing indicator for running timer */
8936 .task-timer-active {
8937 display: inline-block;
8938 width: 8px;
8939 height: 8px;
8940 background: var(--danger);
8941 border-radius: var(--radius-full);
8942 margin-left: 0.375rem;
8943 vertical-align: middle;
8944 animation: timer-pulse 1.5s ease-in-out infinite;
8945 }
8946
8947 @keyframes timer-pulse {
8948 0%, 100% { opacity: 1; transform: scale(1); }
8949 50% { opacity: 0.4; transform: scale(0.8); }
8950 }
8951
8952 /* Timer widget mobile adjustment */
8953 .ui-mode-mobile .timer-widget {
8954 bottom: calc(52px + env(safe-area-inset-bottom, 0px));
8955 }
8956 .ui-mode-mobile .focus-countdown {
8957 font-size: 3rem;
8958 }
8959
8960
8961 /* ===================================================================
8962 66. Timer Subview (Time tab pill)
8963 =================================================================== */
8964
8965 .timer-active-banner {
8966 display: flex;
8967 align-items: center;
8968 gap: 1rem;
8969 padding: 0.875rem 1rem;
8970 background: var(--surface-overlay);
8971 border: var(--border-width) solid var(--action);
8972 border-radius: var(--radius-md);
8973 margin-bottom: 1.5rem;
8974 }
8975
8976 .timer-active-info {
8977 flex: 1;
8978 min-width: 0;
8979 }
8980
8981 .timer-active-label {
8982 display: block;
8983 font-size: 0.75rem;
8984 font-weight: 700;
8985 text-transform: uppercase;
8986 letter-spacing: 0.05em;
8987 color: var(--action);
8988 margin-bottom: 0.125rem;
8989 }
8990
8991 .timer-active-task {
8992 display: block;
8993 font-weight: 600;
8994 overflow: hidden;
8995 text-overflow: ellipsis;
8996 white-space: nowrap;
8997 }
8998
8999 .timer-active-elapsed {
9000 font-family: var(--font-mono, monospace);
9001 font-size: 1.25rem;
9002 font-weight: 700;
9003 color: var(--action);
9004 min-width: 5rem;
9005 text-align: center;
9006 }
9007
9008 .timer-active-actions {
9009 display: flex;
9010 gap: 0.5rem;
9011 }
9012
9013 .timer-focus-split {
9014 display: flex;
9015 align-items: center;
9016 gap: 0.375rem;
9017 padding: 0.5rem 0;
9018 margin-bottom: 0.5rem;
9019 }
9020
9021 .timer-focus-split-label {
9022 font-size: 0.8125rem;
9023 color: var(--content-secondary);
9024 font-weight: 600;
9025 margin-right: 0.25rem;
9026 }
9027
9028 .timer-split-input {
9029 width: 3.5rem;
9030 padding: 0.25rem 0.375rem;
9031 font-size: 0.875rem;
9032 font-family: var(--font-mono, monospace);
9033 text-align: center;
9034 border: var(--border-width) solid var(--border);
9035 border-radius: var(--radius-sm);
9036 background: var(--surface-page);
9037 color: var(--content);
9038 }
9039
9040 .timer-focus-split-sep {
9041 font-size: 0.8125rem;
9042 color: var(--content-secondary);
9043 }
9044
9045 .timer-task-list {
9046 display: flex;
9047 flex-direction: column;
9048 gap: 0;
9049 }
9050
9051 .timer-task-item {
9052 display: flex;
9053 align-items: center;
9054 gap: 1rem;
9055 padding: 0.75rem 0.5rem;
9056 border-bottom: 1px solid var(--border);
9057 }
9058
9059 .timer-task-item:last-child {
9060 border-bottom: none;
9061 }
9062
9063 .timer-task-info {
9064 flex: 1;
9065 min-width: 0;
9066 }
9067
9068 .timer-task-desc {
9069 display: block;
9070 font-weight: 500;
9071 overflow: hidden;
9072 text-overflow: ellipsis;
9073 white-space: nowrap;
9074 }
9075
9076 .timer-task-meta {
9077 display: flex;
9078 gap: 0.5rem;
9079 flex-wrap: wrap;
9080 margin-top: 0.25rem;
9081 font-size: 0.8125rem;
9082 color: var(--content-secondary);
9083 }
9084
9085 .timer-task-project {
9086 font-weight: 600;
9087 }
9088
9089 .timer-task-priority {
9090 font-weight: 600;
9091 }
9092
9093 .timer-task-priority.priority-h,
9094 .timer-task-priority.priority-high {
9095 color: var(--danger);
9096 }
9097
9098 .timer-task-priority.priority-m,
9099 .timer-task-priority.priority-medium {
9100 color: var(--warning);
9101 }
9102
9103 .timer-task-estimate,
9104 .timer-task-tracked {
9105 font-family: var(--font-mono, monospace);
9106 font-size: 0.75rem;
9107 }
9108
9109 .timer-task-actions {
9110 display: flex;
9111 gap: 0.375rem;
9112 flex-shrink: 0;
9113 }
9114
9115 .ui-mode-mobile .timer-active-banner {
9116 flex-wrap: wrap;
9117 }
9118 .ui-mode-mobile .timer-active-elapsed {
9119 font-size: 1rem;
9120 }
9121 .ui-mode-mobile .timer-task-item {
9122 flex-wrap: wrap;
9123 }
9124 .ui-mode-mobile .timer-task-actions {
9125 width: 100%;
9126 justify-content: flex-end;
9127 }
9128
9129
9130 /* ===================================================================
9131 67. Task Overview
9132 =================================================================== */
9133
9134 .task-overview-section {
9135 margin-bottom: 1.5rem;
9136 padding: 1rem;
9137 background: var(--surface-raised);
9138 border: var(--border-width) solid var(--border);
9139 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
9140 }
9141
9142 .task-overview-section-title {
9143 font-family: var(--font-heading);
9144 font-size: 1rem;
9145 font-weight: 700;
9146 margin-bottom: 0.75rem;
9147 display: flex;
9148 align-items: center;
9149 gap: 0.5rem;
9150 }
9151
9152 .task-overview-count {
9153 font-weight: 400;
9154 font-size: 0.85rem;
9155 color: var(--content-secondary);
9156 }
9157
9158 .task-overview-stats {
9159 display: grid;
9160 grid-template-columns: repeat(4, 1fr);
9161 gap: 0.75rem;
9162 margin-bottom: 1rem;
9163 }
9164
9165 .task-overview-stat {
9166 text-align: center;
9167 padding: 0.5rem;
9168 background: var(--surface-overlay);
9169 border: var(--border-width-sm) solid var(--border);
9170 }
9171
9172 .task-overview-stat-value {
9173 font-family: var(--font-heading);
9174 font-size: 1.25rem;
9175 font-weight: 700;
9176 }
9177
9178 .task-overview-stat-label {
9179 font-size: 0.75rem;
9180 color: var(--content-secondary);
9181 margin-top: 0.25rem;
9182 }
9183
9184 .task-overview-heatmap-nav {
9185 display: flex;
9186 align-items: center;
9187 justify-content: center;
9188 gap: 1rem;
9189 margin-bottom: 0.75rem;
9190 font-family: var(--font-heading);
9191 font-weight: 700;
9192 }
9193
9194 .task-overview-meta {
9195 display: flex;
9196 flex-direction: column;
9197 gap: 0.5rem;
9198 }
9199
9200 .task-overview-badges {
9201 display: flex;
9202 flex-wrap: wrap;
9203 gap: 0.5rem;
9204 margin-bottom: 0.25rem;
9205 }
9206
9207 .task-overview-details {
9208 display: flex;
9209 flex-direction: column;
9210 gap: 0.25rem;
9211 color: var(--content-secondary);
9212 font-size: 0.9rem;
9213 }
9214
9215 .task-overview-subtask-list {
9216 display: flex;
9217 flex-direction: column;
9218 gap: 0.25rem;
9219 margin-bottom: 0.75rem;
9220 }
9221
9222 .task-overview-subtask {
9223 display: flex;
9224 align-items: center;
9225 gap: 0.5rem;
9226 padding: 0.25rem 0;
9227 }
9228
9229 .completed-text {
9230 text-decoration: line-through;
9231 color: var(--content-secondary);
9232 }
9233
9234 .task-overview-add-form {
9235 display: flex;
9236 gap: 0.5rem;
9237 margin-top: 0.5rem;
9238 }
9239
9240 .task-overview-add-form .form-input {
9241 flex: 1;
9242 }
9243
9244 .task-overview-sessions {
9245 display: flex;
9246 flex-direction: column;
9247 gap: 0.25rem;
9248 font-size: 0.9rem;
9249 color: var(--content-secondary);
9250 }
9251
9252 .task-overview-session {
9253 padding: 0.25rem 0;
9254 border-bottom: var(--border-width-sm) solid var(--border);
9255 }
9256
9257 .task-overview-annotations {
9258 display: flex;
9259 flex-direction: column;
9260 gap: 0.5rem;
9261 margin-bottom: 0.75rem;
9262 }
9263
9264 .task-overview-annotation {
9265 padding: 0.5rem;
9266 background: var(--surface-overlay);
9267 border: var(--border-width-sm) solid var(--border);
9268 }
9269
9270 .task-overview-annotation-date {
9271 font-size: 0.75rem;
9272 color: var(--content-secondary);
9273 margin-bottom: 0.25rem;
9274 }
9275
9276 .task-overview-completion-list {
9277 margin-top: 0.75rem;
9278 font-size: 0.9rem;
9279 color: var(--content-secondary);
9280 }
9281
9282 .task-overview-completion-item {
9283 padding: 0.25rem 0;
9284 border-bottom: var(--border-width-sm) solid var(--border);
9285 }
9286
9287 .progress-bar {
9288 height: 6px;
9289 background: var(--surface-overlay);
9290 border: var(--border-width-sm) solid var(--border);
9291 margin-bottom: 0.75rem;
9292 overflow: hidden;
9293 }
9294
9295 .progress-fill {
9296 height: 100%;
9297 background: var(--success);
9298 transition: width 0.3s ease;
9299 }
9300
9301 .progress-bar.over-estimate .progress-fill {
9302 background: var(--danger);
9303 }
9304
9305
9306 /* Task overview stats in mobile UI — 2 columns instead of 4. */
9307 .ui-mode-mobile .task-overview-stats {
9308 grid-template-columns: repeat(2, 1fr);
9309 }
9310
9311 /* ===================================================================
9312 68. Plan/Review Toggle Nudge Dot
9313 =================================================================== */
9314
9315 .toggle-nudge-dot {
9316 display: inline-block;
9317 width: 7px;
9318 height: 7px;
9319 background: var(--danger);
9320 border-radius: var(--radius-full);
9321 margin-left: 0.35rem;
9322 vertical-align: middle;
9323 animation: pulse-badge 2s infinite;
9324 }
9325
9326 .view-toggle-btn {
9327 position: relative;
9328 }
9329
9330 /* ===================================================================
9331 69. Finish & Review
9332 =================================================================== */
9333
9334 .finish-review-bar {
9335 display: flex;
9336 justify-content: flex-end;
9337 padding: 1.5rem 0 1rem;
9338 margin-top: 1.5rem;
9339 border-top: 1px dashed var(--border);
9340 }
9341
9342 .finish-review-btn {
9343 position: relative;
9344 font-size: var(--font-size-lg);
9345 padding: 0.65rem 1.5rem;
9346 }
9347
9348 .finish-review-modal-content {
9349 display: flex;
9350 flex-direction: column;
9351 gap: 1.25rem;
9352 }
9353
9354 .past-review-banner {
9355 padding: 0.75rem 1rem;
9356 border: var(--border-width-sm) dashed var(--border);
9357 border-radius: var(--radius-md);
9358 background: var(--surface-overlay);
9359 color: var(--content-secondary);
9360 font-size: 0.9rem;
9361 }
9362
9363 .day-accomplished-inline {
9364 margin-top: 1.5rem;
9365 }
9366
9367 .day-accomplished-inline:empty {
9368 display: none;
9369 }
9370
9371 .day-accomplished-stats {
9372 font-size: 0.8rem;
9373 color: var(--content-secondary);
9374 margin-bottom: 0.5rem;
9375 }
9376
9377 /* ===================================================================
9378 70. Calendar Views
9379 =================================================================== */
9380
9381 .events-calendar-container {
9382 padding: 0;
9383 }
9384
9385 .calendar-nav {
9386 display: flex;
9387 align-items: center;
9388 gap: 0.5rem;
9389 margin-bottom: 1rem;
9390 }
9391
9392 .calendar-nav-label {
9393 font-family: var(--font-heading);
9394 font-size: 1.1rem;
9395 font-weight: 700;
9396 margin-left: 0.5rem;
9397 }
9398
9399 /* Month Grid */
9400 .cal-month-grid {
9401 border: var(--border-width) solid var(--border);
9402 overflow: hidden;
9403 background: var(--surface-raised);
9404 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
9405 }
9406
9407 .cal-month-header,
9408 .cal-month-cells {
9409 display: grid;
9410 grid-template-columns: repeat(7, 1fr);
9411 }
9412
9413 .cal-month-day-header {
9414 font-family: var(--font-heading);
9415 font-size: 0.75rem;
9416 font-weight: 600;
9417 text-align: center;
9418 padding: 0.5rem;
9419 text-transform: uppercase;
9420 background: var(--surface-overlay);
9421 border-bottom: var(--border-width-sm) solid var(--border);
9422 }
9423
9424 .cal-month-cell {
9425 min-height: 90px;
9426 border: var(--border-width-sm) solid var(--border);
9427 padding: 0.25rem;
9428 cursor: pointer;
9429 transition: background var(--transition-fast);
9430 }
9431
9432 .cal-month-cell:hover {
9433 background: var(--surface-overlay);
9434 }
9435
9436 .cal-month-cell.other-month {
9437 opacity: 0.4;
9438 }
9439
9440 .cal-month-cell.today {
9441 border-color: var(--action);
9442 border-width: 2px;
9443 }
9444
9445 .cal-month-cell-header {
9446 margin-bottom: 0.15rem;
9447 }
9448
9449 .cal-day-number {
9450 font-family: var(--font-heading);
9451 font-size: 0.8rem;
9452 font-weight: 600;
9453 }
9454
9455 .cal-event-chip {
9456 font-size: 0.7rem;
9457 padding: 1px 4px;
9458 margin-top: 2px;
9459 border-radius: var(--radius-xs);
9460 background: var(--action);
9461 color: var(--content-on-action);
9462 white-space: nowrap;
9463 overflow: hidden;
9464 text-overflow: ellipsis;
9465 cursor: pointer;
9466 }
9467
9468 .cal-event-chip:hover {
9469 opacity: 0.85;
9470 }
9471
9472 .cal-event-chip.block-focus { background: var(--category-one); }
9473 .cal-event-chip.block-personal { background: var(--category-four); color: var(--content); }
9474 .cal-event-chip.block-free_time { background: var(--category-two); color: var(--content); }
9475
9476 .cal-event-more {
9477 font-size: 0.65rem;
9478 color: var(--content-secondary);
9479 padding: 1px 4px;
9480 }
9481
9482 /* Month Day Detail */
9483 .month-day-detail {
9484 margin-top: 1rem;
9485 border: var(--border-width) solid var(--border);
9486 padding: 1rem;
9487 background: var(--surface-raised);
9488 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
9489 }
9490
9491 .cal-day-detail-event {
9492 display: flex;
9493 gap: 0.75rem;
9494 padding: 0.5rem 0;
9495 border-bottom: 1px solid var(--border);
9496 cursor: pointer;
9497 }
9498
9499 .cal-day-detail-event:hover {
9500 background: var(--surface-overlay);
9501 }
9502
9503 .cal-detail-time {
9504 font-weight: 600;
9505 white-space: nowrap;
9506 min-width: 100px;
9507 }
9508
9509 .cal-detail-location {
9510 color: var(--content-secondary);
9511 font-size: 0.85rem;
9512 }
9513
9514 /* Week Grid */
9515 .cal-week-grid {
9516 border: var(--border-width) solid var(--border);
9517 overflow: hidden;
9518 background: var(--surface-raised);
9519 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--border);
9520 }
9521
9522 .cal-week-header {
9523 display: grid;
9524 grid-template-columns: 60px repeat(7, 1fr);
9525 border-bottom: var(--border-width-sm) solid var(--border);
9526 background: var(--surface-overlay);
9527 }
9528
9529 .cal-week-day-header {
9530 text-align: center;
9531 padding: 0.5rem;
9532 font-family: var(--font-heading);
9533 }
9534
9535 .cal-week-day-header.today {
9536 background: color-mix(in srgb, var(--action) 15%, transparent);
9537 }
9538
9539 .cal-week-day-name {
9540 font-size: 0.75rem;
9541 text-transform: uppercase;
9542 font-weight: 600;
9543 }
9544
9545 .cal-week-day-num {
9546 font-size: 1rem;
9547 font-weight: 700;
9548 display: block;
9549 }
9550
9551 .cal-week-allday-row {
9552 display: grid;
9553 grid-template-columns: 60px repeat(7, 1fr);
9554 border-bottom: var(--border-width-sm) solid var(--border);
9555 min-height: 28px;
9556 }
9557
9558 .cal-allday-label {
9559 font-size: 0.7rem;
9560 color: var(--content-secondary);
9561 display: flex;
9562 align-items: center;
9563 justify-content: center;
9564 }
9565
9566 .cal-week-allday-cell {
9567 padding: 2px;
9568 border-left: 1px solid var(--border);
9569 }
9570
9571 .cal-week-body {
9572 display: grid;
9573 grid-template-columns: 60px repeat(7, 1fr);
9574 position: relative;
9575 overflow-y: auto;
9576 max-height: 70vh;
9577 }
9578
9579 .cal-week-time-gutter {
9580 position: relative;
9581 }
9582
9583 .cal-week-hour-label {
9584 position: absolute;
9585 right: 0.5rem;
9586 font-size: 0.7rem;
9587 color: var(--content-secondary);
9588 transform: translateY(-0.5em);
9589 }
9590
9591 .cal-week-day-col {
9592 position: relative;
9593 border-left: 1px solid var(--border);
9594 }
9595
9596 .cal-week-day-col.today {
9597 background: color-mix(in srgb, var(--action) 5%, transparent);
9598 }
9599
9600 .cal-week-hour-line {
9601 position: absolute;
9602 left: 0;
9603 right: 0;
9604 border-top: 1px dashed color-mix(in srgb, var(--border) 50%, transparent);
9605 }
9606
9607 .cal-week-event {
9608 position: absolute;
9609 left: 2px;
9610 right: 2px;
9611 border: var(--border-width-sm) solid var(--border);
9612 border-radius: var(--radius-sm);
9613 padding: 2px 4px;
9614 background: var(--action);
9615 color: var(--content-on-action);
9616 overflow: hidden;
9617 cursor: pointer;
9618 z-index: 10;
9619 font-size: 0.7rem;
9620 }
9621
9622 .cal-week-event:hover {
9623 opacity: 0.85;
9624 }
9625
9626 .cal-week-event-title {
9627 font-weight: 600;
9628 }
9629
9630 .cal-week-event-time {
9631 font-size: 0.65rem;
9632 opacity: 0.85;
9633 }
9634
9635 .cal-week-event.block-focus { background: var(--category-one); }
9636 .cal-week-event.block-personal { background: var(--category-four); color: var(--content); }
9637 .cal-week-event.block-free_time { background: var(--category-two); color: var(--content); }
9638
9639 /* Calendar in mobile UI — single-day swipe carousel, denser timeline. */
9640 html.ui-mode-mobile {
9641 --timeline-slot-h: 22px;
9642 }
9643
9644 .ui-mode-mobile .cal-month-cell {
9645 min-height: 64px;
9646 padding: 4px;
9647 }
9648 .ui-mode-mobile .cal-day-number {
9649 font-size: 0.95rem;
9650 font-weight: 600;
9651 }
9652 .ui-mode-mobile .cal-event-chip {
9653 font-size: 0.65rem;
9654 }
9655 .ui-mode-mobile .cal-week-body {
9656 max-height: 60vh;
9657 }
9658
9659 /* Single-day swipe carousel for week view */
9660 .ui-mode-mobile .cal-mobile-day {
9661 display: flex;
9662 flex-direction: column;
9663 height: 70vh;
9664 user-select: none;
9665 }
9666 .ui-mode-mobile .cal-mobile-day-header {
9667 padding: 0.75rem;
9668 font-weight: 600;
9669 text-align: center;
9670 border-bottom: 1px solid var(--border);
9671 }
9672 .ui-mode-mobile .cal-mobile-day-header.today {
9673 color: var(--action);
9674 }
9675 .ui-mode-mobile .cal-mobile-allday {
9676 padding: 0.5rem;
9677 display: flex;
9678 flex-direction: column;
9679 gap: 0.25rem;
9680 border-bottom: 1px solid var(--border);
9681 }
9682 .ui-mode-mobile .cal-mobile-day-body {
9683 position: relative;
9684 flex: 1;
9685 overflow-y: auto;
9686 display: grid;
9687 grid-template-columns: 48px 1fr;
9688 }
9689 .ui-mode-mobile .cal-mobile-day-col {
9690 position: relative;
9691 border-left: 1px solid var(--border);
9692 }
9693
9694 /* Settings Page — Mobile */
9695 .ui-mode-mobile .settings-page-layout { flex-direction: column; }
9696 .ui-mode-mobile .settings-sidebar {
9697 width: 100%;
9698 border-right: none;
9699 border-bottom: 1px solid var(--border);
9700 padding: 0.75rem;
9701 flex-direction: row;
9702 flex-wrap: wrap;
9703 align-items: center;
9704 }
9705 .ui-mode-mobile .settings-back { margin-bottom: 0; margin-right: 0.5rem; padding: 0.5rem; }
9706 .ui-mode-mobile .settings-nav-items { flex-direction: row; flex-wrap: wrap; gap: 0.25rem; }
9707 .ui-mode-mobile .settings-nav-item { padding: 0.5rem 0.75rem; border-left: none; border-radius: var(--radius-sm); }
9708 .ui-mode-mobile .settings-nav-item.active { border-left-color: transparent; }
9709 .ui-mode-mobile .settings-content { padding: 1rem; }
9710
9711
9712 /* ============================================================
9713 Compose window (compose.html — standalone Tauri window)
9714 Scoped under body.compose-window so it does not leak to the
9715 main app shell.
9716 ============================================================ */
9717
9718 body.compose-window {
9719 height: 100vh;
9720 display: flex;
9721 flex-direction: column;
9722 overflow: hidden;
9723 }
9724
9725 body.compose-window .compose-toolbar {
9726 display: flex;
9727 gap: 0.5rem;
9728 padding: 0.75rem 1rem;
9729 background: var(--surface-overlay);
9730 border-bottom: 1px solid var(--border);
9731 }
9732
9733 body.compose-window .toolbar-spacer {
9734 flex: 1;
9735 }
9736
9737 body.compose-window .compose-form {
9738 flex: 1;
9739 display: flex;
9740 flex-direction: column;
9741 overflow: hidden;
9742 background: var(--surface-raised);
9743 }
9744
9745 body.compose-window .status-bar {
9746 padding: 0.5rem 1rem;
9747 background: var(--surface-overlay);
9748 border-top: 1px solid var(--border);
9749 font-size: 0.8125rem;
9750 color: var(--content-secondary);
9751 }
9752
9753 body.compose-window .status-bar.error {
9754 color: var(--danger);
9755 }
9756
9757 body.compose-window .status-bar.success {
9758 color: var(--success);
9759 }
9760
9761 body.compose-window .compose-loading {
9762 opacity: 0.6;
9763 pointer-events: none;
9764 }
9765
9766 /* Saved Views modal (Run #27 UX) */
9767 .saved-views-save { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; margin-bottom: var(--space-4); }
9768 .saved-views-save .form-input { flex: 1 1 auto; min-width: 160px; }
9769 .saved-views-list { display: flex; flex-direction: column; gap: var(--space-2); }
9770 .saved-views-row { display: flex; gap: var(--space-2); align-items: center; }
9771 .saved-views-row .saved-views-apply { flex: 1 1 auto; text-align: left; }
9772 .saved-views-empty { color: var(--content-muted); }
9773
9774 /* command palette / search
9775 Moved verbatim from js/search.js runtime style injection (Run #28 CSS cleanup). */
9776 #command-palette {
9777 position: fixed;
9778 inset: 0;
9779 z-index: 5000;
9780 display: flex;
9781 align-items: flex-start;
9782 justify-content: center;
9783 padding-top: 15vh;
9784 }
9785 #command-palette.hidden { display: none; }
9786
9787 .cp-backdrop {
9788 position: absolute;
9789 inset: 0;
9790 background: rgba(0, 0, 0, 0.5);
9791 }
9792
9793 .cp-dialog {
9794 position: relative;
9795 width: 90%;
9796 max-width: 560px;
9797 background: var(--surface-raised);
9798 border: var(--border-width) solid var(--border);
9799 border-radius: var(--radius-md);
9800 box-shadow: var(--shadow-brutal-md);
9801 overflow: hidden;
9802 }
9803
9804 .cp-input-row {
9805 display: flex;
9806 align-items: center;
9807 gap: 0.5rem;
9808 padding: 0.75rem 1rem;
9809 border-bottom: 1px solid var(--border);
9810 }
9811
9812 .cp-icon {
9813 font-size: 1.1rem;
9814 opacity: 0.5;
9815 }
9816
9817 .cp-input {
9818 flex: 1;
9819 border: none;
9820 outline: none;
9821 background: transparent;
9822 font-size: 1rem;
9823 font-family: inherit;
9824 color: var(--content);
9825 }
9826
9827 .cp-esc {
9828 font-size: 0.7rem;
9829 padding: 0.15rem 0.4rem;
9830 background: var(--surface-overlay);
9831 border: 1px solid var(--border);
9832 border-radius: 3px;
9833 color: var(--content-secondary);
9834 }
9835
9836 .cp-filters {
9837 display: flex;
9838 gap: 0.4rem;
9839 padding: 0 1rem;
9840 flex-wrap: wrap;
9841 }
9842 .cp-filters:not(:empty) {
9843 padding-top: 0.5rem;
9844 padding-bottom: 0.25rem;
9845 }
9846
9847 .cp-filter-tag {
9848 font-size: 0.75rem;
9849 padding: 0.15rem 0.5rem;
9850 background: var(--surface-overlay);
9851 border-radius: var(--radius-sm);
9852 color: var(--content-secondary);
9853 }
9854
9855 .cp-results {
9856 max-height: 360px;
9857 overflow-y: auto;
9858 }
9859
9860 .cp-hint, .cp-empty {
9861 padding: 1.5rem 1rem;
9862 text-align: center;
9863 font-size: 0.85rem;
9864 color: var(--content-secondary);
9865 line-height: 1.6;
9866 }
9867 .cp-hint kbd {
9868 font-size: 0.75rem;
9869 padding: 0.1rem 0.35rem;
9870 background: var(--surface-overlay);
9871 border: 1px solid var(--border);
9872 border-radius: 3px;
9873 }
9874
9875 .cp-result {
9876 display: flex;
9877 align-items: center;
9878 gap: 0.6rem;
9879 padding: 0.5rem 1rem;
9880 cursor: pointer;
9881 border-bottom: 1px solid var(--border);
9882 }
9883 .cp-result:last-child { border-bottom: none; }
9884 .cp-result:hover, .cp-result.cp-selected {
9885 background: var(--surface-overlay);
9886 }
9887
9888 .cp-type-icon {
9889 font-size: 1rem;
9890 width: 1.5rem;
9891 text-align: center;
9892 flex-shrink: 0;
9893 }
9894
9895 .cp-result-body {
9896 flex: 1;
9897 min-width: 0;
9898 display: flex;
9899 flex-direction: column;
9900 gap: 0.15rem;
9901 }
9902
9903 .cp-title {
9904 font-size: 0.9rem;
9905 color: var(--content);
9906 white-space: nowrap;
9907 overflow: hidden;
9908 text-overflow: ellipsis;
9909 }
9910
9911 .cp-project {
9912 font-size: 0.75rem;
9913 color: var(--content-secondary);
9914 }
9915
9916 .cp-snippet {
9917 font-size: 0.75rem;
9918 color: var(--content-secondary);
9919 white-space: nowrap;
9920 overflow: hidden;
9921 text-overflow: ellipsis;
9922 }
9923
9924 .cp-type-badge {
9925 font-size: 0.7rem;
9926 padding: 0.15rem 0.4rem;
9927 background: var(--surface-overlay);
9928 border: 1px solid var(--border);
9929 border-radius: var(--radius-sm);
9930 color: var(--content-secondary);
9931 flex-shrink: 0;
9932 }
9933
9934 .cp-more {
9935 padding: 0.5rem 1rem;
9936 text-align: center;
9937 font-size: 0.8rem;
9938 color: var(--content-secondary);
9939 opacity: 0.7;
9940 }
9941