diff --git a/.changeset/themeable-auth-ui.md b/.changeset/themeable-auth-ui.md new file mode 100644 index 0000000..ab3111c --- /dev/null +++ b/.changeset/themeable-auth-ui.md @@ -0,0 +1,11 @@ +--- +'@seamless-auth/react': minor +--- + +feat(styles): make the built-in auth UI themeable with CSS custom properties + +Every colour in the bundled screens now reads from a `--seamless-*` custom property with the previous +literal as its fallback, so consumers can match the auth UI to their brand by setting variables on +`:root` or on any ancestor of ``. + +This is opt-in and non-breaking. Applications that set nothing render exactly as before. diff --git a/README.md b/README.md index 9f69ce3..d5a510b 100644 --- a/README.md +++ b/README.md @@ -849,6 +849,69 @@ Two paths are unchanged because they are owned by contracts outside this package - `/oauth/callback` is registered with OAuth providers as an allowed redirect URI, so renaming it would break configured integrations. +## Theming The Built-In UI + +Every colour in the built-in screens is a CSS custom property with a fallback, so the default look is +unchanged if you set nothing. To match your brand, set the tokens you care about on `:root`, or on any +element that wraps ``. + +```css +:root { + --seamless-accent: #1f3a34; + --seamless-accent-hover: #16302b; + --seamless-surface: #f7f5f0; + --seamless-text: #1a1a1a; +} +``` + +Scoping to a wrapper also works, which is useful when the auth screens should look different from the +rest of the app: + +```css +.auth-shell { + --seamless-accent: #1f3a34; + --seamless-accent-soft: #3c6f63; +} +``` + +There is no provider prop or JavaScript API for this. Setting the variables is the whole interface. + +### Tokens + +| Token | Used for | Default | +| ---------------------------- | ---------------------------------------------------------------------- | --------------------------------------------- | +| `--seamless-accent` | Primary buttons, focus rings, selected states, accent borders, spinner | `#2563eb` fills, `#3b82f6` rings and borders | +| `--seamless-accent-hover` | Hover state of primary buttons | `#1d4ed8` | +| `--seamless-accent-contrast` | Label text on accent-filled buttons | `white` | +| `--seamless-accent-soft` | Links, toggle buttons, accent icons | `#60a5fa`, `#a5b4fc` on the magic-link screen | +| `--seamless-surface` | Card and modal backgrounds | `#1f2937` | +| `--seamless-surface-raised` | Inputs and panels sitting on a card | `#374151`, `#4b5563` on the login form | +| `--seamless-surface-hover` | Hover state of secondary buttons | `#4b5563` | +| `--seamless-border` | Input, button, and panel borders | `#4b5563`, `#d1d5db` | +| `--seamless-text` | Headings and body text | `white` | +| `--seamless-text-muted` | Labels, helper text, secondary copy | `#9ca3af`, `#d1d5db` | +| `--seamless-disabled` | Background of disabled submit buttons | `#9ca3af` | +| `--seamless-danger` | Error messages | `#f87171` | +| `--seamless-success` | Success messages and the verified check icon | `#34d399` | +| `--seamless-warning` | OTP countdown and resend timers | `#facc15` | +| `--seamless-overlay` | Modal backdrop scrim | `rgba(0, 0, 0, 0.45)` | +| `--seamless-shadow` | Card and modal shadow colour | `rgba(0, 0, 0, 0.1)` to `rgba(0, 0, 0, 0.4)` | + +### Notes + +- Where the original design used near-duplicate shades for the same role, each declaration keeps its + own original value as the fallback. That is why some rows list more than one default. Nothing shifts + until you set the token, and once you do, every use of that role picks up your value. +- `--seamless-shadow` is the shadow colour only. Offsets and blur are fixed. Setting it applies one + colour to every shadow in the built-in UI, replacing the per-screen alpha values. +- If you set `--seamless-surface` to a light colour, set `--seamless-text` too. The default text + colour is white and will disappear otherwise. +- Two decorative tints are deliberately not tokenised: the pulse ring behind the magic-link mail icon + and the disc behind the success check. Both are translucent and sit directly under an icon, so an + opaque override would hide the icon it is meant to frame. +- The package ships one palette and no `prefers-color-scheme` rules. If you want the auth UI to follow + the system theme, wrap your own overrides in a media query. + ## Backend Expectations This package assumes a Seamless Auth-compatible backend with the auth adapter mounted at `/auth`. diff --git a/src/styles/deviceNameModal.module.css b/src/styles/deviceNameModal.module.css index f397f49..f2dfefe 100644 --- a/src/styles/deviceNameModal.module.css +++ b/src/styles/deviceNameModal.module.css @@ -1,7 +1,7 @@ .overlay { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.45); + background: var(--seamless-overlay, rgba(0, 0, 0, 0.45)); display: flex; align-items: center; justify-content: center; @@ -9,18 +9,18 @@ } .modal { - background: #1f2937; - color: #fff; + background: var(--seamless-surface, #1f2937); + color: var(--seamless-text, #fff); padding: 24px; border-radius: 12px; width: 100%; max-width: 420px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15); + box-shadow: 0 20px 40px var(--seamless-shadow, rgba(0, 0, 0, 0.15)); } .description { font-size: 14px; - color: #fff; + color: var(--seamless-text, #fff); margin-bottom: 16px; } @@ -28,7 +28,7 @@ width: 100%; padding: 10px 12px; border-radius: 8px; - border: 1px solid #ddd; + border: 1px solid var(--seamless-border, #ddd); margin-bottom: 20px; font-size: 14px; } @@ -40,8 +40,8 @@ } .primary { - background: #2563eb; - color: white; + background: var(--seamless-accent, #2563eb); + color: var(--seamless-accent-contrast, white); border: none; padding: 8px 14px; border-radius: 8px; @@ -50,7 +50,7 @@ .secondary { background: transparent; - border: 1px solid #ccc; + border: 1px solid var(--seamless-border, #ccc); padding: 8px 14px; border-radius: 8px; cursor: pointer; diff --git a/src/styles/login.module.css b/src/styles/login.module.css index 930c9fd..2bdcd6d 100644 --- a/src/styles/login.module.css +++ b/src/styles/login.module.css @@ -2,14 +2,14 @@ display: flex; align-items: center; justify-content: center; - color: white; + color: var(--seamless-text, white); } .card { - background-color: #1f2937; + background-color: var(--seamless-surface, #1f2937); padding: 2rem; border-radius: 0.5rem; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 6px var(--seamless-shadow, rgba(0, 0, 0, 0.1)); width: 100%; max-width: 28rem; } @@ -19,11 +19,11 @@ font-weight: bold; margin-bottom: 1.5rem; text-align: center; - color: white; + color: var(--seamless-text, white); } .message { - color: #68d391; + color: var(--seamless-success, #68d391); text-align: center; } @@ -33,38 +33,38 @@ .label { display: block; - color: #d1d5db; + color: var(--seamless-text-muted, #d1d5db); } .input { width: 100%; padding: 0.5rem; - background-color: #4b5563; - border: 1px solid #d1d5db; + background-color: var(--seamless-surface-raised, #4b5563); + border: 1px solid var(--seamless-border, #d1d5db); border-radius: 0.375rem; margin-top: 0.25rem; } .input:focus { outline: none; - box-shadow: 0 0 0 2px #3b82f6; + box-shadow: 0 0 0 2px var(--seamless-accent, #3b82f6); } .helperText { font-size: 0.75rem; - color: #9ca3af; + color: var(--seamless-text-muted, #9ca3af); margin-top: 0.5rem; } .error { - color: #f87171; + color: var(--seamless-danger, #f87171); font-size: 0.875rem; } .button { width: 100%; - background-color: #2563eb; - color: white; + background-color: var(--seamless-accent, #2563eb); + color: var(--seamless-accent-contrast, white); padding: 0.5rem; border-radius: 0.375rem; transition: background-color 0.3s; @@ -73,11 +73,11 @@ } .button:hover { - background-color: #1d4ed8; + background-color: var(--seamless-accent-hover, #1d4ed8); } .button:disabled { - background-color: #9ca3af; + background-color: var(--seamless-disabled, #9ca3af); cursor: not-allowed; } @@ -85,7 +85,7 @@ margin-top: 1.5rem; width: 100%; font-size: 0.875rem; - color: #60a5fa; + color: var(--seamless-accent-soft, #60a5fa); text-align: center; background: none; border: none; @@ -107,16 +107,16 @@ width: 100%; padding: 0.5rem; border-radius: 0.375rem; - background-color: #4b5563; - border: 1px solid #d1d5db; + background-color: var(--seamless-surface-raised, #4b5563); + border: 1px solid var(--seamless-border, #d1d5db); } .phoneInput { width: 100%; padding: 0.5rem; border-radius: 0.375rem; - background-color: #4b5563; - border: 1px solid #d1d5db; + background-color: var(--seamless-surface-raised, #4b5563); + border: 1px solid var(--seamless-border, #d1d5db); } @media (max-width: 500px) { @@ -131,8 +131,8 @@ margin-top: 18px; padding: 18px; border-radius: 12px; - background: rgba(255, 255, 255, 0.04); - border: 1px solid rgba(255, 255, 255, 0.08); + background: var(--seamless-surface-raised, rgba(255, 255, 255, 0.04)); + border: 1px solid var(--seamless-border, rgba(255, 255, 255, 0.08)); display: flex; flex-direction: column; gap: 14px; @@ -141,12 +141,12 @@ .fallbackHeader { font-size: 0.95rem; font-weight: 600; - color: #f3f4f6; + color: var(--seamless-text, #f3f4f6); } .fallbackDescription { font-size: 0.85rem; - color: #9ca3af; + color: var(--seamless-text-muted, #9ca3af); line-height: 1.4; } @@ -164,27 +164,27 @@ padding: 12px 14px; border-radius: 8px; - background: rgba(0, 0, 0, 0.25); - border: 1px solid rgba(255, 255, 255, 0.08); + background: var(--seamless-surface, rgba(0, 0, 0, 0.25)); + border: 1px solid var(--seamless-border, rgba(255, 255, 255, 0.08)); cursor: pointer; transition: all 0.15s ease; } .fallbackActionButton:hover { - background: rgba(255, 255, 255, 0.06); - border-color: rgba(255, 255, 255, 0.15); + background: var(--seamless-surface-hover, rgba(255, 255, 255, 0.06)); + border-color: var(--seamless-border, rgba(255, 255, 255, 0.15)); } .actionTitle { font-size: 0.9rem; font-weight: 500; - color: #f9fafb; + color: var(--seamless-text, #f9fafb); } .actionSubtext { font-size: 0.75rem; - color: #9ca3af; + color: var(--seamless-text-muted, #9ca3af); margin-top: 2px; } @@ -192,7 +192,7 @@ margin-top: 6px; background: none; border: none; - color: #60a5fa; + color: var(--seamless-accent-soft, #60a5fa); font-size: 0.8rem; cursor: pointer; } diff --git a/src/styles/magiclink.module.css b/src/styles/magiclink.module.css index 98c62da..16fd8f6 100644 --- a/src/styles/magiclink.module.css +++ b/src/styles/magiclink.module.css @@ -2,14 +2,14 @@ display: flex; align-items: center; justify-content: center; - color: white; + color: var(--seamless-text, white); } .card { - background-color: #1f2937; + background-color: var(--seamless-surface, #1f2937); padding: 2.5rem 2rem; border-radius: 0.75rem; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.25); + box-shadow: 0 10px 25px var(--seamless-shadow, rgba(0, 0, 0, 0.25)); width: 100%; max-width: 420px; text-align: center; @@ -27,7 +27,7 @@ .mailIcon { width: 38px; height: 38px; - color: #a5b4fc; + color: var(--seamless-accent-soft, #a5b4fc); z-index: 2; } @@ -63,7 +63,7 @@ } .message { - color: #d1d5db; + color: var(--seamless-text-muted, #d1d5db); font-size: 0.95rem; margin-bottom: 1rem; line-height: 1.4; @@ -72,7 +72,7 @@ .identifier { font-weight: 600; font-size: 1rem; - background: rgba(255, 255, 255, 0.05); + background: var(--seamless-surface-raised, rgba(255, 255, 255, 0.05)); padding: 0.45rem 0.6rem; border-radius: 6px; margin-bottom: 1rem; @@ -80,7 +80,7 @@ } .helperText { - color: #9ca3af; + color: var(--seamless-text-muted, #9ca3af); font-size: 0.85rem; margin-bottom: 0.6rem; line-height: 1.4; @@ -98,15 +98,15 @@ .secondaryButton { padding: 0.65rem; border-radius: 8px; - border: 1px solid #374151; - background: #111827; - color: white; + border: 1px solid var(--seamless-border, #374151); + background: var(--seamless-surface, #111827); + color: var(--seamless-text, white); cursor: pointer; font-weight: 500; } .secondaryButton:hover:not(:disabled) { - background: #1f2937; + background: var(--seamless-surface-hover, #1f2937); } .secondaryButton:disabled { @@ -116,14 +116,14 @@ .cooldown { font-size: 0.8rem; - color: #9ca3af; + color: var(--seamless-text-muted, #9ca3af); } .linkButton { margin-top: 0.4rem; background: none; border: none; - color: #a5b4fc; + color: var(--seamless-accent-soft, #a5b4fc); font-size: 0.85rem; cursor: pointer; } diff --git a/src/styles/mfaLogin.module.css b/src/styles/mfaLogin.module.css index 49e6d47..b16014c 100644 --- a/src/styles/mfaLogin.module.css +++ b/src/styles/mfaLogin.module.css @@ -1,5 +1,5 @@ .container { - color: white; + color: var(--seamless-text, white); display: flex; align-items: center; justify-content: center; @@ -7,9 +7,9 @@ } .card { - background-color: #1f2937; + background-color: var(--seamless-surface, #1f2937); border-radius: 1rem; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); + box-shadow: 0 4px 20px var(--seamless-shadow, rgba(0, 0, 0, 0.4)); padding: 1.5rem; width: 100%; max-width: 400px; @@ -22,11 +22,11 @@ font-size: 1.5rem; font-weight: 600; text-align: center; - color: white; + color: var(--seamless-text, white); } .msg { - color: #4ade80; + color: var(--seamless-success, #4ade80); text-align: center; } @@ -39,21 +39,21 @@ .button { padding: 0.75rem 1rem; border-radius: 0.5rem; - border: 1px solid #4b5563; - background-color: #374151; + border: 1px solid var(--seamless-border, #4b5563); + background-color: var(--seamless-surface-raised, #374151); transition: background-color 0.2s; - color: white; + color: var(--seamless-text, white); font-weight: 500; text-align: left; } .button:hover { - background-color: #4b5563; + background-color: var(--seamless-surface-hover, #4b5563); } .selected { - background-color: #2563eb; - border-color: #3b82f6; + background-color: var(--seamless-accent, #2563eb); + border-color: var(--seamless-accent, #3b82f6); } .codeLabel { @@ -64,7 +64,7 @@ } .countdown { - color: #facc15; + color: var(--seamless-warning, #facc15); font-size: 0.875rem; } @@ -72,9 +72,9 @@ width: 100%; padding: 0.75rem 1rem; border-radius: 0.5rem; - background-color: #374151; - border: 1px solid #4b5563; - color: white; + background-color: var(--seamless-surface-raised, #374151); + border: 1px solid var(--seamless-border, #4b5563); + color: var(--seamless-text, white); font-family: monospace; font-size: 1.25rem; letter-spacing: 0.2em; @@ -82,28 +82,28 @@ .input:focus { outline: none; - border-color: #3b82f6; - box-shadow: 0 0 0 2px #3b82f6; + border-color: var(--seamless-accent, #3b82f6); + box-shadow: 0 0 0 2px var(--seamless-accent, #3b82f6); } .submit { padding: 0.75rem 1rem; border-radius: 0.5rem; - background-color: #2563eb; - border: 1px solid #3b82f6; - color: white; + background-color: var(--seamless-accent, #2563eb); + border: 1px solid var(--seamless-accent, #3b82f6); + color: var(--seamless-accent-contrast, white); font-weight: 500; cursor: pointer; transition: background-color 0.2s; } .submit:disabled { - background-color: #9ca3af; + background-color: var(--seamless-disabled, #9ca3af); cursor: not-allowed; } .error { - color: #f87171; + color: var(--seamless-danger, #f87171); text-align: center; margin-bottom: 0.5rem; } diff --git a/src/styles/otpInput.module.css b/src/styles/otpInput.module.css index 5d29dbe..5c3b294 100644 --- a/src/styles/otpInput.module.css +++ b/src/styles/otpInput.module.css @@ -11,9 +11,9 @@ text-align: center; font-size: 1.2rem; border-radius: 8px; - border: 1px solid #4b5563; - background: #374151; - color: white; + border: 1px solid var(--seamless-border, #4b5563); + background: var(--seamless-surface-raised, #374151); + color: var(--seamless-text, white); transition: border-color 0.15s ease, box-shadow 0.15s ease; @@ -21,6 +21,6 @@ .otpInput:focus { outline: none; - border-color: #60a5fa; - box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.25); + border-color: var(--seamless-accent, #60a5fa); + box-shadow: 0 0 0 2px var(--seamless-accent, rgba(96, 165, 250, 0.25)); } diff --git a/src/styles/passKeyLogin.module.css b/src/styles/passKeyLogin.module.css index 6382b5a..dac1350 100644 --- a/src/styles/passKeyLogin.module.css +++ b/src/styles/passKeyLogin.module.css @@ -1,5 +1,5 @@ .container { - color: white; + color: var(--seamless-text, white); display: flex; align-items: center; justify-content: center; @@ -7,9 +7,9 @@ } .card { - background-color: #1f2937; + background-color: var(--seamless-surface, #1f2937); border-radius: 1rem; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); + box-shadow: 0 4px 20px var(--seamless-shadow, rgba(0, 0, 0, 0.4)); padding: 2rem; width: 100%; max-width: 400px; @@ -22,24 +22,24 @@ font-size: 1.5rem; font-weight: 600; text-align: center; - color: white; + color: var(--seamless-text, white); } .button { width: 100%; padding: 0.75rem 1rem; border-radius: 0.5rem; - background-color: #2563eb; - color: white; + background-color: var(--seamless-accent, #2563eb); + color: var(--seamless-accent-contrast, white); font-weight: 500; text-align: center; cursor: pointer; transition: background-color 0.2s ease; - border: 1px solid #3b82f6; + border: 1px solid var(--seamless-accent, #3b82f6); } .button:hover { - background-color: #1d4ed8; + background-color: var(--seamless-accent-hover, #1d4ed8); } @media (max-width: 480px) { diff --git a/src/styles/registerPasskey.module.css b/src/styles/registerPasskey.module.css index 869ce80..9108d74 100644 --- a/src/styles/registerPasskey.module.css +++ b/src/styles/registerPasskey.module.css @@ -1,5 +1,5 @@ .container { - color: white; + color: var(--seamless-text, white); display: flex; align-items: center; justify-content: center; @@ -7,9 +7,9 @@ } .card { - background-color: #1f2937; + background-color: var(--seamless-surface, #1f2937); border-radius: 1rem; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); + box-shadow: 0 4px 20px var(--seamless-shadow, rgba(0, 0, 0, 0.4)); padding: 1.5rem; width: 100%; max-width: 400px; @@ -21,17 +21,17 @@ justify-content: center; gap: 0.75rem; padding: 1.5rem; - background-color: #f9fafb; - color: #374151; + background-color: var(--seamless-surface, #f9fafb); + color: var(--seamless-text, #374151); border-radius: 0.75rem; font-weight: 500; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 8px var(--seamless-shadow, rgba(0, 0, 0, 0.1)); } .spinner { animation: spin 1s linear infinite; - border-top: 2px solid #3b82f6; - border-bottom: 2px solid #3b82f6; + border-top: 2px solid var(--seamless-accent, #3b82f6); + border-bottom: 2px solid var(--seamless-accent, #3b82f6); border-left: 2px solid transparent; border-right: 2px solid transparent; border-radius: 9999px; @@ -46,11 +46,11 @@ } .supported { - background-color: #ecfdf5; - color: #065f46; + background-color: var(--seamless-surface, #ecfdf5); + color: var(--seamless-text, #065f46); padding: 1.25rem; border-radius: 0.75rem; - box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 12px var(--seamless-shadow, rgba(0, 0, 0, 0.1)); } .title { @@ -66,8 +66,8 @@ .button { width: 100%; padding: 0.75rem 1rem; - background-color: #059669; - color: white; + background-color: var(--seamless-accent, #059669); + color: var(--seamless-accent-contrast, white); border: none; border-radius: 0.5rem; font-weight: 500; @@ -76,7 +76,7 @@ } .button:hover { - background-color: #047857; + background-color: var(--seamless-accent-hover, #047857); } .message { @@ -85,18 +85,18 @@ } .success { - color: #6ee7b7; + color: var(--seamless-success, #6ee7b7); } .error { - color: #f87171; + color: var(--seamless-danger, #f87171); } .skip { margin-top: 1.5rem; width: 100%; font-size: 0.875rem; - color: #60a5fa; + color: var(--seamless-accent-soft, #60a5fa); text-align: center; background: none; border: none; diff --git a/src/styles/termsModal.module.css b/src/styles/termsModal.module.css index 1c651e0..e44be17 100644 --- a/src/styles/termsModal.module.css +++ b/src/styles/termsModal.module.css @@ -2,22 +2,22 @@ position: fixed; inset: 0; z-index: 999; - background-color: rgba(0, 0, 0, 0.7); + background-color: var(--seamless-overlay, rgba(0, 0, 0, 0.7)); display: flex; justify-content: center; align-items: center; } .modal { - background-color: #1a1a1a; - color: white; + background-color: var(--seamless-surface, #1a1a1a); + color: var(--seamless-text, white); padding: 24px; border-radius: 8px; width: 100%; max-width: 640px; max-height: 80vh; overflow-y: auto; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.4); + box-shadow: 0 10px 25px var(--seamless-shadow, rgba(0, 0, 0, 0.4)); outline: none; } @@ -30,30 +30,30 @@ .title { font-size: 1.25rem; - color: #60a5fa; + color: var(--seamless-accent-soft, #60a5fa); font-weight: bold; } .closeBtn { background: none; border: none; - color: #ccc; + color: var(--seamless-text-muted, #ccc); font-size: 1.75rem; cursor: pointer; } .closeBtn:hover { - color: white; + color: var(--seamless-text, white); } .content { font-size: 0.9rem; line-height: 1.6; - color: #d1d5db; + color: var(--seamless-text-muted, #d1d5db); } .link { - color: #60a5fa; + color: var(--seamless-accent-soft, #60a5fa); text-decoration: underline; } diff --git a/src/styles/verifyMagiclink.module.css b/src/styles/verifyMagiclink.module.css index b97a7b4..0d700e6 100644 --- a/src/styles/verifyMagiclink.module.css +++ b/src/styles/verifyMagiclink.module.css @@ -1,5 +1,5 @@ .container { - color: white; + color: var(--seamless-text, white); display: flex; align-items: center; justify-content: center; @@ -7,12 +7,12 @@ } .card { - background-color: #1f2937; + background-color: var(--seamless-surface, #1f2937); width: 100%; max-width: 28rem; padding: 1.5rem; border-radius: 0.5rem; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 10px var(--seamless-shadow, rgba(0, 0, 0, 0.3)); } .title { @@ -20,7 +20,7 @@ font-weight: bold; text-align: center; margin-bottom: 1rem; - color: white; + color: var(--seamless-text, white); } .verificationContent { @@ -35,8 +35,8 @@ width: 28px; height: 28px; border-radius: 50%; - border: 3px solid rgba(255, 255, 255, 0.15); - border-top-color: #60a5fa; + border: 3px solid var(--seamless-border, rgba(255, 255, 255, 0.15)); + border-top-color: var(--seamless-accent, #60a5fa); animation: spin 0.9s linear infinite; } @@ -53,12 +53,12 @@ .checkIcon { width: 22px; height: 22px; - color: #34d399; + color: var(--seamless-success, #34d399); animation: checkPop 0.25s ease-out; } .successText { - color: #34d399; + color: var(--seamless-success, #34d399); font-size: 0.9rem; } diff --git a/src/styles/verifyOTP.module.css b/src/styles/verifyOTP.module.css index 0e1bf18..bb4b77e 100644 --- a/src/styles/verifyOTP.module.css +++ b/src/styles/verifyOTP.module.css @@ -1,5 +1,5 @@ .container { - color: white; + color: var(--seamless-text, white); display: flex; align-items: center; justify-content: center; @@ -7,12 +7,12 @@ } .card { - background-color: #1f2937; + background-color: var(--seamless-surface, #1f2937); width: 100%; max-width: 28rem; padding: 1.5rem; border-radius: 0.5rem; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 10px var(--seamless-shadow, rgba(0, 0, 0, 0.3)); } .title { @@ -20,24 +20,24 @@ font-weight: bold; text-align: center; margin-bottom: 1rem; - color: white; + color: var(--seamless-text, white); } .subtitle { - color: #9ca3af; + color: var(--seamless-text-muted, #9ca3af); font-size: 0.875rem; text-align: center; margin-bottom: 1.5rem; } .error { - color: #f87171; + color: var(--seamless-danger, #f87171); text-align: center; margin-bottom: 1rem; } .success { - color: #34d399; + color: var(--seamless-success, #34d399); text-align: center; margin-bottom: 0.75rem; } @@ -52,11 +52,11 @@ display: block; font-size: 0.875rem; margin-bottom: 0.25rem; - color: #d1d5db; + color: var(--seamless-text-muted, #d1d5db); } .timer { - color: #facc15; + color: var(--seamless-warning, #facc15); font-size: 0.875rem; } @@ -64,20 +64,20 @@ width: 100%; padding: 0.5rem; border-radius: 0.375rem; - background-color: #374151; - border: 1px solid #4b5563; - color: white; + background-color: var(--seamless-surface-raised, #374151); + border: 1px solid var(--seamless-border, #4b5563); + color: var(--seamless-text, white); outline: none; } .input:focus { - box-shadow: 0 0 0 2px #3b82f6; + box-shadow: 0 0 0 2px var(--seamless-accent, #3b82f6); } .resend { margin-top: 0.25rem; font-size: 0.75rem; - color: #60a5fa; + color: var(--seamless-accent-soft, #60a5fa); background: none; border: none; cursor: pointer; @@ -85,13 +85,13 @@ } .resend:hover { - color: #3b82f6; + color: var(--seamless-accent, #3b82f6); } .button { width: 100%; - background-color: #2563eb; - color: white; + background-color: var(--seamless-accent, #2563eb); + color: var(--seamless-accent-contrast, white); padding: 0.5rem; border-radius: 0.375rem; transition: background-color 0.2s; @@ -100,14 +100,14 @@ } .button:hover { - background-color: #1d4ed8; + background-color: var(--seamless-accent-hover, #1d4ed8); } .toggle { margin-top: 1.5rem; width: 100%; font-size: 0.875rem; - color: #60a5fa; + color: var(--seamless-accent-soft, #60a5fa); text-align: center; background: none; border: none;