mirror of
https://github.com/PR0M3TH3AN/bitlogin.git
synced 2026-11-02 19:41:22 +00:00
Redesign demo site around a "one login, every site" pitch
The old landing page led with generic Nostr-signer framing and a templated violet/pink gradient look. Reframe the pitch around the thing that's actually differentiated: one login name and password that works on every BitLogin site, explicitly positioned against NIP-07 extensions and NIP-46 bunkers, with Nostr terminology kept light for the non-technical end users who'll actually be typing a password rather than integrating a widget. Visual redesign: warm parchment/brass accent alongside the existing violet, Fraunces display serif paired with the existing system-ui body font, and a new "one credential, many doors" hero illustration with a staggered stamp-in animation (prefers-reduced-motion aware) replacing the generic feature-grid-only layout. Applied consistently across index.html, docs.html, and account.html.
This commit is contained in:
1 parent
ce6ade73b4
commit
207f4cba10
5 files changed
+453
-111
No files matched your search
@@ -7,12 +7,24 @@
|
||||
<meta name="description" content="Create, sign in to, recover, and manage a BitLogin account — including password rotation and identity export." />
|
||||
<link rel="icon" href="./assets/icon.svg" type="image/svg+xml" />
|
||||
<link rel="manifest" href="./manifest.webmanifest" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,500;0,9..144,600;1,9..144,500&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="./assets/site.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="nav">
|
||||
<a class="brand" href="./index.html"><span class="dot"></span>BitLogin</a>
|
||||
<a class="brand" href="./index.html">
|
||||
<span class="dot">
|
||||
<svg viewBox="0 0 64 64" aria-hidden="true">
|
||||
<circle cx="32" cy="32" r="30" fill="none" stroke="#d1a85a" stroke-width="4" />
|
||||
<circle cx="32" cy="32" r="20" fill="#8368ff" />
|
||||
<path d="M22 32.5l7 7 13-14.5" fill="none" stroke="#fff" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
</span>
|
||||
BitLogin
|
||||
</a>
|
||||
<div class="links">
|
||||
<a href="./index.html">Overview</a>
|
||||
<a href="./docs.html">Integrate</a>
|
||||
@@ -22,13 +34,14 @@
|
||||
|
||||
<div class="app-layout">
|
||||
<div class="side">
|
||||
<span class="eyebrow">Live demo</span>
|
||||
<h1>Try a real account</h1>
|
||||
<p>
|
||||
This page embeds the exact <code><bitlogin-auth></code> element any static site would use — nothing
|
||||
special is happening behind the scenes.
|
||||
</p>
|
||||
<p>
|
||||
Create an account to see a generated passphrase and a 12-word recovery phrase, sign a test Nostr event,
|
||||
Create an account to see a generated passphrase and a 12-word recovery phrase, sign a test event,
|
||||
rotate your password (old capsule is tombstoned), and export a recovery file — or reload this page and
|
||||
sign back in from a "clean" browser state.
|
||||
</p>
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#8b5cf6"/>
|
||||
<stop offset="1" stop-color="#ec4899"/>
|
||||
<linearGradient id="ink" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#17141f" />
|
||||
<stop offset="1" stop-color="#0d0b12" />
|
||||
</linearGradient>
|
||||
<linearGradient id="seal" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#8368ff" />
|
||||
<stop offset="1" stop-color="#6a4de8" />
|
||||
</linearGradient>
|
||||
<linearGradient id="brass" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#e6c481" />
|
||||
<stop offset="1" stop-color="#b3924a" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="64" height="64" rx="16" fill="#0b0b12"/>
|
||||
<circle cx="32" cy="32" r="16" fill="url(#g)"/>
|
||||
<rect width="64" height="64" rx="15" fill="url(#ink)" />
|
||||
<circle cx="32" cy="32" r="21" fill="none" stroke="url(#brass)" stroke-width="2.5" />
|
||||
<circle cx="32" cy="32" r="14" fill="url(#seal)" />
|
||||
<path d="M27 32.5l3.6 3.6L38 28.2" fill="none" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 969 B |
@@ -1,104 +1,315 @@
|
||||
:root {
|
||||
--bg: #0b0b12;
|
||||
--bg-elevated: #141420;
|
||||
--fg: #f2f1f7;
|
||||
--muted: #9995ab;
|
||||
--border: #26243a;
|
||||
--accent: #8b5cf6;
|
||||
--accent2: #ec4899;
|
||||
--code-bg: #100f19;
|
||||
--ink: #0d0b12;
|
||||
--ink-soft: #17141f;
|
||||
--ink-softer: #201c2b;
|
||||
--paper: #f3ead9;
|
||||
--paper-dim: #e8dcc2;
|
||||
--seal: #8368ff;
|
||||
--seal-deep: #6a4de8;
|
||||
--brass: #d1a85a;
|
||||
--brass-soft: #9c824f;
|
||||
--fg: #f4f1ea;
|
||||
--muted: #a49cb0;
|
||||
--line: rgba(244, 241, 234, 0.11);
|
||||
--line-strong: rgba(244, 241, 234, 0.2);
|
||||
--code-bg: #100e17;
|
||||
--shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
|
||||
--font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
|
||||
--font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
--font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
color-scheme: dark;
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--bg: #fbfaff;
|
||||
--bg-elevated: #ffffff;
|
||||
--fg: #17151f;
|
||||
--muted: #6b6478;
|
||||
--border: #e7e4f2;
|
||||
--code-bg: #14121f;
|
||||
--ink: #f7f2e7;
|
||||
--ink-soft: #ffffff;
|
||||
--ink-softer: #efe8d8;
|
||||
--paper: #ffffff;
|
||||
--paper-dim: #efe8d8;
|
||||
--seal: #6a4de8;
|
||||
--seal-deep: #5638c9;
|
||||
--brass: #9c7a2e;
|
||||
--brass-soft: #b3924a;
|
||||
--fg: #211c2c;
|
||||
--muted: #675f75;
|
||||
--line: rgba(33, 28, 44, 0.12);
|
||||
--line-strong: rgba(33, 28, 44, 0.22);
|
||||
--code-bg: #211c2c;
|
||||
color-scheme: light;
|
||||
}
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
html, body { margin: 0; padding: 0; }
|
||||
body {
|
||||
background: var(--bg);
|
||||
background:
|
||||
radial-gradient(1100px 620px at 82% -10%, color-mix(in srgb, var(--seal) 16%, transparent), transparent 60%),
|
||||
radial-gradient(900px 500px at -10% 15%, color-mix(in srgb, var(--brass) 10%, transparent), transparent 55%),
|
||||
var(--ink);
|
||||
color: var(--fg);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
font-family: var(--font-body);
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: var(--accent); text-decoration: none; }
|
||||
a { color: var(--seal); text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--brass);
|
||||
outline-offset: 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* ---------- nav ---------- */
|
||||
.nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
max-width: 1080px;
|
||||
max-width: 1120px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 24px;
|
||||
padding: 22px 24px;
|
||||
}
|
||||
.nav .brand {
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
letter-spacing: -0.02em;
|
||||
font-family: var(--font-display);
|
||||
font-weight: 600;
|
||||
font-size: 19px;
|
||||
letter-spacing: -0.01em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 10px;
|
||||
color: var(--fg);
|
||||
}
|
||||
.nav .brand .dot {
|
||||
width: 10px; height: 10px; border-radius: 50%;
|
||||
background: linear-gradient(135deg, var(--accent), var(--accent2));
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.nav .links { display: flex; gap: 22px; font-size: 14px; }
|
||||
.nav .brand .dot svg { width: 100%; height: 100%; display: block; }
|
||||
.nav .links { display: flex; gap: 26px; font-size: 14px; }
|
||||
.nav .links a { color: var(--muted); }
|
||||
.nav .links a.active, .nav .links a:hover { color: var(--fg); }
|
||||
.nav .links a.active, .nav .links a:hover { color: var(--fg); text-decoration: none; }
|
||||
.nav .links a.active { position: relative; }
|
||||
.nav .links a.active::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0; right: 0; bottom: -8px;
|
||||
height: 2px;
|
||||
background: var(--brass);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.container { max-width: 1080px; margin: 0 auto; padding: 0 24px; }
|
||||
.container { max-width: 1120px; margin: 0 auto; padding: 0 24px; }
|
||||
.narrow { max-width: 760px; }
|
||||
|
||||
/* ---------- hero ---------- */
|
||||
.hero {
|
||||
padding: 72px 24px 40px;
|
||||
text-align: center;
|
||||
padding: 56px 24px 24px;
|
||||
}
|
||||
.hero-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.05fr) minmax(280px, 0.95fr);
|
||||
gap: 56px;
|
||||
align-items: center;
|
||||
max-width: 1120px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
.hero-grid { grid-template-columns: 1fr; gap: 40px; }
|
||||
}
|
||||
.eyebrow {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12.5px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--brass);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.eyebrow::before {
|
||||
content: "";
|
||||
width: 7px; height: 7px;
|
||||
border-radius: 50%;
|
||||
background: var(--brass);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--brass) 25%, transparent);
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: clamp(34px, 6vw, 56px);
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.03em;
|
||||
margin: 0 0 18px;
|
||||
background: linear-gradient(135deg, var(--fg) 30%, var(--accent) 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(38px, 5.4vw, 68px);
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.02;
|
||||
margin: 0 0 22px;
|
||||
color: var(--fg);
|
||||
}
|
||||
.hero h1 em {
|
||||
font-style: italic;
|
||||
color: var(--seal);
|
||||
}
|
||||
.hero p.lead {
|
||||
color: var(--muted);
|
||||
font-size: 18px;
|
||||
max-width: 620px;
|
||||
margin: 0 auto 30px;
|
||||
font-size: 17.5px;
|
||||
max-width: 480px;
|
||||
margin: 0 0 30px;
|
||||
}
|
||||
.cta-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
|
||||
.cta-row { display: flex; gap: 12px; flex-wrap: wrap; }
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 22px;
|
||||
border-radius: 10px;
|
||||
padding: 13px 24px;
|
||||
border-radius: 11px;
|
||||
font-weight: 600;
|
||||
font-size: 14.5px;
|
||||
border: 1px solid var(--border);
|
||||
border: 1px solid var(--line-strong);
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
|
||||
}
|
||||
.btn.primary {
|
||||
background: linear-gradient(135deg, var(--accent), var(--accent2));
|
||||
color: white;
|
||||
background: linear-gradient(160deg, var(--seal), var(--seal-deep));
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
box-shadow: 0 12px 28px color-mix(in srgb, var(--seal) 35%, transparent);
|
||||
}
|
||||
.btn.primary:hover { opacity: 0.92; text-decoration: none; }
|
||||
.btn.primary:hover { transform: translateY(-1px); text-decoration: none; }
|
||||
.btn.secondary { color: var(--fg); }
|
||||
.btn.secondary:hover { background: var(--bg-elevated); text-decoration: none; }
|
||||
.btn.secondary:hover { background: var(--ink-soft); text-decoration: none; transform: translateY(-1px); }
|
||||
|
||||
/* ---------- signature visual: one credential, many doors ---------- */
|
||||
.credential-scene {
|
||||
position: relative;
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
justify-items: stretch;
|
||||
}
|
||||
.credential-card {
|
||||
position: relative;
|
||||
background: linear-gradient(155deg, var(--paper), var(--paper-dim));
|
||||
color: #241d12;
|
||||
border-radius: 16px;
|
||||
padding: 20px 22px;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1px solid color-mix(in srgb, var(--brass) 40%, transparent);
|
||||
z-index: 2;
|
||||
}
|
||||
.credential-card .cc-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.credential-card .cc-seal {
|
||||
width: 30px; height: 30px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(155deg, var(--seal), var(--seal-deep));
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
box-shadow: inset 0 0 0 2px rgba(255,255,255,0.35);
|
||||
}
|
||||
.credential-card .cc-seal svg { width: 15px; height: 15px; }
|
||||
.credential-card .cc-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: #6b5a34; font-weight: 700; }
|
||||
.credential-card .cc-name { font-family: var(--font-display); font-size: 17px; font-weight: 600; }
|
||||
.credential-card .cc-id {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11.5px;
|
||||
color: #6b5a34;
|
||||
letter-spacing: 0.01em;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.door-rail {
|
||||
position: relative;
|
||||
background: var(--ink-soft);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 16px;
|
||||
padding: 8px;
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
.door-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 11px;
|
||||
}
|
||||
.door-row .door-icon {
|
||||
width: 30px; height: 30px;
|
||||
border-radius: 8px;
|
||||
background: var(--ink-softer);
|
||||
border: 1px solid var(--line);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
color: var(--muted);
|
||||
}
|
||||
.door-row .door-icon svg { width: 16px; height: 16px; }
|
||||
.door-row .door-label { font-size: 13.5px; color: var(--fg); font-weight: 550; flex: 1; }
|
||||
.door-row .door-stamp {
|
||||
width: 22px; height: 22px;
|
||||
border-radius: 50%;
|
||||
border: 1.5px solid var(--line-strong);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
animation: stamp-in 0.5s ease-out both;
|
||||
animation-delay: calc(var(--stamp-order, 0) * 0.32s + 0.5s);
|
||||
}
|
||||
.door-row .door-stamp svg { width: 12px; height: 12px; }
|
||||
@keyframes stamp-in {
|
||||
0% { transform: scale(1.7); border-color: var(--line-strong); color: transparent; background: transparent; }
|
||||
55% { transform: scale(0.92); }
|
||||
70% { border-color: var(--brass); background: color-mix(in srgb, var(--brass) 22%, transparent); color: var(--brass); }
|
||||
100% { transform: scale(1); border-color: var(--brass); background: color-mix(in srgb, var(--brass) 22%, transparent); color: var(--brass); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.door-row .door-stamp {
|
||||
animation: none;
|
||||
border-color: var(--brass);
|
||||
background: color-mix(in srgb, var(--brass) 22%, transparent);
|
||||
color: var(--brass);
|
||||
}
|
||||
}
|
||||
.credential-scene .scene-caption {
|
||||
text-align: center;
|
||||
font-size: 12.5px;
|
||||
color: var(--muted);
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
/* ---------- compare section ---------- */
|
||||
.compare-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
margin: 36px 0 8px;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.compare-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
.compare-card {
|
||||
background: var(--ink-soft);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 16px;
|
||||
padding: 22px;
|
||||
}
|
||||
.compare-card h3 { margin: 0 0 4px; font-size: 15.5px; font-family: var(--font-display); font-weight: 600; }
|
||||
.compare-card .compare-kicker { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); margin-bottom: 6px; display: block; }
|
||||
.compare-card p { margin: 0; color: var(--muted); font-size: 13.5px; }
|
||||
.compare-card.is-bitlogin {
|
||||
background: linear-gradient(165deg, color-mix(in srgb, var(--seal) 16%, var(--ink-soft)), var(--ink-soft));
|
||||
border-color: color-mix(in srgb, var(--brass) 55%, var(--line));
|
||||
box-shadow: 0 18px 40px color-mix(in srgb, var(--seal) 18%, transparent);
|
||||
transform: translateY(-6px);
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.compare-card.is-bitlogin { transform: none; }
|
||||
}
|
||||
.compare-card.is-bitlogin .compare-kicker { color: var(--brass); }
|
||||
.compare-card.is-bitlogin p { color: var(--fg); opacity: 0.85; }
|
||||
|
||||
/* ---------- diagram (kept for docs/account pages) ---------- */
|
||||
.diagram {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -109,16 +320,17 @@ a:hover { text-decoration: underline; }
|
||||
font-size: 13.5px;
|
||||
}
|
||||
.diagram .step {
|
||||
background: var(--bg-elevated);
|
||||
border: 1px solid var(--border);
|
||||
background: var(--ink-soft);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
min-width: 140px;
|
||||
text-align: center;
|
||||
}
|
||||
.diagram .step .k { color: var(--muted); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 4px; }
|
||||
.diagram .arrow { color: var(--muted); font-size: 18px; }
|
||||
.diagram .arrow { color: var(--brass); font-size: 18px; }
|
||||
|
||||
/* ---------- feature grid ---------- */
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
|
||||
@@ -126,32 +338,40 @@ a:hover { text-decoration: underline; }
|
||||
margin: 40px 0;
|
||||
}
|
||||
.feature {
|
||||
background: var(--bg-elevated);
|
||||
border: 1px solid var(--border);
|
||||
background: var(--ink-soft);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 14px;
|
||||
padding: 20px;
|
||||
transition: border-color 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
.feature h3 { margin: 0 0 8px; font-size: 15.5px; }
|
||||
.feature:hover { border-color: var(--line-strong); transform: translateY(-2px); }
|
||||
.feature h3 { margin: 0 0 8px; font-size: 15.5px; font-family: var(--font-display); font-weight: 600; }
|
||||
.feature p { margin: 0; color: var(--muted); font-size: 13.5px; }
|
||||
|
||||
section { padding: 20px 0 40px; }
|
||||
h2 { font-size: 26px; letter-spacing: -0.02em; margin: 0 0 6px; }
|
||||
p.section-sub { color: var(--muted); margin: 0 0 28px; }
|
||||
h2 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
p.section-sub { color: var(--muted); margin: 0 0 28px; max-width: 620px; }
|
||||
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
color: #e8e6f5;
|
||||
border: 1px solid var(--border);
|
||||
color: #ece8f5;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 18px;
|
||||
overflow-x: auto;
|
||||
font-size: 13px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
code { font-family: var(--font-mono); }
|
||||
:not(pre) > code {
|
||||
background: var(--bg-elevated);
|
||||
border: 1px solid var(--border);
|
||||
background: var(--ink-soft);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 5px;
|
||||
padding: 1px 5px;
|
||||
font-size: 0.92em;
|
||||
@@ -162,7 +382,7 @@ code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
counter-increment: step;
|
||||
position: relative;
|
||||
padding: 0 0 28px 44px;
|
||||
border-left: 2px solid var(--border);
|
||||
border-left: 2px solid var(--line);
|
||||
margin-left: 15px;
|
||||
}
|
||||
.step-list > li:last-child { border-left-color: transparent; padding-bottom: 0; }
|
||||
@@ -173,7 +393,7 @@ code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
top: 0;
|
||||
width: 28px; height: 28px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, var(--accent), var(--accent2));
|
||||
background: linear-gradient(155deg, var(--seal), var(--seal-deep));
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
@@ -181,11 +401,11 @@ code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.step-list h3 { margin: 2px 0 8px; font-size: 16px; }
|
||||
.step-list h3 { margin: 2px 0 8px; font-size: 16px; font-family: var(--font-display); font-weight: 600; }
|
||||
|
||||
.callout {
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg-elevated);
|
||||
border: 1px solid var(--line);
|
||||
background: var(--ink-soft);
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
font-size: 13.5px;
|
||||
@@ -198,20 +418,26 @@ code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 48px 24px 80px;
|
||||
gap: 40px;
|
||||
}
|
||||
.app-layout .side {
|
||||
max-width: 340px;
|
||||
margin-right: 40px;
|
||||
}
|
||||
.app-layout .side h1 { font-size: 26px; margin: 0 0 10px; }
|
||||
.app-layout .side h1 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 10px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.app-layout .side p { color: var(--muted); font-size: 14px; }
|
||||
@media (max-width: 820px) {
|
||||
.app-layout { flex-direction: column; align-items: center; }
|
||||
.app-layout .side { margin-right: 0; margin-bottom: 24px; text-align: center; }
|
||||
.app-layout { flex-direction: column; align-items: center; gap: 24px; }
|
||||
.app-layout .side { max-width: 460px; text-align: center; }
|
||||
}
|
||||
|
||||
footer {
|
||||
border-top: 1px solid var(--border);
|
||||
border-top: 1px solid var(--line);
|
||||
padding: 28px 24px;
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
|
||||
@@ -7,12 +7,24 @@
|
||||
<meta name="description" content="How to add the BitLogin login widget to any static site in a few minutes." />
|
||||
<link rel="icon" href="./assets/icon.svg" type="image/svg+xml" />
|
||||
<link rel="manifest" href="./manifest.webmanifest" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,500;0,9..144,600;1,9..144,500&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="./assets/site.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="nav">
|
||||
<a class="brand" href="./index.html"><span class="dot"></span>BitLogin</a>
|
||||
<a class="brand" href="./index.html">
|
||||
<span class="dot">
|
||||
<svg viewBox="0 0 64 64" aria-hidden="true">
|
||||
<circle cx="32" cy="32" r="30" fill="none" stroke="#d1a85a" stroke-width="4" />
|
||||
<circle cx="32" cy="32" r="20" fill="#8368ff" />
|
||||
<path d="M22 32.5l7 7 13-14.5" fill="none" stroke="#fff" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
</span>
|
||||
BitLogin
|
||||
</a>
|
||||
<div class="links">
|
||||
<a href="./index.html">Overview</a>
|
||||
<a class="active" href="./docs.html">Integrate</a>
|
||||
@@ -20,9 +32,10 @@
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header class="hero" style="padding-top:48px">
|
||||
<h1 style="font-size:38px">Add BitLogin to your site</h1>
|
||||
<p class="lead">No npm install required. Two files, one custom element.</p>
|
||||
<header class="hero" style="padding-top:48px; padding-bottom:8px">
|
||||
<span class="eyebrow">Integration guide</span>
|
||||
<h1 style="font-size:clamp(32px, 4.5vw, 44px)">Add BitLogin to your site</h1>
|
||||
<p class="lead" style="max-width:520px">No npm install required. Two files, one custom element — and every user who already has a BitLogin account elsewhere can sign in with the login they already know.</p>
|
||||
</header>
|
||||
|
||||
<section class="container narrow">
|
||||
|
||||
+107
-27
@@ -3,16 +3,28 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>BitLogin — a portable login for the open web</title>
|
||||
<meta name="description" content="A familiar login name and password that unlocks a portable Nostr identity, stored as encrypted capsules across public relays. No account server required." />
|
||||
<title>BitLogin — one login for every site that uses it</title>
|
||||
<meta name="description" content="A login name and password that work on every BitLogin site — no extension to install, no separate signer to keep running. Built on the open Nostr network, with no account server anyone can shut down." />
|
||||
<link rel="icon" href="./assets/icon.svg" type="image/svg+xml" />
|
||||
<link rel="manifest" href="./manifest.webmanifest" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,500;0,9..144,600;1,9..144,500&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="./assets/site.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="nav">
|
||||
<a class="brand" href="./index.html"><span class="dot"></span>BitLogin</a>
|
||||
<a class="brand" href="./index.html">
|
||||
<span class="dot">
|
||||
<svg viewBox="0 0 64 64" aria-hidden="true">
|
||||
<circle cx="32" cy="32" r="30" fill="none" stroke="#d1a85a" stroke-width="4" />
|
||||
<circle cx="32" cy="32" r="20" fill="#8368ff" />
|
||||
<path d="M22 32.5l7 7 13-14.5" fill="none" stroke="#fff" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
</span>
|
||||
BitLogin
|
||||
</a>
|
||||
<div class="links">
|
||||
<a class="active" href="./index.html">Overview</a>
|
||||
<a href="./docs.html">Integrate</a>
|
||||
@@ -21,58 +33,126 @@
|
||||
</nav>
|
||||
|
||||
<header class="hero">
|
||||
<h1>A login your users<br />actually take with them.</h1>
|
||||
<p class="lead">
|
||||
Login name and password on the outside. A portable Nostr identity underneath —
|
||||
encrypted and stored on public relays, with no account server, no password-reset
|
||||
email, and no vendor lock-in.
|
||||
</p>
|
||||
<div class="cta-row">
|
||||
<a class="btn primary" href="./account.html">Try the demo →</a>
|
||||
<a class="btn secondary" href="./docs.html">Add it to your site</a>
|
||||
<div class="hero-grid">
|
||||
<div>
|
||||
<span class="eyebrow">One login. Every BitLogin site.</span>
|
||||
<h1>One password.<br />Every door it <em>opens</em>.</h1>
|
||||
<p class="lead">
|
||||
Create a BitLogin account on any site that supports it, and the same login name
|
||||
and password sign you into every other one. No new account to make, no extension
|
||||
to install, no separate signer app to keep paired and running.
|
||||
</p>
|
||||
<div class="cta-row">
|
||||
<a class="btn primary" href="./account.html">Try the demo →</a>
|
||||
<a class="btn secondary" href="./docs.html">Add it to your site</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="credential-scene" aria-hidden="true">
|
||||
<div class="credential-card">
|
||||
<div class="cc-top">
|
||||
<span class="cc-seal">
|
||||
<svg viewBox="0 0 24 24" fill="none"><path d="M6 12.5l4 4 8-9" stroke="#fff" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</span>
|
||||
<div>
|
||||
<div class="cc-label">One credential</div>
|
||||
<div class="cc-name">river · a few good words</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cc-id">npub1a3x…f92e</div>
|
||||
</div>
|
||||
<div class="door-rail">
|
||||
<div class="door-row" style="--stamp-order:0">
|
||||
<span class="door-icon"><svg viewBox="0 0 24 24" fill="none"><path d="M4 9l8-5 8 5v10H4V9z" stroke="currentColor" stroke-width="1.6"/></svg></span>
|
||||
<span class="door-label">Marketplace</span>
|
||||
<span class="door-stamp"><svg viewBox="0 0 24 24" fill="none"><path d="M5 12l4 4 10-10" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||||
</div>
|
||||
<div class="door-row" style="--stamp-order:1">
|
||||
<span class="door-icon"><svg viewBox="0 0 24 24" fill="none"><path d="M4 5h16v10H8l-4 4V5z" stroke="currentColor" stroke-width="1.6"/></svg></span>
|
||||
<span class="door-label">Community forum</span>
|
||||
<span class="door-stamp"><svg viewBox="0 0 24 24" fill="none"><path d="M5 12l4 4 10-10" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||||
</div>
|
||||
<div class="door-row" style="--stamp-order:2">
|
||||
<span class="door-icon"><svg viewBox="0 0 24 24" fill="none"><rect x="4" y="4" width="16" height="16" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M4 9h16" stroke="currentColor" stroke-width="1.6"/></svg></span>
|
||||
<span class="door-label">Personal blog</span>
|
||||
<span class="door-stamp"><svg viewBox="0 0 24 24" fill="none"><path d="M5 12l4 4 10-10" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||||
</div>
|
||||
<div class="door-row" style="--stamp-order:3">
|
||||
<span class="door-icon"><svg viewBox="0 0 24 24" fill="none"><path d="M12 3l7 3v6c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6l7-3z" stroke="currentColor" stroke-width="1.6"/></svg></span>
|
||||
<span class="door-label">Your site, next</span>
|
||||
<span class="door-stamp"><svg viewBox="0 0 24 24" fill="none"><path d="M5 12l4 4 10-10" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scene-caption">Same login name and password. Every site that speaks BitLogin.</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="container">
|
||||
<h2>What actually happens at sign-in</h2>
|
||||
<p class="section-sub">No account database to breach, no password-reset email to intercept — just math, run locally, every time.</p>
|
||||
<div class="diagram">
|
||||
<div class="step"><div class="k">Everyday login</div>Login name + password</div>
|
||||
<div class="arrow">→</div>
|
||||
<div class="step"><div class="k">Locally derived</div>Password-locked locator key</div>
|
||||
<div class="arrow">→</div>
|
||||
<div class="step"><div class="k">Public relays</div>Encrypted capsule lookup</div>
|
||||
<div class="step"><div class="k">Public network</div>Encrypted capsule lookup</div>
|
||||
<div class="arrow">→</div>
|
||||
<div class="step"><div class="k">Result</div>Portable Nostr identity</div>
|
||||
<div class="step"><div class="k">Result</div>Your portable identity, unlocked</div>
|
||||
</div>
|
||||
</header>
|
||||
</section>
|
||||
|
||||
<section class="container">
|
||||
<h2>Two independent ways in, one identity</h2>
|
||||
<p class="section-sub">Forgetting a password and losing a device are different emergencies. BitLogin keeps them cryptographically separate.</p>
|
||||
<div class="grid">
|
||||
<div class="feature">
|
||||
<h3>🔑 Password path</h3>
|
||||
<p>Login name + password deterministically derive a private "locator" key and an encryption key. That key finds and decrypts a small credential capsule on public relays — no lookup table, no server, no email.</p>
|
||||
<h3>Password path</h3>
|
||||
<p>Login name + password deterministically derive a private "locator" key and an encryption key. That key finds and decrypts a small credential capsule — no lookup table, no server, no email.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>🌱 Recovery phrase</h3>
|
||||
<h3>Recovery phrase</h3>
|
||||
<p>A 12-word phrase derives a completely independent recovery identity. A cracked password can never sign, replace, or delete the recovery capsule — it has no authority over that path at all.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>🪪 One everyday identity</h3>
|
||||
<p>Both paths unlock the exact same everyday Nostr keypair — your real, canonical, portable identity. Change your password as often as you like; the identity never moves.</p>
|
||||
<h3>One everyday identity</h3>
|
||||
<p>Both paths unlock the exact same everyday keypair — your real, canonical, portable identity. Change your password as often as you like; the identity underneath never moves.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="container">
|
||||
<h2>Not a browser extension. Not a remote signer.</h2>
|
||||
<p class="section-sub">Both of those are good tools for the people already running them. BitLogin exists for everyone else.</p>
|
||||
<div class="compare-grid">
|
||||
<div class="compare-card">
|
||||
<span class="compare-kicker">A browser extension (NIP-07)</span>
|
||||
<h3>Lives in one browser</h3>
|
||||
<p>Sign in on your phone, at work, or in a private window, and you're locked out — the keys never left that one browser profile.</p>
|
||||
</div>
|
||||
<div class="compare-card">
|
||||
<span class="compare-kicker">A remote signer (NIP-46)</span>
|
||||
<h3>Needs another device online</h3>
|
||||
<p>Every sign-in bounces through a separate signing app or "bunker" that you have to keep running, paired, and reachable.</p>
|
||||
</div>
|
||||
<div class="compare-card is-bitlogin">
|
||||
<span class="compare-kicker">BitLogin</span>
|
||||
<h3>Just a login name and password</h3>
|
||||
<p>The two things you already remember. Nothing to install, nothing else to keep online, works the same on any device or browser.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="container">
|
||||
<h2>Why this is different</h2>
|
||||
<p class="section-sub">Every design choice traces back to one constraint: it has to work with nothing but static files and public relays.</p>
|
||||
<p class="section-sub">Every design choice traces back to one constraint: it has to work with nothing but static files and a public network.</p>
|
||||
<div class="grid">
|
||||
<div class="feature">
|
||||
<h3>Static-first</h3>
|
||||
<p>The whole client — crypto, UI, worker — ships as files. Host it anywhere: Pages, IPFS, a folder on a CDN. No backend to run or pay for.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>Relay-redundant storage</h3>
|
||||
<p>Encrypted capsules are published to multiple Nostr relays with quorum reads and readback verification, so no single relay is a single point of failure.</p>
|
||||
<h3>No single point of failure</h3>
|
||||
<p>Encrypted capsules are published to multiple independent relays with quorum reads and readback verification, so losing any one of them doesn't lock anyone out.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>Generated by default, never weak</h3>
|
||||
@@ -80,15 +160,15 @@
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>Argon2id + AES-256-GCM</h3>
|
||||
<p>Memory-hard key derivation, authenticated encryption, canonical JSON serialization, and fixed padding buckets so ciphertext size doesn't leak contents.</p>
|
||||
<p>Memory-hard key derivation, authenticated encryption, canonical serialization, and fixed padding buckets so ciphertext size doesn't leak contents.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>Rollback-resistant</h3>
|
||||
<p>A local generation high-water mark and monotonic timestamps mean a stale or malicious relay can't quietly roll a logged-in device back to an older capsule.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>NIP-07-compatible signing</h3>
|
||||
<p>Once unlocked, BitLogin exposes a <code>window.nostr</code> provider — the same shape browser extensions use. Existing Nostr apps work with zero code changes.</p>
|
||||
<h3>Works with existing Nostr apps</h3>
|
||||
<p>Once unlocked, BitLogin quietly plugs into the same <code>window.nostr</code> interface browser extensions use — apps built for those work with zero code changes.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -102,7 +182,7 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
BitLogin is an experimental alpha protocol. This demo is a reference implementation, not a production account service.
|
||||
BitLogin is an experimental alpha protocol, built on the open Nostr network. This demo is a reference implementation, not a production account service.
|
||||
<div class="footer-links"><a href="https://github.com/PR0M3TH3AN/bitlogin">Source on GitHub</a> · MIT licensed — <a href="https://github.com/PR0M3TH3AN/bitlogin/blob/main/LICENSE">LICENSE</a></div>
|
||||
</footer>
|
||||
|
||||
|
||||
Reference in new issue
Block a user