@codemation/next-host 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/README.md +25 -0
  2. package/app/(shell)/credentials/page.tsx +5 -0
  3. package/app/(shell)/dashboard/page.tsx +14 -0
  4. package/app/(shell)/layout.tsx +11 -0
  5. package/app/(shell)/page.tsx +5 -0
  6. package/app/(shell)/users/page.tsx +5 -0
  7. package/app/(shell)/workflows/[workflowId]/page.tsx +19 -0
  8. package/app/(shell)/workflows/page.tsx +5 -0
  9. package/app/api/[[...path]]/route.ts +40 -0
  10. package/app/api/auth/[...nextauth]/route.ts +3 -0
  11. package/app/globals.css +997 -0
  12. package/app/invite/[token]/page.tsx +10 -0
  13. package/app/layout.tsx +65 -0
  14. package/app/login/layout.tsx +25 -0
  15. package/app/login/page.tsx +22 -0
  16. package/components.json +21 -0
  17. package/docs/FORMS.md +46 -0
  18. package/docs/TAILWIND_SHADCN_MIGRATION.md +89 -0
  19. package/eslint.config.mjs +56 -0
  20. package/middleware.ts +29 -0
  21. package/next-env.d.ts +6 -0
  22. package/next.config.ts +34 -0
  23. package/package.json +76 -0
  24. package/postcss.config.mjs +7 -0
  25. package/public/canvas-icons/builtin/openai.svg +5 -0
  26. package/src/api/CodemationApiClient.ts +107 -0
  27. package/src/api/CodemationApiHttpError.ts +17 -0
  28. package/src/auth/CodemationNextAuthConfigResolver.ts +14 -0
  29. package/src/auth/CodemationNextAuthOAuthProviderDescriptorMapper.ts +30 -0
  30. package/src/auth/CodemationNextAuthOAuthProviderSnapshotResolver.ts +17 -0
  31. package/src/auth/CodemationNextAuthProviderCatalog.ts +107 -0
  32. package/src/auth/codemationEdgeAuth.ts +25 -0
  33. package/src/auth/codemationNextAuth.ts +32 -0
  34. package/src/components/Codemation.tsx +6 -0
  35. package/src/components/CodemationDataTable.tsx +37 -0
  36. package/src/components/CodemationDialog.tsx +137 -0
  37. package/src/components/CodemationFormattedDateTime.tsx +46 -0
  38. package/src/components/GoogleColorGIcon.tsx +39 -0
  39. package/src/components/OauthProviderIcon.tsx +33 -0
  40. package/src/components/PasswordStrengthMeter.tsx +59 -0
  41. package/src/components/forms/index.ts +28 -0
  42. package/src/components/json/JsonMonacoEditor.tsx +75 -0
  43. package/src/components/oauthProviderIconData.ts +17 -0
  44. package/src/components/ui/alert.tsx +56 -0
  45. package/src/components/ui/badge.tsx +40 -0
  46. package/src/components/ui/button.tsx +64 -0
  47. package/src/components/ui/card.tsx +70 -0
  48. package/src/components/ui/collapsible.tsx +26 -0
  49. package/src/components/ui/dialog.tsx +137 -0
  50. package/src/components/ui/dropdown-menu.tsx +238 -0
  51. package/src/components/ui/form.tsx +147 -0
  52. package/src/components/ui/input.tsx +19 -0
  53. package/src/components/ui/label.tsx +26 -0
  54. package/src/components/ui/scroll-area.tsx +47 -0
  55. package/src/components/ui/select.tsx +169 -0
  56. package/src/components/ui/separator.tsx +28 -0
  57. package/src/components/ui/switch.tsx +28 -0
  58. package/src/components/ui/table.tsx +72 -0
  59. package/src/components/ui/tabs.tsx +76 -0
  60. package/src/components/ui/textarea.tsx +18 -0
  61. package/src/components/ui/toggle.tsx +41 -0
  62. package/src/features/credentials/components/CredentialConfirmDialog.tsx +58 -0
  63. package/src/features/credentials/components/CredentialDialog.tsx +252 -0
  64. package/src/features/credentials/components/CredentialDialogFeedback.tsx +36 -0
  65. package/src/features/credentials/components/CredentialDialogFieldRows.tsx +257 -0
  66. package/src/features/credentials/components/CredentialDialogFormSections.tsx +230 -0
  67. package/src/features/credentials/components/CredentialEnvFieldStatusRow.tsx +64 -0
  68. package/src/features/credentials/components/CredentialFieldCopyButton.tsx +48 -0
  69. package/src/features/credentials/components/CredentialsScreenHealthBadge.tsx +21 -0
  70. package/src/features/credentials/components/CredentialsScreenInstancesTable.tsx +108 -0
  71. package/src/features/credentials/components/CredentialsScreenTestFailureAlert.tsx +33 -0
  72. package/src/features/credentials/hooks/useCredentialCreateDialog.ts +33 -0
  73. package/src/features/credentials/hooks/useCredentialDialogSession.ts +616 -0
  74. package/src/features/credentials/hooks/useCredentialsScreen.ts +213 -0
  75. package/src/features/credentials/lib/credentialFieldHelpers.ts +35 -0
  76. package/src/features/credentials/lib/credentialFormTypes.ts +1 -0
  77. package/src/features/credentials/lib/credentialInstanceTestPayloadParser.ts +10 -0
  78. package/src/features/credentials/screens/CredentialsScreen.tsx +187 -0
  79. package/src/features/invite/screens/InviteAcceptScreen.tsx +190 -0
  80. package/src/features/users/components/UsersInviteDialog.tsx +121 -0
  81. package/src/features/users/components/UsersRegenerateDialog.tsx +81 -0
  82. package/src/features/users/components/UsersScreenUserStatusBadge.tsx +19 -0
  83. package/src/features/users/schemas/usersInviteFormSchema.ts +7 -0
  84. package/src/features/users/screens/UsersScreen.tsx +240 -0
  85. package/src/features/workflows/components/WorkflowListFolderSection.tsx +91 -0
  86. package/src/features/workflows/components/WorkflowListItemCard.tsx +67 -0
  87. package/src/features/workflows/components/WorkflowListRoot.tsx +39 -0
  88. package/src/features/workflows/components/WorkflowsListTree.tsx +28 -0
  89. package/src/features/workflows/components/canvas/CanvasNodeChromeTooltip.tsx +96 -0
  90. package/src/features/workflows/components/canvas/CanvasNodeIconSlot.tsx +25 -0
  91. package/src/features/workflows/components/canvas/VisibleNodeStatusResolver.tsx +84 -0
  92. package/src/features/workflows/components/canvas/WorkflowCanvas.tsx +248 -0
  93. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNode.tsx +182 -0
  94. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeAccents.tsx +73 -0
  95. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeAgentBottomSourceHandles.tsx +43 -0
  96. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeAgentLabels.tsx +47 -0
  97. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeCard.tsx +202 -0
  98. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeHandles.tsx +77 -0
  99. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeLabelBelow.tsx +51 -0
  100. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeMainGlyph.tsx +64 -0
  101. package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeToolbar.tsx +95 -0
  102. package/src/features/workflows/components/canvas/WorkflowCanvasLoadingPlaceholder.tsx +69 -0
  103. package/src/features/workflows/components/canvas/WorkflowCanvasNodeIcon.tsx +102 -0
  104. package/src/features/workflows/components/canvas/WorkflowCanvasSimpleIconGlyph.tsx +21 -0
  105. package/src/features/workflows/components/canvas/WorkflowCanvasStraightCountEdge.tsx +33 -0
  106. package/src/features/workflows/components/canvas/WorkflowCanvasStructureSignature.tsx +7 -0
  107. package/src/features/workflows/components/canvas/WorkflowCanvasSymmetricForkEdge.tsx +32 -0
  108. package/src/features/workflows/components/canvas/WorkflowCanvasToolbarIconButton.tsx +95 -0
  109. package/src/features/workflows/components/canvas/lib/WorkflowCanvasBuiltinIconRegistry.ts +26 -0
  110. package/src/features/workflows/components/canvas/lib/WorkflowCanvasEdgeCountResolver.ts +51 -0
  111. package/src/features/workflows/components/canvas/lib/WorkflowCanvasEdgeStyleResolver.ts +35 -0
  112. package/src/features/workflows/components/canvas/lib/WorkflowCanvasLabelLayoutEstimator.ts +42 -0
  113. package/src/features/workflows/components/canvas/lib/WorkflowCanvasOverlapResolver.ts +78 -0
  114. package/src/features/workflows/components/canvas/lib/WorkflowCanvasPortOrderResolver.ts +25 -0
  115. package/src/features/workflows/components/canvas/lib/WorkflowCanvasRoundedOrthogonalPathPlanner.ts +56 -0
  116. package/src/features/workflows/components/canvas/lib/WorkflowCanvasSiIconRegistry.ts +18 -0
  117. package/src/features/workflows/components/canvas/lib/WorkflowCanvasSymmetricForkPathPlanner.ts +43 -0
  118. package/src/features/workflows/components/canvas/lib/layoutWorkflow.ts +315 -0
  119. package/src/features/workflows/components/canvas/lib/workflowCanvasEdgeGeometry.ts +3 -0
  120. package/src/features/workflows/components/canvas/lib/workflowCanvasEmbeddedStyles.ts +62 -0
  121. package/src/features/workflows/components/canvas/lib/workflowCanvasFlowTypes.ts +10 -0
  122. package/src/features/workflows/components/canvas/lib/workflowCanvasNodeData.ts +41 -0
  123. package/src/features/workflows/components/canvas/lib/workflowCanvasNodeGeometry.ts +99 -0
  124. package/src/features/workflows/components/canvas/workflowCanvasNodeChrome.tsx +46 -0
  125. package/src/features/workflows/components/realtime/RealtimeContext.tsx +14 -0
  126. package/src/features/workflows/components/realtime/WorkflowRealtimeProvider.tsx +15 -0
  127. package/src/features/workflows/components/workflowDetail/NodeCredentialBindingRow.tsx +209 -0
  128. package/src/features/workflows/components/workflowDetail/NodeCredentialBindingsSection.tsx +227 -0
  129. package/src/features/workflows/components/workflowDetail/NodePropertiesConfigSection.tsx +51 -0
  130. package/src/features/workflows/components/workflowDetail/NodePropertiesPanelHeader.tsx +50 -0
  131. package/src/features/workflows/components/workflowDetail/NodePropertiesSlidePanel.tsx +134 -0
  132. package/src/features/workflows/components/workflowDetail/WorkflowActivationErrorDialog.tsx +71 -0
  133. package/src/features/workflows/components/workflowDetail/WorkflowActivationHeaderControl.tsx +64 -0
  134. package/src/features/workflows/components/workflowDetail/WorkflowDetailIcons.tsx +52 -0
  135. package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspector.tsx +110 -0
  136. package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorDetailBody.tsx +213 -0
  137. package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorPanes.tsx +239 -0
  138. package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorSidebarResizer.tsx +31 -0
  139. package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorTreePanel.tsx +133 -0
  140. package/src/features/workflows/components/workflowDetail/WorkflowInspectorAttachmentGroupingPresenter.tsx +31 -0
  141. package/src/features/workflows/components/workflowDetail/WorkflowInspectorAttachmentList.tsx +118 -0
  142. package/src/features/workflows/components/workflowDetail/WorkflowInspectorBinaryView.tsx +15 -0
  143. package/src/features/workflows/components/workflowDetail/WorkflowInspectorErrorView.tsx +107 -0
  144. package/src/features/workflows/components/workflowDetail/WorkflowInspectorJsonView.tsx +114 -0
  145. package/src/features/workflows/components/workflowDetail/WorkflowInspectorPrettyTreePresenter.tsx +132 -0
  146. package/src/features/workflows/components/workflowDetail/WorkflowInspectorPrettyTreeViewRenderer.tsx +147 -0
  147. package/src/features/workflows/components/workflowDetail/WorkflowInspectorPrettyView.tsx +65 -0
  148. package/src/features/workflows/components/workflowDetail/WorkflowInspectorViews.tsx +5 -0
  149. package/src/features/workflows/components/workflowDetail/WorkflowJsonEditorBinaryAttachmentRow.tsx +74 -0
  150. package/src/features/workflows/components/workflowDetail/WorkflowJsonEditorBinaryUploadRow.tsx +69 -0
  151. package/src/features/workflows/components/workflowDetail/WorkflowJsonEditorDialog.tsx +254 -0
  152. package/src/features/workflows/components/workflowDetail/WorkflowRunsList.tsx +89 -0
  153. package/src/features/workflows/components/workflowDetail/WorkflowRunsSidebar.tsx +50 -0
  154. package/src/features/workflows/hooks/canvas/useWorkflowCanvasVisibleNodeStatuses.ts +14 -0
  155. package/src/features/workflows/hooks/realtime/realtime.tsx +271 -0
  156. package/src/features/workflows/hooks/realtime/runQueryPolling.ts +34 -0
  157. package/src/features/workflows/hooks/realtime/useWorkflowRealtimeInfrastructure.ts +541 -0
  158. package/src/features/workflows/hooks/realtime/useWorkflowRealtimeShowDisconnectedBadge.ts +9 -0
  159. package/src/features/workflows/hooks/workflowDetail/useWorkflowDetailController.tsx +1300 -0
  160. package/src/features/workflows/lib/realtime/realtimeApi.ts +78 -0
  161. package/src/features/workflows/lib/realtime/realtimeClientBridge.ts +52 -0
  162. package/src/features/workflows/lib/realtime/realtimeDomainTypes.ts +191 -0
  163. package/src/features/workflows/lib/realtime/realtimeQueryKeys.ts +15 -0
  164. package/src/features/workflows/lib/realtime/realtimeRunMutations.ts +167 -0
  165. package/src/features/workflows/lib/realtime/workflowTypes.ts +5 -0
  166. package/src/features/workflows/lib/workflowDetail/PersistedWorkflowSnapshotMapper.ts +205 -0
  167. package/src/features/workflows/lib/workflowDetail/WorkflowActivationHttpErrorFormat.ts +32 -0
  168. package/src/features/workflows/lib/workflowDetail/WorkflowDetailPresenter.ts +1017 -0
  169. package/src/features/workflows/lib/workflowDetail/WorkflowDetailUrlCodec.ts +70 -0
  170. package/src/features/workflows/lib/workflowDetail/workflowDetailTypes.ts +152 -0
  171. package/src/features/workflows/lib/workflowDetailTreeStyles.ts +65 -0
  172. package/src/features/workflows/screens/WorkflowDetailScreen.tsx +236 -0
  173. package/src/features/workflows/screens/WorkflowDetailScreenInspectorPanel.tsx +55 -0
  174. package/src/features/workflows/screens/WorkflowsList.tsx +35 -0
  175. package/src/features/workflows/screens/WorkflowsScreen.tsx +31 -0
  176. package/src/index.ts +1 -0
  177. package/src/lib/utils.ts +6 -0
  178. package/src/middleware/CodemationNextHostMiddlewarePathRules.ts +31 -0
  179. package/src/providers/CodemationSessionProvider.tsx +23 -0
  180. package/src/providers/Providers.tsx +36 -0
  181. package/src/providers/RealtimeBoundary.tsx +17 -0
  182. package/src/providers/WhitelabelProvider.tsx +22 -0
  183. package/src/server/CodemationAuthPrismaClient.ts +21 -0
  184. package/src/server/CodemationNextHost.ts +379 -0
  185. package/src/shell/AppLayout.tsx +141 -0
  186. package/src/shell/AppLayoutNavItems.tsx +129 -0
  187. package/src/shell/AppLayoutPageHeader.tsx +79 -0
  188. package/src/shell/AppLayoutSidebarBrand.tsx +33 -0
  189. package/src/shell/AppMainContent.tsx +17 -0
  190. package/src/shell/AppShellHeaderActions.tsx +12 -0
  191. package/src/shell/AppShellHeaderActionsAuthenticated.tsx +51 -0
  192. package/src/shell/CodemationNextClientShell.tsx +17 -0
  193. package/src/shell/CredentialsSignInRedirectResolver.ts +21 -0
  194. package/src/shell/LoginPageClient.tsx +231 -0
  195. package/src/shell/WorkflowDetailChromeContext.tsx +42 -0
  196. package/src/shell/WorkflowFolderTreeBuilder.ts +62 -0
  197. package/src/shell/WorkflowFolderUi.ts +42 -0
  198. package/src/shell/WorkflowSidebarNavFolder.tsx +112 -0
  199. package/src/shell/WorkflowSidebarNavTree.tsx +68 -0
  200. package/src/shell/appLayoutPageTitle.ts +16 -0
  201. package/src/shell/appLayoutSidebarIcons.tsx +108 -0
  202. package/src/whitelabel/CodemationWhitelabelSnapshot.ts +4 -0
  203. package/src/whitelabel/CodemationWhitelabelSnapshotFactory.ts +18 -0
  204. package/tsconfig.json +40 -0
  205. package/tsconfig.tsbuildinfo +1 -0
  206. package/vitest.config.ts +34 -0
@@ -0,0 +1,997 @@
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+ @import "shadcn/tailwind.css";
4
+
5
+ @custom-variant dark (&:is(.dark *));
6
+
7
+ @theme inline {
8
+ --color-background: var(--background);
9
+ --color-foreground: var(--foreground);
10
+ --color-card: var(--card);
11
+ --color-card-foreground: var(--card-foreground);
12
+ --color-popover: var(--popover);
13
+ --color-popover-foreground: var(--popover-foreground);
14
+ --color-primary: var(--primary);
15
+ --color-primary-foreground: var(--primary-foreground);
16
+ --color-secondary: var(--secondary);
17
+ --color-secondary-foreground: var(--secondary-foreground);
18
+ --color-muted: var(--muted);
19
+ --color-muted-foreground: var(--muted-foreground);
20
+ --color-accent: var(--accent);
21
+ --color-accent-foreground: var(--accent-foreground);
22
+ --color-destructive: var(--destructive);
23
+ --color-destructive-foreground: var(--destructive-foreground);
24
+ --color-border: var(--border);
25
+ --color-input: var(--input);
26
+ --color-ring: var(--ring);
27
+ --color-chart-1: var(--chart-1);
28
+ --color-chart-2: var(--chart-2);
29
+ --color-chart-3: var(--chart-3);
30
+ --color-chart-4: var(--chart-4);
31
+ --color-chart-5: var(--chart-5);
32
+ --radius-sm: calc(var(--radius) * 0.6);
33
+ --radius-md: calc(var(--radius) * 0.8);
34
+ --radius-lg: var(--radius);
35
+ --radius-xl: calc(var(--radius) * 1.4);
36
+ --radius-2xl: calc(var(--radius) * 1.8);
37
+ --radius-3xl: calc(var(--radius) * 2.2);
38
+ --radius-4xl: calc(var(--radius) * 2.6);
39
+ --color-sidebar: var(--sidebar);
40
+ --color-sidebar-foreground: var(--sidebar-foreground);
41
+ --color-sidebar-primary: var(--sidebar-primary);
42
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
43
+ --color-sidebar-accent: var(--sidebar-accent);
44
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
45
+ --color-sidebar-border: var(--sidebar-border);
46
+ --color-sidebar-ring: var(--sidebar-ring);
47
+ }
48
+
49
+ :root {
50
+ --radius: 0.625rem;
51
+ --background: oklch(0.985 0.002 247);
52
+ --foreground: oklch(0.2 0.02 255);
53
+ --card: oklch(1 0 0);
54
+ --card-foreground: oklch(0.2 0.02 255);
55
+ --popover: oklch(1 0 0);
56
+ --popover-foreground: oklch(0.2 0.02 255);
57
+ --primary: oklch(0.488 0.2 264);
58
+ --primary-foreground: oklch(0.99 0 0);
59
+ --secondary: oklch(0.96 0.01 255);
60
+ --secondary-foreground: oklch(0.25 0.02 255);
61
+ --muted: oklch(0.96 0.01 255);
62
+ --muted-foreground: oklch(0.5 0.02 255);
63
+ --accent: oklch(0.96 0.01 255);
64
+ --accent-foreground: oklch(0.25 0.02 255);
65
+ --destructive: oklch(0.577 0.245 27.325);
66
+ --destructive-foreground: oklch(0.99 0 0);
67
+ --border: oklch(0.9 0.01 255);
68
+ --input: oklch(0.9 0.01 255);
69
+ --ring: oklch(0.55 0.12 264);
70
+ --chart-1: oklch(0.646 0.222 41.116);
71
+ --chart-2: oklch(0.6 0.118 184.704);
72
+ --chart-3: oklch(0.398 0.07 227.392);
73
+ --chart-4: oklch(0.828 0.189 84.429);
74
+ --chart-5: oklch(0.769 0.188 70.08);
75
+ --sidebar: oklch(0.975 0.01 255);
76
+ --sidebar-foreground: oklch(0.2 0.02 255);
77
+ --sidebar-primary: oklch(0.488 0.2 264);
78
+ --sidebar-primary-foreground: oklch(0.99 0 0);
79
+ --sidebar-accent: oklch(0.94 0.02 255);
80
+ --sidebar-accent-foreground: oklch(0.25 0.02 255);
81
+ --sidebar-border: oklch(0.9 0.01 255);
82
+ --sidebar-ring: oklch(0.55 0.12 264);
83
+ }
84
+
85
+ .dark {
86
+ --background: oklch(0.145 0.02 255);
87
+ --foreground: oklch(0.985 0 0);
88
+ --card: oklch(0.2 0.02 255);
89
+ --card-foreground: oklch(0.985 0 0);
90
+ --popover: oklch(0.2 0.02 255);
91
+ --popover-foreground: oklch(0.985 0 0);
92
+ --primary: oklch(0.65 0.18 264);
93
+ --primary-foreground: oklch(0.15 0.02 255);
94
+ --secondary: oklch(0.28 0.02 255);
95
+ --secondary-foreground: oklch(0.985 0 0);
96
+ --muted: oklch(0.28 0.02 255);
97
+ --muted-foreground: oklch(0.7 0.02 255);
98
+ --accent: oklch(0.28 0.02 255);
99
+ --accent-foreground: oklch(0.985 0 0);
100
+ --destructive: oklch(0.704 0.191 22.216);
101
+ --destructive-foreground: oklch(0.985 0 0);
102
+ --border: oklch(1 0 0 / 10%);
103
+ --input: oklch(1 0 0 / 15%);
104
+ --ring: oklch(0.556 0 0);
105
+ --chart-1: oklch(0.488 0.243 264.376);
106
+ --chart-2: oklch(0.696 0.17 162.48);
107
+ --chart-3: oklch(0.769 0.188 70.08);
108
+ --chart-4: oklch(0.627 0.265 303.9);
109
+ --chart-5: oklch(0.645 0.246 16.439);
110
+ --sidebar: oklch(0.2 0.02 255);
111
+ --sidebar-foreground: oklch(0.985 0 0);
112
+ --sidebar-primary: oklch(0.65 0.18 264);
113
+ --sidebar-primary-foreground: oklch(0.985 0 0);
114
+ --sidebar-accent: oklch(0.28 0.02 255);
115
+ --sidebar-accent-foreground: oklch(0.985 0 0);
116
+ --sidebar-border: oklch(1 0 0 / 10%);
117
+ --sidebar-ring: oklch(0.556 0 0);
118
+ }
119
+
120
+ @layer base {
121
+ * {
122
+ @apply border-border outline-ring/50;
123
+ }
124
+ body {
125
+ @apply bg-background text-foreground;
126
+ }
127
+ }
128
+
129
+ /* Legacy class names (pre-Tailwind) — map old custom properties to tokens */
130
+ :root {
131
+ --sidebar-width: 16rem;
132
+ --sidebar-width-collapsed: 3.5rem;
133
+ --font-sans: var(--font-league-spartan), ui-sans-serif, system-ui, sans-serif;
134
+ --font-mono: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, monospace;
135
+ --spacing-xs: 0.25rem;
136
+ --spacing-sm: 0.5rem;
137
+ --spacing-md: 0.75rem;
138
+ --spacing-lg: 1rem;
139
+ --spacing-xl: 1.5rem;
140
+ --spacing-2xl: 2rem;
141
+ --btn-radius: 2px;
142
+ --btn-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
143
+ --btn-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.08);
144
+ --btn-shadow-active: 0 0 0 1px rgba(0, 0, 0, 0.05);
145
+ --color-bg: var(--background);
146
+ --color-surface: var(--card);
147
+ --color-surface-elevated: var(--card);
148
+ --color-border: var(--border);
149
+ --color-border-subtle: hsl(214 12% 94%);
150
+ --color-text: var(--foreground);
151
+ --color-text-muted: var(--muted-foreground);
152
+ --color-text-subtle: hsl(215 14% 60%);
153
+ --color-primary: hsl(221 83% 53%);
154
+ --color-primary-hover: hsl(221 83% 45%);
155
+ --color-primary-active: hsl(221 83% 40%);
156
+ --color-link: hsl(221 83% 53%);
157
+ --color-link-hover: hsl(221 83% 45%);
158
+ --sidebar-bg: var(--sidebar);
159
+ --sidebar-text: var(--sidebar-foreground);
160
+ --sidebar-text-muted: var(--muted-foreground);
161
+ --sidebar-item-hover: var(--sidebar-accent);
162
+ --sidebar-item-active: var(--sidebar-accent);
163
+ --sidebar-item-active-text: var(--sidebar-primary);
164
+ }
165
+ /* App layout */
166
+ .app-layout {
167
+ display: flex;
168
+ height: 100vh;
169
+ min-height: 0;
170
+ overflow: hidden;
171
+ }
172
+
173
+ .app-layout--resizing {
174
+ user-select: none;
175
+ }
176
+
177
+ .app-sidebar {
178
+ position: relative;
179
+ background: var(--sidebar-bg);
180
+ border-right: 1px solid var(--sidebar-border);
181
+ display: flex;
182
+ flex-direction: column;
183
+ transition:
184
+ width 0.2s ease,
185
+ min-width 0.2s ease;
186
+ }
187
+
188
+ .app-sidebar--collapsed {
189
+ transition:
190
+ width 0.2s ease,
191
+ min-width 0.2s ease;
192
+ }
193
+
194
+ .app-sidebar__resize-handle {
195
+ position: absolute;
196
+ top: 0;
197
+ right: 0;
198
+ width: 4px;
199
+ height: 100%;
200
+ cursor: col-resize;
201
+ background: transparent;
202
+ }
203
+
204
+ .app-sidebar__resize-handle:hover,
205
+ .app-layout--resizing .app-sidebar__resize-handle {
206
+ background: var(--color-primary);
207
+ opacity: 0.3;
208
+ }
209
+
210
+ .app-sidebar__tooltip-wrap {
211
+ position: relative;
212
+ display: flex;
213
+ overflow: visible;
214
+ }
215
+
216
+ .app-sidebar__tooltip-wrap::after {
217
+ content: attr(data-tooltip);
218
+ position: absolute;
219
+ left: 100%;
220
+ margin-left: 8px;
221
+ top: 50%;
222
+ transform: translateY(-50%) translateX(-4px);
223
+ padding: var(--spacing-sm) var(--spacing-md);
224
+ background: var(--color-text);
225
+ color: var(--color-surface);
226
+ font-size: 0.8125rem;
227
+ font-weight: 500;
228
+ border-radius: var(--spacing-sm);
229
+ white-space: nowrap;
230
+ opacity: 0;
231
+ pointer-events: none;
232
+ transition:
233
+ opacity 0.15s ease,
234
+ transform 0.15s ease;
235
+ z-index: 1000;
236
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
237
+ }
238
+
239
+ .app-sidebar--collapsed .app-sidebar__tooltip-wrap:hover::after {
240
+ opacity: 1;
241
+ transform: translateY(-50%) translateX(0);
242
+ }
243
+
244
+ .app-sidebar__header {
245
+ display: flex;
246
+ align-items: center;
247
+ justify-content: space-between;
248
+ padding: 0 var(--spacing-lg);
249
+ height: 3.5rem;
250
+ flex-shrink: 0;
251
+ border-bottom: 1px solid var(--sidebar-border);
252
+ }
253
+
254
+ .app-sidebar__brand {
255
+ font-weight: 600;
256
+ font-size: 1.125rem;
257
+ text-decoration: none;
258
+ color: var(--sidebar-text);
259
+ }
260
+
261
+ .app-sidebar__brand:hover {
262
+ color: var(--color-primary);
263
+ }
264
+
265
+ .app-sidebar__toggle {
266
+ display: flex;
267
+ align-items: center;
268
+ justify-content: center;
269
+ width: 2rem;
270
+ height: 2rem;
271
+ padding: 0;
272
+ border: none;
273
+ border-radius: var(--btn-radius);
274
+ background: transparent;
275
+ color: var(--sidebar-text-muted);
276
+ cursor: pointer;
277
+ transition:
278
+ background 0.15s ease,
279
+ color 0.15s ease,
280
+ transform 0.1s ease;
281
+ }
282
+
283
+ .app-sidebar__toggle:hover {
284
+ background: var(--sidebar-item-hover);
285
+ color: var(--sidebar-text);
286
+ }
287
+
288
+ .app-sidebar__toggle:active {
289
+ transform: scale(0.95);
290
+ }
291
+
292
+ .app-sidebar__nav {
293
+ flex: 1;
294
+ overflow-y: auto;
295
+ padding: var(--spacing-md);
296
+ display: flex;
297
+ flex-direction: column;
298
+ gap: var(--spacing-xs);
299
+ }
300
+
301
+ .app-sidebar__item {
302
+ display: flex;
303
+ align-items: center;
304
+ gap: var(--spacing-md);
305
+ padding: var(--spacing-md) var(--spacing-lg);
306
+ border-radius: var(--btn-radius);
307
+ text-decoration: none;
308
+ color: var(--sidebar-text);
309
+ transition:
310
+ background 0.15s ease,
311
+ color 0.15s ease;
312
+ }
313
+
314
+ .app-sidebar__item:hover {
315
+ background: var(--sidebar-item-hover);
316
+ }
317
+
318
+ .app-sidebar__item--active {
319
+ background: var(--sidebar-item-active);
320
+ color: var(--sidebar-item-active-text);
321
+ font-weight: 500;
322
+ }
323
+
324
+ .app-sidebar__item-icon {
325
+ flex-shrink: 0;
326
+ display: flex;
327
+ align-items: center;
328
+ justify-content: center;
329
+ }
330
+
331
+ .app-sidebar__item-label {
332
+ white-space: nowrap;
333
+ overflow: hidden;
334
+ text-overflow: ellipsis;
335
+ }
336
+
337
+ .app-sidebar__section {
338
+ margin-top: var(--spacing-lg);
339
+ display: flex;
340
+ flex-direction: column;
341
+ gap: var(--spacing-xs);
342
+ }
343
+
344
+ .app-sidebar__section-label {
345
+ font-size: 0.6875rem;
346
+ font-weight: 600;
347
+ letter-spacing: 0.05em;
348
+ text-transform: uppercase;
349
+ color: var(--sidebar-text-muted);
350
+ padding: var(--spacing-sm) var(--spacing-lg);
351
+ }
352
+
353
+ .app-sidebar__workflows {
354
+ display: flex;
355
+ flex-direction: column;
356
+ gap: var(--spacing-xs);
357
+ }
358
+
359
+ .app-sidebar__workflow {
360
+ display: flex;
361
+ align-items: center;
362
+ gap: var(--spacing-md);
363
+ padding: var(--spacing-sm) var(--spacing-lg);
364
+ border-radius: var(--btn-radius);
365
+ text-decoration: none;
366
+ color: var(--sidebar-text);
367
+ font-size: 0.875rem;
368
+ transition:
369
+ background 0.15s ease,
370
+ color 0.15s ease;
371
+ }
372
+
373
+ .app-sidebar__workflow:hover {
374
+ background: var(--sidebar-item-hover);
375
+ }
376
+
377
+ .app-sidebar__workflow-icon {
378
+ flex-shrink: 0;
379
+ opacity: 0.7;
380
+ }
381
+
382
+ .app-sidebar__workflow-label {
383
+ white-space: nowrap;
384
+ overflow: hidden;
385
+ text-overflow: ellipsis;
386
+ }
387
+
388
+ .app-sidebar__workflow-placeholder {
389
+ font-size: 0.8125rem;
390
+ color: var(--sidebar-text-muted);
391
+ padding: var(--spacing-sm) var(--spacing-lg);
392
+ }
393
+
394
+ .app-sidebar__workflows--icons-only {
395
+ margin-top: var(--spacing-md);
396
+ gap: var(--spacing-xs);
397
+ }
398
+
399
+ .app-sidebar__workflow--icon-only {
400
+ justify-content: center;
401
+ padding: var(--spacing-md);
402
+ }
403
+
404
+ .app-sidebar__workflow--icon-only .app-sidebar__workflow-label {
405
+ display: none;
406
+ }
407
+
408
+ .app-main {
409
+ flex: 1;
410
+ display: flex;
411
+ flex-direction: column;
412
+ min-width: 0;
413
+ min-height: 0;
414
+ overflow: hidden;
415
+ }
416
+
417
+ .app-main__header {
418
+ display: flex;
419
+ align-items: center;
420
+ justify-content: space-between;
421
+ gap: var(--spacing-xl);
422
+ padding: 0 var(--spacing-2xl);
423
+ height: 3.5rem;
424
+ flex-shrink: 0;
425
+ border-bottom: 1px solid var(--color-border-subtle);
426
+ background: var(--color-surface);
427
+ }
428
+
429
+ .app-main__header-lead {
430
+ min-width: 0;
431
+ flex: 1;
432
+ }
433
+
434
+ .app-main__title {
435
+ margin: 0;
436
+ font-size: 1.25rem;
437
+ font-weight: 600;
438
+ color: var(--color-text);
439
+ line-height: 1;
440
+ }
441
+
442
+ .app-shell-header-actions {
443
+ display: flex;
444
+ align-items: center;
445
+ gap: var(--spacing-lg);
446
+ flex-shrink: 0;
447
+ }
448
+
449
+ .app-shell-header-actions__email {
450
+ max-width: 14rem;
451
+ font-size: 0.8125rem;
452
+ color: var(--color-text-muted);
453
+ white-space: nowrap;
454
+ overflow: hidden;
455
+ text-overflow: ellipsis;
456
+ }
457
+
458
+ .app-shell-header-actions__logout {
459
+ padding: var(--spacing-sm) var(--spacing-md);
460
+ font-size: 0.8125rem;
461
+ font-weight: 500;
462
+ font-family: inherit;
463
+ border: 1px solid var(--color-border);
464
+ border-radius: var(--spacing-md);
465
+ background: var(--color-surface);
466
+ color: var(--color-text);
467
+ cursor: pointer;
468
+ transition:
469
+ background 0.15s ease,
470
+ border-color 0.15s ease;
471
+ }
472
+
473
+ .app-shell-header-actions__logout:hover:not(:disabled) {
474
+ background: var(--color-bg);
475
+ border-color: hsl(214 20% 85%);
476
+ }
477
+
478
+ .app-shell-header-actions__logout:disabled {
479
+ opacity: 0.65;
480
+ cursor: not-allowed;
481
+ }
482
+
483
+ .app-main__content {
484
+ flex: 1;
485
+ padding: var(--spacing-2xl);
486
+ overflow: auto;
487
+ min-height: 0;
488
+ }
489
+
490
+ .app-main__content--full-bleed {
491
+ padding: 0;
492
+ overflow: hidden;
493
+ }
494
+
495
+ /* —— Login (auth shell) —— */
496
+ .codemation-login-root {
497
+ min-height: 100vh;
498
+ }
499
+
500
+ .login-page {
501
+ position: relative;
502
+ min-height: 100vh;
503
+ display: flex;
504
+ align-items: center;
505
+ justify-content: center;
506
+ padding: var(--spacing-2xl) var(--spacing-lg);
507
+ isolation: isolate;
508
+ overflow-x: hidden;
509
+ }
510
+
511
+ .login-page__backdrop {
512
+ position: absolute;
513
+ inset: 0;
514
+ z-index: -1;
515
+ background:
516
+ radial-gradient(ellipse 120% 80% at 20% 0%, hsl(221 83% 53% / 0.14), transparent 55%),
517
+ radial-gradient(ellipse 100% 70% at 100% 30%, hsl(215 60% 45% / 0.1), transparent 50%),
518
+ radial-gradient(ellipse 80% 60% at 50% 100%, hsl(214 40% 70% / 0.08), transparent 45%), var(--color-bg);
519
+ }
520
+
521
+ .login-page__noise {
522
+ position: absolute;
523
+ inset: 0;
524
+ z-index: -1;
525
+ opacity: 0.04;
526
+ pointer-events: none;
527
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
528
+ }
529
+
530
+ .login-page__card {
531
+ width: 100%;
532
+ max-width: 26rem;
533
+ background: var(--color-surface);
534
+ border: 1px solid var(--color-border-subtle);
535
+ border-radius: var(--spacing-lg);
536
+ box-shadow:
537
+ 0 1px 2px rgba(15, 23, 42, 0.04),
538
+ 0 24px 48px -12px rgba(15, 23, 42, 0.12);
539
+ padding: var(--spacing-2xl);
540
+ animation: login-card-enter 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
541
+ }
542
+
543
+ @keyframes login-card-enter {
544
+ from {
545
+ opacity: 0;
546
+ transform: translateY(12px) scale(0.98);
547
+ }
548
+ to {
549
+ opacity: 1;
550
+ transform: translateY(0) scale(1);
551
+ }
552
+ }
553
+
554
+ .login-page__brand {
555
+ display: flex;
556
+ align-items: center;
557
+ gap: var(--spacing-md);
558
+ margin-bottom: var(--spacing-xl);
559
+ }
560
+
561
+ .login-page__mark {
562
+ flex-shrink: 0;
563
+ width: 2.75rem;
564
+ height: 2.75rem;
565
+ border-radius: var(--spacing-md);
566
+ background: linear-gradient(145deg, hsl(221 83% 53%), hsl(221 83% 40%));
567
+ box-shadow:
568
+ 0 2px 8px hsl(221 83% 53% / 0.35),
569
+ inset 0 1px 0 hsl(0 0% 100% / 0.2);
570
+ display: flex;
571
+ align-items: center;
572
+ justify-content: center;
573
+ color: white;
574
+ font-weight: 700;
575
+ font-size: 1.125rem;
576
+ letter-spacing: -0.02em;
577
+ }
578
+
579
+ .login-page__titles {
580
+ min-width: 0;
581
+ }
582
+
583
+ .login-page__title {
584
+ margin: 0;
585
+ font-size: 1.375rem;
586
+ font-weight: 600;
587
+ color: var(--color-text);
588
+ line-height: 1.2;
589
+ letter-spacing: -0.02em;
590
+ }
591
+
592
+ .login-page__subtitle {
593
+ margin: var(--spacing-xs) 0 0;
594
+ font-size: 0.9375rem;
595
+ color: var(--color-text-muted);
596
+ line-height: 1.4;
597
+ }
598
+
599
+ .login-page__form {
600
+ display: flex;
601
+ flex-direction: column;
602
+ gap: var(--spacing-lg);
603
+ }
604
+
605
+ .login-page__field {
606
+ display: flex;
607
+ flex-direction: column;
608
+ gap: var(--spacing-sm);
609
+ }
610
+
611
+ .login-page__label {
612
+ font-size: 0.8125rem;
613
+ font-weight: 600;
614
+ letter-spacing: 0.02em;
615
+ color: var(--color-text);
616
+ }
617
+
618
+ .login-page__input {
619
+ width: 100%;
620
+ padding: var(--spacing-md) var(--spacing-lg);
621
+ font-size: 0.9375rem;
622
+ border: 1px solid var(--color-border);
623
+ border-radius: var(--spacing-md);
624
+ background: var(--color-surface);
625
+ color: var(--color-text);
626
+ font-family: inherit;
627
+ transition:
628
+ border-color 0.15s ease,
629
+ box-shadow 0.15s ease;
630
+ }
631
+
632
+ .login-page__input:hover {
633
+ border-color: hsl(214 20% 82%);
634
+ }
635
+
636
+ .login-page__input:focus {
637
+ outline: none;
638
+ border-color: var(--color-primary);
639
+ box-shadow: 0 0 0 3px hsl(221 83% 53% / 0.18);
640
+ }
641
+
642
+ .login-page__input::placeholder {
643
+ color: var(--color-text-subtle);
644
+ }
645
+
646
+ .login-page__input:disabled {
647
+ opacity: 0.72;
648
+ cursor: not-allowed;
649
+ background: var(--color-bg);
650
+ }
651
+
652
+ .login-page__error {
653
+ margin: 0;
654
+ padding: var(--spacing-md) var(--spacing-lg);
655
+ font-size: 0.875rem;
656
+ color: hsl(0 72% 38%);
657
+ background: hsl(0 84% 97%);
658
+ border: 1px solid hsl(0 72% 88%);
659
+ border-radius: var(--spacing-md);
660
+ line-height: 1.45;
661
+ }
662
+
663
+ .login-page__submit {
664
+ margin-top: var(--spacing-sm);
665
+ padding: var(--spacing-md) var(--spacing-xl);
666
+ font-size: 0.9375rem;
667
+ font-weight: 600;
668
+ letter-spacing: 0.02em;
669
+ border: none;
670
+ border-radius: var(--spacing-md);
671
+ background: linear-gradient(180deg, var(--color-primary) 0%, var(--color-primary-hover) 100%);
672
+ color: white;
673
+ cursor: pointer;
674
+ box-shadow:
675
+ 0 1px 2px hsl(221 83% 30% / 0.2),
676
+ 0 4px 12px hsl(221 83% 53% / 0.28);
677
+ transition:
678
+ transform 0.12s ease,
679
+ box-shadow 0.15s ease,
680
+ filter 0.15s ease;
681
+ }
682
+
683
+ .login-page__submit:hover {
684
+ filter: brightness(1.05);
685
+ box-shadow:
686
+ 0 2px 4px hsl(221 83% 30% / 0.22),
687
+ 0 8px 20px hsl(221 83% 53% / 0.32);
688
+ }
689
+
690
+ .login-page__submit:active {
691
+ transform: translateY(1px);
692
+ box-shadow:
693
+ 0 1px 2px hsl(221 83% 30% / 0.18),
694
+ 0 2px 8px hsl(221 83% 53% / 0.22);
695
+ }
696
+
697
+ .login-page__submit:disabled {
698
+ opacity: 0.85;
699
+ cursor: wait;
700
+ transform: none;
701
+ filter: none;
702
+ }
703
+
704
+ .login-page__submit-inner {
705
+ display: inline-flex;
706
+ align-items: center;
707
+ justify-content: center;
708
+ gap: var(--spacing-md);
709
+ }
710
+
711
+ .login-page__spinner {
712
+ width: 1.125rem;
713
+ height: 1.125rem;
714
+ border: 2px solid hsl(0 0% 100% / 0.35);
715
+ border-top-color: white;
716
+ border-radius: 50%;
717
+ animation: login-spinner-rotate 0.65s linear infinite;
718
+ }
719
+
720
+ @keyframes login-spinner-rotate {
721
+ to {
722
+ transform: rotate(360deg);
723
+ }
724
+ }
725
+
726
+ .login-page__divider {
727
+ display: flex;
728
+ align-items: center;
729
+ gap: var(--spacing-lg);
730
+ margin: var(--spacing-xl) 0 var(--spacing-lg);
731
+ color: var(--color-text-subtle);
732
+ font-size: 0.75rem;
733
+ font-weight: 600;
734
+ letter-spacing: 0.06em;
735
+ text-transform: uppercase;
736
+ }
737
+
738
+ .login-page__divider::before,
739
+ .login-page__divider::after {
740
+ content: "";
741
+ flex: 1;
742
+ height: 1px;
743
+ background: linear-gradient(90deg, transparent, var(--color-border), transparent);
744
+ }
745
+
746
+ .login-page__oauth {
747
+ display: flex;
748
+ flex-direction: column;
749
+ gap: var(--spacing-md);
750
+ }
751
+
752
+ .login-page__oauth-list {
753
+ display: flex;
754
+ flex-direction: column;
755
+ gap: var(--spacing-md);
756
+ }
757
+
758
+ .login-page__oauth-label {
759
+ margin: 0 0 var(--spacing-sm);
760
+ font-size: 0.875rem;
761
+ color: var(--color-text-muted);
762
+ }
763
+
764
+ .login-page__oauth-btn {
765
+ padding: var(--spacing-md) var(--spacing-lg);
766
+ font-size: 0.875rem;
767
+ font-weight: 500;
768
+ border: 1px solid var(--color-border);
769
+ border-radius: var(--spacing-md);
770
+ background: var(--color-surface);
771
+ color: var(--color-text);
772
+ cursor: pointer;
773
+ font-family: inherit;
774
+ transition:
775
+ background 0.15s ease,
776
+ border-color 0.15s ease,
777
+ box-shadow 0.15s ease;
778
+ box-shadow: var(--btn-shadow);
779
+ }
780
+
781
+ .login-page__oauth-btn-inner {
782
+ display: inline-flex;
783
+ align-items: center;
784
+ justify-content: center;
785
+ gap: 0.625rem;
786
+ }
787
+
788
+ .login-page__oauth-icon {
789
+ width: 1.25rem;
790
+ height: 1.25rem;
791
+ flex-shrink: 0;
792
+ }
793
+
794
+ .login-page__oauth-btn:hover {
795
+ background: var(--color-bg);
796
+ border-color: hsl(214 20% 85%);
797
+ box-shadow: var(--btn-shadow-hover);
798
+ }
799
+
800
+ .login-page__oauth-btn:disabled {
801
+ opacity: 0.75;
802
+ cursor: wait;
803
+ }
804
+
805
+ .login-page__footer {
806
+ margin-top: var(--spacing-2xl);
807
+ padding-top: var(--spacing-xl);
808
+ border-top: 1px solid var(--color-border-subtle);
809
+ text-align: center;
810
+ font-size: 0.8125rem;
811
+ color: var(--color-text-subtle);
812
+ }
813
+
814
+ .visually-hidden {
815
+ position: absolute;
816
+ width: 1px;
817
+ height: 1px;
818
+ padding: 0;
819
+ margin: -1px;
820
+ overflow: hidden;
821
+ clip: rect(0, 0, 0, 0);
822
+ white-space: nowrap;
823
+ border: 0;
824
+ }
825
+
826
+ .users-screen__header {
827
+ display: flex;
828
+ flex-wrap: wrap;
829
+ align-items: flex-start;
830
+ justify-content: space-between;
831
+ gap: var(--spacing-lg);
832
+ margin-bottom: var(--spacing-xl);
833
+ }
834
+
835
+ .users-screen__description {
836
+ margin: 0;
837
+ max-width: 42rem;
838
+ color: var(--color-text-muted);
839
+ font-size: 0.9375rem;
840
+ }
841
+
842
+ .users-screen__primary-btn {
843
+ padding: var(--spacing-md) var(--spacing-xl);
844
+ font-weight: 600;
845
+ font-size: 0.875rem;
846
+ letter-spacing: 0.02em;
847
+ border: none;
848
+ border-radius: var(--btn-radius);
849
+ background: var(--color-primary);
850
+ color: white;
851
+ cursor: pointer;
852
+ box-shadow: var(--btn-shadow);
853
+ font-family: inherit;
854
+ transition:
855
+ background 0.15s ease,
856
+ box-shadow 0.15s ease;
857
+ }
858
+
859
+ .users-screen__primary-btn:hover {
860
+ background: var(--color-primary-hover);
861
+ box-shadow: var(--btn-shadow-hover);
862
+ }
863
+
864
+ .users-screen__alert {
865
+ padding: var(--spacing-lg);
866
+ margin-bottom: var(--spacing-lg);
867
+ background: hsl(0 84% 97%);
868
+ border: 1px solid hsl(0 72% 85%);
869
+ border-radius: var(--spacing-md);
870
+ }
871
+
872
+ .users-screen__loading,
873
+ .users-screen__empty {
874
+ padding: var(--spacing-2xl);
875
+ text-align: center;
876
+ color: var(--color-text-muted);
877
+ background: var(--color-surface);
878
+ border-radius: var(--spacing-md);
879
+ }
880
+
881
+ .users-screen__status-select {
882
+ padding: var(--spacing-sm) var(--spacing-md);
883
+ font-size: 0.8125rem;
884
+ border: 1px solid var(--color-border);
885
+ border-radius: var(--btn-radius);
886
+ background: var(--color-surface);
887
+ font-family: inherit;
888
+ }
889
+
890
+ .users-dialog__row {
891
+ margin-top: var(--spacing-md);
892
+ display: flex;
893
+ gap: var(--spacing-sm);
894
+ flex-wrap: wrap;
895
+ }
896
+
897
+ .users-dialog-overlay {
898
+ z-index: 1100;
899
+ }
900
+
901
+ .invite-accept-screen {
902
+ max-width: 28rem;
903
+ margin: var(--spacing-2xl) auto;
904
+ padding: var(--spacing-2xl);
905
+ background: var(--color-surface);
906
+ border-radius: var(--spacing-md);
907
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
908
+ }
909
+
910
+ .invite-accept-screen__title {
911
+ margin: 0 0 var(--spacing-md);
912
+ font-size: 1.375rem;
913
+ font-weight: 600;
914
+ }
915
+
916
+ .invite-accept-screen__help {
917
+ margin: 0 0 var(--spacing-xl);
918
+ color: var(--color-text-muted);
919
+ font-size: 0.9375rem;
920
+ }
921
+
922
+ .invite-accept-screen__field {
923
+ display: flex;
924
+ flex-direction: column;
925
+ gap: var(--spacing-xs);
926
+ margin-bottom: var(--spacing-lg);
927
+ }
928
+
929
+ .invite-accept-screen__label {
930
+ font-size: 0.8125rem;
931
+ font-weight: 500;
932
+ color: var(--color-text-muted);
933
+ }
934
+
935
+ .invite-accept-screen__input {
936
+ padding: var(--spacing-md);
937
+ font-size: 0.9375rem;
938
+ border: 1px solid var(--color-border);
939
+ border-radius: var(--btn-radius);
940
+ font-family: inherit;
941
+ }
942
+
943
+ .invite-accept-screen__error {
944
+ padding: var(--spacing-md);
945
+ margin-bottom: var(--spacing-lg);
946
+ background: hsl(0 84% 97%);
947
+ border: 1px solid hsl(0 72% 85%);
948
+ border-radius: var(--btn-radius);
949
+ font-size: 0.875rem;
950
+ }
951
+
952
+ .invite-accept-screen__submit {
953
+ display: inline-block;
954
+ box-sizing: border-box;
955
+ width: 100%;
956
+ padding: var(--spacing-md) var(--spacing-lg);
957
+ font-size: 0.9375rem;
958
+ font-weight: 600;
959
+ border: none;
960
+ border-radius: var(--btn-radius);
961
+ background: var(--color-primary);
962
+ color: white;
963
+ cursor: pointer;
964
+ font-family: inherit;
965
+ box-shadow: var(--btn-shadow);
966
+ text-align: center;
967
+ text-decoration: none;
968
+ }
969
+
970
+ .invite-accept-screen__submit:hover:not(:disabled) {
971
+ background: var(--color-primary-hover);
972
+ }
973
+
974
+ .invite-accept-screen__submit:disabled {
975
+ opacity: 0.65;
976
+ cursor: not-allowed;
977
+ }
978
+
979
+ .invite-accept-screen__secondary-link {
980
+ display: inline-block;
981
+ margin-top: var(--spacing-lg);
982
+ font-size: 0.9375rem;
983
+ font-weight: 600;
984
+ color: var(--color-link);
985
+ text-decoration: none;
986
+ }
987
+
988
+ .invite-accept-screen__secondary-link:hover {
989
+ color: var(--color-link-hover);
990
+ text-decoration: underline;
991
+ }
992
+
993
+ .invite-accept-layout {
994
+ min-height: 100vh;
995
+ padding: var(--spacing-xl);
996
+ background: var(--color-bg);
997
+ }