ui(auth): compact, scroll-safe sign-in dialog

- Fix the real bug: the dialog clipped its bottom links (flex column + max-h
  calc(100dvh-2rem), content min-h-0 flex-1 overflow-y-auto).
- One dominant action per state: 'New here' is a compact row, not a second hero.
- Plain card labels (Browser extension / Signer app / Sign in with your phone)
  with tiny NIP-07/46/55 hints; protocol jargon out of the main labels.
- Bunker: input + Connect with instructions collapsed under 'Where do I get a
  bunker?'; no duplicate heading/divider.
- Secret key moved to a quiet bottom link; subtitle says 'or keep browsing'.
- 8px spacing grid (px-5 gutters, space-y-4 sections, gap-2 cards, p-2.5 cards,
  448px max width). New strings backfilled into all 20 locales.
Verified with headless 1280x900 + 390x844 screenshots.
This commit is contained in:
SkateSpots 2026-10-26 12:12:36 +07:00
parent f56a8b28e5
commit fe3d9bae22
24 changed files with 237 additions and 71 deletions

View file

@ -1533,8 +1533,20 @@ session with **no other memory of this project**. So:
**Sign in with your phone** (NostrConnect) — plus a quiet **Secret Key** link;
the cards are a **controlled tab chooser** (`loginTab` state) over the existing
panels, and the NostrConnect QR moved from the bunker tab into its own
`connect` panel. Verified with a headless 1280×900 screenshot of the
auto-opened welcome modal. ⚠️ `SignupDialog` is a **default-only** export, so
`connect` panel. **Compact pass (2026-10-26):** the dialog is now
scroll-safe (`flex flex-col` + `max-h-[calc(100dvh-2rem)]`, content
`min-h-0 flex-1 overflow-y-auto` — it used to clip the bottom links), the
New-here block is a compact row (one dominant action per state), bunker
instructions are a collapsed `<details>` ("Where do I get a bunker?"), and the
secret-key option is a quiet bottom link. Labels are plain ("Browser
extension · Signer app · Sign in with your phone") with **NIP-07/46/55** as
tiny hints (`settingsUi.loginDialog.{extensionCard,signerCard,secretKeyLink,
whereBunker,welcomeSubtitleBrowse}`; backfilled to all 20 locales). Spacing is
an **8px grid**: `px-5` (20px) gutters, `space-y-4` (16px) between sections,
`gap-2` (8px) between cards, `p-2.5` (10px) card padding, `pt-5/pb-3` header —
a 448px max width keeps 3 cards ≥~120px each while staying a single focused
column. Verified with headless 1280×900 and 390×844 screenshots.
⚠️ `SignupDialog` is a **default-only** export, so
lazy-load it as
`lazy(() => import('…/SignupDialog'))`.
- **Pass the app on — Android only (2026-10-26):** the About page renders

View file

@ -321,47 +321,51 @@ export const LoginDialog: React.FC<LoginDialogProps> = ({ isOpen, onClose, onLog
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className={cn("w-[calc(100%-1rem)] sm:max-w-md max-h-[90vh] max-h-[90dvh] p-0 overflow-hidden rounded-2xl bg-black border-2 border-[#ff0040]/50")}>
<DialogHeader className={cn('px-4 sm:px-6 pt-4 sm:pt-6 pb-1')}>
<DialogTitle className="text-center font-black uppercase tracking-wide text-xl">
<DialogContent className={cn("flex w-[calc(100%-1rem)] flex-col sm:max-w-md max-h-[calc(100dvh-2rem)] p-0 overflow-hidden rounded-2xl bg-black border-2 border-[#ff0040]/50")}>
<DialogHeader className={cn('px-5 pt-5 pb-3')}>
<DialogTitle className="text-center font-black uppercase tracking-wide text-lg">
{t('settingsUi.loginDialog.welcomeTitle')}
</DialogTitle>
<DialogDescription className="text-center text-sm text-gray-400">
{t('settingsUi.loginDialog.welcomeSubtitle')}
<DialogDescription className="text-center text-xs text-gray-400">
{t('settingsUi.loginDialog.welcomeSubtitleBrowse')}
</DialogDescription>
</DialogHeader>
<div className='px-4 sm:px-6 pt-2 pb-6 space-y-4 overflow-y-auto'>
{/* Sign Up */}
<div className='relative p-5 rounded-2xl bg-black border-2 border-[#ccff00]/50 overflow-hidden'>
<div className="absolute inset-0 bg-[#ccff00]/5 blur-xl" />
<div className='relative z-10 text-center space-y-3'>
<div className='flex justify-center items-center gap-2'>
<Sparkles className='w-5 h-5 text-[#ccff00]' />
<span className='font-bold text-[#ccff00] uppercase tracking-wide'>{t('settingsUi.loginDialog.newHere')}</span>
</div>
<p className='text-xs text-gray-300'>{t('settingsUi.loginDialog.createFree')}</p>
<Button onClick={() => { onClose(); onSignup?.(); }} className='w-full rounded-full py-3 font-bold bg-[#ccff00] text-black hover:bg-[#ccff00]/90 uppercase'>
<UserPlus className='w-4 h-4 mr-2' />{t('settingsUi.loginDialog.createAccount')}
</Button>
<div className='min-h-0 flex-1 overflow-y-auto px-5 pb-5 pt-1 space-y-4'>
{/* Sign up — a compact row, not a second hero: the dialog should have
ONE dominant action per state, and logging in is the main path. */}
<div className='flex items-center gap-3 rounded-xl border border-[#ccff00]/40 bg-[#ccff00]/5 p-3'>
<div className='flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[#ccff00]/15'>
<Sparkles className='h-4 w-4 text-[#ccff00]' />
</div>
<div className='min-w-0 flex-1'>
<p className='text-sm font-bold text-[#ccff00]'>{t('settingsUi.loginDialog.newHere')}</p>
<p className='text-[11px] leading-snug text-gray-400'>{t('settingsUi.loginDialog.createFree')}</p>
</div>
<Button
size='sm'
onClick={() => { onClose(); onSignup?.(); }}
className='h-9 shrink-0 gap-1.5 bg-[#ccff00] px-3 text-xs font-bold text-black hover:bg-[#ccff00]/90'
>
<UserPlus className='h-3.5 w-3.5' />{t('settingsUi.loginDialog.createAccount')}
</Button>
</div>
<div className='relative flex items-center'>
<div className='flex-1 border-t border-gray-800' />
<span className='px-3 text-xs text-gray-500'>{t('settingsUi.loginDialog.orLogIn')}</span>
<span className='px-3 text-[11px] text-gray-500'>{t('settingsUi.loginDialog.orLogIn')}</span>
<div className='flex-1 border-t border-gray-800' />
</div>
<Tabs value={loginTab} onValueChange={(v) => setLoginTab(v as typeof loginTab)} className="w-full">
{/* Method cards — a clear three-way choice (the old 4-tab strip was
jargon-heavy). The secret-key option stays as a quiet link. */}
{/* Method cards — plain-language labels; protocol names move to a
tiny hint so newcomers aren't met with "NIP-46" as the main word. */}
<div className="mb-3 grid grid-cols-3 gap-2">
{([
{ id: 'extension', Icon: Shield, label: t('settingsUi.loginDialog.browserExtensionTitle') },
{ id: isAndroid ? 'amber' : 'bunker', Icon: isAndroid ? Smartphone : Cloud, label: isAndroid ? t('settingsUi.loginDialog.loginWithAmber') : t('settingsUi.loginDialog.bunkerTitle') },
{ id: 'connect', Icon: QrCode, label: t('settingsUi.loginDialog.signInWithPhone') },
] as const).map(({ id, Icon, label }) => {
{ id: 'extension', Icon: Shield, label: t('settingsUi.loginDialog.extensionCard'), hint: 'NIP-07' },
{ id: isAndroid ? 'amber' : 'bunker', Icon: isAndroid ? Smartphone : Cloud, label: t('settingsUi.loginDialog.signerCard'), hint: isAndroid ? 'NIP-55' : 'NIP-46' },
{ id: 'connect', Icon: QrCode, label: t('settingsUi.loginDialog.signInWithPhone'), hint: 'NIP-46' },
] as const).map(({ id, Icon, label, hint }) => {
const active = loginTab === id;
return (
<button
@ -369,7 +373,7 @@ export const LoginDialog: React.FC<LoginDialogProps> = ({ isOpen, onClose, onLog
type="button"
onClick={() => setLoginTab(id)}
className={cn(
'flex min-h-0 flex-col items-center gap-1.5 rounded-xl border p-3 text-center transition-colors',
'flex min-h-0 flex-col items-center gap-1 rounded-xl border p-2.5 text-center transition-colors',
active
? 'border-[#ccff00]/60 bg-[#ccff00]/10 text-[#ccff00]'
: 'border-white/10 bg-black/40 text-gray-300 hover:border-white/25 hover:text-white',
@ -377,22 +381,11 @@ export const LoginDialog: React.FC<LoginDialogProps> = ({ isOpen, onClose, onLog
>
<Icon className="h-5 w-5" />
<span className="text-[11px] font-bold leading-tight">{label}</span>
<span className="text-[9px] uppercase tracking-widest text-gray-500">{hint}</span>
</button>
);
})}
</div>
<div className="mb-3 text-center">
<button
type="button"
onClick={() => setLoginTab('nsec')}
className={cn(
'text-[11px] underline underline-offset-2',
loginTab === 'nsec' ? 'text-yellow-300' : 'text-gray-500 hover:text-gray-300',
)}
>
{t('settingsUi.loginDialog.secretKeyTitle')}
</button>
</div>
{/* ── AMBER TAB ── */}
<TabsContent value='amber' className='space-y-3'>
@ -576,35 +569,32 @@ export const LoginDialog: React.FC<LoginDialogProps> = ({ isOpen, onClose, onLog
</div>
</TabsContent>
{/* ── BUNKER TAB ── */}
{/* ── SIGNER (BUNKER) TAB ── */}
<TabsContent value='bunker' className='space-y-3'>
<div className='relative flex items-center'>
<div className='flex-1 border-t border-gray-800' />
<span className='px-3 text-xs text-gray-500'>{t('settingsUi.loginDialog.orPasteBunker')}</span>
<div className='flex-1 border-t border-gray-800' />
</div>
<div className='p-5 rounded-xl bg-black/50 border-2 border-blue-500/30 space-y-4'>
<div className='text-center'>
<Cloud className='w-10 h-10 mx-auto mb-2 text-blue-400' />
<p className='text-sm text-white font-bold'>{t('settingsUi.loginDialog.bunkerTitle')}</p>
<p className='text-xs text-gray-400 mt-1'>{t('settingsUi.loginDialog.bunkerPasteBefore')} <code className='text-blue-300'>bunker://</code> {t('settingsUi.loginDialog.bunkerPasteAfter')}</p>
<div className='space-y-3 rounded-xl border border-blue-500/30 bg-black/50 p-4'>
<div className='flex items-center gap-2'>
<Cloud className='h-4 w-4 text-blue-400' />
<p className='text-sm font-bold text-white'>{t('settingsUi.loginDialog.signerCard')}</p>
</div>
<div className='text-xs text-gray-300 bg-black/40 rounded-lg p-3 space-y-1 border border-gray-800'>
<p><strong className='text-blue-300'>Amber:</strong> {t('settingsUi.loginDialog.amberInstructions')}</p>
<p><strong className='text-blue-300'>nsec.app:</strong> {t('settingsUi.loginDialog.nsecAppInstructions')}</p>
</div>
<div className='space-y-2'>
<Input placeholder='bunker://...' value={bunkerUri} onChange={e => { setBunkerUri(e.target.value); setBunkerError(''); }} className='bg-black/60 border-blue-500/30 text-white placeholder:text-gray-600 text-xs font-mono' autoComplete='off' autoCorrect='off' spellCheck={false} />
{bunkerError && <p className="text-xs text-red-400">{bunkerError}</p>}
</div>
<Button className='w-full rounded-full py-3 bg-blue-500 hover:bg-blue-600 text-white font-bold uppercase' disabled={isLoading || !bunkerUri.trim()} onClick={handleBunkerLogin}>
<Input placeholder='bunker://...' value={bunkerUri} onChange={e => { setBunkerUri(e.target.value); setBunkerError(''); }} className='bg-black/60 border-blue-500/30 text-white placeholder:text-gray-600 text-xs font-mono' autoComplete='off' autoCorrect='off' spellCheck={false} />
{bunkerError && <p className="text-xs text-red-400">{bunkerError}</p>}
<Button className='w-full rounded-full py-2.5 bg-blue-500 hover:bg-blue-600 text-white font-bold uppercase' disabled={isLoading || !bunkerUri.trim()} onClick={handleBunkerLogin}>
{isLoading ? <Loader2 className='w-4 h-4 animate-spin mr-2' /> : <Cloud className='w-4 h-4 mr-2' />}{t('settingsUi.loginDialog.connect')}
</Button>
<div className='flex gap-2 justify-center'>
<a href="https://nsec.app" target="_blank" rel="noopener noreferrer" className="text-xs px-3 py-1 bg-blue-500/20 text-blue-400 rounded-full hover:bg-blue-500/30">nsec.app →</a>
<a href="https://nostrum.social" target="_blank" rel="noopener noreferrer" className="text-xs px-3 py-1 bg-blue-500/20 text-blue-400 rounded-full hover:bg-blue-500/30">Nostrum →</a>
</div>
{/* Instructions collapse: the default state is just input + Connect. */}
<details>
<summary className='cursor-pointer text-[11px] text-gray-500 hover:text-gray-300'>
{t('settingsUi.loginDialog.whereBunker')}
</summary>
<div className='mt-2 space-y-1 rounded-lg border border-gray-800 bg-black/40 p-3 text-[11px] text-gray-400'>
<p><strong className='text-blue-300'>Amber:</strong> {t('settingsUi.loginDialog.amberInstructions')}</p>
<p><strong className='text-blue-300'>nsec.app:</strong> {t('settingsUi.loginDialog.nsecAppInstructions')}</p>
<div className='flex gap-2 pt-1'>
<a href="https://nsec.app" target="_blank" rel="noopener noreferrer" className="rounded-full bg-blue-500/20 px-2.5 py-0.5 text-blue-400 hover:bg-blue-500/30">nsec.app →</a>
<a href="https://nostrum.social" target="_blank" rel="noopener noreferrer" className="rounded-full bg-blue-500/20 px-2.5 py-0.5 text-blue-400 hover:bg-blue-500/30">Nostrum →</a>
</div>
</div>
</details>
</div>
</TabsContent>
@ -691,18 +681,32 @@ export const LoginDialog: React.FC<LoginDialogProps> = ({ isOpen, onClose, onLog
{/* ── EXTENSION TAB ── */}
<TabsContent value='extension' className='space-y-3'>
<div className='text-center p-5 rounded-xl bg-black/50 border-2 border-[#ff0040]/30 space-y-4'>
<Shield className='w-10 h-10 mx-auto text-[#ff0040]' />
<div>
<p className='text-sm text-white font-bold'>{t('settingsUi.loginDialog.browserExtensionTitle')}</p>
<p className='text-xs text-gray-400 mt-1'>{t('settingsUi.loginDialog.browserExtensionDesc')}</p>
<div className='space-y-3 rounded-xl border border-[#ff0040]/30 bg-black/50 p-4'>
<div className='flex items-center gap-2'>
<Shield className='h-4 w-4 text-[#ff0040]' />
<p className='text-sm font-bold text-white'>{t('settingsUi.loginDialog.browserExtensionTitle')}</p>
</div>
<Button className='w-full rounded-full py-3 bg-[#ff0040] hover:bg-[#ff0040]/90 text-white font-bold uppercase' onClick={handleExtensionLogin}>
<p className='text-xs text-gray-400'>{t('settingsUi.loginDialog.browserExtensionDesc')}</p>
<Button className='w-full rounded-full py-2.5 bg-[#ff0040] hover:bg-[#ff0040]/90 text-white font-bold uppercase' onClick={handleExtensionLogin}>
{t('settingsUi.loginDialog.loginWithExtension')}
</Button>
</div>
</TabsContent>
</Tabs>
{/* Quiet fallback for advanced users; not a third hero action. */}
<div className='pt-1 text-center'>
<button
type="button"
onClick={() => setLoginTab('nsec')}
className={cn(
'text-[11px] underline underline-offset-2',
loginTab === 'nsec' ? 'text-yellow-300' : 'text-gray-500 hover:text-gray-300',
)}
>
{t('settingsUi.loginDialog.secretKeyLink')}
</button>
</div>
</div>
</DialogContent>
</Dialog>

View file

@ -93,6 +93,13 @@ const drift = {
}
},
"settingsUi": {
"loginDialog": {
"welcomeSubtitleBrowse": "Zaregistruj se nebo se přihlas — nebo si dál prohlížej.",
"extensionCard": "Rozšíření prohlížeče",
"signerCard": "Podepisovací aplikace",
"secretKeyLink": "Použít místo toho tajný klíč",
"whereBunker": "Kde získám bunker?",
},
"settingsPage": {
"trust": "Důvěra",
"trustSub": "Zdroje a zobrazení"

View file

@ -95,6 +95,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Registriere dich oder melde dich an – oder stöbere weiter.",
extensionCard: "Browser-Erweiterung",
signerCard: "Signer-App",
secretKeyLink: "Stattdessen einen geheimen Schlüssel verwenden",
whereBunker: "Wo bekomme ich einen Bunker?",
},
settingsPage: {
trust: "Vertrauen",
trustSub: "Quellen und Anzeige",

View file

@ -97,6 +97,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Εγγραφείτε ή συνδεθείτε — ή συνεχίστε την περιήγηση.",
extensionCard: "Επέκταση προγράμματος περιήγησης",
signerCard: "Εφαρμογή υπογραφής",
secretKeyLink: "Χρήση μυστικού κλειδιού",
whereBunker: "Πού βρίσκω bunker;",
},
settingsPage: {
trust: "Εμπιστοσύνη",
trustSub: "Πηγές και εμφάνιση",

View file

@ -4552,6 +4552,11 @@ settingsUi: {
loginWithAmber: 'Login with Amber (Android)',
welcomeTitle: 'Welcome to SkateSpots',
welcomeSubtitle: 'Sign up or log in to continue',
welcomeSubtitleBrowse: 'Sign up or log in — or keep browsing.',
extensionCard: 'Browser extension',
signerCard: 'Signer app',
secretKeyLink: 'Use a secret key instead',
whereBunker: 'Where do I get a bunker?',
newHere: 'New here?',
createFree: 'Create a free account. No email required.',
createAccount: 'Create Account',

View file

@ -4552,6 +4552,11 @@ settingsUi: {
loginWithAmber: 'Iniciar sesión con Amber (Android)',
welcomeTitle: 'Bienvenido a SkateSpots',
welcomeSubtitle: 'Regístrate o inicia sesión para continuar',
welcomeSubtitleBrowse: 'Regístrate o inicia sesión, o sigue explorando.',
extensionCard: 'Extensión del navegador',
signerCard: 'App firmante',
secretKeyLink: 'Usar una clave secreta',
whereBunker: '¿Dónde consigo un bunker?',
newHere: '¿Nuevo por aquí?',
createFree: 'Crea una cuenta gratis. Sin correo electrónico.',
createAccount: 'Crear cuenta',

View file

@ -95,6 +95,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Inscris-toi ou connecte-toi — ou continue à explorer.",
extensionCard: "Extension navigateur",
signerCard: "App signataire",
secretKeyLink: "Utiliser une clé secrète",
whereBunker: "Où trouver un bunker ?",
},
settingsPage: {
trust: "Confiance",
trustSub: "Sources et affichage",

View file

@ -89,6 +89,13 @@ const driftStrings = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Daftar atau masuk — atau tetap jelajahi.",
extensionCard: "Ekstensi peramban",
signerCard: "Aplikasi penandatangan",
secretKeyLink: "Gunakan kunci rahasia saja",
whereBunker: "Di mana saya mendapatkan bunker?",
},
settingsPage: {
trust: 'Kepercayaan',
trustSub: 'Sumber dan tampilan',

View file

@ -95,6 +95,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Registrati o accedi — oppure continua a esplorare.",
extensionCard: "Estensione del browser",
signerCard: "App firmataria",
secretKeyLink: "Usa invece una chiave segreta",
whereBunker: "Dove trovo un bunker?",
},
settingsPage: {
trust: "Fiducia",
trustSub: "Fonti e visualizzazione",

View file

@ -105,6 +105,13 @@ const drift: Dict = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "登録またはログイン — または閲覧を続ける。",
extensionCard: "ブラウザ拡張",
signerCard: "署名アプリ",
secretKeyLink: "代わりに秘密鍵を使う",
whereBunker: "バンカーはどこで入手?",
},
settingsPage: {
trust: '信頼',
trustSub: 'ソースと表示',

View file

@ -105,6 +105,13 @@ const drift: Dict = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "가입하거나 로그인하세요 — 또는 계속 둘러보세요.",
extensionCard: "브라우저 확장",
signerCard: "서명 앱",
secretKeyLink: "대신 비밀 키 사용",
whereBunker: "벙커는 어디서 구하나요?",
},
settingsPage: {
trust: '신뢰',
trustSub: '출처와 표시',

View file

@ -93,6 +93,13 @@ const drift = {
}
},
"settingsUi": {
"loginDialog": {
"welcomeSubtitleBrowse": "Meld je aan of log in — of blijf rondkijken.",
"extensionCard": "Browserextensie",
"signerCard": "Signeer-app",
"secretKeyLink": "Gebruik in plaats daarvan een geheime sleutel",
"whereBunker": "Waar vind ik een bunker?",
},
"settingsPage": {
"trust": "Vertrouwen",
"trustSub": "Bronnen en weergave"

View file

@ -93,6 +93,13 @@ const drift = {
}
},
"settingsUi": {
"loginDialog": {
"welcomeSubtitleBrowse": "Zarejestruj się lub zaloguj — albo przeglądaj dalej.",
"extensionCard": "Rozszerzenie przeglądarki",
"signerCard": "Aplikacja podpisująca",
"secretKeyLink": "Użyj zamiast tego klucza tajnego",
"whereBunker": "Gdzie znajdę bunkier?",
},
"settingsPage": {
"trust": "Zaufanie",
"trustSub": "Źródła i wyświetlanie"

View file

@ -95,6 +95,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Cadastre-se ou entre — ou continue explorando.",
extensionCard: "Extensão do navegador",
signerCard: "App assinador",
secretKeyLink: "Usar uma chave secreta",
whereBunker: "Onde consigo um bunker?",
},
settingsPage: {
trust: "Confiança",
trustSub: "Fontes e exibição",

View file

@ -93,6 +93,13 @@ const drift = {
}
},
"settingsUi": {
"loginDialog": {
"welcomeSubtitleBrowse": "Înregistrează-te sau autentifică-te — sau continuă să explorezi.",
"extensionCard": "Extensie de browser",
"signerCard": "Aplicație de semnare",
"secretKeyLink": "Folosește în schimb o cheie secretă",
"whereBunker": "De unde obțin un bunker?",
},
"settingsPage": {
"trust": "Încredere",
"trustSub": "Surse și afișare"

View file

@ -97,6 +97,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Зарегистрируйтесь или войдите — или продолжайте просмотр.",
extensionCard: "Расширение браузера",
signerCard: "Приложение-подписант",
secretKeyLink: "Использовать секретный ключ",
whereBunker: "Где взять бункер?",
},
settingsPage: {
trust: "Доверие",
trustSub: "Источники и отображение",

View file

@ -97,6 +97,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Registrera dig eller logga in — eller fortsätt bläddra.",
extensionCard: "Webbläsartillägg",
signerCard: "Signeringsapp",
secretKeyLink: "Använd en hemlig nyckel i stället",
whereBunker: "Var hittar jag en bunker?",
},
settingsPage: {
trust: "Förtroende",
trustSub: "Källor och visning",

View file

@ -89,6 +89,13 @@ const driftStrings = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "สมัครหรือเข้าสู่ระบบ — หรือสำรวจต่อ",
extensionCard: "ส่วนขยายเบราว์เซอร์",
signerCard: "แอปเซ็นชื่อ",
secretKeyLink: "ใช้คีย์ลับแทน",
whereBunker: "หา bunker ได้ที่ไหน?",
},
settingsPage: {
trust: 'ความน่าเชื่อถือ',
trustSub: 'แหล่งที่มาและการแสดงผล',

View file

@ -89,6 +89,13 @@ const driftStrings = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Kaydol veya giriş yap — ya da göz atmaya devam et.",
extensionCard: "Tarayıcı uzantısı",
signerCard: "İmzalayıcı uygulama",
secretKeyLink: "Bunun yerine gizli anahtar kullan",
whereBunker: "Bunker'ı nereden bulurum?",
},
settingsPage: {
trust: 'Güven',
trustSub: 'Kaynaklar ve görünüm',

View file

@ -97,6 +97,13 @@ const drift = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Зареєструйтеся або увійдіть — або продовжуйте перегляд.",
extensionCard: "Розширення браузера",
signerCard: "Застосунок-підписувач",
secretKeyLink: "Використати секретний ключ",
whereBunker: "Де взяти бункер?",
},
settingsPage: {
trust: "Довіра",
trustSub: "Джерела та відображення",

View file

@ -89,6 +89,13 @@ const driftStrings = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "Đăng ký hoặc đăng nhập — hoặc tiếp tục khám phá.",
extensionCard: "Tiện ích trình duyệt",
signerCard: "Ứng dụng ký",
secretKeyLink: "Dùng khóa bí mật thay thế",
whereBunker: "Tìm bunker ở đâu?",
},
settingsPage: {
trust: 'Tin cậy',
trustSub: 'Nguồn và hiển thị',

View file

@ -105,6 +105,13 @@ const drift: Dict = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "注册或登录 — 或继续浏览。",
extensionCard: "浏览器扩展",
signerCard: "签名应用",
secretKeyLink: "改用私钥",
whereBunker: "在哪里获取 bunker?",
},
settingsPage: {
trust: '信任',
trustSub: '来源与显示',

View file

@ -105,6 +105,13 @@ const drift: Dict = {
},
},
settingsUi: {
loginDialog: {
welcomeSubtitleBrowse: "註冊或登入 — 或繼續瀏覽。",
extensionCard: "瀏覽器擴充功能",
signerCard: "簽章應用程式",
secretKeyLink: "改用私密金鑰",
whereBunker: "在哪裡取得 bunker?",
},
settingsPage: {
trust: '信任',
trustSub: '來源與顯示',