astryx-dracula 0.4.0 → 0.5.0

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 (50) hide show
  1. package/package.json +6 -2
  2. package/shared/auth-chrome.tsx +156 -6
  3. package/shared/chaptered-doc.tsx +3 -4
  4. package/shared/chart-hues.ts +0 -5
  5. package/shared/chart-legend.tsx +2 -3
  6. package/shared/data-bar.tsx +5 -5
  7. package/shared/format-money.ts +3 -0
  8. package/shared/metric-card.tsx +127 -0
  9. package/shared/scene-hues.ts +0 -8
  10. package/shared/scene-tile.tsx +3 -11
  11. package/shared/settings-data.ts +28 -0
  12. package/shared/settings-rows.tsx +1 -6
  13. package/shared/stars.tsx +28 -0
  14. package/templates/ai-chat-landing.tsx +88 -58
  15. package/templates/ai-chat.tsx +65 -78
  16. package/templates/centered-hero.tsx +2 -2
  17. package/templates/dashboard-portfolio.tsx +77 -155
  18. package/templates/dashboard.tsx +17 -134
  19. package/templates/detail-page.tsx +14 -18
  20. package/templates/documentation-design.tsx +66 -519
  21. package/templates/documentation-technical.tsx +2 -22
  22. package/templates/editor.tsx +168 -185
  23. package/templates/file-explorer.tsx +10 -24
  24. package/templates/ide.tsx +12 -18
  25. package/templates/incident-console.tsx +48 -46
  26. package/templates/kanban-board.tsx +36 -85
  27. package/templates/library.tsx +42 -66
  28. package/templates/login-card.tsx +33 -126
  29. package/templates/login-split.tsx +91 -123
  30. package/templates/login-sso.tsx +12 -33
  31. package/templates/login.tsx +21 -121
  32. package/templates/messaging-shell.tsx +162 -168
  33. package/templates/payment-form.tsx +24 -26
  34. package/templates/product-detail.tsx +7 -40
  35. package/templates/product-tour.tsx +38 -60
  36. package/templates/settings-dialog.tsx +10 -32
  37. package/templates/settings-sidebar.tsx +44 -77
  38. package/templates/settings.tsx +208 -121
  39. package/templates/shell-nav.tsx +20 -75
  40. package/templates/shell-side-nav.tsx +16 -90
  41. package/templates/shell-top-nav.tsx +20 -53
  42. package/templates/side-gallery.tsx +19 -19
  43. package/templates/table-grouped.tsx +17 -164
  44. package/templates/table-page-chart.tsx +12 -11
  45. package/templates/table-page-heatmap-status.tsx +0 -17
  46. package/templates/table-page-shoe-store-heatmap.tsx +12 -12
  47. package/templates/table-page.tsx +4 -31
  48. package/templates/table.tsx +7 -10
  49. package/templates/tech-report.tsx +58 -72
  50. package/templates/theme-showcase.tsx +124 -415
@@ -6,31 +6,16 @@ import {useState, useTransition} from 'react';
6
6
  import {demoLogin} from 'astryx-dracula/shared/login-demo';
7
7
  import {AppleIcon, GoogleIcon} from 'astryx-dracula/shared/sso-icons';
8
8
  import {
9
- AUTH_HEADING,
10
- AUTH_SUBTITLE,
11
- AUTH_PRIMARY_CTA,
12
- AUTH_SIGNUP_PROMPT,
13
- AUTH_SIGNUP_LINK,
14
9
  AUTH_SSO_DIVIDER,
15
- AUTH_FORGOT_PASSWORD,
16
10
  AUTH_ERROR_MESSAGE,
17
- AUTH_EMAIL_PLACEHOLDER,
18
- AUTH_PASSWORD_PLACEHOLDER,
19
- AUTH_TERMS_PREFIX,
20
- AUTH_TERMS_SERVICE,
21
- AUTH_TERMS_PRIVACY,
22
11
  } from 'astryx-dracula/shared/auth-copy';
23
12
  import {VStack} from '@astryxdesign/core/Layout';
24
13
  import {Center} from '@astryxdesign/core/Center';
25
- import {Text, Heading} from '@astryxdesign/core/Text';
26
- import {TextInput} from '@astryxdesign/core/TextInput';
27
14
  import {Button} from '@astryxdesign/core/Button';
28
- import {Card} from '@astryxdesign/core/Card';
29
- import {Link} from '@astryxdesign/core/Link';
30
15
  import {Divider} from '@astryxdesign/core/Divider';
31
16
 
32
- import {authPageStyle as pageStyle, authContentStyle as contentStyle, inputAutoComplete} from 'astryx-dracula/shared/auth-chrome-config';
33
- import {LoginBrand} from 'astryx-dracula/shared/auth-chrome';
17
+ import {authPageStyle as pageStyle, authContentStyle as contentStyle} from 'astryx-dracula/shared/auth-chrome-config';
18
+ import {LoginBrand, AuthCard, AuthLoginFields} from 'astryx-dracula/shared/auth-chrome';
34
19
 
35
20
  export default function LoginCard() {
36
21
  const [email, setEmail] = useState('');
@@ -55,121 +40,43 @@ export default function LoginCard() {
55
40
  <VStack gap={4} hAlign="center" style={contentStyle}>
56
41
  <LoginBrand />
57
42
 
58
- {/* Card */}
59
- <Card padding={4} width="100%">
60
- <VStack gap={4} hAlign="stretch">
61
- {/* Header */}
62
- <VStack gap={1} hAlign="center">
63
- <Heading level={1} type="display-2">
64
- {AUTH_HEADING}
65
- </Heading>
66
- <Text type="body" color="secondary">
67
- {AUTH_SUBTITLE}
68
- </Text>
69
- </VStack>
43
+ <AuthCard selfHash="#/templates/login-card">
44
+ <AuthLoginFields
45
+ email={email}
46
+ password={password}
47
+ error={error}
48
+ selfHash="#/templates/login-card"
49
+ isLoading={isLoading}
50
+ onEmailChange={(v: string) => {
51
+ setEmail(v);
52
+ setError(null);
53
+ }}
54
+ onPasswordChange={(v: string) => {
55
+ setPassword(v);
56
+ setError(null);
57
+ }}
58
+ onSubmit={handleLogin}
59
+ />
70
60
 
71
- {/* Form fields */}
72
- <VStack gap={2}>
73
- <TextInput
74
- label="Email"
75
- isLabelHidden
76
- type="email"
77
- {...inputAutoComplete('email')}
78
- placeholder={AUTH_EMAIL_PLACEHOLDER}
79
- value={email}
80
- onChange={(v: string) => {
81
- setEmail(v);
82
- setError(null);
83
- }}
84
- size="lg"
85
- onEnter={handleLogin}
86
- status={error ? {type: 'error', message: error} : undefined}
87
- />
88
- <VStack gap={1}>
89
- <TextInput
90
- label="Password"
91
- isLabelHidden
92
- placeholder={AUTH_PASSWORD_PLACEHOLDER}
93
- type="password"
94
- {...inputAutoComplete('current-password')}
95
- value={password}
96
- onChange={(v: string) => {
97
- setPassword(v);
98
- setError(null);
99
- }}
100
- size="lg"
101
- onEnter={handleLogin}
102
- status={error ? {type: 'error', message: error} : undefined}
103
- />
104
- {error && (
105
- <VStack hAlign="end">
106
- <Link
107
- href="#/templates/login-card"
108
- color="secondary"
109
- isStandalone>
110
- {AUTH_FORGOT_PASSWORD}
111
- </Link>
112
- </VStack>
113
- )}
114
- </VStack>
115
- </VStack>
61
+ {/* Divider */}
62
+ <Divider label={AUTH_SSO_DIVIDER} />
116
63
 
117
- {/* Login button */}
64
+ {/* Social buttons */}
65
+ <VStack gap={3} hAlign="stretch">
118
66
  <Button
119
- label={AUTH_PRIMARY_CTA}
120
- variant="primary"
67
+ label="Login with Apple"
68
+ variant="secondary"
69
+ icon={<AppleIcon />}
70
+ size="lg"
71
+ />
72
+ <Button
73
+ label="Login with Google"
74
+ variant="secondary"
75
+ icon={<GoogleIcon />}
121
76
  size="lg"
122
- isLoading={isLoading}
123
- onClick={handleLogin}
124
77
  />
125
-
126
- {/* Divider */}
127
- <Divider label={AUTH_SSO_DIVIDER} />
128
-
129
- {/* Social buttons */}
130
- <VStack gap={3} hAlign="stretch">
131
- <Button
132
- label="Login with Apple"
133
- variant="secondary"
134
- icon={<AppleIcon />}
135
- size="lg"
136
- />
137
- <Button
138
- label="Login with Google"
139
- variant="secondary"
140
- icon={<GoogleIcon />}
141
- size="lg"
142
- />
143
- </VStack>
144
-
145
- {/* Prose links. A link inside a sentence needs a persistent
146
- underline — colour alone is not a cue (WCAG 1.4.1 / F73),
147
- and the kit underlines on hover only. */}
148
- <VStack hAlign="center">
149
- <Text type="supporting" color="secondary">
150
- {AUTH_SIGNUP_PROMPT}{' '}
151
- <Link href="#/templates/login-card" type="supporting" hasUnderline>
152
- {AUTH_SIGNUP_LINK}
153
- </Link>
154
- </Text>
155
- </VStack>
156
78
  </VStack>
157
- </Card>
158
-
159
- {/* Terms */}
160
- <VStack hAlign="center" width="100%">
161
- <Text type="supporting" color="secondary" justify="center">
162
- {AUTH_TERMS_PREFIX}{' '}
163
- <Link href="#/templates/login-card" type="supporting" hasUnderline>
164
- {AUTH_TERMS_SERVICE}
165
- </Link>{' '}
166
- and{' '}
167
- <Link href="#/templates/login-card" type="supporting" hasUnderline>
168
- {AUTH_TERMS_PRIVACY}
169
- </Link>
170
- .
171
- </Text>
172
- </VStack>
79
+ </AuthCard>
173
80
  </VStack>
174
81
  </Center>
175
82
  );
@@ -2,22 +2,22 @@
2
2
  // XLE (canonical structure, validated with `bunx astryx layout check`):
3
3
  // Ctr > V[g=4] > (Ctr.horizontal > C[p=0] > G[c={min:240} g=8 a=stretch] > (S[p=0] > V[g=4] > (H[g=2 a=center] > Ic + Tx"Castle Dracula"[t=body]) + (V[g=4] > (V[g=1] > Hd"Welcome back to the night"[level=1] + Tx"Sign in to your crypt"[t=body]) + (V[g=2] > TI"Email"[t=email] + (V[g=1] > TI"Password"[t=password] + Lk"Forgot password?")) + B.primary"Enter the night" + D"Or continue with" + (G[c={min:200} g=3] > B.secondary"Login with Apple" + B.secondary"Login with Google")) + (V[a=center] > Tx"New to the castle?"[t=supporting] + Lk"Sign up")) + (C[p=0] > AR)) + (V[a=center] > Tx"By clicking continue, you agree to our Terms of service and Privacy policy"[t=supporting])
4
4
 
5
- import {useState, useTransition, type CSSProperties} from 'react';
6
- import {inputAutoComplete} from 'astryx-dracula/shared/auth-chrome-config';
5
+ import {useState, useTransition} from 'react';
6
+ import {authPageStyle, inputAutoComplete} from 'astryx-dracula/shared/auth-chrome-config';
7
7
  import {demoLogin} from 'astryx-dracula/shared/login-demo';
8
8
  import {AppleIcon, GoogleIcon} from 'astryx-dracula/shared/sso-icons';
9
9
  import {
10
10
  AUTH_HEADING,
11
11
  AUTH_SUBTITLE,
12
12
  AUTH_PRIMARY_CTA,
13
- AUTH_SIGNUP_PROMPT,
14
- AUTH_SIGNUP_LINK,
15
13
  AUTH_SSO_DIVIDER,
16
14
  AUTH_FORGOT_PASSWORD,
17
15
  AUTH_ERROR_MESSAGE,
18
16
  AUTH_EMAIL_PLACEHOLDER,
19
17
  AUTH_PASSWORD_PLACEHOLDER,
20
18
  AUTH_BRAND_NAME,
19
+ AUTH_SIGNUP_PROMPT,
20
+ AUTH_SIGNUP_LINK,
21
21
  AUTH_TERMS_PREFIX,
22
22
  AUTH_TERMS_SERVICE,
23
23
  AUTH_TERMS_PRIVACY,
@@ -30,40 +30,23 @@ import {Card} from '@astryxdesign/core/Card';
30
30
  import {Section} from '@astryxdesign/core/Section';
31
31
  import {Text, Heading} from '@astryxdesign/core/Text';
32
32
  import {Icon} from '@astryxdesign/core/Icon';
33
- import {EmptyState} from '@astryxdesign/core/EmptyState';
34
33
  import {TextInput} from '@astryxdesign/core/TextInput';
35
34
  import {Button} from '@astryxdesign/core/Button';
36
35
  import {Link} from '@astryxdesign/core/Link';
37
36
  import {Divider} from '@astryxdesign/core/Divider';
38
37
 
39
38
  // ============= ICONS (verified lucide-react exports) =============
40
- // Moon is the castle brand mark (see login, login-card); CircleCheck ←
41
- // CheckCircleIcon. The SquaresPlusIcon brand mark has no place here.
42
- import {Moon, CircleCheck} from 'lucide-react';
39
+ // Moon is the castle brand mark (see login, login-card).
40
+ import {Moon} from 'lucide-react';
43
41
 
44
42
  // Cover art lives in shared/scene-castle (`rooftops` variant:
45
43
  // crescent-overlay moon over a rooftop skyline). The transparent Card clips
46
44
  // it to rounded corners (overflow:clip + radius), so the art needs no radius.
47
- // Grid emits minmax(MIN, 1fr) where MIN is a hard floor, so MIN plus the
48
- // grid inset and page padding must fit the narrowest phone or the column is
49
- // clipped. 320 − 2×24 (page) − 2×16 (stacked inset) = 240.
50
- const COLUMN_MIN_WIDTH = 240;
51
- // repeat:'fit' (auto-fit) collapses the two columns to one — expanding to fill —
52
- // below 2×MIN + 32(gap) = 512px. The container query reorders the image and
53
- // tightens the inset at that same point, keyed to the card width (not the
54
- // window) so it never desyncs.
55
- // minHeight:100% fills the host so the centered card never leaves an unpainted
56
- // band; padding keeps it off the surface edges.
57
- const pageStyle: CSSProperties = {
58
- minHeight: '100%',
59
- backgroundColor: 'var(--color-background-body)',
60
- padding: 'var(--spacing-6)',
61
- };
62
- const cardWrap: CSSProperties = {
45
+ const cardWrap = {
63
46
  width: '100%',
64
47
  maxWidth: 1000,
65
48
  marginInline: 'auto',
66
- };
49
+ } as const;
67
50
 
68
51
  // The container query lives in a plain <style> tag so it needs NO CSS compiler.
69
52
  // - Pad the grid, not the Card: the form's Section escapes Card's
@@ -72,6 +55,9 @@ const cardWrap: CSSProperties = {
72
55
  // - repeat:'fit' (auto-fit) collapses the two columns to one below 511px; the
73
56
  // query reorders the image (order:-1) and tightens the inset at that point,
74
57
  // keyed to the card width (not the window) so it never desyncs.
58
+ // Grid emits minmax(240, 1fr) where 240 is a hard floor, so MIN plus the grid
59
+ // inset and page padding must fit the narrowest phone: 320 − 2×24 (page) −
60
+ // 2×16 (stacked inset) = 240.
75
61
  const LOGIN_SPLIT_CSS = `
76
62
  .login-split-grid {
77
63
  container-type: inline-size;
@@ -97,7 +83,6 @@ export default function LoginSplit() {
97
83
  const [password, setPassword] = useState('');
98
84
  const [error, setError] = useState<string | null>(null);
99
85
  const [isLoading, startTransition] = useTransition();
100
- const [isSuccess, setIsSuccess] = useState(false);
101
86
 
102
87
  const handleLogin = () => {
103
88
  if (!email || !password) {
@@ -107,18 +92,17 @@ export default function LoginSplit() {
107
92
  setError(null);
108
93
  startTransition(async () => {
109
94
  await demoLogin();
110
- setIsSuccess(true);
111
95
  });
112
96
  };
113
97
 
114
98
  return (
115
- <Center axis="both" style={pageStyle}>
99
+ <Center axis="both" style={authPageStyle}>
116
100
  <style>{LOGIN_SPLIT_CSS}</style>
117
101
  <VStack gap={4} width="100%">
118
102
  <Center axis="horizontal" style={cardWrap}>
119
103
  <Card padding={0} width="100%">
120
104
  <Grid
121
- columns={{minWidth: COLUMN_MIN_WIDTH, repeat: 'fit'}}
105
+ columns={{minWidth: 240, repeat: 'fit'}}
122
106
  gap={8}
123
107
  align="stretch"
124
108
  className="login-split-grid">
@@ -134,105 +118,91 @@ export default function LoginSplit() {
134
118
 
135
119
  <StackItem size="fill">
136
120
  <Center axis="vertical" height="100%">
137
- {isSuccess ? (
138
- <EmptyState
139
- title="You're in for the night"
140
- description="Drifting to your crypt…"
141
- icon={
142
- <Icon
143
- icon={CircleCheck}
144
- size="lg"
145
- color="secondary"
146
- />
147
- }
148
- />
149
- ) : (
150
- <VStack gap={4} hAlign="stretch" width="100%">
151
- <VStack gap={1}>
152
- <Heading level={1} type="display-2">
153
- {AUTH_HEADING}
154
- </Heading>
155
- <Text type="body" color="secondary">
156
- {AUTH_SUBTITLE}
157
- </Text>
158
- </VStack>
121
+ <VStack gap={4} hAlign="stretch" width="100%">
122
+ <VStack gap={1}>
123
+ <Heading level={1} type="display-2">
124
+ {AUTH_HEADING}
125
+ </Heading>
126
+ <Text type="body" color="secondary">
127
+ {AUTH_SUBTITLE}
128
+ </Text>
129
+ </VStack>
159
130
 
160
- <VStack gap={2}>
131
+ <VStack gap={2}>
132
+ <TextInput
133
+ label="Email"
134
+ isLabelHidden
135
+ type="email"
136
+ {...inputAutoComplete('email')}
137
+ placeholder={AUTH_EMAIL_PLACEHOLDER}
138
+ value={email}
139
+ onChange={(v: string) => {
140
+ setEmail(v);
141
+ setError(null);
142
+ }}
143
+ size="lg"
144
+ onEnter={handleLogin}
145
+ status={error ? {type: 'error', message: error} : undefined}
146
+ />
147
+ <VStack gap={1}>
161
148
  <TextInput
162
- label="Email"
149
+ label="Password"
163
150
  isLabelHidden
164
- type="email"
165
- {...inputAutoComplete('email')}
166
- placeholder={AUTH_EMAIL_PLACEHOLDER}
167
- value={email}
151
+ placeholder={AUTH_PASSWORD_PLACEHOLDER}
152
+ type="password"
153
+ {...inputAutoComplete('current-password')}
154
+ value={password}
168
155
  onChange={(v: string) => {
169
- setEmail(v);
156
+ setPassword(v);
170
157
  setError(null);
171
158
  }}
172
159
  size="lg"
173
160
  onEnter={handleLogin}
174
161
  status={error ? {type: 'error', message: error} : undefined}
175
162
  />
176
- <VStack gap={1}>
177
- <TextInput
178
- label="Password"
179
- isLabelHidden
180
- placeholder={AUTH_PASSWORD_PLACEHOLDER}
181
- type="password"
182
- {...inputAutoComplete('current-password')}
183
- value={password}
184
- onChange={(v: string) => {
185
- setPassword(v);
186
- setError(null);
187
- }}
188
- size="lg"
189
- onEnter={handleLogin}
190
- status={error ? {type: 'error', message: error} : undefined}
191
- />
192
- {error && (
193
- <VStack hAlign="end">
194
- <Link
195
- href="#/templates/login-split"
196
- isStandalone>
197
- {AUTH_FORGOT_PASSWORD}
198
- </Link>
199
- </VStack>
200
- )}
201
- </VStack>
163
+ {error && (
164
+ <VStack hAlign="end">
165
+ <Link
166
+ href="#/templates/login-split"
167
+ isStandalone>
168
+ {AUTH_FORGOT_PASSWORD}
169
+ </Link>
170
+ </VStack>
171
+ )}
202
172
  </VStack>
173
+ </VStack>
203
174
 
175
+ <Button
176
+ label={AUTH_PRIMARY_CTA}
177
+ variant="primary"
178
+ size="lg"
179
+ isLoading={isLoading}
180
+ onClick={handleLogin}
181
+ />
182
+
183
+ <Divider label={AUTH_SSO_DIVIDER} />
184
+
185
+ {/* minWidth (not a fixed 2-up) so the pair stacks inside
186
+ the narrow single-column container instead of
187
+ giving each button ~114px for an icon + label. */}
188
+ <Grid
189
+ columns={{minWidth: 200, repeat: 'fit'}}
190
+ gap={3}
191
+ justify="stretch">
204
192
  <Button
205
- label={AUTH_PRIMARY_CTA}
206
- variant="primary"
193
+ label="Login with Apple"
194
+ variant="secondary"
195
+ icon={<AppleIcon />}
207
196
  size="lg"
208
- isLoading={isLoading}
209
- onClick={handleLogin}
210
197
  />
211
-
212
- <Divider label={AUTH_SSO_DIVIDER} />
213
-
214
- {/* minWidth (not a fixed 2-up) so the pair stacks inside
215
- the narrow single-column container instead of
216
- giving each button ~114px for an icon + label. */}
217
- <Grid
218
- columns={{minWidth: 200, repeat: 'fit'}}
219
- gap={3}
220
- justify="stretch">
221
- <Button
222
- label="Login with Apple"
223
- variant="secondary"
224
- icon={<AppleIcon />}
225
- size="lg"
226
- />
227
- <Button
228
- label="Login with Google"
229
- variant="secondary"
230
- icon={<GoogleIcon />}
231
- size="lg"
232
- />
233
- </Grid>
234
- </VStack>
235
- )}
198
+ <Button
199
+ label="Login with Google"
200
+ variant="secondary"
201
+ icon={<GoogleIcon />}
202
+ size="lg"
203
+ />
204
+ </Grid>
205
+ </VStack>
236
206
  </Center>
237
207
  </StackItem>
238
208
 
@@ -241,16 +211,14 @@ export default function LoginSplit() {
241
211
  only gives on hover. The VStack centres the line, as the
242
212
  other three login templates do — it was sitting flush
243
213
  left under a left-aligned form. */}
244
- {!isSuccess && (
245
- <VStack hAlign="center">
246
- <Text type="supporting" color="secondary">
247
- {AUTH_SIGNUP_PROMPT}{' '}
248
- <Link href="#/templates/login-split" type="supporting" hasUnderline>
249
- {AUTH_SIGNUP_LINK}
250
- </Link>
251
- </Text>
252
- </VStack>
253
- )}
214
+ <VStack hAlign="center">
215
+ <Text type="supporting" color="secondary">
216
+ {AUTH_SIGNUP_PROMPT}{' '}
217
+ <Link href="#/templates/login-split" type="supporting" hasUnderline>
218
+ {AUTH_SIGNUP_LINK}
219
+ </Link>
220
+ </Text>
221
+ </VStack>
254
222
  </VStack>
255
223
  </Section>
256
224
 
@@ -5,7 +5,8 @@
5
5
  // Step-conditional h1: the email and SSO-confirm steps each render their own
6
6
  // h1 (email entry vs provider confirm); the password fallback reuses the
7
7
  // family heading, so exactly one h1 shows per step.
8
- import {useState, useTransition, type CSSProperties} from 'react';
8
+ import {useState, useTransition} from 'react';
9
+ import {authPageStyle as pageStyle, inputAutoComplete} from 'astryx-dracula/shared/auth-chrome-config';
9
10
  import {demoLogin} from 'astryx-dracula/shared/login-demo';
10
11
  import {
11
12
  AUTH_HEADING,
@@ -25,7 +26,6 @@ import {Text, Heading} from '@astryxdesign/core/Text';
25
26
  import {TextInput} from '@astryxdesign/core/TextInput';
26
27
  import {Button} from '@astryxdesign/core/Button';
27
28
  import {Card} from '@astryxdesign/core/Card';
28
- import {Section} from '@astryxdesign/core/Section';
29
29
  import {Link} from '@astryxdesign/core/Link';
30
30
  import {Divider} from '@astryxdesign/core/Divider';
31
31
  import {Icon} from '@astryxdesign/core/Icon';
@@ -34,18 +34,6 @@ import {Avatar} from '@astryxdesign/core/Avatar';
34
34
  // ============= ICONS (verified lucide-react exports) =============
35
35
  // ShieldCheck ← ShieldCheckIcon.
36
36
  import {ShieldCheck} from 'lucide-react';
37
- import {inputAutoComplete} from 'astryx-dracula/shared/auth-chrome-config';
38
-
39
- // ---------------------------------------------------------------------------
40
- // Styles
41
- // ---------------------------------------------------------------------------
42
-
43
- // Standalone auth page paints its own body background (no host shell).
44
- const pageStyle: CSSProperties = {
45
- minHeight: '100%',
46
- backgroundColor: 'var(--color-background-body)',
47
- padding: 'var(--spacing-6)',
48
- };
49
37
 
50
38
  type SSOProvider = {
51
39
  name: string;
@@ -208,25 +196,16 @@ export default function LoginSso() {
208
196
  </Text>
209
197
  </VStack>
210
198
 
211
- {/* The gutter lives on the Card, not the Section. A Section
212
- escapes its container's --container-padding-* (Section.tsx:
213
- 56-71), but with Card padding={0} that published var is
214
- --spacing-0, so the escape cancelled nothing and the muted
215
- fill painted flush to the card border. 3 + 1 keeps the text
216
- inset at the 16px it already had while giving the fill a
217
- real one. */}
218
- <Card padding={3}>
219
- <Section variant="muted" padding={1}>
220
- <HStack gap={2} vAlign="center">
221
- <Icon icon={ShieldCheck} color="secondary" />
222
- <VStack gap={0}>
223
- <Text type="label">{provider.name}</Text>
224
- <Text type="supporting" color="secondary">
225
- {email}
226
- </Text>
227
- </VStack>
228
- </HStack>
229
- </Section>
199
+ <Card padding={4} variant="muted">
200
+ <HStack gap={2} vAlign="center">
201
+ <Icon icon={ShieldCheck} color="secondary" />
202
+ <VStack gap={0}>
203
+ <Text type="label">{provider.name}</Text>
204
+ <Text type="supporting" color="secondary">
205
+ {email}
206
+ </Text>
207
+ </VStack>
208
+ </HStack>
230
209
  </Card>
231
210
 
232
211
  <VStack gap={3}>