@cyberia-auth/auth 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -69,6 +69,7 @@ Props:
69
69
  - `apiToken: string` - app API token
70
70
  - `oauthRedirectUri?: string` - redirect URL for Google/Microsoft OAuth
71
71
  - `initialMode?: 'login' | 'register'` - default mode
72
+ - `theme?: 'system' | 'light' | 'dark'` - color mode (`system` by default)
72
73
  - `hideModeSwitch?: boolean` - hide sign-in/sign-up toggle footer
73
74
  - `onAuthSuccess?: (result) => void` - callback with `{ token, user }`
74
75
 
@@ -81,6 +82,7 @@ Props:
81
82
  - `backendUrl: string`
82
83
  - `apiToken: string`
83
84
  - `oauthRedirectUri?: string`
85
+ - `theme?: 'system' | 'light' | 'dark'` - applies to modal + `UserButton` UI
84
86
  - `children: ReactNode`
85
87
  - `storageKey?: string` - localStorage key override (default `cyberia_auth_session`)
86
88
 
package/dist/index.cjs CHANGED
@@ -60,10 +60,13 @@ function CyberiaAuth({
60
60
  apiToken,
61
61
  oauthRedirectUri,
62
62
  initialMode = "register",
63
+ theme = "system",
63
64
  hideModeSwitch = false,
64
65
  onAuthSuccess
65
66
  }) {
66
67
  const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
68
+ const resolvedTheme = useResolvedTheme(theme);
69
+ const palette = getThemePalette(resolvedTheme);
67
70
  const [mode, setMode] = (0, import_react.useState)(initialMode);
68
71
  const [config, setConfig] = (0, import_react.useState)(() => getCachedAppConfig(apiToken));
69
72
  const [isBrandingResolved, setIsBrandingResolved] = (0, import_react.useState)(
@@ -140,15 +143,15 @@ function CyberiaAuth({
140
143
  "div",
141
144
  {
142
145
  style: {
143
- border: "1px solid #e5e7eb",
146
+ border: `1px solid ${palette.border}`,
144
147
  borderRadius: 14,
145
148
  padding: 20,
146
- background: "#ffffff",
149
+ background: palette.surface,
147
150
  fontFamily: "Inter, Arial, sans-serif",
148
151
  minHeight: 320,
149
152
  display: "grid",
150
153
  placeItems: "center",
151
- color: "#6b7280"
154
+ color: palette.textMuted
152
155
  },
153
156
  children: "Loading sign-in..."
154
157
  }
@@ -158,15 +161,16 @@ function CyberiaAuth({
158
161
  "div",
159
162
  {
160
163
  style: {
161
- border: "1px solid #e5e7eb",
164
+ border: `1px solid ${palette.border}`,
162
165
  borderRadius: 14,
163
166
  padding: 0,
164
- background: "#ffffff",
167
+ background: palette.surface,
165
168
  overflow: "hidden",
166
169
  fontFamily: "Inter, Arial, sans-serif",
167
170
  width: "100%",
168
171
  maxWidth: 500,
169
- margin: "0 auto"
172
+ margin: "0 auto",
173
+ color: palette.text
170
174
  },
171
175
  children: [
172
176
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: 20, display: "grid", gap: 14 }, children: [
@@ -190,15 +194,15 @@ function CyberiaAuth({
190
194
  ),
191
195
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center" }, children: [
192
196
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: { margin: "0 0 6px 0", fontSize: 16 }, children: title }),
193
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { margin: 0, color: "#6b7280", fontSize: 13 }, children: subtitle })
197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { margin: 0, color: palette.textMuted, fontSize: 13 }, children: subtitle })
194
198
  ] })
195
199
  ] }),
196
200
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }, children: [
197
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("google"), children: [
201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("google"), children: [
198
202
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GoogleIcon, {}),
199
203
  "Google"
200
204
  ] }),
201
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("microsoft"), children: [
205
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("microsoft"), children: [
202
206
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MicrosoftIcon, {}),
203
207
  "Microsoft"
204
208
  ] })
@@ -213,14 +217,14 @@ function CyberiaAuth({
213
217
  gap: 12
214
218
  },
215
219
  children: [
216
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background: "#e5e7eb" } }),
217
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#9ca3af", fontSize: 14 }, children: "or" }),
218
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background: "#e5e7eb" } })
220
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background: palette.border } }),
221
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: palette.textMuted, fontSize: 14 }, children: "or" }),
222
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background: palette.border } })
219
223
  ]
220
224
  }
221
225
  ),
222
226
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, style: { display: "grid", gap: 10 }, children: [
223
- mode === "register" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle, children: [
227
+ mode === "register" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle(palette), children: [
224
228
  "Full name",
225
229
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
226
230
  "input",
@@ -228,15 +232,15 @@ function CyberiaAuth({
228
232
  name: "displayName",
229
233
  placeholder: "Enter your full name",
230
234
  required: true,
231
- style: inputStyle
235
+ style: inputStyle(palette)
232
236
  }
233
237
  )
234
238
  ] }),
235
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle, children: [
239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle(palette), children: [
236
240
  "Email address",
237
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle })
241
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle(palette) })
238
242
  ] }),
239
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle, children: [
243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle(palette), children: [
240
244
  "Password",
241
245
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
242
246
  "input",
@@ -246,7 +250,7 @@ function CyberiaAuth({
246
250
  placeholder: "Enter your password",
247
251
  minLength: 8,
248
252
  required: true,
249
- style: inputStyle
253
+ style: inputStyle(palette)
250
254
  }
251
255
  )
252
256
  ] }),
@@ -274,10 +278,11 @@ function CyberiaAuth({
274
278
  "div",
275
279
  {
276
280
  style: {
277
- borderTop: "1px solid #e5e7eb",
281
+ borderTop: `1px solid ${palette.border}`,
278
282
  padding: 14,
279
283
  textAlign: "center",
280
- background: "#fafafa"
284
+ fontSize: 13,
285
+ background: palette.surfaceAlt
281
286
  },
282
287
  children: [
283
288
  mode === "login" ? "Don't have an account? " : "Already have an account? ",
@@ -289,7 +294,7 @@ function CyberiaAuth({
289
294
  style: {
290
295
  border: "none",
291
296
  background: "transparent",
292
- color: "#111827",
297
+ color: palette.text,
293
298
  textDecoration: "underline",
294
299
  fontWeight: 600,
295
300
  cursor: "pointer",
@@ -310,10 +315,12 @@ function CyberiaAuthProvider({
310
315
  backendUrl,
311
316
  apiToken,
312
317
  oauthRedirectUri,
318
+ theme = "system",
313
319
  children,
314
320
  storageKey = "cyberia_auth_session"
315
321
  }) {
316
322
  const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
323
+ const resolvedTheme = useResolvedTheme(theme);
317
324
  const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
318
325
  const [session, setSession] = (0, import_react.useState)(null);
319
326
  const [modalOpen, setModalOpen] = (0, import_react.useState)(false);
@@ -386,9 +393,10 @@ function CyberiaAuthProvider({
386
393
  setModalOpen(true);
387
394
  },
388
395
  signOut,
389
- setSessionFromAuth
396
+ setSessionFromAuth,
397
+ theme: resolvedTheme
390
398
  }),
391
- [isLoaded, session, setSessionFromAuth]
399
+ [isLoaded, resolvedTheme, session, setSessionFromAuth]
392
400
  );
393
401
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CyberiaAuthContext.Provider, { value, children: [
394
402
  children,
@@ -416,6 +424,7 @@ function CyberiaAuthProvider({
416
424
  backendUrl: backendBaseUrl,
417
425
  apiToken,
418
426
  oauthRedirectUri,
427
+ theme,
419
428
  initialMode: modalMode,
420
429
  hideModeSwitch: false,
421
430
  onAuthSuccess: (result) => {
@@ -474,7 +483,8 @@ function SignOutButton({ children }) {
474
483
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: signOut, children: children ?? "Sign out" });
475
484
  }
476
485
  function UserButton() {
477
- const { user, signOut, openSignIn, openSignUp } = useCyberiaAuth();
486
+ const { user, signOut, openSignIn, openSignUp, theme } = useCyberiaAuth();
487
+ const palette = getThemePalette(theme);
478
488
  const [open, setOpen] = (0, import_react.useState)(false);
479
489
  const [manageOpen, setManageOpen] = (0, import_react.useState)(false);
480
490
  const [tab, setTab] = (0, import_react.useState)("profile");
@@ -505,8 +515,9 @@ function UserButton() {
505
515
  width: 36,
506
516
  height: 36,
507
517
  borderRadius: 999,
508
- border: "1px solid #d1d5db",
509
- background: "#fff",
518
+ border: `1px solid ${palette.border}`,
519
+ background: palette.surface,
520
+ color: palette.text,
510
521
  fontWeight: 700,
511
522
  cursor: "pointer"
512
523
  },
@@ -522,8 +533,8 @@ function UserButton() {
522
533
  right: 0,
523
534
  top: 42,
524
535
  minWidth: 320,
525
- background: "#fff",
526
- border: "1px solid #e5e7eb",
536
+ background: palette.surface,
537
+ border: `1px solid ${palette.border}`,
527
538
  borderRadius: 12,
528
539
  boxShadow: "0 12px 24px rgba(0,0,0,0.08)",
529
540
  padding: 0,
@@ -538,22 +549,22 @@ function UserButton() {
538
549
  width: 44,
539
550
  height: 44,
540
551
  borderRadius: 999,
541
- border: "1px solid #d1d5db",
552
+ border: `1px solid ${palette.border}`,
542
553
  display: "grid",
543
554
  placeItems: "center",
544
555
  fontWeight: 700,
545
- color: "#111827",
546
- background: "#f8fafc"
556
+ color: palette.text,
557
+ background: palette.surfaceAlt
547
558
  },
548
559
  children: initials
549
560
  }
550
561
  ),
551
562
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid" }, children: [
552
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { fontSize: 16, color: "#111827", lineHeight: 1.2 }, children: profileName }),
553
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#111827", fontSize: 14 }, children: profileEmail })
563
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { fontSize: 16, color: palette.text, lineHeight: 1.2 }, children: profileName }),
564
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: palette.text, fontSize: 14 }, children: profileEmail })
554
565
  ] })
555
566
  ] }),
556
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop: "1px solid #e5e7eb", margin: 0 } }),
567
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: 0 } }),
557
568
  !user && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
558
569
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
559
570
  "button",
@@ -607,9 +618,9 @@ function UserButton() {
607
618
  }
608
619
  )
609
620
  ] }),
610
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { borderTop: "1px solid #e5e7eb", textAlign: "center", padding: "12px 10px", color: "#6b7280" }, children: [
621
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { borderTop: `1px solid ${palette.border}`, textAlign: "center", padding: "12px 10px", color: palette.textMuted, fontSize: 13 }, children: [
611
622
  "Secured by ",
612
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "cyberia auth" })
623
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Cyberia Auth" })
613
624
  ] })
614
625
  ]
615
626
  }
@@ -634,9 +645,9 @@ function UserButton() {
634
645
  width: "100%",
635
646
  maxWidth: 940,
636
647
  minHeight: 540,
637
- background: "#fff",
648
+ background: palette.surface,
638
649
  borderRadius: 10,
639
- border: "1px solid #e5e7eb",
650
+ border: `1px solid ${palette.border}`,
640
651
  display: "grid",
641
652
  gridTemplateColumns: "220px 1fr",
642
653
  overflow: "hidden"
@@ -647,15 +658,15 @@ function UserButton() {
647
658
  "aside",
648
659
  {
649
660
  style: {
650
- borderRight: "1px solid #e5e7eb",
661
+ borderRight: `1px solid ${palette.border}`,
651
662
  padding: 22,
652
- background: "#fafafa",
663
+ background: palette.surfaceAlt,
653
664
  display: "flex",
654
665
  flexDirection: "column"
655
666
  },
656
667
  children: [
657
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: { margin: 0, fontSize: 30, color: "#111827" }, children: "Account" }),
658
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { marginTop: 6, color: "#6b7280", fontSize: 12 }, children: "Manage your account info." }),
668
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: { margin: 0, fontSize: 30, color: palette.text }, children: "Account" }),
669
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { marginTop: 6, color: palette.textMuted, fontSize: 12 }, children: "Manage your account info." }),
659
670
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: 20, display: "grid", gap: 8 }, children: [
660
671
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
661
672
  "button",
@@ -664,8 +675,8 @@ function UserButton() {
664
675
  onClick: () => setTab("profile"),
665
676
  style: {
666
677
  ...tabButtonStyle,
667
- background: tab === "profile" ? "#ece8ff" : "transparent",
668
- color: tab === "profile" ? "#6d28d9" : "#4b5563"
678
+ background: tab === "profile" ? "#ffe8e8" : "transparent",
679
+ color: tab === "profile" ? "#d92828" : palette.textMuted
669
680
  },
670
681
  children: "Profile"
671
682
  }
@@ -677,14 +688,14 @@ function UserButton() {
677
688
  onClick: () => setTab("security"),
678
689
  style: {
679
690
  ...tabButtonStyle,
680
- background: tab === "security" ? "#ece8ff" : "transparent",
681
- color: tab === "security" ? "#6d28d9" : "#4b5563"
691
+ background: tab === "security" ? "#ffe8e8" : "transparent",
692
+ color: tab === "security" ? "#d92828" : palette.textMuted
682
693
  },
683
694
  children: "Security"
684
695
  }
685
696
  )
686
697
  ] }),
687
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: "auto", paddingTop: 24, color: "#6b7280", fontSize: 15 }, children: [
698
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: "auto", paddingTop: 24, color: palette.textMuted, fontSize: 15 }, children: [
688
699
  "Secure by ",
689
700
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Cyberia Auth" })
690
701
  ] })
@@ -693,7 +704,7 @@ function UserButton() {
693
704
  ),
694
705
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { style: { padding: 26 }, children: [
695
706
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
696
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: { margin: 0, fontSize: 22, color: "#111827" }, children: tab === "profile" ? "Profile details" : "Security" }),
707
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: { margin: 0, fontSize: 22, color: palette.text }, children: tab === "profile" ? "Profile details" : "Security" }),
697
708
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
698
709
  "button",
699
710
  {
@@ -704,10 +715,10 @@ function UserButton() {
704
715
  }
705
716
  )
706
717
  ] }),
707
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop: "1px solid #e5e7eb", margin: "16px 0 20px" } }),
718
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: "16px 0 20px" } }),
708
719
  tab === "profile" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 20 }, children: [
709
720
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
710
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#374151", fontSize: 14 }, children: "Profile" }),
721
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Profile" }),
711
722
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
712
723
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: avatarLargeStyle, children: initials }),
713
724
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 16 }, children: profileName })
@@ -715,25 +726,25 @@ function UserButton() {
715
726
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: linkButtonStyle, children: "Update profile" })
716
727
  ] }),
717
728
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
718
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#374151", fontSize: 14 }, children: "Email addresses" }),
729
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Email addresses" }),
719
730
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 16 }, children: profileEmail }),
720
731
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#6b7280", fontSize: 14 }, children: "Primary" })
721
732
  ] }),
722
733
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
723
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#374151", fontSize: 14 }, children: "Connected accounts" }),
734
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Connected accounts" }),
724
735
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 16 }, children: "Google / Microsoft" }),
725
736
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: linkButtonStyle, children: "Connect account" })
726
737
  ] })
727
738
  ] }),
728
739
  tab === "security" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 20 }, children: [
729
740
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
730
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#374151", fontSize: 14 }, children: "Password" }),
741
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Password" }),
731
742
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {}),
732
743
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: linkButtonStyle, children: "Set password" })
733
744
  ] }),
734
745
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...profileRowStyle, alignItems: "start" }, children: [
735
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#374151", fontSize: 14 }, children: "Active devices" }),
736
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 14, color: "#374151", maxWidth: 430 }, children: userAgent }),
746
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Active devices" }),
747
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 14, color: "#c5c7ca", maxWidth: 430 }, children: userAgent }),
737
748
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#6b7280", fontSize: 14 }, children: "This device" })
738
749
  ] }),
739
750
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
@@ -787,25 +798,28 @@ var menuItemButtonStyle = {
787
798
  background: "transparent",
788
799
  cursor: "pointer"
789
800
  };
790
- var inputStyle = {
801
+ var inputStyle = (palette) => ({
791
802
  width: "100%",
792
803
  padding: 11,
793
804
  borderRadius: 9,
794
- border: "1px solid #d1d5db",
805
+ border: `1px solid ${palette.border}`,
806
+ background: palette.surface,
807
+ color: palette.text,
795
808
  fontSize: 13
796
- };
797
- var fieldLabelStyle = {
809
+ });
810
+ var fieldLabelStyle = (palette) => ({
798
811
  display: "grid",
799
812
  gap: 6,
800
813
  fontSize: 14,
801
- color: "#111827",
814
+ color: palette.text,
802
815
  fontWeight: 600
803
- };
804
- var socialButtonStyle = {
805
- border: "1px solid #d1d5db",
816
+ });
817
+ var socialButtonStyle = (palette) => ({
818
+ border: `1px solid ${palette.border}`,
806
819
  borderRadius: 9,
807
820
  padding: "10px 12px",
808
- background: "#ffffff",
821
+ background: palette.surface,
822
+ color: palette.text,
809
823
  cursor: "pointer",
810
824
  fontSize: 16,
811
825
  fontWeight: 300,
@@ -813,7 +827,7 @@ var socialButtonStyle = {
813
827
  alignItems: "center",
814
828
  justifyContent: "center",
815
829
  gap: 8
816
- };
830
+ });
817
831
  function GoogleIcon() {
818
832
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", height: "20", viewBox: "0 0 20 20", width: "20", "aria-hidden": "true", children: [
819
833
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M19.9905 10.1871C19.9905 9.36773 19.9224 8.7698 19.7752 8.14972H10.1992V11.848H15.8201C15.7068 12.7671 15.0948 14.1512 13.7349 15.0813L13.7159 15.2051L16.7436 17.497L16.9534 17.5174C18.8798 15.779 19.9905 13.2211 19.9905 10.1871Z", fill: "#4285F4" }),
@@ -841,6 +855,50 @@ function resolveBackendBaseUrl(backendUrl) {
841
855
  const candidate = backendUrl?.trim() || DEFAULT_BACKEND_URL;
842
856
  return candidate.replace(/\/+$/, "");
843
857
  }
858
+ function getThemePalette(theme) {
859
+ if (theme === "dark") {
860
+ return {
861
+ surface: "#445364",
862
+ surfaceAlt: "#1f2937",
863
+ border: "#374151",
864
+ text: "#f9fafb",
865
+ textMuted: "#9ca3af"
866
+ };
867
+ }
868
+ return {
869
+ surface: "#ffffff",
870
+ surfaceAlt: "#fafafa",
871
+ border: "#e5e7eb",
872
+ text: "#111827",
873
+ textMuted: "#6b7280"
874
+ };
875
+ }
876
+ function useResolvedTheme(theme) {
877
+ const [resolvedTheme, setResolvedTheme] = (0, import_react.useState)(() => {
878
+ if (theme === "light" || theme === "dark") {
879
+ return theme;
880
+ }
881
+ if (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
882
+ return "dark";
883
+ }
884
+ return "light";
885
+ });
886
+ (0, import_react.useEffect)(() => {
887
+ if (theme === "light" || theme === "dark") {
888
+ setResolvedTheme(theme);
889
+ return;
890
+ }
891
+ if (typeof window === "undefined") {
892
+ return;
893
+ }
894
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
895
+ const updateTheme = () => setResolvedTheme(mediaQuery.matches ? "dark" : "light");
896
+ updateTheme();
897
+ mediaQuery.addEventListener("change", updateTheme);
898
+ return () => mediaQuery.removeEventListener("change", updateTheme);
899
+ }, [theme]);
900
+ return resolvedTheme;
901
+ }
844
902
  function getBrandingCacheKey(apiToken) {
845
903
  return `cyberia_auth_branding:${apiToken}`;
846
904
  }
@@ -887,7 +945,7 @@ var tabButtonStyle = {
887
945
  };
888
946
  var profileRowStyle = {
889
947
  display: "grid",
890
- gridTemplateColumns: "220px 1fr auto",
948
+ gridTemplateColumns: "150px 1fr auto",
891
949
  alignItems: "center",
892
950
  gap: 12,
893
951
  paddingBottom: 12,
@@ -907,7 +965,7 @@ var avatarLargeStyle = {
907
965
  var linkButtonStyle = {
908
966
  border: "none",
909
967
  background: "transparent",
910
- color: "#6d28d9",
968
+ color: "#d92828",
911
969
  cursor: "pointer",
912
970
  fontSize: 14
913
971
  };
package/dist/index.d.cts CHANGED
@@ -2,6 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
4
  type AuthMode = 'register' | 'login';
5
+ type ThemeMode = 'system' | 'light' | 'dark';
6
+ type ResolvedTheme = 'light' | 'dark';
5
7
  type AuthUser = {
6
8
  id: string;
7
9
  email: string;
@@ -16,10 +18,11 @@ type CyberiaAuthProps = {
16
18
  apiToken: string;
17
19
  oauthRedirectUri?: string;
18
20
  initialMode?: AuthMode;
21
+ theme?: ThemeMode;
19
22
  hideModeSwitch?: boolean;
20
23
  onAuthSuccess?: (data: AuthResult) => void;
21
24
  };
22
- declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
25
+ declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, theme, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
23
26
  type CyberiaAuthContextValue = {
24
27
  isLoaded: boolean;
25
28
  isSignedIn: boolean;
@@ -29,15 +32,17 @@ type CyberiaAuthContextValue = {
29
32
  openSignUp: () => void;
30
33
  signOut: () => void;
31
34
  setSessionFromAuth: (result: AuthResult) => void;
35
+ theme: ResolvedTheme;
32
36
  };
33
37
  type CyberiaAuthProviderProps = {
34
38
  backendUrl?: string;
35
39
  apiToken: string;
36
40
  oauthRedirectUri?: string;
41
+ theme?: ThemeMode;
37
42
  children: ReactNode;
38
43
  storageKey?: string;
39
44
  };
40
- declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
45
+ declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, theme, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
41
46
  declare function useCyberiaAuth(): CyberiaAuthContextValue;
42
47
  declare function Show({ when, children }: {
43
48
  when: 'signed-in' | 'signed-out';
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
4
  type AuthMode = 'register' | 'login';
5
+ type ThemeMode = 'system' | 'light' | 'dark';
6
+ type ResolvedTheme = 'light' | 'dark';
5
7
  type AuthUser = {
6
8
  id: string;
7
9
  email: string;
@@ -16,10 +18,11 @@ type CyberiaAuthProps = {
16
18
  apiToken: string;
17
19
  oauthRedirectUri?: string;
18
20
  initialMode?: AuthMode;
21
+ theme?: ThemeMode;
19
22
  hideModeSwitch?: boolean;
20
23
  onAuthSuccess?: (data: AuthResult) => void;
21
24
  };
22
- declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
25
+ declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, theme, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
23
26
  type CyberiaAuthContextValue = {
24
27
  isLoaded: boolean;
25
28
  isSignedIn: boolean;
@@ -29,15 +32,17 @@ type CyberiaAuthContextValue = {
29
32
  openSignUp: () => void;
30
33
  signOut: () => void;
31
34
  setSessionFromAuth: (result: AuthResult) => void;
35
+ theme: ResolvedTheme;
32
36
  };
33
37
  type CyberiaAuthProviderProps = {
34
38
  backendUrl?: string;
35
39
  apiToken: string;
36
40
  oauthRedirectUri?: string;
41
+ theme?: ThemeMode;
37
42
  children: ReactNode;
38
43
  storageKey?: string;
39
44
  };
40
- declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
45
+ declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, theme, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
41
46
  declare function useCyberiaAuth(): CyberiaAuthContextValue;
42
47
  declare function Show({ when, children }: {
43
48
  when: 'signed-in' | 'signed-out';
package/dist/index.js CHANGED
@@ -21,10 +21,13 @@ function CyberiaAuth({
21
21
  apiToken,
22
22
  oauthRedirectUri,
23
23
  initialMode = "register",
24
+ theme = "system",
24
25
  hideModeSwitch = false,
25
26
  onAuthSuccess
26
27
  }) {
27
28
  const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
29
+ const resolvedTheme = useResolvedTheme(theme);
30
+ const palette = getThemePalette(resolvedTheme);
28
31
  const [mode, setMode] = useState(initialMode);
29
32
  const [config, setConfig] = useState(() => getCachedAppConfig(apiToken));
30
33
  const [isBrandingResolved, setIsBrandingResolved] = useState(
@@ -101,15 +104,15 @@ function CyberiaAuth({
101
104
  "div",
102
105
  {
103
106
  style: {
104
- border: "1px solid #e5e7eb",
107
+ border: `1px solid ${palette.border}`,
105
108
  borderRadius: 14,
106
109
  padding: 20,
107
- background: "#ffffff",
110
+ background: palette.surface,
108
111
  fontFamily: "Inter, Arial, sans-serif",
109
112
  minHeight: 320,
110
113
  display: "grid",
111
114
  placeItems: "center",
112
- color: "#6b7280"
115
+ color: palette.textMuted
113
116
  },
114
117
  children: "Loading sign-in..."
115
118
  }
@@ -119,15 +122,16 @@ function CyberiaAuth({
119
122
  "div",
120
123
  {
121
124
  style: {
122
- border: "1px solid #e5e7eb",
125
+ border: `1px solid ${palette.border}`,
123
126
  borderRadius: 14,
124
127
  padding: 0,
125
- background: "#ffffff",
128
+ background: palette.surface,
126
129
  overflow: "hidden",
127
130
  fontFamily: "Inter, Arial, sans-serif",
128
131
  width: "100%",
129
132
  maxWidth: 500,
130
- margin: "0 auto"
133
+ margin: "0 auto",
134
+ color: palette.text
131
135
  },
132
136
  children: [
133
137
  /* @__PURE__ */ jsxs("div", { style: { padding: 20, display: "grid", gap: 14 }, children: [
@@ -151,15 +155,15 @@ function CyberiaAuth({
151
155
  ),
152
156
  /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
153
157
  /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 6px 0", fontSize: 16 }, children: title }),
154
- /* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#6b7280", fontSize: 13 }, children: subtitle })
158
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, color: palette.textMuted, fontSize: 13 }, children: subtitle })
155
159
  ] })
156
160
  ] }),
157
161
  /* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }, children: [
158
- /* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("google"), children: [
162
+ /* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("google"), children: [
159
163
  /* @__PURE__ */ jsx(GoogleIcon, {}),
160
164
  "Google"
161
165
  ] }),
162
- /* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("microsoft"), children: [
166
+ /* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("microsoft"), children: [
163
167
  /* @__PURE__ */ jsx(MicrosoftIcon, {}),
164
168
  "Microsoft"
165
169
  ] })
@@ -174,14 +178,14 @@ function CyberiaAuth({
174
178
  gap: 12
175
179
  },
176
180
  children: [
177
- /* @__PURE__ */ jsx("div", { style: { height: 1, background: "#e5e7eb" } }),
178
- /* @__PURE__ */ jsx("span", { style: { color: "#9ca3af", fontSize: 14 }, children: "or" }),
179
- /* @__PURE__ */ jsx("div", { style: { height: 1, background: "#e5e7eb" } })
181
+ /* @__PURE__ */ jsx("div", { style: { height: 1, background: palette.border } }),
182
+ /* @__PURE__ */ jsx("span", { style: { color: palette.textMuted, fontSize: 14 }, children: "or" }),
183
+ /* @__PURE__ */ jsx("div", { style: { height: 1, background: palette.border } })
180
184
  ]
181
185
  }
182
186
  ),
183
187
  /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, style: { display: "grid", gap: 10 }, children: [
184
- mode === "register" && /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle, children: [
188
+ mode === "register" && /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle(palette), children: [
185
189
  "Full name",
186
190
  /* @__PURE__ */ jsx(
187
191
  "input",
@@ -189,15 +193,15 @@ function CyberiaAuth({
189
193
  name: "displayName",
190
194
  placeholder: "Enter your full name",
191
195
  required: true,
192
- style: inputStyle
196
+ style: inputStyle(palette)
193
197
  }
194
198
  )
195
199
  ] }),
196
- /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle, children: [
200
+ /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle(palette), children: [
197
201
  "Email address",
198
- /* @__PURE__ */ jsx("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle })
202
+ /* @__PURE__ */ jsx("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle(palette) })
199
203
  ] }),
200
- /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle, children: [
204
+ /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle(palette), children: [
201
205
  "Password",
202
206
  /* @__PURE__ */ jsx(
203
207
  "input",
@@ -207,7 +211,7 @@ function CyberiaAuth({
207
211
  placeholder: "Enter your password",
208
212
  minLength: 8,
209
213
  required: true,
210
- style: inputStyle
214
+ style: inputStyle(palette)
211
215
  }
212
216
  )
213
217
  ] }),
@@ -235,10 +239,11 @@ function CyberiaAuth({
235
239
  "div",
236
240
  {
237
241
  style: {
238
- borderTop: "1px solid #e5e7eb",
242
+ borderTop: `1px solid ${palette.border}`,
239
243
  padding: 14,
240
244
  textAlign: "center",
241
- background: "#fafafa"
245
+ fontSize: 13,
246
+ background: palette.surfaceAlt
242
247
  },
243
248
  children: [
244
249
  mode === "login" ? "Don't have an account? " : "Already have an account? ",
@@ -250,7 +255,7 @@ function CyberiaAuth({
250
255
  style: {
251
256
  border: "none",
252
257
  background: "transparent",
253
- color: "#111827",
258
+ color: palette.text,
254
259
  textDecoration: "underline",
255
260
  fontWeight: 600,
256
261
  cursor: "pointer",
@@ -271,10 +276,12 @@ function CyberiaAuthProvider({
271
276
  backendUrl,
272
277
  apiToken,
273
278
  oauthRedirectUri,
279
+ theme = "system",
274
280
  children,
275
281
  storageKey = "cyberia_auth_session"
276
282
  }) {
277
283
  const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
284
+ const resolvedTheme = useResolvedTheme(theme);
278
285
  const [isLoaded, setIsLoaded] = useState(false);
279
286
  const [session, setSession] = useState(null);
280
287
  const [modalOpen, setModalOpen] = useState(false);
@@ -347,9 +354,10 @@ function CyberiaAuthProvider({
347
354
  setModalOpen(true);
348
355
  },
349
356
  signOut,
350
- setSessionFromAuth
357
+ setSessionFromAuth,
358
+ theme: resolvedTheme
351
359
  }),
352
- [isLoaded, session, setSessionFromAuth]
360
+ [isLoaded, resolvedTheme, session, setSessionFromAuth]
353
361
  );
354
362
  return /* @__PURE__ */ jsxs(CyberiaAuthContext.Provider, { value, children: [
355
363
  children,
@@ -377,6 +385,7 @@ function CyberiaAuthProvider({
377
385
  backendUrl: backendBaseUrl,
378
386
  apiToken,
379
387
  oauthRedirectUri,
388
+ theme,
380
389
  initialMode: modalMode,
381
390
  hideModeSwitch: false,
382
391
  onAuthSuccess: (result) => {
@@ -435,7 +444,8 @@ function SignOutButton({ children }) {
435
444
  return /* @__PURE__ */ jsx("button", { type: "button", onClick: signOut, children: children ?? "Sign out" });
436
445
  }
437
446
  function UserButton() {
438
- const { user, signOut, openSignIn, openSignUp } = useCyberiaAuth();
447
+ const { user, signOut, openSignIn, openSignUp, theme } = useCyberiaAuth();
448
+ const palette = getThemePalette(theme);
439
449
  const [open, setOpen] = useState(false);
440
450
  const [manageOpen, setManageOpen] = useState(false);
441
451
  const [tab, setTab] = useState("profile");
@@ -466,8 +476,9 @@ function UserButton() {
466
476
  width: 36,
467
477
  height: 36,
468
478
  borderRadius: 999,
469
- border: "1px solid #d1d5db",
470
- background: "#fff",
479
+ border: `1px solid ${palette.border}`,
480
+ background: palette.surface,
481
+ color: palette.text,
471
482
  fontWeight: 700,
472
483
  cursor: "pointer"
473
484
  },
@@ -483,8 +494,8 @@ function UserButton() {
483
494
  right: 0,
484
495
  top: 42,
485
496
  minWidth: 320,
486
- background: "#fff",
487
- border: "1px solid #e5e7eb",
497
+ background: palette.surface,
498
+ border: `1px solid ${palette.border}`,
488
499
  borderRadius: 12,
489
500
  boxShadow: "0 12px 24px rgba(0,0,0,0.08)",
490
501
  padding: 0,
@@ -499,22 +510,22 @@ function UserButton() {
499
510
  width: 44,
500
511
  height: 44,
501
512
  borderRadius: 999,
502
- border: "1px solid #d1d5db",
513
+ border: `1px solid ${palette.border}`,
503
514
  display: "grid",
504
515
  placeItems: "center",
505
516
  fontWeight: 700,
506
- color: "#111827",
507
- background: "#f8fafc"
517
+ color: palette.text,
518
+ background: palette.surfaceAlt
508
519
  },
509
520
  children: initials
510
521
  }
511
522
  ),
512
523
  /* @__PURE__ */ jsxs("div", { style: { display: "grid" }, children: [
513
- /* @__PURE__ */ jsx("strong", { style: { fontSize: 16, color: "#111827", lineHeight: 1.2 }, children: profileName }),
514
- /* @__PURE__ */ jsx("span", { style: { color: "#111827", fontSize: 14 }, children: profileEmail })
524
+ /* @__PURE__ */ jsx("strong", { style: { fontSize: 16, color: palette.text, lineHeight: 1.2 }, children: profileName }),
525
+ /* @__PURE__ */ jsx("span", { style: { color: palette.text, fontSize: 14 }, children: profileEmail })
515
526
  ] })
516
527
  ] }),
517
- /* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop: "1px solid #e5e7eb", margin: 0 } }),
528
+ /* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: 0 } }),
518
529
  !user && /* @__PURE__ */ jsxs(Fragment, { children: [
519
530
  /* @__PURE__ */ jsx(
520
531
  "button",
@@ -568,9 +579,9 @@ function UserButton() {
568
579
  }
569
580
  )
570
581
  ] }),
571
- /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid #e5e7eb", textAlign: "center", padding: "12px 10px", color: "#6b7280" }, children: [
582
+ /* @__PURE__ */ jsxs("div", { style: { borderTop: `1px solid ${palette.border}`, textAlign: "center", padding: "12px 10px", color: palette.textMuted, fontSize: 13 }, children: [
572
583
  "Secured by ",
573
- /* @__PURE__ */ jsx("strong", { children: "cyberia auth" })
584
+ /* @__PURE__ */ jsx("strong", { children: "Cyberia Auth" })
574
585
  ] })
575
586
  ]
576
587
  }
@@ -595,9 +606,9 @@ function UserButton() {
595
606
  width: "100%",
596
607
  maxWidth: 940,
597
608
  minHeight: 540,
598
- background: "#fff",
609
+ background: palette.surface,
599
610
  borderRadius: 10,
600
- border: "1px solid #e5e7eb",
611
+ border: `1px solid ${palette.border}`,
601
612
  display: "grid",
602
613
  gridTemplateColumns: "220px 1fr",
603
614
  overflow: "hidden"
@@ -608,15 +619,15 @@ function UserButton() {
608
619
  "aside",
609
620
  {
610
621
  style: {
611
- borderRight: "1px solid #e5e7eb",
622
+ borderRight: `1px solid ${palette.border}`,
612
623
  padding: 22,
613
- background: "#fafafa",
624
+ background: palette.surfaceAlt,
614
625
  display: "flex",
615
626
  flexDirection: "column"
616
627
  },
617
628
  children: [
618
- /* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: 30, color: "#111827" }, children: "Account" }),
619
- /* @__PURE__ */ jsx("p", { style: { marginTop: 6, color: "#6b7280", fontSize: 12 }, children: "Manage your account info." }),
629
+ /* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: 30, color: palette.text }, children: "Account" }),
630
+ /* @__PURE__ */ jsx("p", { style: { marginTop: 6, color: palette.textMuted, fontSize: 12 }, children: "Manage your account info." }),
620
631
  /* @__PURE__ */ jsxs("div", { style: { marginTop: 20, display: "grid", gap: 8 }, children: [
621
632
  /* @__PURE__ */ jsx(
622
633
  "button",
@@ -625,8 +636,8 @@ function UserButton() {
625
636
  onClick: () => setTab("profile"),
626
637
  style: {
627
638
  ...tabButtonStyle,
628
- background: tab === "profile" ? "#ece8ff" : "transparent",
629
- color: tab === "profile" ? "#6d28d9" : "#4b5563"
639
+ background: tab === "profile" ? "#ffe8e8" : "transparent",
640
+ color: tab === "profile" ? "#d92828" : palette.textMuted
630
641
  },
631
642
  children: "Profile"
632
643
  }
@@ -638,14 +649,14 @@ function UserButton() {
638
649
  onClick: () => setTab("security"),
639
650
  style: {
640
651
  ...tabButtonStyle,
641
- background: tab === "security" ? "#ece8ff" : "transparent",
642
- color: tab === "security" ? "#6d28d9" : "#4b5563"
652
+ background: tab === "security" ? "#ffe8e8" : "transparent",
653
+ color: tab === "security" ? "#d92828" : palette.textMuted
643
654
  },
644
655
  children: "Security"
645
656
  }
646
657
  )
647
658
  ] }),
648
- /* @__PURE__ */ jsxs("div", { style: { marginTop: "auto", paddingTop: 24, color: "#6b7280", fontSize: 15 }, children: [
659
+ /* @__PURE__ */ jsxs("div", { style: { marginTop: "auto", paddingTop: 24, color: palette.textMuted, fontSize: 15 }, children: [
649
660
  "Secure by ",
650
661
  /* @__PURE__ */ jsx("strong", { children: "Cyberia Auth" })
651
662
  ] })
@@ -654,7 +665,7 @@ function UserButton() {
654
665
  ),
655
666
  /* @__PURE__ */ jsxs("main", { style: { padding: 26 }, children: [
656
667
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
657
- /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: 22, color: "#111827" }, children: tab === "profile" ? "Profile details" : "Security" }),
668
+ /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: 22, color: palette.text }, children: tab === "profile" ? "Profile details" : "Security" }),
658
669
  /* @__PURE__ */ jsx(
659
670
  "button",
660
671
  {
@@ -665,10 +676,10 @@ function UserButton() {
665
676
  }
666
677
  )
667
678
  ] }),
668
- /* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop: "1px solid #e5e7eb", margin: "16px 0 20px" } }),
679
+ /* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: "16px 0 20px" } }),
669
680
  tab === "profile" && /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 20 }, children: [
670
681
  /* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
671
- /* @__PURE__ */ jsx("div", { style: { color: "#374151", fontSize: 14 }, children: "Profile" }),
682
+ /* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Profile" }),
672
683
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
673
684
  /* @__PURE__ */ jsx("div", { style: avatarLargeStyle, children: initials }),
674
685
  /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: profileName })
@@ -676,25 +687,25 @@ function UserButton() {
676
687
  /* @__PURE__ */ jsx("button", { type: "button", style: linkButtonStyle, children: "Update profile" })
677
688
  ] }),
678
689
  /* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
679
- /* @__PURE__ */ jsx("div", { style: { color: "#374151", fontSize: 14 }, children: "Email addresses" }),
690
+ /* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Email addresses" }),
680
691
  /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: profileEmail }),
681
692
  /* @__PURE__ */ jsx("span", { style: { color: "#6b7280", fontSize: 14 }, children: "Primary" })
682
693
  ] }),
683
694
  /* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
684
- /* @__PURE__ */ jsx("div", { style: { color: "#374151", fontSize: 14 }, children: "Connected accounts" }),
695
+ /* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Connected accounts" }),
685
696
  /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: "Google / Microsoft" }),
686
697
  /* @__PURE__ */ jsx("button", { type: "button", style: linkButtonStyle, children: "Connect account" })
687
698
  ] })
688
699
  ] }),
689
700
  tab === "security" && /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 20 }, children: [
690
701
  /* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
691
- /* @__PURE__ */ jsx("div", { style: { color: "#374151", fontSize: 14 }, children: "Password" }),
702
+ /* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Password" }),
692
703
  /* @__PURE__ */ jsx("div", {}),
693
704
  /* @__PURE__ */ jsx("button", { type: "button", style: linkButtonStyle, children: "Set password" })
694
705
  ] }),
695
706
  /* @__PURE__ */ jsxs("div", { style: { ...profileRowStyle, alignItems: "start" }, children: [
696
- /* @__PURE__ */ jsx("div", { style: { color: "#374151", fontSize: 14 }, children: "Active devices" }),
697
- /* @__PURE__ */ jsx("div", { style: { fontSize: 14, color: "#374151", maxWidth: 430 }, children: userAgent }),
707
+ /* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Active devices" }),
708
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 14, color: "#c5c7ca", maxWidth: 430 }, children: userAgent }),
698
709
  /* @__PURE__ */ jsx("span", { style: { color: "#6b7280", fontSize: 14 }, children: "This device" })
699
710
  ] }),
700
711
  /* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
@@ -748,25 +759,28 @@ var menuItemButtonStyle = {
748
759
  background: "transparent",
749
760
  cursor: "pointer"
750
761
  };
751
- var inputStyle = {
762
+ var inputStyle = (palette) => ({
752
763
  width: "100%",
753
764
  padding: 11,
754
765
  borderRadius: 9,
755
- border: "1px solid #d1d5db",
766
+ border: `1px solid ${palette.border}`,
767
+ background: palette.surface,
768
+ color: palette.text,
756
769
  fontSize: 13
757
- };
758
- var fieldLabelStyle = {
770
+ });
771
+ var fieldLabelStyle = (palette) => ({
759
772
  display: "grid",
760
773
  gap: 6,
761
774
  fontSize: 14,
762
- color: "#111827",
775
+ color: palette.text,
763
776
  fontWeight: 600
764
- };
765
- var socialButtonStyle = {
766
- border: "1px solid #d1d5db",
777
+ });
778
+ var socialButtonStyle = (palette) => ({
779
+ border: `1px solid ${palette.border}`,
767
780
  borderRadius: 9,
768
781
  padding: "10px 12px",
769
- background: "#ffffff",
782
+ background: palette.surface,
783
+ color: palette.text,
770
784
  cursor: "pointer",
771
785
  fontSize: 16,
772
786
  fontWeight: 300,
@@ -774,7 +788,7 @@ var socialButtonStyle = {
774
788
  alignItems: "center",
775
789
  justifyContent: "center",
776
790
  gap: 8
777
- };
791
+ });
778
792
  function GoogleIcon() {
779
793
  return /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", height: "20", viewBox: "0 0 20 20", width: "20", "aria-hidden": "true", children: [
780
794
  /* @__PURE__ */ jsx("path", { d: "M19.9905 10.1871C19.9905 9.36773 19.9224 8.7698 19.7752 8.14972H10.1992V11.848H15.8201C15.7068 12.7671 15.0948 14.1512 13.7349 15.0813L13.7159 15.2051L16.7436 17.497L16.9534 17.5174C18.8798 15.779 19.9905 13.2211 19.9905 10.1871Z", fill: "#4285F4" }),
@@ -802,6 +816,50 @@ function resolveBackendBaseUrl(backendUrl) {
802
816
  const candidate = backendUrl?.trim() || DEFAULT_BACKEND_URL;
803
817
  return candidate.replace(/\/+$/, "");
804
818
  }
819
+ function getThemePalette(theme) {
820
+ if (theme === "dark") {
821
+ return {
822
+ surface: "#445364",
823
+ surfaceAlt: "#1f2937",
824
+ border: "#374151",
825
+ text: "#f9fafb",
826
+ textMuted: "#9ca3af"
827
+ };
828
+ }
829
+ return {
830
+ surface: "#ffffff",
831
+ surfaceAlt: "#fafafa",
832
+ border: "#e5e7eb",
833
+ text: "#111827",
834
+ textMuted: "#6b7280"
835
+ };
836
+ }
837
+ function useResolvedTheme(theme) {
838
+ const [resolvedTheme, setResolvedTheme] = useState(() => {
839
+ if (theme === "light" || theme === "dark") {
840
+ return theme;
841
+ }
842
+ if (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
843
+ return "dark";
844
+ }
845
+ return "light";
846
+ });
847
+ useEffect(() => {
848
+ if (theme === "light" || theme === "dark") {
849
+ setResolvedTheme(theme);
850
+ return;
851
+ }
852
+ if (typeof window === "undefined") {
853
+ return;
854
+ }
855
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
856
+ const updateTheme = () => setResolvedTheme(mediaQuery.matches ? "dark" : "light");
857
+ updateTheme();
858
+ mediaQuery.addEventListener("change", updateTheme);
859
+ return () => mediaQuery.removeEventListener("change", updateTheme);
860
+ }, [theme]);
861
+ return resolvedTheme;
862
+ }
805
863
  function getBrandingCacheKey(apiToken) {
806
864
  return `cyberia_auth_branding:${apiToken}`;
807
865
  }
@@ -848,7 +906,7 @@ var tabButtonStyle = {
848
906
  };
849
907
  var profileRowStyle = {
850
908
  display: "grid",
851
- gridTemplateColumns: "220px 1fr auto",
909
+ gridTemplateColumns: "150px 1fr auto",
852
910
  alignItems: "center",
853
911
  gap: 12,
854
912
  paddingBottom: 12,
@@ -868,7 +926,7 @@ var avatarLargeStyle = {
868
926
  var linkButtonStyle = {
869
927
  border: "none",
870
928
  background: "transparent",
871
- color: "#6d28d9",
929
+ color: "#d92828",
872
930
  cursor: "pointer",
873
931
  fontSize: 14
874
932
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyberia-auth/auth",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Cyberia Auth React components and provider",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",