this repo has no description
1<script lang="ts"> 2 import { _ } from '../lib/i18n' 3 import { getAuthState } from '../lib/auth.svelte' 4 const auth = getAuthState() 5</script> 6<div class="home"> 7 <header class="hero"> 8 <h1>Tranquil PDS</h1> 9 <p class="tagline">A Personal Data Server for the AT Protocol</p> 10 </header> 11 <section> 12 <h2>What is a PDS?</h2> 13 <p> 14 Bluesky runs on a federated protocol called AT Protocol. Your account lives on a PDS, 15 a server that stores your posts, profile, follows, and cryptographic keys. Bluesky hosts 16 one for you at bsky.social, but you can run your own. Self-hosting means you control your 17 data; you're not dependent on any company's servers, and your account + data is actually yours. 18 </p> 19 </section> 20 <section> 21 <h2>What's different about Tranquil?</h2> 22 <p> 23 This software isn't an afterthought by a company with limited resources. 24 It is a superset of the reference PDS, including: 25 </p> 26 <ul> 27 <li>Passkeys and 2FA (WebAuthn/FIDO2, TOTP, backup codes, trusted devices)</li> 28 <li>did:web support (PDS-hosted subdomains or bring-your-own)</li> 29 <li>Multi-channel notifications (email, discord, telegram, signal)</li> 30 <li>Granular OAuth scopes with a consent UI</li> 31 <li>Built-in web UI for account management, repo browsing, and admin</li> 32 </ul> 33 <p> 34 Full compatibility with Bluesky's reference PDS: same endpoints, same behavior, 35 same client compatibility. Everything works. 36 </p> 37 </section> 38 <div class="cta"> 39 {#if auth.session} 40 <a href="#/dashboard" class="btn">@{auth.session.handle}</a> 41 {:else} 42 <a href="#/login" class="btn">{$_('login.button')}</a> 43 <a href="#/register" class="btn secondary">{$_('login.createAccount')}</a> 44 {/if} 45 </div> 46 <footer> 47 <a href="https://tangled.org/lewis.moe/bspds-sandbox" target="_blank" rel="noopener">Source code</a> 48 </footer> 49</div> 50<style> 51 .home { 52 max-width: var(--width-md); 53 margin: 0 auto; 54 padding: var(--space-7); 55 } 56 57 .hero { 58 text-align: center; 59 margin-bottom: var(--space-8); 60 padding-top: var(--space-7); 61 } 62 63 .hero h1 { 64 font-size: var(--text-4xl); 65 margin-bottom: var(--space-3); 66 } 67 68 .tagline { 69 color: var(--text-secondary); 70 font-size: var(--text-xl); 71 } 72 73 section { 74 margin-bottom: var(--space-7); 75 } 76 77 h2 { 78 margin-bottom: var(--space-4); 79 } 80 81 p { 82 color: var(--text-secondary); 83 margin-bottom: var(--space-4); 84 } 85 86 ul { 87 color: var(--text-secondary); 88 margin: 0 0 var(--space-4) 0; 89 padding-left: var(--space-6); 90 line-height: var(--leading-relaxed); 91 } 92 93 li { 94 margin-bottom: var(--space-2); 95 } 96 97 .cta { 98 display: flex; 99 gap: var(--space-4); 100 justify-content: center; 101 margin: var(--space-8) 0; 102 } 103 104 .btn { 105 display: inline-block; 106 padding: var(--space-4) var(--space-7); 107 border-radius: var(--radius-md); 108 font-size: var(--text-base); 109 font-weight: var(--font-medium); 110 text-decoration: none; 111 transition: background var(--transition-normal), border-color var(--transition-normal); 112 background: var(--accent); 113 color: var(--text-inverse); 114 } 115 116 .btn:hover { 117 background: var(--accent-hover); 118 text-decoration: none; 119 } 120 121 .btn.secondary { 122 background: transparent; 123 color: var(--accent); 124 border: 1px solid var(--accent); 125 } 126 127 .btn.secondary:hover { 128 background: var(--accent); 129 color: var(--text-inverse); 130 } 131 132 footer { 133 text-align: center; 134 padding-top: var(--space-7); 135 border-top: 1px solid var(--border-color); 136 } 137 138 footer a { 139 color: var(--text-muted); 140 font-size: var(--text-sm); 141 } 142 143 footer a:hover { 144 color: var(--accent); 145 } 146</style>