thatcher 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +398 -0
  3. package/package.json +73 -0
  4. package/src/adapters/google-auth.js +148 -0
  5. package/src/adapters/google-drive.js +209 -0
  6. package/src/app/api/[entity]/[[...path]]/route.js +33 -0
  7. package/src/app/api/audit/dashboard/route.js +77 -0
  8. package/src/app/api/audit/logs/route.js +46 -0
  9. package/src/app/api/audit/permissions/[id]/route.js +37 -0
  10. package/src/app/api/audit/permissions/route.js +93 -0
  11. package/src/app/api/audit/permissions/stats/route.js +29 -0
  12. package/src/app/api/audit/route.js +79 -0
  13. package/src/app/api/audit/stats/route.js +18 -0
  14. package/src/app/api/auth/google/callback/route.js +94 -0
  15. package/src/app/api/auth/google/route.js +58 -0
  16. package/src/app/api/auth/login/route.js +121 -0
  17. package/src/app/api/auth/logout/route.js +52 -0
  18. package/src/app/api/auth/me/route.js +16 -0
  19. package/src/app/api/auth/mwr-bridge/route.js +77 -0
  20. package/src/app/api/auth/password-reset/route.js +65 -0
  21. package/src/app/api/cron/trigger/route.js +58 -0
  22. package/src/app/api/csrf-token/route.js +8 -0
  23. package/src/app/api/debug/config/route.js +22 -0
  24. package/src/app/api/debug/hooks/route.js +16 -0
  25. package/src/app/api/debug/plugins/route.js +20 -0
  26. package/src/app/api/debug/sqlite/route.js +21 -0
  27. package/src/app/api/debug/sync/route.js +29 -0
  28. package/src/app/api/debug/workflow/route.js +20 -0
  29. package/src/app/api/domains/[domain]/route.js +26 -0
  30. package/src/app/api/domains/route.js +21 -0
  31. package/src/app/api/email/allocate/batch/route.js +106 -0
  32. package/src/app/api/email/allocate/route.js +141 -0
  33. package/src/app/api/email/receive/route.js +158 -0
  34. package/src/app/api/email/route.js +3 -0
  35. package/src/app/api/email/send/route.js +77 -0
  36. package/src/app/api/email/unallocated/route.js +47 -0
  37. package/src/app/api/files/[id]/route.js +38 -0
  38. package/src/app/api/health/route.js +95 -0
  39. package/src/app/api/metrics/route.js +73 -0
  40. package/src/app/api/monitoring/dashboard/route.js +18 -0
  41. package/src/cli.js +243 -0
  42. package/src/config/config-loader.js +112 -0
  43. package/src/config/constants.js +127 -0
  44. package/src/config/env.js +164 -0
  45. package/src/config/spec-helpers.js +232 -0
  46. package/src/engine.server.js +212 -0
  47. package/src/index.js +368 -0
  48. package/src/lib/accessibility.js +162 -0
  49. package/src/lib/action-factory.js +34 -0
  50. package/src/lib/action-utils.js +21 -0
  51. package/src/lib/alert-manager.js +189 -0
  52. package/src/lib/api-error-wrapper.js +125 -0
  53. package/src/lib/api-helpers.js +53 -0
  54. package/src/lib/api.js +82 -0
  55. package/src/lib/audit-logger-enhanced.js +117 -0
  56. package/src/lib/audit-logger.js +193 -0
  57. package/src/lib/auth-middleware.js +102 -0
  58. package/src/lib/auth-route-helpers.js +83 -0
  59. package/src/lib/business-rules-engine.js +86 -0
  60. package/src/lib/compression.js +44 -0
  61. package/src/lib/config-field-helpers.js +91 -0
  62. package/src/lib/config-generator-engine.js +445 -0
  63. package/src/lib/config-helpers.js +120 -0
  64. package/src/lib/connection-guard.js +79 -0
  65. package/src/lib/crud-action-helpers.js +34 -0
  66. package/src/lib/crud-factory.js +83 -0
  67. package/src/lib/crud-handlers.js +244 -0
  68. package/src/lib/csrf-protection.js +63 -0
  69. package/src/lib/database-core.js +258 -0
  70. package/src/lib/database-migrations.js +96 -0
  71. package/src/lib/date-utils.js +159 -0
  72. package/src/lib/db-backup.js +97 -0
  73. package/src/lib/db-monitor.js +127 -0
  74. package/src/lib/domain-loader.js +82 -0
  75. package/src/lib/email-sender.js +100 -0
  76. package/src/lib/error-boundary.js +134 -0
  77. package/src/lib/error-handler.js +84 -0
  78. package/src/lib/error-recovery.js +190 -0
  79. package/src/lib/error-resilience.js +130 -0
  80. package/src/lib/errors.js +69 -0
  81. package/src/lib/events-engine.js +182 -0
  82. package/src/lib/field-iterator.js +50 -0
  83. package/src/lib/field-registry.js +68 -0
  84. package/src/lib/field-types.js +154 -0
  85. package/src/lib/generic-crud-handler.js +32 -0
  86. package/src/lib/health-monitor.js +134 -0
  87. package/src/lib/hook-engine.js +169 -0
  88. package/src/lib/hot-reload/cache-invalidator.js +115 -0
  89. package/src/lib/hot-reload/checkpoint.js +95 -0
  90. package/src/lib/hot-reload/debug-exposure.js +67 -0
  91. package/src/lib/hot-reload/directory-watcher.js +96 -0
  92. package/src/lib/hot-reload/index.js +50 -0
  93. package/src/lib/hot-reload/mutex.js +75 -0
  94. package/src/lib/hot-reload/promise-container.js +66 -0
  95. package/src/lib/hot-reload/route-wrapper.js +46 -0
  96. package/src/lib/hot-reload/safe-error.js +51 -0
  97. package/src/lib/hot-reload/supervisor.js +161 -0
  98. package/src/lib/hot-reload/timeout-wrapper.js +52 -0
  99. package/src/lib/http-methods-factory.js +25 -0
  100. package/src/lib/index-optimizer.js +96 -0
  101. package/src/lib/index.js +35 -0
  102. package/src/lib/list-data-transform.js +39 -0
  103. package/src/lib/log-aggregator.js +116 -0
  104. package/src/lib/logger.js +55 -0
  105. package/src/lib/metrics-collector.js +102 -0
  106. package/src/lib/minifier.js +19 -0
  107. package/src/lib/monitoring-init.js +67 -0
  108. package/src/lib/next-compat.js +80 -0
  109. package/src/lib/next-polyfills.js +135 -0
  110. package/src/lib/perf-monitor.js +91 -0
  111. package/src/lib/progress-components.js +181 -0
  112. package/src/lib/query-cache.js +126 -0
  113. package/src/lib/query-engine-write.js +221 -0
  114. package/src/lib/query-engine.js +399 -0
  115. package/src/lib/query-perf.js +117 -0
  116. package/src/lib/query-string-adapter.js +75 -0
  117. package/src/lib/realtime-server.js +67 -0
  118. package/src/lib/render-cache.js +61 -0
  119. package/src/lib/request-tracker.js +43 -0
  120. package/src/lib/resource-hints.js +29 -0
  121. package/src/lib/resource-monitor.js +117 -0
  122. package/src/lib/response-formatter.js +80 -0
  123. package/src/lib/route-helpers.js +33 -0
  124. package/src/lib/route-resolver.js +142 -0
  125. package/src/lib/safe-json.js +8 -0
  126. package/src/lib/server-bootstrap.js +71 -0
  127. package/src/lib/stage-pipeline.js +153 -0
  128. package/src/lib/state-protocol.js +171 -0
  129. package/src/lib/state-transport-client.js +169 -0
  130. package/src/lib/state-transport-reconnect.js +121 -0
  131. package/src/lib/state-transport-server.js +181 -0
  132. package/src/lib/static-server.js +97 -0
  133. package/src/lib/status-helpers.js +98 -0
  134. package/src/lib/universal-handler.js +7 -0
  135. package/src/lib/utils.js +93 -0
  136. package/src/lib/validate.js +197 -0
  137. package/src/lib/validation/business-validators.js +61 -0
  138. package/src/lib/validation/csrf.js +51 -0
  139. package/src/lib/validation/file-validators.js +34 -0
  140. package/src/lib/validation/format-validators.js +106 -0
  141. package/src/lib/validation/index.js +19 -0
  142. package/src/lib/validation/rate-limit.js +31 -0
  143. package/src/lib/validation/security-validators.js +78 -0
  144. package/src/lib/validation-middleware.js +133 -0
  145. package/src/lib/validators.js +105 -0
  146. package/src/lib/with-audit-logging.js +63 -0
  147. package/src/lib/with-error-handler.js +31 -0
  148. package/src/lib/workflow-engine.js +250 -0
  149. package/src/server/server.js +305 -0
  150. package/src/services/collaborator-role.service.js +205 -0
  151. package/src/services/email-sender.js +105 -0
  152. package/src/services/notification-engine.js +110 -0
  153. package/src/services/permission.service.js +181 -0
  154. package/src/ui/advanced-search-renderer.js +42 -0
  155. package/src/ui/advanced-widgets.js +47 -0
  156. package/src/ui/auth-pages.js +114 -0
  157. package/src/ui/auth-styles.js +53 -0
  158. package/src/ui/client.js +99 -0
  159. package/src/ui/collaboration-dialogs.js +31 -0
  160. package/src/ui/common-handlers.js +156 -0
  161. package/src/ui/component-engine.js +103 -0
  162. package/src/ui/dashboard-renderer.js +150 -0
  163. package/src/ui/dialog-engine.js +147 -0
  164. package/src/ui/dialog-factory.js +38 -0
  165. package/src/ui/engagement-cards.js +76 -0
  166. package/src/ui/engagement-dialogs.js +100 -0
  167. package/src/ui/engagement-grid-renderer.js +109 -0
  168. package/src/ui/entity-renderer.js +176 -0
  169. package/src/ui/event-delegation.js +108 -0
  170. package/src/ui/fetch-json.js +24 -0
  171. package/src/ui/file-dialogs.js +81 -0
  172. package/src/ui/flexup-report-renderer.js +173 -0
  173. package/src/ui/format-helpers.js +102 -0
  174. package/src/ui/global-tags.js +144 -0
  175. package/src/ui/highlight-threading-renderer.js +176 -0
  176. package/src/ui/idle-logout.js +156 -0
  177. package/src/ui/job-management-renderer.js +61 -0
  178. package/src/ui/layout.js +219 -0
  179. package/src/ui/letter-dialogs.js +37 -0
  180. package/src/ui/ml-console-renderer.js +108 -0
  181. package/src/ui/monitoring-dashboard-client.js +136 -0
  182. package/src/ui/monitoring-dashboard.js +134 -0
  183. package/src/ui/notifications-renderer.js +51 -0
  184. package/src/ui/page-handler-admin.js +121 -0
  185. package/src/ui/page-handler-helpers.js +111 -0
  186. package/src/ui/page-handler-reviews.js +165 -0
  187. package/src/ui/page-handler-rfi.js +42 -0
  188. package/src/ui/page-handler.js +210 -0
  189. package/src/ui/password-reset-page.js +146 -0
  190. package/src/ui/perf-helpers.js +96 -0
  191. package/src/ui/perf-renderer.js +71 -0
  192. package/src/ui/permissions-ui.js +163 -0
  193. package/src/ui/picker-dialogs.js +100 -0
  194. package/src/ui/render-helpers.js +124 -0
  195. package/src/ui/renderer.js +35 -0
  196. package/src/ui/review-comparison-renderer.js +58 -0
  197. package/src/ui/review-detail-panels.js +71 -0
  198. package/src/ui/review-detail-renderer.js +170 -0
  199. package/src/ui/review-detail-script.js +95 -0
  200. package/src/ui/review-mwr-renderer.js +113 -0
  201. package/src/ui/review-renderer.js +202 -0
  202. package/src/ui/review-widgets.js +88 -0
  203. package/src/ui/review-zone-nav.js +12 -0
  204. package/src/ui/rfi-detail-renderer.js +191 -0
  205. package/src/ui/rfi-renderer.js +194 -0
  206. package/src/ui/rfi-report-renderer.js +56 -0
  207. package/src/ui/rippleui.css +1 -0
  208. package/src/ui/settings-renderer-advanced.js +195 -0
  209. package/src/ui/settings-renderer-advanced2.js +158 -0
  210. package/src/ui/settings-renderer-teams.js +112 -0
  211. package/src/ui/settings-renderer.js +166 -0
  212. package/src/ui/spacing-system.js +155 -0
  213. package/src/ui/standalone-login.js +109 -0
  214. package/src/ui/styles.css +2530 -0
  215. package/src/ui/styles2.css +1602 -0
  216. package/src/ui/test-page.js +23 -0
  217. package/src/ui/validation-rules.js +73 -0
  218. package/src/ui/validation-ui.js +147 -0
  219. package/src/ui/virtual-scroll.js +107 -0
  220. package/src/ui/webjsx.js +61 -0
  221. package/src/ui/widgets.js +152 -0
@@ -0,0 +1,1602 @@
1
+ /* === 247420 Design System — anentrypoint.github.io/design === */
2
+ /* Layered surfaces, monospace labels, loud content inside quiet chrome. */
3
+ @import url('https://fonts.googleapis.com/css2?family=Archivo+Black&family=Nunito:wght@400;600;700&family=JetBrains+Mono:wght@400;600&display=swap');
4
+
5
+ :root {
6
+ --ds-bg: #1a1b1e;
7
+ --ds-surface: #25272b;
8
+ --ds-elevated: #2b2d31;
9
+ --ds-fg: #eceef2;
10
+ --ds-muted: #b0b3b8;
11
+ --ds-border: #3a3d42;
12
+ --ds-accent: #247420;
13
+ --ds-accent-light: #3A9A34;
14
+ --ds-mint: rgb(182, 222, 193);
15
+ --ds-pill-radius: 999px;
16
+ --ds-font-body: 'Nunito', Inter, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
17
+ --ds-font-display: 'Archivo Black', Archivo, 'Nunito', system-ui, sans-serif;
18
+ --ds-font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
19
+ }
20
+
21
+ html, body { font-family: var(--ds-font-body); }
22
+ body[data-ds-theme="247420"], body { background: var(--ds-bg); color: var(--ds-fg); }
23
+ h1, .page-title, h2 { font-family: var(--ds-font-display); letter-spacing: -0.3px; }
24
+ .pill, .badge, .info-label, .meta, code, kbd, .mono { font-family: var(--ds-font-mono); }
25
+ .btn, button.btn-primary, button.btn-secondary, .btn-ghost, .btn-outline { border-radius: var(--ds-pill-radius); padding: 8px 18px; font-family: var(--ds-font-body); font-weight: 600; }
26
+ .btn-primary { background: var(--ds-accent); color: var(--ds-fg); border: 1px solid var(--ds-accent-light); }
27
+ .btn-primary:hover { background: var(--ds-accent-light); }
28
+
29
+ /* Layered surfaces */
30
+ .card-clean, .dialog-panel, .modal-content { background: var(--ds-surface); border: 1px solid var(--ds-border); }
31
+ .info-card, .pill-neutral, .table-toolbar { background: var(--ds-elevated); }
32
+
33
+ /* Online/offline indicator */
34
+ #ds-online-status { position: fixed; bottom: 12px; left: 12px; z-index: 9999; padding: 4px 10px; border-radius: var(--ds-pill-radius); background: var(--ds-elevated); border: 1px solid var(--ds-border); color: var(--ds-fg); font-family: var(--ds-font-mono); font-size: 11px; display: none; }
35
+ #ds-online-status.offline { display: inline-block; background: #4a1d1d; border-color: #6b2828; color: #ffd6d6; }
36
+
37
+ /* FlexUp chat dock */
38
+ #flexup-fab { position: fixed; bottom: 20px; right: 20px; z-index: 9998; width: 52px; height: 52px; border-radius: 999px; background: var(--ds-accent); color: white; border: 1px solid var(--ds-accent-light); cursor: pointer; font-family: var(--ds-font-display); font-size: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.4); }
39
+ #flexup-dock { position: fixed; bottom: 84px; right: 20px; z-index: 9998; width: 360px; max-height: 480px; background: var(--ds-surface); border: 1px solid var(--ds-border); border-radius: 12px; display: none; flex-direction: column; box-shadow: 0 12px 32px rgba(0,0,0,0.5); }
40
+ #flexup-dock.open { display: flex; }
41
+ #flexup-dock .fx-header { padding: 12px 14px; border-bottom: 1px solid var(--ds-border); font-family: var(--ds-font-display); font-size: 14px; }
42
+ #flexup-dock .fx-body { flex: 1; overflow-y: auto; padding: 12px; font-size: 13px; min-height: 160px; }
43
+ #flexup-dock .fx-msg { margin-bottom: 10px; padding: 8px 10px; border-radius: 8px; }
44
+ #flexup-dock .fx-msg.user { background: var(--ds-elevated); }
45
+ #flexup-dock .fx-msg.bot { background: var(--ds-bg); border: 1px solid var(--ds-border); }
46
+ #flexup-dock .fx-input-row { display: flex; gap: 6px; padding: 10px; border-top: 1px solid var(--ds-border); }
47
+ #flexup-dock input.fx-input { flex: 1; background: var(--ds-bg); color: var(--ds-fg); border: 1px solid var(--ds-border); border-radius: 8px; padding: 8px 10px; font-family: var(--ds-font-body); }
48
+ #flexup-dock button.fx-send { background: var(--ds-accent); color: var(--ds-fg); border: 0; border-radius: 8px; padding: 6px 14px; font-family: var(--ds-font-body); font-weight: 600; cursor: pointer; }
49
+
50
+ /* Priority star */
51
+ .review-priority-star { background: transparent; border: 0; cursor: pointer; color: var(--ds-muted); padding: 2px 6px; font-size: 16px; }
52
+ .review-priority-star.is-priority { color: gold; }
53
+
54
+ /* === end 247420 layer === */
55
+
56
+ /* Prevent horizontal overflow at page level */
57
+ html, body { overflow-x: hidden; max-width: 100%; }
58
+
59
+ /* Responsive gutter — single source of truth for page padding & card bleed */
60
+ :root {
61
+ --page-gutter: 1.5rem;
62
+ }
63
+
64
+ /* Page content max-width constraint for large screens */
65
+ .page-shell-inner, .page-shell > *:not(nav) { max-width: 1600px; margin-left: auto; margin-right: auto; }
66
+ .page-container { width: 100%; max-width: 1400px; margin: 0 auto; }
67
+
68
+ /* Override Ripple UI .modal opacity/visibility - we use display:none/flex to show/hide */
69
+ .modal { opacity: 1 !important; visibility: visible !important; z-index: var(--z-modal) !important; }
70
+ /* Modal backdrop */
71
+ .modal-overlay, .confirm-overlay { z-index: var(--z-modal-backdrop); }
72
+
73
+ /* Design tokens */
74
+ :root {
75
+ --color-primary: #04141f;
76
+ --color-primary-hover: #0a2535;
77
+ --color-surface: #ffffff;
78
+ --color-bg: #f1f5f9;
79
+ --color-border: #e2e8f0;
80
+ --color-text: #0f172a;
81
+ --color-text-muted: #64748b;
82
+ --color-text-light: #94a3b8;
83
+ --color-success: #16a34a;
84
+ --color-warning: #d97706;
85
+ --color-danger: #dc2626;
86
+ --color-info: #2563eb;
87
+ --radius: 8px;
88
+ --shadow-sm: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.04);
89
+ --shadow-md: 0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.05);
90
+ --shadow-lg: 0 10px 15px rgba(0,0,0,0.1), 0 4px 6px rgba(0,0,0,0.05);
91
+ }
92
+
93
+ /* Dark mode support */
94
+ @media (prefers-color-scheme: dark) {
95
+ :root {
96
+ --color-primary: #64b5f6;
97
+ --color-primary-hover: #42a5f5;
98
+ --color-surface: #1a1a1a;
99
+ --color-bg: #0f172a;
100
+ --color-border: #334155;
101
+ --color-text: #f1f5f9;
102
+ --color-text-muted: #cbd5e1;
103
+ --color-text-light: #94a3b8;
104
+ --color-success: #4ade80;
105
+ --color-warning: #fbbf24;
106
+ --color-danger: #f87171;
107
+ --color-info: #60a5fa;
108
+ --shadow-sm: 0 1px 3px rgba(0,0,0,0.5), 0 1px 2px rgba(0,0,0,0.3);
109
+ --shadow-md: 0 4px 6px rgba(0,0,0,0.5), 0 2px 4px rgba(0,0,0,0.3);
110
+ --shadow-lg: 0 10px 15px rgba(0,0,0,0.6), 0 4px 6px rgba(0,0,0,0.4);
111
+ }
112
+ }
113
+
114
+ /* Page layout */
115
+ .page-shell { background: var(--color-bg); min-height: calc(100vh - 56px); padding: 1rem var(--page-gutter); }
116
+ .page-shell-inner { width: 100%; }
117
+ .page-shell-flush { background: var(--color-bg); min-height: calc(100vh - 56px); padding: 0; }
118
+ .page-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 28px; gap: 12px; flex-wrap: wrap; }
119
+ .page-title { font-size: 24px; font-weight: 700; color: var(--color-primary); letter-spacing: -0.3px; margin: 0; }
120
+ .page-subtitle { font-size: 14px; color: var(--color-text-muted); margin-top: 4px; }
121
+ @media (max-width: 479px) {
122
+ .page-shell { padding: 0.75rem var(--page-gutter); }
123
+ .page-title { font-size: 20px; }
124
+ }
125
+
126
+ /* Card components */
127
+ .card-clean { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-sm); border: 1px solid var(--color-border); }
128
+ .card-clean-body { padding: 24px; }
129
+ .card-header { font-size: 0.875rem; font-weight: 600; margin-bottom: 16px; color: var(--color-text-muted); }
130
+ .card-actions { display: flex; flex-wrap: wrap; gap: 8px; }
131
+
132
+ /* Info cards for data display */
133
+ .info-card { background: var(--color-bg); border-radius: var(--radius); padding: 16px; }
134
+ .info-label { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-muted); margin-bottom: 6px; }
135
+ .info-value { font-size: 0.875rem; color: var(--color-text); }
136
+
137
+ /* Table system */
138
+ .table-wrap { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-sm); border: 1px solid var(--color-border); overflow: hidden; }
139
+ .table-toolbar { display: flex; gap: 12px; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--color-border); flex-wrap: wrap; }
140
+ .table-search { flex: 1; min-width: 200px; position: relative; }
141
+ .table-search input { width: 100%; padding: 8px 12px 8px 36px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 14px; outline: none; box-sizing: border-box; }
142
+ .table-search input:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(4,20,31,0.08); }
143
+ .table-search::before { content: '🔍'; position: absolute; left: 10px; top: 50%; transform: translateY(-50%); font-size: 13px; pointer-events: none; }
144
+ .table-filter select { padding: 8px 12px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 14px; background: var(--color-surface); color: var(--color-text); cursor: pointer; outline: none; }
145
+ .table-filter select:focus { border-color: var(--color-primary); }
146
+ .table-count { font-size: 13px; color: var(--color-text-muted); white-space: nowrap; margin-left: auto; }
147
+ .data-table { width: 100%; border-collapse: collapse; }
148
+ .data-table th { padding: 12px 20px; text-align: left; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-muted); background: var(--color-bg); border-bottom: 1px solid var(--color-border); cursor: pointer; user-select: none; white-space: nowrap; }
149
+ .data-table th:hover { color: var(--color-primary); }
150
+ @media (prefers-color-scheme: dark) {
151
+ .data-table tbody tr:hover td { background: #2d2d2d; }
152
+ }
153
+ .data-table th.sort-asc::after { content: ' ↑'; }
154
+ .data-table th.sort-desc::after { content: ' ↓'; }
155
+ .data-table td { padding: 14px 20px; font-size: 14px; color: var(--color-text); border-bottom: 1px solid #f1f5f9; vertical-align: middle; }
156
+ .data-table tr:last-child td { border-bottom: none; }
157
+ .data-table tbody tr:hover td { background: #f8fafc; transition: background 0.15s ease; }
158
+ .data-table tbody tr { transition: background 0.15s ease; }
159
+ .data-table .col-actions { text-align: right; white-space: nowrap; }
160
+
161
+ /* Badges / Pills */
162
+ .pill { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 100px; font-size: 12px; font-weight: 500; }
163
+ .pill-success { background: #dcfce7; color: #15803d; }
164
+ .pill-danger { background: #fee2e2; color: #b91c1c; }
165
+ .pill-warning { background: #fef3c7; color: #92400e; }
166
+ .pill-info { background: #dbeafe; color: #1d4ed8; }
167
+ .pill-neutral { background: #f1f5f9; color: #475569; }
168
+ .pill-primary { background: #e0f2fe; color: #0369a1; }
169
+
170
+ /* Stage pills */
171
+ .stage-pill { display: inline-flex; align-items: center; padding: 4px 12px; border-radius: 100px; font-size: 12px; font-weight: 600; letter-spacing: 0.2px; }
172
+ .stage-info_gathering { background: #fee2e2; color: #991b1b; }
173
+ .stage-commencement { background: #fef3c7; color: #92400e; }
174
+ .stage-team_execution { background: #dbeafe; color: #1e40af; }
175
+ .stage-partner_review { background: #ede9fe; color: #5b21b6; }
176
+ .stage-finalization { background: #dcfce7; color: #15803d; }
177
+ .stage-closeout { background: #f1f5f9; color: #475569; }
178
+
179
+ /* Buttons */
180
+ .btn-primary-clean { display: inline-flex; align-items: center; gap: 6px; padding: 9px 18px; background: var(--color-primary); color: white; border: none; border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; text-decoration: none; transition: all 0.15s ease; min-height: 40px; }
181
+ .btn-primary-clean:hover { background: var(--color-primary-hover); color: white; transform: translateY(-1px); box-shadow: var(--shadow-md); }
182
+ .btn-primary-clean:active { transform: translateY(0); }
183
+ .btn-primary-clean:focus-visible { outline: 2px solid var(--color-info); outline-offset: 2px; }
184
+ .btn-ghost-clean { display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; background: transparent; color: var(--color-text); border: 1px solid var(--color-border); border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; text-decoration: none; transition: all 0.15s ease; min-height: 40px; }
185
+ .btn-ghost-clean:hover { background: var(--color-bg); border-color: #94a3b8; }
186
+ @media (prefers-color-scheme: dark) {
187
+ .btn-ghost-clean:hover { background: #2d2d2d; border-color: #4d4d4d; }
188
+ }
189
+ .btn-ghost-clean:active { opacity: 0.8; }
190
+ .btn-ghost-clean:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
191
+ .btn-danger-clean { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: transparent; color: var(--color-danger); border: 1px solid #fca5a5; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; text-decoration: none; transition: all 0.15s ease; min-height: 36px; }
192
+ .btn-danger-clean:hover { background: #fee2e2; }
193
+ @media (prefers-color-scheme: dark) {
194
+ .btn-danger-clean:hover { background: #7f1d1d; }
195
+ }
196
+ .btn-danger-clean:active { opacity: 0.8; }
197
+ .btn-danger-clean:focus-visible { outline: 2px solid var(--color-danger); outline-offset: 2px; }
198
+ .btn-edit-clean { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: transparent; color: var(--color-info); border: 1px solid #bfdbfe; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; text-decoration: none; transition: all 0.15s ease; min-height: 36px; }
199
+ .btn-edit-clean:hover { background: #eff6ff; }
200
+ @media (prefers-color-scheme: dark) {
201
+ .btn-edit-clean:hover { background: #1e40af; }
202
+ }
203
+ .btn-edit-clean:active { opacity: 0.8; }
204
+ .btn-edit-clean:focus-visible { outline: 2px solid var(--color-info); outline-offset: 2px; }
205
+
206
+ /* Tabs */
207
+ .tab-bar { display: flex; gap: 4px; padding: 4px; background: #f1f5f9; border-radius: 8px; margin-bottom: 24px; flex-wrap: wrap; }
208
+ .tab-btn { padding: 8px 16px; border: none; background: transparent; border-radius: 6px; font-size: 14px; font-weight: 500; color: var(--color-text-muted); cursor: pointer; transition: all 0.15s; white-space: nowrap; }
209
+ .tab-btn.active { background: var(--color-surface); color: var(--color-primary); box-shadow: var(--shadow-sm); font-weight: 600; }
210
+ .tab-btn:hover:not(.active) { color: var(--color-text); background: rgba(255,255,255,0.6); }
211
+ @media (prefers-color-scheme: dark) {
212
+ .tab-bar { background: #1a1a1a; }
213
+ .tab-btn { color: #9ca3af; }
214
+ .tab-btn:hover:not(.active) { color: #f5f5f5; background: #2d2d2d; }
215
+ .tab-btn.active { background: #2d2d2d; color: var(--color-primary); }
216
+ .tab-count { background: #1e40af; color: #93c5fd; }
217
+ }
218
+ .tab-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; background: #e2e8f0; border-radius: 100px; font-size: 11px; font-weight: 700; margin-left: 6px; }
219
+ .tab-btn.active .tab-count { background: var(--color-primary); color: white; }
220
+
221
+ /* Stats row */
222
+ .stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; margin-bottom: 28px; }
223
+ .stat-card { background: var(--color-surface); border-radius: var(--radius); border: 1px solid var(--color-border); padding: 20px; box-shadow: var(--shadow-sm); }
224
+ .stat-card-clickable { cursor: pointer; transition: all 0.15s ease; }
225
+ .stat-card-clickable:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
226
+ @media (prefers-color-scheme: dark) {
227
+ .stat-card { background: #1a1a1a; border-color: #3d3d3d; }
228
+ }
229
+ .stat-card-clickable:active { transform: translateY(0); }
230
+ .stat-card-value { font-size: 28px; font-weight: 700; color: var(--color-primary); line-height: 1; }
231
+ .stat-card-warn { color: var(--color-danger) !important; }
232
+ .stat-card-label { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-muted); margin-top: 6px; }
233
+ .stat-card-sub { font-size: 12px; color: var(--color-text-light); margin-top: 4px; }
234
+
235
+ /* Breadcrumb */
236
+ .breadcrumb-clean { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--color-text-muted); margin-bottom: 20px; }
237
+ .breadcrumb-clean a { color: var(--color-text-muted); text-decoration: none; }
238
+ .breadcrumb-clean a:hover { color: var(--color-primary); }
239
+ @media (prefers-color-scheme: dark) {
240
+ .breadcrumb-clean { color: #9ca3af; }
241
+ .breadcrumb-clean a { color: #9ca3af; }
242
+ .breadcrumb-clean a:hover { color: var(--color-primary); }
243
+ }
244
+ .breadcrumb-sep { color: var(--color-text-light); }
245
+
246
+ /* Forms */
247
+ .form-shell { max-width: 860px; }
248
+ .form-section { background: var(--color-surface); border-radius: var(--radius); border: 1px solid var(--color-border); padding: 24px; margin-bottom: 20px; box-shadow: var(--shadow-sm); }
249
+ .form-section-title { font-size: 15px; font-weight: 600; color: var(--color-primary); margin: 0 0 20px 0; padding-bottom: 12px; border-bottom: 1px solid var(--color-border); }
250
+ .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
251
+ .form-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; }
252
+ .form-field { display: flex; flex-direction: column; gap: 6px; }
253
+ .form-field.full { grid-column: 1/-1; }
254
+ .form-label { font-size: 13px; font-weight: 600; color: var(--color-text); }
255
+ .form-label .req { color: var(--color-danger); margin-left: 2px; }
256
+ .form-input { padding: 9px 12px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 14px; color: var(--color-text); outline: none; transition: border-color 0.15s, box-shadow 0.15s; width: 100%; box-sizing: border-box; background: var(--color-surface); }
257
+ .form-input:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(4,20,31,0.08); }
258
+ .form-hint { font-size: 12px; color: var(--color-text-muted); }
259
+ .form-actions { display: flex; gap: 12px; justify-content: flex-end; padding-top: 20px; margin-top: 4px; }
260
+
261
+ /* Sort/filter script injection marker */
262
+ .table-wrap .data-table { display: table; }
263
+
264
+ /* Overdue / status alerts */
265
+ .alert-strip { display: flex; align-items: center; justify-content: space-between; padding: 12px 20px; border-radius: var(--radius); margin-bottom: 20px; font-size: 14px; font-weight: 500; }
266
+ .alert-strip-danger { background: #fee2e2; color: #b91c1c; border: 1px solid #fca5a5; }
267
+ .alert-strip-warning { background: #fef3c7; color: #92400e; border: 1px solid #fde68a; }
268
+
269
+ /* Nav: hide desktop links on mobile, show hamburger */
270
+ .nav-links-desktop { display: flex; }
271
+ .nav-hamburger { display: none; }
272
+ @media (max-width: 768px) {
273
+ .nav-links-desktop { display: none !important; }
274
+ .nav-hamburger { display: flex !important; }
275
+ }
276
+
277
+ /* Responsive */
278
+ @media (max-width: 768px) {
279
+ :root { --page-gutter: 0.75rem; }
280
+ .page-shell { padding: 0.75rem var(--page-gutter); }
281
+ .page-shell-flush { padding: 0; }
282
+ .form-grid, .form-grid-3 { grid-template-columns: 1fr; }
283
+ .stats-row { grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
284
+ .table-toolbar { flex-direction: column; align-items: stretch; padding: 1rem; }
285
+ .table-search { min-width: unset; width: 100%; }
286
+ .table-search input { font-size: 1rem; padding: 0.75rem 0.75rem 0.75rem 2.25rem; }
287
+ .table-filter { width: 100%; }
288
+ .table-filter select { width: 100%; min-height: 44px; }
289
+ .data-table th, .data-table td { padding: 0.75rem; font-size: 0.875rem; }
290
+ .data-table { min-width: unset; width: 100%; }
291
+ .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 0; border-left: none; border-right: none; margin-left: calc(-1 * var(--page-gutter)); margin-right: calc(-1 * var(--page-gutter)); }
292
+ .page-header { flex-direction: column; align-items: flex-start; gap: 0.75rem; }
293
+ .page-title { font-size: 1.25rem; }
294
+ .page-subtitle { font-size: 0.8125rem; }
295
+ .card-clean { border-radius: 0; border-left: none; border-right: none; margin-left: calc(-1 * var(--page-gutter)); margin-right: calc(-1 * var(--page-gutter)); }
296
+ .card-clean-body { padding: 1rem; }
297
+ .form-section { border-radius: 0; border-left: none; border-right: none; margin-left: calc(-1 * var(--page-gutter)); margin-right: calc(-1 * var(--page-gutter)); padding: 1rem; }
298
+ .form-shell { max-width: 100%; }
299
+ .form-actions { flex-direction: column; gap: 0.5rem; }
300
+ .form-actions .btn { width: 100%; justify-content: center; }
301
+ .btn-primary-clean, .btn-ghost-clean { min-height: 44px; padding: 0.75rem 1rem; }
302
+ .stat-card { padding: 1rem; }
303
+ .stat-card-value { font-size: 1.5rem; }
304
+ .stat-card-label { font-size: 0.625rem; }
305
+ .breadcrumb-clean { font-size: 0.8125rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
306
+ .tab-bar { overflow-x: auto; -webkit-overflow-scrolling: touch; flex-wrap: nowrap; padding: 0.5rem; scrollbar-width: none; }
307
+ .tab-bar::-webkit-scrollbar { display: none; }
308
+ .tab-btn { flex-shrink: 0; padding: 0.625rem 0.875rem; font-size: 0.875rem; }
309
+ .alert-strip { flex-direction: column; gap: 0.5rem; text-align: center; padding: 1rem; }
310
+ .table-count { text-align: center; margin-left: 0; margin-top: 0.5rem; }
311
+ .form-label { font-size: 0.9375rem; }
312
+ .form-input { min-height: 44px; font-size: 1rem; }
313
+ .form-hint { font-size: 0.75rem; }
314
+ }
315
+
316
+ /* Tablet */
317
+ @media (min-width: 769px) and (max-width: 1023px) {
318
+ :root { --page-gutter: 1.25rem; }
319
+ .page-shell { padding: 1rem var(--page-gutter); }
320
+ .stats-row { grid-template-columns: repeat(3, 1fr); }
321
+ .card-clean, .table-wrap { margin-left: 0; margin-right: 0; border-radius: var(--radius); }
322
+ .form-grid { grid-template-columns: repeat(2, 1fr); }
323
+ }
324
+
325
+ /* Small mobile */
326
+ @media (max-width: 479px) {
327
+ :root { --page-gutter: 0.5rem; }
328
+ .page-shell { padding: 0.5rem var(--page-gutter); }
329
+ .page-title { font-size: 1.125rem; }
330
+ .stats-row { grid-template-columns: 1fr; }
331
+ .stat-card { padding: 0.875rem; }
332
+ .table-toolbar { padding: 0.75rem; }
333
+ .card-clean-body { padding: 0.875rem; }
334
+ .form-section { padding: 0.875rem; }
335
+ }
336
+
337
+ /* Touch device optimizations */
338
+ @media (hover: none) and (pointer: coarse) {
339
+ .btn-primary-clean, .btn-ghost-clean, .btn-danger-clean, .btn-edit-clean {
340
+ min-height: 44px;
341
+ touch-action: manipulation;
342
+ }
343
+ .form-input, select, textarea {
344
+ min-height: 44px;
345
+ font-size: 16px; /* Prevents iOS zoom */
346
+ }
347
+ a, button, [role="button"] {
348
+ min-height: 44px;
349
+ min-width: 44px;
350
+ touch-action: manipulation;
351
+ }
352
+ .data-table tr:hover td { background: transparent; }
353
+ .table-hover tbody tr:hover { background: transparent; }
354
+ }
355
+
356
+ /* Safe area for notched phones */
357
+ @supports (padding: env(safe-area-inset-bottom)) {
358
+ .page-shell {
359
+ padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
360
+ padding-left: calc(var(--page-gutter) + env(safe-area-inset-left));
361
+ padding-right: calc(var(--page-gutter) + env(safe-area-inset-right));
362
+ }
363
+ .action-bar-mobile {
364
+ padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
365
+ }
366
+ }
367
+
368
+ /* Large desktop */
369
+ @media (min-width: 1440px) {
370
+ :root { --page-gutter: 2.5rem; }
371
+ .page-shell { padding: 1.5rem var(--page-gutter); }
372
+ }
373
+ @media (min-width: 1920px) {
374
+ :root { --page-gutter: 3rem; }
375
+ }
376
+
377
+ /* Landscape mobile */
378
+ @media (max-height: 480px) and (orientation: landscape) {
379
+ .modal-overlay, .confirm-overlay, .dialog-overlay {
380
+ align-items: center;
381
+ padding: 1rem;
382
+ }
383
+ .modal-dialog, .confirm-dialog, .modal-content, .dialog-panel {
384
+ max-height: 80vh;
385
+ border-radius: 0.5rem;
386
+ }
387
+ }
388
+
389
+ /* Review sub-page components */
390
+ .review-page-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 24px; flex-wrap: wrap; gap: 16px; }
391
+ .review-page-title { font-size: 24px; font-weight: 700; color: var(--color-primary); margin: 0; }
392
+ .review-page-desc { font-size: 14px; color: var(--color-text-muted); margin-top: 4px; }
393
+ .review-page-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
394
+
395
+ /* Thread cards for highlight discussions */
396
+ .thread-card { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-sm); border: 1px solid var(--color-border); margin-bottom: 16px; overflow: hidden; }
397
+ .thread-card-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 16px; gap: 12px; }
398
+ .thread-card-meta { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
399
+ .thread-card-idx { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; color: white; font-size: 12px; font-weight: 700; flex-shrink: 0; }
400
+ .thread-card-text { font-size: 14px; font-weight: 500; color: var(--color-text); overflow: hidden; text-overflow: ellipsis; }
401
+ .thread-card-page { font-size: 12px; color: var(--color-text-light); padding: 0 16px 12px; }
402
+ .thread-card-body { border-top: 1px solid var(--color-border); }
403
+ .thread-card-empty { padding: 24px; text-align: center; font-size: 14px; color: var(--color-text-light); }
404
+ .thread-card-actions { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--color-border); flex-wrap: wrap; }
405
+ .thread-reply { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--color-border); }
406
+ .thread-reply textarea { flex: 1; padding: 8px 12px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 14px; resize: vertical; min-height: 60px; outline: none; }
407
+ .thread-reply textarea:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(4,20,31,0.08); }
408
+
409
+ /* Response items in threads */
410
+ .response-item { display: flex; gap: 12px; padding: 12px 16px; border-bottom: 1px solid #f1f5f9; }
411
+ .response-item:last-child { border-bottom: none; }
412
+ .response-avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--color-text-light); color: white; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; flex-shrink: 0; }
413
+ .response-content { flex: 1; min-width: 0; }
414
+ .response-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
415
+ .response-name { font-size: 13px; font-weight: 600; color: var(--color-text); }
416
+ .response-date { font-size: 12px; color: var(--color-text-light); }
417
+ .response-text { font-size: 14px; color: var(--color-text); white-space: pre-wrap; line-height: 1.5; }
418
+ .response-attachment { display: flex; align-items: center; gap: 4px; margin-top: 8px; font-size: 12px; color: var(--color-info); }
419
+ .response-attachment a { color: var(--color-info); text-decoration: none; }
420
+ .response-attachment a:hover { text-decoration: underline; }
421
+
422
+ /* Section resolution cards */
423
+ .section-card { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-sm); border: 1px solid var(--color-border); margin-bottom: 16px; overflow: hidden; }
424
+ .section-card-complete { border-left: 4px solid var(--color-success); }
425
+ .section-card-mandatory { border-left: 4px solid var(--color-danger); }
426
+ .section-card-default { border-left: 4px solid var(--color-border); }
427
+ .section-card-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 16px; gap: 12px; }
428
+ .section-card-name { font-size: 15px; font-weight: 600; color: var(--color-text); }
429
+ .section-card-count { font-size: 13px; color: var(--color-text-muted); margin-top: 2px; }
430
+ .section-card-body { padding: 0 16px 16px; }
431
+ .section-card-actions { padding: 12px 16px; border-top: 1px solid var(--color-border); }
432
+
433
+ /* Resolution progress bar */
434
+ .resolution-bar { width: 100%; height: 8px; background: #e5e7eb; border-radius: 100px; overflow: hidden; display: flex; }
435
+ .resolution-bar-segment { height: 100%; transition: width 0.3s; }
436
+ .resolution-bar-resolved { background: var(--color-success); }
437
+ .resolution-bar-partial { background: var(--color-warning); }
438
+ .resolution-bar-open { background: #ef4444; }
439
+ .resolution-legend { display: flex; justify-content: space-between; font-size: 12px; margin-top: 6px; }
440
+ .resolution-legend-resolved { color: var(--color-success); font-weight: 500; }
441
+ .resolution-legend-partial { color: var(--color-warning); font-weight: 500; }
442
+ .resolution-legend-open { color: #ef4444; font-weight: 500; }
443
+
444
+ /* Summary card with large percentage */
445
+ .summary-card { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-sm); border: 1px solid var(--color-border); padding: 24px; margin-bottom: 24px; }
446
+ .summary-card-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 16px; }
447
+ .summary-card-pct { font-size: 48px; font-weight: 700; line-height: 1; }
448
+ .summary-card-pct-success { color: var(--color-success); }
449
+ .summary-card-pct-warning { color: var(--color-warning); }
450
+ .summary-card-pct-danger { color: #ef4444; }
451
+ .summary-card-alert { padding: 12px; border-radius: 6px; font-size: 13px; margin-top: 16px; display: flex; align-items: center; gap: 8px; }
452
+ .summary-card-alert-danger { background: #fee2e2; color: #b91c1c; border: 1px solid #fca5a5; }
453
+ .summary-card-alert-success { background: #dcfce7; color: #15803d; border: 1px solid #bbf7d0; }
454
+
455
+ /* Highlight items in sidebar */
456
+ .highlight-sidebar-item { padding: 12px; border-bottom: 1px solid var(--color-border); cursor: pointer; transition: background 0.15s; }
457
+ .highlight-sidebar-item:hover { background: #f8fafc; }
458
+ @media (prefers-color-scheme: dark) {
459
+ .highlight-sidebar-item { border-color: #2d2d2d; }
460
+ .highlight-sidebar-item:hover { background: #2d2d2d; }
461
+ .highlight-sidebar-num, .highlight-sidebar-meta { color: #9ca3af; }
462
+ .highlight-sidebar-text { color: #f5f5f5; }
463
+ }
464
+ .highlight-sidebar-item:last-child { border-bottom: none; }
465
+ .highlight-sidebar-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
466
+ .highlight-sidebar-num { font-size: 12px; font-weight: 600; color: var(--color-text-muted); }
467
+ .highlight-sidebar-page { font-size: 12px; color: var(--color-text-light); margin-left: auto; }
468
+ .highlight-sidebar-text { font-size: 13px; color: var(--color-text); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
469
+ .highlight-sidebar-responses { font-size: 12px; color: var(--color-info); margin-top: 4px; display: flex; align-items: center; gap: 4px; }
470
+
471
+ /* PDF viewer layout */
472
+ .pdf-layout { display: flex; height: calc(100vh - 140px); }
473
+ .pdf-sidebar { width: 280px; border-right: 1px solid var(--color-border); background: var(--color-surface); flex-shrink: 0; overflow: hidden; display: flex; flex-direction: column; }
474
+ .pdf-sidebar-header { padding: 16px; border-bottom: 1px solid var(--color-border); background: var(--color-bg); }
475
+ .pdf-sidebar-filters { display: flex; gap: 4px; margin-top: 12px; }
476
+ .pdf-sidebar-list { flex: 1; overflow-y: auto; }
477
+ .pdf-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
478
+ .pdf-toolbar { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--color-border); background: var(--color-surface); gap: 12px; flex-wrap: wrap; }
479
+ .pdf-toolbar-group { display: flex; align-items: center; gap: 4px; background: var(--color-bg); border-radius: 6px; padding: 4px 8px; }
480
+ .pdf-toolbar-label { font-size: 12px; color: var(--color-text); min-width: 45px; text-align: center; font-variant-numeric: tabular-nums; }
481
+ .pdf-tool-btn { display: inline-flex; align-items: center; justify-content: center; padding: 4px 10px; background: transparent; border: 1px solid var(--color-border); border-radius: 4px; font-size: 12px; font-weight: 500; color: var(--color-text); cursor: pointer; transition: all 0.15s; min-height: 28px; }
482
+ .pdf-tool-btn:hover { background: var(--color-bg); border-color: var(--color-text-light); }
483
+ @media (prefers-color-scheme: dark) {
484
+ .pdf-sidebar-header { background: #1a1a1a; }
485
+ .pdf-toolbar { background: #1a1a1a; border-color: #3d3d3d; }
486
+ .pdf-tool-btn { color: #f5f5f5; border-color: #3d3d3d; background: #1a1a1a; }
487
+ .pdf-tool-btn:hover { background: #2d2d2d; border-color: #4d4d4d; }
488
+ }
489
+ .pdf-tool-btn.active { background: var(--color-primary); color: white; border-color: var(--color-primary); }
490
+ .pdf-zoom-display { font-size: 12px; color: var(--color-text); min-width: 45px; text-align: center; font-variant-numeric: tabular-nums; }
491
+ .review-meta-tag { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 500; background: var(--color-bg); color: var(--color-text-muted); }
492
+ .pdf-viewer-container { flex: 1; background: var(--color-bg); overflow: auto; position: relative; }
493
+ .pdf-pages { display: flex; flex-direction: column; align-items: center; padding: 16px; gap: 16px; }
494
+ .pdf-page-wrapper { position: relative; background: white; box-shadow: var(--shadow-sm); }
495
+ .pdf-overlay { position: absolute; inset: 0; pointer-events: none; }
496
+ .pdf-canvas-area { flex: 1; background: var(--color-bg); overflow: auto; position: relative; }
497
+ .pdf-page-label { position: absolute; bottom: 8px; right: 8px; background: rgba(255,255,255,0.85); backdrop-filter: blur(4px); font-size: 12px; color: var(--color-text-muted); padding: 4px 10px; border-radius: 100px; box-shadow: var(--shadow-sm); }
498
+
499
+ /* Thread layout classes (highlight-threading-renderer) */
500
+ .thread-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
501
+ .thread-title { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; flex-wrap: wrap; }
502
+ .thread-number { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; color: white; font-size: 12px; font-weight: 700; flex-shrink: 0; }
503
+ .thread-text { font-size: 14px; font-weight: 500; color: var(--color-text); }
504
+ .thread-page-label { font-size: 12px; color: var(--color-text-light); margin-bottom: 12px; }
505
+ .thread-responses { border-top: 1px solid var(--color-border); }
506
+ .thread-empty { padding: 24px; text-align: center; font-size: 14px; color: var(--color-text-light); }
507
+ .thread-response { display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px solid #f1f5f9; }
508
+ .thread-response:last-child { border-bottom: none; }
509
+ .thread-response-avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--color-text-light); color: white; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; flex-shrink: 0; }
510
+ .thread-response-body { flex: 1; min-width: 0; }
511
+ .thread-response-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
512
+ .thread-response-name { font-size: 13px; font-weight: 600; color: var(--color-text); }
513
+ .thread-response-date { font-size: 12px; color: var(--color-text-light); }
514
+ .thread-response-text { font-size: 14px; color: var(--color-text); white-space: pre-wrap; line-height: 1.5; }
515
+ .thread-resolve { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--color-border); }
516
+ .thread-resolve-label { font-size: 12px; color: var(--color-text-muted); }
517
+ .thread-reply { display: flex; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--color-border); }
518
+
519
+ /* Resolution bar (section-resolution-renderer) */
520
+ .resolution-bar-track { width: 100%; height: 8px; background: #e5e7eb; border-radius: 100px; overflow: hidden; display: flex; }
521
+ .resolution-bar-fill { height: 100%; transition: width 0.3s; }
522
+ .resolution-bar-labels { display: flex; justify-content: space-between; font-size: 12px; font-weight: 500; margin-top: 6px; }
523
+
524
+ /* Filter bar for review sub-pages */
525
+ .review-filter-bar { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
526
+
527
+ /* Highlight item in section card */
528
+ .section-highlight-row { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid #f8fafc; }
529
+ .section-highlight-row:last-child { border-bottom: none; }
530
+ .section-highlight-status { font-size: 12px; flex-shrink: 0; }
531
+ .section-highlight-text { font-size: 13px; color: var(--color-text); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
532
+ .section-highlight-page { font-size: 12px; color: var(--color-text-light); flex-shrink: 0; }
533
+
534
+ /* Role breakdown grid */
535
+ .role-breakdown { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
536
+ .role-breakdown-item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--color-text-muted); }
537
+ .role-breakdown-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
538
+
539
+ /* Required tag */
540
+ .tag-required { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 700; background: #fee2e2; color: #b91c1c; text-transform: uppercase; letter-spacing: 0.5px; }
541
+
542
+ @media (max-width: 768px) {
543
+ .review-page-header { flex-direction: column; align-items: stretch; }
544
+ .review-page-actions { justify-content: flex-start; }
545
+ .thread-card-header { flex-direction: column; gap: 8px; }
546
+ .thread-reply { flex-direction: column; }
547
+ .thread-reply textarea { min-height: 80px; }
548
+ .summary-card-row { flex-direction: column; align-items: flex-start; }
549
+ .summary-card-pct { font-size: 36px; }
550
+ .pdf-layout { flex-direction: column; height: auto; min-height: calc(100vh - 140px); }
551
+ .pdf-sidebar { width: 100%; height: 200px; border-right: none; border-bottom: 1px solid var(--color-border); order: 2; }
552
+ .pdf-main { order: 1; min-height: 60vh; }
553
+ .pdf-toolbar { padding: 8px 12px; }
554
+ .section-card-header { flex-direction: column; }
555
+ .resolution-legend { flex-direction: column; gap: 4px; }
556
+ .role-breakdown { grid-template-columns: 1fr; }
557
+ }
558
+
559
+ @media (max-width: 479px) {
560
+ .review-page-title { font-size: 1.125rem; }
561
+ .thread-card-meta { flex-direction: column; align-items: flex-start; }
562
+ .pdf-sidebar { height: 160px; }
563
+ }
564
+
565
+ /* Review meta tags row */
566
+ .review-meta-row { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
567
+ .review-meta-tag { display: inline-flex; align-items: center; padding: 2px 8px; background: var(--color-bg); border-radius: 4px; font-size: 12px; color: var(--color-text-muted); }
568
+
569
+ /* Collapsed review group */
570
+ .review-group-items.collapsed { display: none; }
571
+
572
+ /* List item rows (review lists, activity lists) */
573
+ .list-item-row { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--color-border); cursor: pointer; transition: background 0.15s ease; }
574
+ .list-item-row:hover { background: var(--color-bg); }
575
+ @media (prefers-color-scheme: dark) {
576
+ .list-item-row { border-color: #2d2d2d; }
577
+ .list-item-row:hover { background: #2d2d2d; }
578
+ .list-item-name { color: #f5f5f5; }
579
+ }
580
+ .list-item-row:active { opacity: 0.8; }
581
+ .list-item-row:last-child { border-bottom: none; }
582
+ /* Link styles with hover states */
583
+ a { transition: color 0.15s ease; }
584
+ a:hover { color: var(--color-primary); }
585
+ a:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
586
+ .list-item-name { font-weight: 500; font-size: 14px; color: var(--color-text); }
587
+ .list-item-meta { display: flex; align-items: center; gap: 8px; }
588
+ .activity-item-row { display: flex; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--color-border); }
589
+ .activity-item-row:last-child { border-bottom: none; }
590
+ .activity-item-date { font-size: 12px; color: var(--color-text-light); white-space: nowrap; flex-shrink: 0; }
591
+ .activity-item-desc { font-size: 14px; color: var(--color-text); }
592
+
593
+ /* Review detail tab panels */
594
+ .rv-panel { animation: fadeIn 0.15s ease; }
595
+ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
596
+
597
+ /* Dialog overlay - use z-index scale */
598
+ .dialog-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: var(--z-modal); padding: 16px; }
599
+ .dialog-panel { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 24px; }
600
+
601
+ /* Entity detail 2-column grid */
602
+ .detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
603
+ .detail-grid .detail-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: 12px 16px; border-bottom: 1px solid var(--color-border); }
604
+ .detail-grid .detail-row:nth-child(odd) { border-right: 1px solid var(--color-border); }
605
+ .detail-row-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-muted); flex-shrink: 0; min-width: 6rem; }
606
+ .detail-row-value { font-size: 14px; color: var(--color-text); text-align: right; }
607
+ .detail-row.full { grid-column: 1 / -1; }
608
+ @media (max-width: 768px) { .detail-grid { grid-template-columns: 1fr; } .detail-grid .detail-row:nth-child(odd) { border-right: none; } }
609
+
610
+ /* Engagement tab content spacing */
611
+ .eng-tab-panel { margin-top: 8px; }
612
+ .eng-tab-panel > .card-clean { margin-bottom: 16px; }
613
+
614
+ /* Skeleton loading */
615
+ .skeleton { background: linear-gradient(90deg, var(--color-border) 25%, var(--color-bg) 50%, var(--color-border) 75%); background-size: 200% 100%; animation: skeleton-shimmer 1.5s infinite; border-radius: 4px; }
616
+ @keyframes skeleton-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
617
+ .skeleton-text { height: 14px; margin-bottom: 8px; border-radius: 4px; }
618
+ .skeleton-title { height: 20px; width: 60%; margin-bottom: 12px; border-radius: 4px; }
619
+ .skeleton-pill { height: 22px; width: 64px; border-radius: 100px; display: inline-block; }
620
+ .skeleton-row { display: flex; gap: 16px; align-items: center; padding: 14px 20px; border-bottom: 1px solid var(--color-border); }
621
+ .skeleton-row:last-child { border-bottom: none; }
622
+
623
+ /* Improved empty states */
624
+ .empty-state-full { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 24px; text-align: center; color: var(--color-text-muted); }
625
+ .empty-state-icon { font-size: 40px; margin-bottom: 16px; opacity: 0.35; }
626
+ .empty-state-title { font-size: 16px; font-weight: 600; color: var(--color-text); margin-bottom: 8px; }
627
+ .empty-state-desc { font-size: 14px; color: var(--color-text-muted); margin-bottom: 20px; max-width: 320px; line-height: 1.5; }
628
+
629
+ /* Textarea dark mode */
630
+ textarea { background: var(--color-surface); color: var(--color-text); border-color: var(--color-border); }
631
+ textarea:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(4,20,31,0.08); }
632
+ .thread-reply textarea { background: var(--color-surface); color: var(--color-text); }
633
+
634
+ /* Select dark mode */
635
+ select { background: var(--color-surface); color: var(--color-text); border-color: var(--color-border); }
636
+ select:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(4,20,31,0.08); }
637
+
638
+ /* Input dark mode explicit */
639
+ input[type="text"], input[type="email"], input[type="password"], input[type="search"], input[type="number"], input[type="date"] {
640
+ background: var(--color-surface); color: var(--color-text); border-color: var(--color-border);
641
+ }
642
+ input:focus { border-color: var(--color-primary); }
643
+
644
+ /* Better button loading state */
645
+ .btn-loading { position: relative; pointer-events: none; opacity: 0.8; }
646
+ .btn-loading::after { content: ''; position: absolute; width: 14px; height: 14px; border: 2px solid transparent; border-top-color: currentColor; border-radius: 50%; animation: btn-spin 0.6s linear infinite; right: 10px; top: 50%; transform: translateY(-50%); }
647
+ @keyframes btn-spin { to { transform: translateY(-50%) rotate(360deg); } }
648
+
649
+ /* Confirm dialog */
650
+ .confirm-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: var(--z-modal); padding: 16px; }
651
+ .confirm-dialog { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 28px; max-width: 420px; width: 100%; }
652
+ .confirm-title { font-size: 18px; font-weight: 700; color: var(--color-text); margin: 0 0 12px; }
653
+ .confirm-message { font-size: 14px; color: var(--color-text-muted); margin-bottom: 24px; line-height: 1.5; }
654
+ .confirm-actions { display: flex; gap: 12px; justify-content: flex-end; }
655
+
656
+ /* Page transition fade */
657
+ .page-fade { animation: fadeIn 0.2s ease; }
658
+
659
+ /* Notification badge */
660
+ .notification-dot { width: 8px; height: 8px; background: var(--color-danger); border-radius: 50%; display: inline-block; }
661
+
662
+ /* Inline status indicators */
663
+ .status-online { color: var(--color-success); }
664
+ .status-offline { color: var(--color-text-light); }
665
+
666
+ /* Improved scrollbars */
667
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
668
+ ::-webkit-scrollbar-track { background: transparent; }
669
+ ::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; }
670
+ ::-webkit-scrollbar-thumb:hover { background: var(--color-text-light); }
671
+
672
+ /* Focus ring consistent */
673
+ button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
674
+ outline: 2px solid var(--color-info);
675
+ outline-offset: 2px;
676
+ border-radius: 4px;
677
+ }
678
+
679
+ /* Card hover interactivity */
680
+ .card-interactive { cursor: pointer; transition: box-shadow 0.15s ease, transform 0.15s ease; }
681
+ .card-interactive:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
682
+ .card-interactive:active { transform: translateY(0); box-shadow: var(--shadow-sm); }
683
+
684
+ /* Data label/value pair */
685
+ .data-pair { display: flex; flex-direction: column; gap: 2px; }
686
+ .data-pair-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-muted); }
687
+ .data-pair-value { font-size: 14px; color: var(--color-text); }
688
+
689
+ /* Divider */
690
+ .divider-h { height: 1px; background: var(--color-border); margin: 16px 0; }
691
+ .divider-v { width: 1px; background: var(--color-border); align-self: stretch; }
692
+
693
+ /* Print */
694
+ @media print {
695
+ .no-print { display: none !important; }
696
+ .page-shell { padding: 0; }
697
+ .card-clean, .table-wrap { box-shadow: none; border: 1px solid #ccc; }
698
+ }
699
+
700
+ /* User dropdown */
701
+ .user-dropdown {
702
+ position: fixed;
703
+ top: 50px;
704
+ right: 1rem;
705
+ background: var(--color-surface);
706
+ border: 1px solid var(--color-border);
707
+ border-radius: 0.375rem;
708
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
709
+ min-width: 200px;
710
+ z-index: 9999;
711
+ display: none;
712
+ }
713
+ .user-dropdown-header {
714
+ padding: 0.75rem;
715
+ border-bottom: 1px solid var(--color-border);
716
+ font-size: 0.875rem;
717
+ }
718
+ .user-dropdown-name { font-weight: 600; color: var(--color-text); }
719
+ .user-dropdown-email { color: var(--color-text-muted); font-size: 0.75rem; }
720
+ .user-dropdown-role { color: var(--color-text-muted); font-size: 0.7rem; margin-top: 2px; text-transform: capitalize; }
721
+ .user-dropdown-item {
722
+ display: flex;
723
+ align-items: center;
724
+ gap: 8px;
725
+ padding: 0.75rem;
726
+ color: var(--color-text);
727
+ text-decoration: none;
728
+ font-size: 0.875rem;
729
+ transition: background 0.1s;
730
+ }
731
+ .user-dropdown-item:hover { background: var(--color-bg); }
732
+ @media (prefers-color-scheme: dark) {
733
+ .user-dropdown { background: #1a1a1a; border-color: #3d3d3d; }
734
+ .user-dropdown-header { border-color: #2d2d2d; }
735
+ .user-dropdown-name { color: #f5f5f5; }
736
+ .user-dropdown-email, .user-dropdown-role { color: #9ca3af; }
737
+ .user-dropdown-item { color: #f5f5f5; }
738
+ .user-dropdown-item:hover { background: #2d2d2d; }
739
+ }
740
+
741
+ /* Pill variants */
742
+ .pill-warning { background: #fef3c7; color: #92400e; border: 1px solid #fbbf24; }
743
+ .pill-info { background: var(--color-info-bg, #dbeafe); color: var(--color-info, #1d4ed8); border: 1px solid var(--color-info-border, #93c5fd); }
744
+
745
+ /* Client dashboard responsive grids */
746
+ .client-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; }
747
+ .client-detail-grid { display: grid; grid-template-columns: 2fr 3fr; gap: 16px; }
748
+ @media (max-width: 1023px) {
749
+ .client-stats-grid { grid-template-columns: repeat(2, 1fr); }
750
+ .client-detail-grid { grid-template-columns: 1fr; }
751
+ }
752
+ @media (max-width: 479px) {
753
+ .client-stats-grid { grid-template-columns: 1fr; }
754
+ }
755
+
756
+ /* Settings home responsive grid */
757
+ .settings-home-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
758
+ @media (max-width: 1023px) { .settings-home-grid { grid-template-columns: repeat(2, 1fr); } }
759
+ @media (max-width: 599px) { .settings-home-grid { grid-template-columns: 1fr; } }
760
+
761
+ /* Settings system info grid */
762
+ .settings-info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
763
+ @media (max-width: 767px) { .settings-info-grid { grid-template-columns: 1fr; } }
764
+
765
+ /* Nav CSS classes (replace inline styles) */
766
+ .main-nav { background: #04141f; height: 56px; display: flex; align-items: center; padding: 0; position: relative; z-index: 100; box-shadow: 0 1px 0 rgba(255,255,255,0.06); }
767
+ .main-nav-brand { display: flex; align-items: center; flex: 1; gap: 1rem; padding: 0 1rem; min-width: 0; }
768
+ .main-nav-brand-link { display: flex; align-items: center; gap: 0.5rem; text-decoration: none; flex-shrink: 0; }
769
+ .main-nav-brand-text { color: #f8f9fa; font-size: 0.9rem; font-weight: 700; letter-spacing: 0; margin-left: 0.25rem; }
770
+ .main-nav-actions { display: flex; align-items: center; gap: 0.75rem; margin-left: 1rem; padding-right: 1rem; flex-shrink: 0; }
771
+ .nav-links-desktop { display: flex; align-items: center; gap: 1.25rem; flex-shrink: 0; padding: 0 0.75rem; }
772
+ @media (max-width: 768px) { .nav-links-desktop { display: none; } }
773
+ .nav-link { color: #adb5bd; font-size: 0.875rem; font-weight: 500; letter-spacing: 0; text-decoration: none; transition: color 0.15s; }
774
+ .nav-link:hover { color: #fff; }
775
+ .nav-link-active { color: #fff; font-size: 0.875rem; font-weight: 600; letter-spacing: 0; text-decoration: none; border-bottom: 2px solid rgba(255,255,255,0.7); padding-bottom: 2px; }
776
+ .nav-sep { color: #0d4d6d; }
777
+ .nav-avatar { display: flex; align-items: center; justify-content: center; width: 2.2rem; height: 2.2rem; border-radius: 50%; color: #fff; font-weight: 700; font-size: 0.82rem; cursor: pointer; flex-shrink: 0; min-width: 44px; min-height: 44px; }
778
+ .mobile-nav-link { display: flex; align-items: center; padding: 14px 20px; color: #ced4da; text-decoration: none; font-size: 0.9375rem; font-weight: 500; min-height: 48px; transition: color 0.15s, background 0.15s; }
779
+ .mobile-nav-link:hover { background: rgba(255,255,255,0.05); }
780
+ .mobile-nav-header-bar { padding: 1rem; border-bottom: 1px solid #0d4d6d; display: flex; align-items: center; justify-content: space-between; }
781
+ .mobile-nav-header-title { color: #f8f9fa; font-weight: 700; font-size: 0.95rem; }
782
+ .mobile-nav-close-btn { background: none; border: none; color: #ced4da; cursor: pointer; font-size: 1.5rem; padding: 8px; min-width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; }
783
+ .mobile-nav-footer { padding: 1rem; border-top: 1px solid #0d4d6d; }
784
+ .mobile-nav-user-name { color: #888; font-size: 0.875rem; margin-bottom: 4px; font-weight: 600; }
785
+ .mobile-nav-user-email { color: #666; font-size: 0.75rem; margin-bottom: 12px; word-break: break-all; }
786
+ .mobile-nav-logout { display: flex; align-items: center; justify-content: center; padding: 12px 16px; background: rgba(255,255,255,0.08); color: #ced4da; text-decoration: none; font-size: 0.875rem; font-weight: 500; border-radius: 6px; text-align: center; min-height: 44px; transition: background 0.15s; }
787
+
788
+ /* Engagement table mobile: hide lower-priority columns */
789
+ @media (max-width: 767px) {
790
+ .eng-col-type, .eng-col-year, .eng-col-team, .eng-col-rfi, .eng-col-progress { display: none; }
791
+ .eng-table-mobile-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
792
+ }
793
+ @media (min-width: 768px) and (max-width: 1023px) {
794
+ .eng-col-year, .eng-col-rfi { display: none; }
795
+ }
796
+
797
+ /* Review search input responsive */
798
+ .review-search-input { max-width: 220px; height: 36px; }
799
+ @media (max-width: 768px) { .review-search-input { max-width: 100%; width: 100%; } }
800
+
801
+ /* Page header actions wrap on mobile */
802
+ .page-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
803
+
804
+ /* Dialog improvements for mobile */
805
+ .dialog-panel, .confirm-dialog, .modal-content {
806
+ max-height: 90vh;
807
+ overflow-y: auto;
808
+ }
809
+ @media (max-width: 479px) {
810
+ .dialog-panel, .confirm-dialog, .modal-content { padding: 16px; width: 95%; }
811
+ .modal-action { flex-wrap: wrap; }
812
+ .modal-action .btn { flex: 1; min-width: 0; justify-content: center; }
813
+ }
814
+
815
+ /* Engagement card grid */
816
+ .engagement-card-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
817
+ @media (max-width: 1023px) { .engagement-card-grid { grid-template-columns: repeat(3, 1fr); } }
818
+ @media (max-width: 767px) { .engagement-card-grid { grid-template-columns: repeat(2, 1fr); } }
819
+ @media (max-width: 479px) { .engagement-card-grid { grid-template-columns: 1fr; } }
820
+
821
+ /* Stage pipeline scroll on mobile */
822
+ .stage-pipeline { display: flex; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding-bottom: 4px; }
823
+ .stage-pipeline::-webkit-scrollbar { display: none; }
824
+
825
+ /* Missing mb-5 utility */
826
+ .mb-5 { margin-bottom: 1.25rem; }
827
+
828
+ /* RFI detail info grid - responsive */
829
+ .rfi-info-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
830
+ @media (max-width: 767px) { .rfi-info-grid { grid-template-columns: repeat(2, 1fr); } }
831
+ @media (max-width: 479px) { .rfi-info-grid { grid-template-columns: 1fr; } }
832
+
833
+ /* Review row truncation */
834
+ .review-row-name { font-weight: 500; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
835
+ @media (max-width: 767px) { .review-row-name { max-width: 140px; } }
836
+
837
+ /* ═══════════════════════════════════════════════════════════
838
+ TAILWIND-COMPATIBLE UTILITY CLASSES
839
+ Required because rippleui.css is PurgeCSS-built without
840
+ general utilities. These cover all classes used in UI files.
841
+ ═══════════════════════════════════════════════════════════ */
842
+
843
+ /* Display */
844
+ .flex { display: flex; }
845
+ .inline-flex { display: inline-flex; }
846
+ .grid { display: grid; }
847
+ .block { display: block; }
848
+ .inline-block { display: inline-block; }
849
+ .inline { display: inline; }
850
+ .hidden { display: none; }
851
+ .contents { display: contents; }
852
+
853
+ /* Flex direction */
854
+ .flex-row { flex-direction: row; }
855
+ .flex-col { flex-direction: column; }
856
+ .flex-wrap { flex-wrap: wrap; }
857
+ .flex-nowrap { flex-wrap: nowrap; }
858
+
859
+ /* Flex sizing */
860
+ .flex-1 { flex: 1 1 0%; }
861
+ .flex-auto { flex: 1 1 auto; }
862
+ .flex-none { flex: none; }
863
+ .flex-shrink-0 { flex-shrink: 0; }
864
+ .shrink-0 { flex-shrink: 0; }
865
+ .grow { flex-grow: 1; }
866
+ .grow-0 { flex-grow: 0; }
867
+
868
+ /* Align */
869
+ .items-start { align-items: flex-start; }
870
+ .items-center { align-items: center; }
871
+ .items-end { align-items: flex-end; }
872
+ .items-baseline { align-items: baseline; }
873
+ .items-stretch { align-items: stretch; }
874
+ .self-start { align-self: flex-start; }
875
+ .self-center { align-self: center; }
876
+ .self-end { align-self: flex-end; }
877
+
878
+ /* Justify */
879
+ .justify-start { justify-content: flex-start; }
880
+ .justify-center { justify-content: center; }
881
+ .justify-end { justify-content: flex-end; }
882
+ .justify-between { justify-content: space-between; }
883
+ .justify-around { justify-content: space-around; }
884
+ .justify-evenly { justify-content: space-evenly; }
885
+
886
+ /* Gap */
887
+ .gap-0 { gap: 0; }
888
+ .gap-1 { gap: 0.25rem; }
889
+ .gap-2 { gap: 0.5rem; }
890
+ .gap-3 { gap: 0.75rem; }
891
+ .gap-4 { gap: 1rem; }
892
+ .gap-5 { gap: 1.25rem; }
893
+ .gap-6 { gap: 1.5rem; }
894
+ .gap-8 { gap: 2rem; }
895
+ .gap-10 { gap: 2.5rem; }
896
+ .gap-x-2 { column-gap: 0.5rem; }
897
+ .gap-x-3 { column-gap: 0.75rem; }
898
+ .gap-x-4 { column-gap: 1rem; }
899
+ .gap-y-2 { row-gap: 0.5rem; }
900
+ .gap-y-3 { row-gap: 0.75rem; }
901
+ .gap-y-4 { row-gap: 1rem; }
902
+
903
+ /* Grid columns */
904
+ .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
905
+ .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
906
+ .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
907
+ .grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
908
+ .grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
909
+ .grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
910
+ .col-span-1 { grid-column: span 1 / span 1; }
911
+ .col-span-2 { grid-column: span 2 / span 2; }
912
+ .col-span-3 { grid-column: span 3 / span 3; }
913
+ .col-span-full { grid-column: 1 / -1; }
914
+
915
+ /* Width */
916
+ .w-full { width: 100%; }
917
+ .w-auto { width: auto; }
918
+ .w-screen { width: 100vw; }
919
+ .w-4 { width: 1rem; }
920
+ .w-5 { width: 1.25rem; }
921
+ .w-6 { width: 1.5rem; }
922
+ .w-8 { width: 2rem; }
923
+ .w-10 { width: 2.5rem; }
924
+ .w-12 { width: 3rem; }
925
+ .w-16 { width: 4rem; }
926
+ .w-20 { width: 5rem; }
927
+ .w-24 { width: 6rem; }
928
+ .w-32 { width: 8rem; }
929
+ .w-48 { width: 12rem; }
930
+ .w-64 { width: 16rem; }
931
+
932
+ /* Height */
933
+ .h-full { height: 100%; }
934
+ .h-screen { height: 100vh; }
935
+ .h-4 { height: 1rem; }
936
+ .h-5 { height: 1.25rem; }
937
+ .h-6 { height: 1.5rem; }
938
+ .h-8 { height: 2rem; }
939
+ .h-10 { height: 2.5rem; }
940
+ .h-12 { height: 3rem; }
941
+ .h-16 { height: 4rem; }
942
+
943
+ /* Min/Max */
944
+ .min-h-0 { min-height: 0; }
945
+ .min-h-screen { min-height: 100vh; }
946
+ .min-h-full { min-height: 100%; }
947
+ .max-w-full { max-width: 100%; }
948
+ .max-w-xs { max-width: 20rem; }
949
+ .max-w-sm { max-width: 24rem; }
950
+ .max-w-md { max-width: 28rem; }
951
+ .max-w-lg { max-width: 32rem; }
952
+ .max-w-xl { max-width: 36rem; }
953
+ .max-w-2xl { max-width: 42rem; }
954
+ .max-w-3xl { max-width: 48rem; }
955
+ .max-w-4xl { max-width: 56rem; }
956
+ .max-w-5xl { max-width: 64rem; }
957
+ .max-w-6xl { max-width: 72rem; }
958
+ .max-w-7xl { max-width: 80rem; }
959
+
960
+ /* Padding */
961
+ .p-0 { padding: 0; }
962
+ .p-1 { padding: 0.25rem; }
963
+ .p-2 { padding: 0.5rem; }
964
+ .p-3 { padding: 0.75rem; }
965
+ .p-4 { padding: 1rem; }
966
+ .p-5 { padding: 1.25rem; }
967
+ .p-6 { padding: 1.5rem; }
968
+ .p-8 { padding: 2rem; }
969
+ .px-1 { padding-left: 0.25rem; padding-right: 0.25rem; }
970
+ .px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
971
+ .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
972
+ .px-4 { padding-left: 1rem; padding-right: 1rem; }
973
+ .px-5 { padding-left: 1.25rem; padding-right: 1.25rem; }
974
+ .px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
975
+ .px-8 { padding-left: 2rem; padding-right: 2rem; }
976
+ .py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
977
+ .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
978
+ .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
979
+ .py-4 { padding-top: 1rem; padding-bottom: 1rem; }
980
+ .py-5 { padding-top: 1.25rem; padding-bottom: 1.25rem; }
981
+ .py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
982
+ .py-8 { padding-top: 2rem; padding-bottom: 2rem; }
983
+ .py-10 { padding-top: 2.5rem; padding-bottom: 2.5rem; }
984
+ .py-12 { padding-top: 3rem; padding-bottom: 3rem; }
985
+ .pt-1 { padding-top: 0.25rem; }
986
+ .pt-2 { padding-top: 0.5rem; }
987
+ .pt-4 { padding-top: 1rem; }
988
+ .pt-6 { padding-top: 1.5rem; }
989
+ .pb-1 { padding-bottom: 0.25rem; }
990
+ .pb-2 { padding-bottom: 0.5rem; }
991
+ .pb-4 { padding-bottom: 1rem; }
992
+ .pl-2 { padding-left: 0.5rem; }
993
+ .pl-3 { padding-left: 0.75rem; }
994
+ .pl-4 { padding-left: 1rem; }
995
+ .pr-2 { padding-right: 0.5rem; }
996
+ .pr-3 { padding-right: 0.75rem; }
997
+ .pr-4 { padding-right: 1rem; }
998
+
999
+ /* Margin */
1000
+ .m-0 { margin: 0; }
1001
+ .m-auto { margin: auto; }
1002
+ .m-1 { margin: 0.25rem; }
1003
+ .m-2 { margin: 0.5rem; }
1004
+ .m-3 { margin: 0.75rem; }
1005
+ .m-4 { margin: 1rem; }
1006
+ .mx-auto { margin-left: auto; margin-right: auto; }
1007
+ .mx-1 { margin-left: 0.25rem; margin-right: 0.25rem; }
1008
+ .mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
1009
+ .my-1 { margin-top: 0.25rem; margin-bottom: 0.25rem; }
1010
+ .my-2 { margin-top: 0.5rem; margin-bottom: 0.5rem; }
1011
+ .my-4 { margin-top: 1rem; margin-bottom: 1rem; }
1012
+ .mt-0 { margin-top: 0; }
1013
+ .mt-1 { margin-top: 0.25rem; }
1014
+ .mt-2 { margin-top: 0.5rem; }
1015
+ .mt-3 { margin-top: 0.75rem; }
1016
+ .mt-4 { margin-top: 1rem; }
1017
+ .mt-6 { margin-top: 1.5rem; }
1018
+ .mt-8 { margin-top: 2rem; }
1019
+ .mb-0 { margin-bottom: 0; }
1020
+ .mb-1 { margin-bottom: 0.25rem; }
1021
+ .mb-2 { margin-bottom: 0.5rem; }
1022
+ .mb-3 { margin-bottom: 0.75rem; }
1023
+ .mb-4 { margin-bottom: 1rem; }
1024
+ .mb-6 { margin-bottom: 1.5rem; }
1025
+ .mb-8 { margin-bottom: 2rem; }
1026
+ .ml-0 { margin-left: 0; }
1027
+ .ml-1 { margin-left: 0.25rem; }
1028
+ .ml-2 { margin-left: 0.5rem; }
1029
+ .ml-4 { margin-left: 1rem; }
1030
+ .ml-6 { margin-left: 1.5rem; }
1031
+ .ml-auto { margin-left: auto; }
1032
+ .mr-0 { margin-right: 0; }
1033
+ .mr-1 { margin-right: 0.25rem; }
1034
+ .mr-2 { margin-right: 0.5rem; }
1035
+ .mr-4 { margin-right: 1rem; }
1036
+ .mr-auto { margin-right: auto; }
1037
+
1038
+ /* Typography */
1039
+ .text-xs { font-size: 0.75rem; line-height: 1rem; }
1040
+ .text-sm { font-size: 0.875rem; line-height: 1.25rem; }
1041
+ .text-base { font-size: 1rem; line-height: 1.5rem; }
1042
+ .text-lg { font-size: 1.125rem; line-height: 1.75rem; }
1043
+ .text-xl { font-size: 1.25rem; line-height: 1.75rem; }
1044
+ .text-2xl { font-size: 1.5rem; line-height: 2rem; }
1045
+ .text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
1046
+ .text-4xl { font-size: 2.25rem; line-height: 2.5rem; }
1047
+ .font-light { font-weight: 300; }
1048
+ .font-normal { font-weight: 400; }
1049
+ .font-medium { font-weight: 500; }
1050
+ .font-semibold { font-weight: 600; }
1051
+ .font-bold { font-weight: 700; }
1052
+ .font-extrabold { font-weight: 800; }
1053
+ .text-left { text-align: left; }
1054
+ .text-center { text-align: center; }
1055
+ .text-right { text-align: right; }
1056
+ .leading-tight { line-height: 1.25; }
1057
+ .leading-snug { line-height: 1.375; }
1058
+ .leading-normal { line-height: 1.5; }
1059
+ .leading-relaxed { line-height: 1.625; }
1060
+ .tracking-tight { letter-spacing: -0.025em; }
1061
+ .tracking-normal { letter-spacing: 0; }
1062
+ .tracking-wide { letter-spacing: 0.025em; }
1063
+ .tracking-wider { letter-spacing: 0.05em; }
1064
+ .uppercase { text-transform: uppercase; }
1065
+ .lowercase { text-transform: lowercase; }
1066
+ .capitalize { text-transform: capitalize; }
1067
+ .normal-case { text-transform: none; }
1068
+ .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1069
+ .whitespace-nowrap { white-space: nowrap; }
1070
+ .whitespace-pre-wrap { white-space: pre-wrap; }
1071
+ .break-words { overflow-wrap: break-word; word-break: break-word; }
1072
+ .break-all { word-break: break-all; }
1073
+ .line-clamp-2 { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
1074
+
1075
+ /* Text colors */
1076
+ .text-white { color: #ffffff; }
1077
+ .text-black { color: #000000; }
1078
+ .text-gray-400 { color: #9ca3af; }
1079
+ .text-gray-500 { color: #6b7280; }
1080
+ .text-gray-600 { color: #4b5563; }
1081
+ .text-gray-700 { color: #374151; }
1082
+ .text-gray-800 { color: #1f2937; }
1083
+ .text-gray-900 { color: #111827; }
1084
+ .text-red-500 { color: #ef4444; }
1085
+ .text-red-600 { color: #dc2626; }
1086
+ .text-green-500 { color: #22c55e; }
1087
+ .text-green-600 { color: #16a34a; }
1088
+ .text-blue-500 { color: #3b82f6; }
1089
+ .text-blue-600 { color: #2563eb; }
1090
+ .text-yellow-600 { color: #ca8a04; }
1091
+ /* Ripple UI content tokens */
1092
+ .text-base-content { color: var(--color-text); }
1093
+ .text-base-content\/40 { color: rgba(15,23,42,0.4); }
1094
+ .text-base-content\/50 { color: rgba(15,23,42,0.5); }
1095
+ .text-base-content\/60 { color: rgba(15,23,42,0.6); }
1096
+ @media (prefers-color-scheme: dark) {
1097
+ .text-base-content\/40 { color: rgba(241,245,249,0.4); }
1098
+ .text-base-content\/50 { color: rgba(241,245,249,0.5); }
1099
+ .text-base-content\/60 { color: rgba(241,245,249,0.6); }
1100
+ }
1101
+
1102
+ /* Background colors */
1103
+ .bg-white { background-color: #ffffff; }
1104
+ .bg-gray-50 { background-color: #f9fafb; }
1105
+ .bg-gray-100 { background-color: #f3f4f6; }
1106
+ .bg-gray-200 { background-color: #e5e7eb; }
1107
+ .bg-transparent { background-color: transparent; }
1108
+ /* Ripple UI base tokens */
1109
+ .bg-base-100 { background-color: var(--color-surface); }
1110
+ .bg-base-200 { background-color: var(--color-bg); }
1111
+ .bg-base-300 { background-color: var(--color-border); }
1112
+
1113
+ /* Border */
1114
+ .border { border: 1px solid var(--color-border); }
1115
+ .border-0 { border: 0; }
1116
+ .border-t { border-top: 1px solid var(--color-border); }
1117
+ .border-b { border-bottom: 1px solid var(--color-border); }
1118
+ .border-l { border-left: 1px solid var(--color-border); }
1119
+ .border-r { border-right: 1px solid var(--color-border); }
1120
+ .border-base-200 { border-color: var(--color-border); }
1121
+ .border-base-300 { border-color: var(--color-border); }
1122
+ .divide-y > * + * { border-top: 1px solid var(--color-border); }
1123
+
1124
+ /* Border radius */
1125
+ .rounded-none { border-radius: 0; }
1126
+ .rounded-sm { border-radius: 0.125rem; }
1127
+ .rounded { border-radius: 0.25rem; }
1128
+ .rounded-md { border-radius: 0.375rem; }
1129
+ .rounded-lg { border-radius: 0.5rem; }
1130
+ .rounded-xl { border-radius: 0.75rem; }
1131
+ .rounded-2xl { border-radius: 1rem; }
1132
+ .rounded-full { border-radius: 9999px; }
1133
+ .rounded-box { border-radius: 0.75rem; }
1134
+
1135
+ /* Shadow */
1136
+ .shadow-none { box-shadow: none; }
1137
+ .shadow-sm { box-shadow: var(--shadow-sm); }
1138
+ .shadow { box-shadow: var(--shadow-md); }
1139
+ .shadow-md { box-shadow: var(--shadow-md); }
1140
+ .shadow-lg { box-shadow: var(--shadow-lg); }
1141
+
1142
+ /* Position */
1143
+ .static { position: static; }
1144
+ .relative { position: relative; }
1145
+ .absolute { position: absolute; }
1146
+ .fixed { position: fixed; }
1147
+ .sticky { position: sticky; }
1148
+ .inset-0 { top: 0; right: 0; bottom: 0; left: 0; }
1149
+ .top-0 { top: 0; }
1150
+ .right-0 { right: 0; }
1151
+ .bottom-0 { bottom: 0; }
1152
+ .left-0 { left: 0; }
1153
+ .z-10 { z-index: 10; }
1154
+ .z-20 { z-index: 20; }
1155
+ .z-50 { z-index: 50; }
1156
+ .z-100 { z-index: 100; }
1157
+
1158
+ /* Overflow */
1159
+ .overflow-hidden { overflow: hidden; }
1160
+ .overflow-auto { overflow: auto; }
1161
+ .overflow-x-auto { overflow-x: auto; }
1162
+ .overflow-y-auto { overflow-y: auto; }
1163
+ .overflow-visible { overflow: visible; }
1164
+
1165
+ /* Cursor */
1166
+ .cursor-pointer { cursor: pointer; }
1167
+ .cursor-default { cursor: default; }
1168
+ .cursor-not-allowed { cursor: not-allowed; }
1169
+ .cursor-wait { cursor: wait; }
1170
+
1171
+ /* Select */
1172
+ .select-none { user-select: none; }
1173
+ .select-text { user-select: text; }
1174
+ .select-all { user-select: all; }
1175
+ .pointer-events-none { pointer-events: none; }
1176
+ .pointer-events-auto { pointer-events: auto; }
1177
+
1178
+ /* Opacity */
1179
+ .opacity-0 { opacity: 0; }
1180
+ .opacity-25 { opacity: 0.25; }
1181
+ .opacity-50 { opacity: 0.5; }
1182
+ .opacity-75 { opacity: 0.75; }
1183
+ .opacity-100 { opacity: 1; }
1184
+
1185
+ /* Object fit */
1186
+ .object-cover { object-fit: cover; }
1187
+ .object-contain { object-fit: contain; }
1188
+
1189
+ /* Transition */
1190
+ .transition { transition-property: color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter; transition-timing-function: cubic-bezier(.4,0,.2,1); transition-duration: 150ms; }
1191
+ .transition-colors { transition-property: color,background-color,border-color; transition-timing-function: cubic-bezier(.4,0,.2,1); transition-duration: 150ms; }
1192
+ .transition-all { transition-property: all; transition-timing-function: cubic-bezier(.4,0,.2,1); transition-duration: 150ms; }
1193
+ .duration-150 { transition-duration: 150ms; }
1194
+ .duration-200 { transition-duration: 200ms; }
1195
+ .duration-300 { transition-duration: 300ms; }
1196
+ .ease-in-out { transition-timing-function: cubic-bezier(.4,0,.2,1); }
1197
+
1198
+ /* Transform */
1199
+ .scale-95 { transform: scale(.95); }
1200
+ .scale-100 { transform: scale(1); }
1201
+ .-translate-y-1 { transform: translateY(-0.25rem); }
1202
+ .translate-y-0 { transform: translateY(0); }
1203
+
1204
+ /* Space (between children) */
1205
+ .space-x-2 > * + * { margin-left: 0.5rem; }
1206
+ .space-x-3 > * + * { margin-left: 0.75rem; }
1207
+ .space-x-4 > * + * { margin-left: 1rem; }
1208
+ .space-y-2 > * + * { margin-top: 0.5rem; }
1209
+ .space-y-3 > * + * { margin-top: 0.75rem; }
1210
+ .space-y-4 > * + * { margin-top: 1rem; }
1211
+
1212
+ /* Ripple UI select/form utilities */
1213
+ .select-bordered { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); color: var(--color-text); padding: 0.5rem 0.75rem; font-size: 0.875rem; width: 100%; outline: none; cursor: pointer; }
1214
+ .select-bordered:focus { border-color: var(--color-info); box-shadow: 0 0 0 3px rgba(37,99,235,0.12); }
1215
+ .select-sm { padding: 0.375rem 0.625rem; font-size: 0.8125rem; min-height: 32px; }
1216
+ .select-solid { background: var(--color-bg); border: 1px solid var(--color-border); }
1217
+ .input-bordered { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); color: var(--color-text); padding: 0.5rem 0.75rem; font-size: 0.875rem; width: 100%; outline: none; }
1218
+ .input-bordered:focus { border-color: var(--color-info); box-shadow: 0 0 0 3px rgba(37,99,235,0.12); }
1219
+ .input-sm { padding: 0.375rem 0.625rem; font-size: 0.8125rem; min-height: 32px; }
1220
+ .input-primary:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(4,20,31,0.12); }
1221
+
1222
+ /* Divider */
1223
+ .divider { display: flex; align-items: center; gap: 1rem; margin: 1rem 0; }
1224
+ .divider::before, .divider::after { content: ''; flex: 1; height: 1px; background: var(--color-border); }
1225
+
1226
+ /* Loading / skeleton */
1227
+ .skeleton { background: linear-gradient(90deg, var(--color-bg) 25%, var(--color-border) 50%, var(--color-bg) 75%); background-size: 200% 100%; animation: skeleton-shimmer 1.5s ease-in-out infinite; border-radius: var(--radius); }
1228
+ @keyframes skeleton-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
1229
+
1230
+ /* Empty state component */
1231
+ .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 3rem 2rem; text-align: center; color: var(--color-text-muted); }
1232
+ .empty-state-icon { width: 48px; height: 48px; margin-bottom: 1rem; opacity: 0.4; }
1233
+ .empty-state-title { font-size: 1rem; font-weight: 600; color: var(--color-text); margin-bottom: 0.5rem; }
1234
+ .empty-state-desc { font-size: 0.875rem; color: var(--color-text-muted); margin-bottom: 1.5rem; max-width: 320px; }
1235
+
1236
+ /* Tooltip */
1237
+ .tooltip { position: relative; display: inline-flex; }
1238
+ .tooltip:hover::after { content: attr(data-tip); position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); white-space: nowrap; background: rgba(15,23,42,0.9); color: #fff; font-size: 0.75rem; padding: 4px 10px; border-radius: 6px; pointer-events: none; z-index: 120; }
1239
+
1240
+ /* Alert component */
1241
+ .alert { display: flex; align-items: flex-start; gap: 0.75rem; padding: 1rem; border-radius: var(--radius); border: 1px solid; }
1242
+ .alert-info { background: #eff6ff; border-color: #bfdbfe; color: #1e40af; }
1243
+ .alert-success { background: #f0fdf4; border-color: #bbf7d0; color: #15803d; }
1244
+ .alert-warning { background: #fffbeb; border-color: #fed7aa; color: #92400e; }
1245
+ .alert-error { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
1246
+ @media (prefers-color-scheme: dark) {
1247
+ .alert-info { background: #1e3a8a22; border-color: #1d4ed844; color: #60a5fa; }
1248
+ .alert-success { background: #14532d22; border-color: #16a34a44; color: #4ade80; }
1249
+ .alert-warning { background: #78350f22; border-color: #d9770644; color: #fbbf24; }
1250
+ .alert-error { background: #7f1d1d22; border-color: #dc262644; color: #f87171; }
1251
+ }
1252
+
1253
+ /* Badge component (Ripple UI compatibility) */
1254
+ .badge { display: inline-flex; align-items: center; padding: 0.2rem 0.6rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 500; }
1255
+ .badge-primary { background: #e0f2fe; color: #0369a1; }
1256
+ .badge-secondary { background: #f3e8ff; color: #7e22ce; }
1257
+ .badge-success { background: #dcfce7; color: #15803d; }
1258
+ .badge-error { background: #fee2e2; color: #b91c1c; }
1259
+ .badge-warning { background: #fef3c7; color: #92400e; }
1260
+ .badge-neutral { background: #f1f5f9; color: #475569; }
1261
+ .badge-ghost { background: transparent; border: 1px solid var(--color-border); }
1262
+ .badge-outline { background: transparent; border: 1px solid currentColor; }
1263
+ .badge-sm { font-size: 0.6875rem; padding: 0.15rem 0.5rem; }
1264
+ .badge-lg { font-size: 0.875rem; padding: 0.25rem 0.75rem; }
1265
+
1266
+ /* Stat component (Ripple UI compatibility) */
1267
+ .stats { display: flex; flex-wrap: wrap; }
1268
+ .stat { padding: 1.25rem 1.5rem; display: flex; flex-direction: column; gap: 0.25rem; min-width: 160px; }
1269
+ .stat-title { font-size: 0.8125rem; font-weight: 500; color: var(--color-text-muted); opacity: 0.8; }
1270
+ .stat-value { font-size: 2rem; font-weight: 700; color: var(--color-text); line-height: 1.2; }
1271
+ .stat-desc { font-size: 0.8125rem; color: var(--color-text-muted); }
1272
+ .stat-figure { display: flex; align-items: center; justify-content: center; }
1273
+
1274
+ /* Misc */
1275
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border-width: 0; }
1276
+ .not-sr-only { position: static; width: auto; height: auto; padding: 0; margin: 0; overflow: visible; clip: auto; white-space: normal; }
1277
+ .list-none { list-style: none; }
1278
+ .list-disc { list-style-type: disc; }
1279
+ .appearance-none { appearance: none; }
1280
+ .resize-none { resize: none; }
1281
+ .resize-y { resize: vertical; }
1282
+ .ring { box-shadow: 0 0 0 3px rgba(59,130,246,0.5); }
1283
+ .ring-primary { box-shadow: 0 0 0 3px rgba(4,20,31,0.2); }
1284
+ .no-underline { text-decoration: none; }
1285
+ .underline { text-decoration: underline; }
1286
+ .line-through { text-decoration: line-through; }
1287
+ .italic { font-style: italic; }
1288
+ .not-italic { font-style: normal; }
1289
+
1290
+ /* ═══════════════════════════════════════════════════════════
1291
+ VISUAL POLISH & IMPROVED COMPONENT STYLES
1292
+ ═══════════════════════════════════════════════════════════ */
1293
+
1294
+ /* Nav separator hidden */
1295
+ .nav-sep { display: none; }
1296
+
1297
+ /* Nav link hover with underline indicator */
1298
+ .nav-links-desktop .nav-link:hover { color: #fff; }
1299
+ .nav-links-desktop .nav-link-active { position: relative; }
1300
+
1301
+ /* Mobile nav active page highlight */
1302
+ .mobile-nav-link.active { color: #fff; background: rgba(255,255,255,0.08); }
1303
+
1304
+ /* Better user dropdown */
1305
+ .user-dropdown { position: absolute; right: 1rem; top: calc(100% + 4px); min-width: 200px; background: #fff; border: 1px solid var(--color-border); border-radius: 10px; box-shadow: var(--shadow-lg); display: none; overflow: hidden; z-index: var(--z-dropdown); }
1306
+ @media (prefers-color-scheme: dark) { .user-dropdown { background: #1e2a38; border-color: #334155; } }
1307
+ .user-dropdown-header { padding: 14px 16px; background: var(--color-bg); border-bottom: 1px solid var(--color-border); }
1308
+ .user-dropdown-name { font-size: 14px; font-weight: 600; color: var(--color-text); }
1309
+ .user-dropdown-email { font-size: 12px; color: var(--color-text-muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1310
+ .user-dropdown-role { font-size: 11px; color: var(--color-text-light); margin-top: 4px; }
1311
+ .user-dropdown-item { display: flex; align-items: center; gap: 8px; padding: 10px 16px; color: var(--color-text); text-decoration: none; font-size: 14px; transition: background 0.15s; }
1312
+ .user-dropdown-item:hover { background: var(--color-bg); }
1313
+ @media (prefers-color-scheme: dark) { .user-dropdown-item:hover { background: #2d3748; } }
1314
+
1315
+ /* Improved page shell */
1316
+ .page-shell { background: var(--color-bg); min-height: calc(100vh - 56px); }
1317
+
1318
+ /* Better page header */
1319
+ .page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; gap: 12px; flex-wrap: wrap; padding-bottom: 0; }
1320
+ @media (max-width: 767px) { .page-header { flex-direction: column; align-items: flex-start; } }
1321
+
1322
+ /* Typography improvements */
1323
+ .page-title { font-size: 1.5rem; font-weight: 700; color: var(--color-text); letter-spacing: -0.3px; margin: 0; line-height: 1.3; }
1324
+ @media (max-width: 479px) { .page-title { font-size: 1.25rem; } }
1325
+ .section-title { font-size: 1rem; font-weight: 600; color: var(--color-text); margin: 0 0 1rem; }
1326
+ .label-caps { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-muted); }
1327
+
1328
+ /* Better card */
1329
+ .card-clean { background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-sm); border: 1px solid var(--color-border); }
1330
+ .card-clean-body { padding: 1.25rem; }
1331
+
1332
+ /* Improved stat cards with hover animation */
1333
+ .stat-card { background: var(--color-surface); border-radius: var(--radius); border: 1px solid var(--color-border); padding: 1.25rem; box-shadow: var(--shadow-sm); }
1334
+ .stat-card-clickable:hover { border-color: var(--color-info); box-shadow: var(--shadow-md); transform: translateY(-1px); transition: all 0.15s ease; }
1335
+ .stat-card-clickable:active { transform: translateY(0); }
1336
+ .stat-card-value { font-size: 2rem; font-weight: 700; color: var(--color-text); line-height: 1.2; }
1337
+ .stat-card-warn { color: var(--color-danger); }
1338
+ .stat-card-label { font-size: 0.875rem; font-weight: 600; color: var(--color-text); margin-top: 0.25rem; }
1339
+ .stat-card-sub { font-size: 0.8125rem; color: var(--color-text-muted); margin-top: 0.2rem; }
1340
+
1341
+ /* Better table improvements */
1342
+ .data-table td { vertical-align: middle; padding: 12px 16px; }
1343
+ .data-table th { padding: 10px 16px; }
1344
+
1345
+ /* Better breadcrumb */
1346
+ .breadcrumb-clean { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; margin-bottom: 1rem; font-size: 13px; }
1347
+ .breadcrumb-clean a { color: var(--color-text-muted); text-decoration: none; }
1348
+ .breadcrumb-clean a:hover { color: var(--color-primary); text-decoration: underline; }
1349
+ .breadcrumb-clean span[aria-current] { color: var(--color-text); font-weight: 500; }
1350
+ .breadcrumb-sep { color: var(--color-text-light); }
1351
+
1352
+ /* Tab bar improvements */
1353
+ .tab-bar { display: flex; gap: 0; border-bottom: 2px solid var(--color-border); margin-bottom: 1.25rem; overflow-x: auto; scrollbar-width: none; }
1354
+ .tab-bar::-webkit-scrollbar { display: none; }
1355
+ .tab-btn { background: none; border: none; cursor: pointer; padding: 10px 16px; font-size: 14px; font-weight: 500; color: var(--color-text-muted); border-bottom: 2px solid transparent; margin-bottom: -2px; white-space: nowrap; transition: color 0.15s, border-color 0.15s; display: flex; align-items: center; gap: 6px; }
1356
+ .tab-btn:hover { color: var(--color-text); }
1357
+ .tab-btn.active { color: var(--color-primary); border-bottom-color: var(--color-primary); font-weight: 600; }
1358
+ .tab-count { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 100px; font-size: 11px; font-weight: 600; padding: 1px 7px; color: var(--color-text-muted); }
1359
+ .tab-btn.active .tab-count { background: var(--color-primary); color: #fff; border-color: transparent; }
1360
+
1361
+ /* Form improvements */
1362
+ .form-field { margin-bottom: 1rem; }
1363
+ .form-label { display: block; font-size: 0.8125rem; font-weight: 600; color: var(--color-text); margin-bottom: 5px; }
1364
+ .form-input { width: 100%; padding: 9px 12px; border: 1.5px solid var(--color-border); border-radius: 7px; font-size: 0.9rem; outline: none; transition: border-color 0.15s, box-shadow 0.15s; background: var(--color-surface); color: var(--color-text); min-height: 40px; }
1365
+ .form-input:focus { border-color: var(--color-info); box-shadow: 0 0 0 3px rgba(37,99,235,0.1); }
1366
+ .form-input::placeholder { color: var(--color-text-light); }
1367
+ .form-input:disabled { opacity: 0.6; cursor: not-allowed; background: var(--color-bg); }
1368
+ .form-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding-top: 1rem; border-top: 1px solid var(--color-border); margin-top: 1rem; }
1369
+
1370
+ /* Alert strip improvements */
1371
+ .alert-strip { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; border-radius: var(--radius); border: 1px solid; flex-wrap: wrap; }
1372
+ .alert-strip-danger { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
1373
+ .alert-strip-warning { background: #fffbeb; border-color: #fed7aa; color: #92400e; }
1374
+ .alert-strip-info { background: #eff6ff; border-color: #bfdbfe; color: #1e40af; }
1375
+ @media (prefers-color-scheme: dark) {
1376
+ .alert-strip-danger { background: #7f1d1d22; border-color: #b91c1c44; color: #f87171; }
1377
+ .alert-strip-warning { background: #78350f22; border-color: #d9770644; color: #fbbf24; }
1378
+ }
1379
+
1380
+ /* Review meta row */
1381
+ .review-meta-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
1382
+
1383
+ /* Resolution bar improvements */
1384
+ .resolution-bar { background: var(--color-bg); border-radius: 4px; height: 6px; overflow: hidden; border: 1px solid var(--color-border); }
1385
+ .resolution-bar-segment { height: 100%; border-radius: 4px; transition: width 0.3s ease; }
1386
+ .resolution-bar-resolved { background: var(--color-success); }
1387
+
1388
+ /* Smooth button spinner */
1389
+ .btn-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: #fff; border-radius: 50%; animation: spin 0.7s linear infinite; vertical-align: middle; }
1390
+ @keyframes spin { to { transform: rotate(360deg); } }
1391
+
1392
+ /* Toast notification improvements */
1393
+ .toast-container { position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: var(--z-notification); display: flex; flex-direction: column; gap: 8px; }
1394
+ .toast { padding: 12px 18px; border-radius: 8px; font-size: 14px; font-weight: 500; color: #fff; box-shadow: var(--shadow-lg); opacity: 1; transition: opacity 0.3s ease; max-width: 320px; }
1395
+ .toast-success { background: var(--color-success); }
1396
+ .toast-error { background: var(--color-danger); }
1397
+ .toast-warning { background: var(--color-warning); }
1398
+ .toast-info { background: var(--color-info); }
1399
+
1400
+ /* Better confirm dialog */
1401
+ .confirm-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: var(--z-modal-backdrop); padding: 1rem; backdrop-filter: blur(2px); }
1402
+ .confirm-dialog { background: var(--color-surface); border-radius: 12px; padding: 24px; max-width: 420px; width: 100%; box-shadow: var(--shadow-lg); }
1403
+ .confirm-title { font-size: 1.125rem; font-weight: 700; color: var(--color-text); margin: 0 0 8px; }
1404
+ .confirm-message { font-size: 14px; color: var(--color-text-muted); line-height: 1.6; margin-bottom: 20px; }
1405
+ .confirm-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
1406
+
1407
+ /* Stage pill improvements */
1408
+ .stage-pill { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 100px; font-size: 11px; font-weight: 600; letter-spacing: 0.3px; }
1409
+
1410
+ /* Better nav hamburger */
1411
+ .nav-hamburger { display: none; background: none; border: none; color: #9ca3af; cursor: pointer; padding: 8px; border-radius: 6px; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; transition: color 0.15s, background 0.15s; }
1412
+ .nav-hamburger:hover { color: #fff; background: rgba(255,255,255,0.08); }
1413
+ @media (max-width: 768px) { .nav-hamburger { display: flex; } }
1414
+
1415
+ /* Section headers in detail pages */
1416
+ .detail-section-header { font-size: 0.875rem; font-weight: 600; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--color-border); }
1417
+
1418
+ /* Better pill badge */
1419
+ .pill { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 100px; font-size: 11.5px; font-weight: 500; }
1420
+
1421
+ /* Progress bar in tables */
1422
+ .progress-bar-wrap { display: flex; align-items: center; gap: 6px; min-width: 80px; }
1423
+ .progress-bar-track { flex: 1; height: 5px; background: var(--color-bg); border-radius: 3px; overflow: hidden; border: 1px solid var(--color-border); }
1424
+ .progress-bar-fill { height: 100%; border-radius: 3px; transition: width 0.3s ease; }
1425
+
1426
+ /* ============================================================
1427
+ 247420 DESIGN SYSTEM
1428
+ Panel token system, topbar, breadcrumb, IDE-density
1429
+ ============================================================ */
1430
+
1431
+ /* --- 247420 tokens: light mode --- */
1432
+ :root {
1433
+ --paper: #EFE9DD;
1434
+ --ink: #0B0B09;
1435
+ --acid: #B8FF00;
1436
+ --link: #1F4DFF;
1437
+ --warn: #FF3B1F;
1438
+ --live: #00A86B;
1439
+ --green: #30A46C;
1440
+ --purple: #8E4EC6;
1441
+
1442
+ --ff-display: 'Archivo Black', sans-serif;
1443
+ --ff-mono: 'JetBrains Mono', monospace;
1444
+ --ff-prose: 'Instrument Serif', serif;
1445
+
1446
+ --r-1: 0;
1447
+ --r-2: 0;
1448
+
1449
+ /* Panel surfaces (light) */
1450
+ --panel-0: #f5f5f0;
1451
+ --panel-1: #ece9e0;
1452
+ --panel-2: #e0ddd4;
1453
+ --panel-3: #d4d1c8;
1454
+ --panel-text: #0B0B09;
1455
+ --panel-text-2: #444444;
1456
+ --panel-text-3: #888888;
1457
+ --panel-hover: rgba(0,0,0,0.04);
1458
+ --panel-select: rgba(0,0,0,0.08);
1459
+ --panel-accent: #B8FF00;
1460
+ --panel-accent-fg: #0B0B09;
1461
+ }
1462
+
1463
+ /* --- 247420 tokens: dark mode --- */
1464
+ [data-theme="dark"] {
1465
+ --panel-0: #0f0f0d;
1466
+ --panel-1: #1a1a16;
1467
+ --panel-2: #222220;
1468
+ --panel-3: #2a2a27;
1469
+ --panel-text: #EFE9DD;
1470
+ --panel-text-2: #aaaaaa;
1471
+ --panel-text-3: #666666;
1472
+ --panel-hover: rgba(255,255,255,0.06);
1473
+ --panel-select: rgba(255,255,255,0.10);
1474
+ --panel-accent: #B8FF00;
1475
+ --panel-accent-fg: #0B0B09;
1476
+ }
1477
+
1478
+ @media (prefers-color-scheme: dark) {
1479
+ :root:not([data-theme="light"]) {
1480
+ --panel-0: #0f0f0d;
1481
+ --panel-1: #1a1a16;
1482
+ --panel-2: #222220;
1483
+ --panel-3: #2a2a27;
1484
+ --panel-text: #EFE9DD;
1485
+ --panel-text-2: #aaaaaa;
1486
+ --panel-text-3: #666666;
1487
+ --panel-hover: rgba(255,255,255,0.06);
1488
+ --panel-select: rgba(255,255,255,0.10);
1489
+ --panel-accent: #B8FF00;
1490
+ --panel-accent-fg: #0B0B09;
1491
+ }
1492
+ }
1493
+
1494
+ /* --- Base density (13px IDE-style) --- */
1495
+ body { font-size: 13px; }
1496
+
1497
+ /* --- Zero border-radius override --- */
1498
+ .btn, .button, button, input, select, textarea, .card, .modal-box, .badge, .stage-pill, .pill { border-radius: var(--r-1) !important; }
1499
+
1500
+ /* --- Sticky 40px topbar --- */
1501
+ .app-topbar {
1502
+ position: sticky;
1503
+ top: 0;
1504
+ z-index: 100;
1505
+ height: 40px;
1506
+ display: flex;
1507
+ align-items: center;
1508
+ padding: 0 12px;
1509
+ background: var(--panel-1);
1510
+ border-bottom: 1px solid var(--panel-2);
1511
+ gap: 8px;
1512
+ font-size: 13px;
1513
+ color: var(--panel-text);
1514
+ }
1515
+ .app-topbar-brand { font-family: var(--ff-display); font-size: 13px; font-weight: 900; letter-spacing: -0.3px; color: var(--panel-text); text-decoration: none; }
1516
+ .app-topbar-spacer { flex: 1; }
1517
+ .app-topbar-actions { display: flex; align-items: center; gap: 4px; }
1518
+
1519
+ /* --- Breadcrumb bar (monospace, under topbar) --- */
1520
+ .app-crumb {
1521
+ height: 32px;
1522
+ display: flex;
1523
+ align-items: center;
1524
+ padding: 0 12px;
1525
+ background: var(--panel-0);
1526
+ border-bottom: 1px solid var(--panel-2);
1527
+ font-family: var(--ff-mono);
1528
+ font-size: 11px;
1529
+ color: var(--panel-text-3);
1530
+ gap: 4px;
1531
+ white-space: nowrap;
1532
+ overflow: hidden;
1533
+ }
1534
+ .app-crumb a { color: var(--panel-text-2); text-decoration: none; }
1535
+ .app-crumb a:hover { color: var(--panel-text); }
1536
+ .app-crumb-sep { color: var(--panel-text-3); margin: 0 2px; }
1537
+ .app-crumb-current { color: var(--panel-text); font-weight: 600; }
1538
+
1539
+ /* --- Row hover pattern (bg tint, no border separators) --- */
1540
+ .hover-row { transition: background 0.1s; }
1541
+ .hover-row:hover { background: var(--panel-hover) !important; }
1542
+ tr.hover-row:hover td, tr.hover-row:hover th { background: var(--panel-hover) !important; }
1543
+
1544
+ /* --- Panel surface utility classes --- */
1545
+ .panel-0 { background: var(--panel-0); color: var(--panel-text); }
1546
+ .panel-1 { background: var(--panel-1); color: var(--panel-text); }
1547
+ .panel-2 { background: var(--panel-2); color: var(--panel-text); }
1548
+ .panel-3 { background: var(--panel-3); color: var(--panel-text); }
1549
+ .panel-accent-chip { background: var(--panel-accent); color: var(--panel-accent-fg); padding: 1px 6px; font-size: 11px; font-weight: 700; }
1550
+
1551
+ /* --- Mono / display text helpers --- */
1552
+ .text-mono { font-family: var(--ff-mono); }
1553
+ .text-display { font-family: var(--ff-display); }
1554
+ .text-prose { font-family: var(--ff-prose); }
1555
+ .text-muted-2 { color: var(--panel-text-2); }
1556
+ .text-muted-3 { color: var(--panel-text-3); }
1557
+ .text-acid { color: var(--acid); }
1558
+ .text-warn { color: var(--warn); }
1559
+ .text-live { color: var(--live); }
1560
+ .text-green { color: var(--green); }
1561
+ .text-purple { color: var(--purple); }
1562
+
1563
+
1564
+ /* === Theme toggle — light overrides; dark = default surfaces above === */
1565
+ html[data-theme="light"] {
1566
+ --ds-bg: #f7f8fa;
1567
+ --ds-surface: #ffffff;
1568
+ --ds-elevated: #f1f3f5;
1569
+ --ds-fg: #1a1b1e;
1570
+ --ds-muted: #5a5d62;
1571
+ --ds-border: #d8dadd;
1572
+ }
1573
+ html[data-theme="light"] body { background: var(--ds-bg); color: var(--ds-fg); }
1574
+ html[data-theme="light"] #flexup-dock .fx-msg.bot { background: #fff; }
1575
+ html[data-theme="light"] #flexup-dock .fx-msg.user { background: var(--ds-elevated); }
1576
+ html[data-theme="light"] #ds-online-status.offline { background: #ffd6d6; color: #4a1d1d; }
1577
+ #theme-toggle:hover { color: #fff !important; background: rgba(255,255,255,0.08); }
1578
+
1579
+ /* === Mobile breakpoint hardening: prevent horizontal overflow at 375 === */
1580
+ @media (max-width: 480px) {
1581
+ html, body { overflow-x: hidden; }
1582
+ .dialog-panel, .modal-content, .confirm-dialog { max-width: calc(100vw - 1rem) !important; box-sizing: border-box; }
1583
+ .card-clean { max-width: 100%; box-sizing: border-box; }
1584
+ table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
1585
+ #flexup-dock { width: calc(100vw - 24px) !important; right: 12px; bottom: 80px; }
1586
+ .nav-links-desktop { display: none !important; }
1587
+ }
1588
+
1589
+ /* === Print stylesheet — engagement report and review pages === */
1590
+ @media print {
1591
+ .main-nav, #main-nav, .sidebar, .sidebar-collapsible, .nav-hamburger, #flexup-fab, #flexup-dock,
1592
+ .no-print, #notif-bell, #user-avatar, #user-dropdown, .skip-link, #ds-online-status,
1593
+ #theme-toggle, .dialog-overlay, .confirm-overlay, .modal-overlay, .toast-container,
1594
+ .table-toolbar, .breadcrumb-clean { display: none !important; }
1595
+ .page-shell, .page-shell-flush, main { padding: 0 !important; margin: 0 !important; max-width: 100% !important; }
1596
+ body, html { background: #fff !important; color: #000 !important; }
1597
+ .card-clean, .info-card, .table-wrap, .dialog-panel { background: #fff !important; box-shadow: none !important; border: 1px solid #ccc !important; page-break-inside: avoid; }
1598
+ a { color: #000 !important; text-decoration: underline; }
1599
+ table { width: 100% !important; border-collapse: collapse; }
1600
+ table, th, td { border: 1px solid #999 !important; }
1601
+ h1, h2, h3 { color: #000 !important; page-break-after: avoid; }
1602
+ }