diff --git a/README.md b/README.md new file mode 100644 index 0000000..a770569 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# bitblocks.network + +The umbrella site for the BitBlocks stack — composable Nostr + Bitcoin building +blocks for apps that can't lock anyone in. + +Static site, no build step. Deployed to the apex `bitblocks.network`. + +## The blocks + +| Block | Question | Site | +| --- | --- | --- | +| BitLogin | who are you | login.bitblocks.network | +| BitGate | what may you do | gate.bitblocks.network | +| BitFeed | what do you see | feed.bitblocks.network | +| BitUnlock | how you're paid | bitunlock.network | +| Tessera | what you can do | tessera.bitblocks.network | + +## Design + +Deliberately distinct from any single product: a monochrome, architectural +parent identity where the five product colours are the only chroma — the +Alphabet-to-Google relationship rendered in design. Monumental condensed +Ubuntu Sans display, Ubuntu Sans Mono for annotations, theme-aware. + +## Local + +```sh +python3 -m http.server 8080 # then open localhost:8080 +``` diff --git a/assets/bitblocks.css b/assets/bitblocks.css new file mode 100644 index 0000000..0b5b70b --- /dev/null +++ b/assets/bitblocks.css @@ -0,0 +1,208 @@ +/* BitBlocks — the foundation. A deliberately monochrome, architectural + identity for the parent: the colour belongs to the products (the five + blocks), not the holding brand. Think an architect's white table with + coloured blocks on it — Alphabet to the products' Google. + + Type: Ubuntu Sans on a condensed, heavy width axis carries the monumental + display voice (distinct from the products' regular-width sans); Ubuntu Sans + Mono is the technical annotation layer. */ + +@font-face { + font-family: 'Ubuntu Sans V'; + src: url('./fonts/UbuntuSans-var.woff2') format('woff2'); + font-weight: 100 800; font-stretch: 75% 125%; font-display: swap; +} +@font-face { + font-family: 'Ubuntu Sans Mono V'; + src: url('./fonts/UbuntuSansMono-var.woff2') format('woff2'); + font-weight: 100 800; font-display: swap; +} + +:root { + /* Architectural monochrome — cooler and flatter than any product palette. */ + --paper: #eef0f4; + --surface: #ffffff; + --ink: #0b0c0e; + --muted: #5b6270; + --line: #d3d6de; + --line-soft: #e4e6ec; + --ink-invert: #ffffff; + + /* The only chroma on the whole site: the five product blocks. */ + --c-login: #6c4df6; /* BitLogin — identity */ + --c-gate: #e0a12b; /* BitGate — policy */ + --c-feed: #23b3c6; /* BitFeed — feed */ + --c-unlock: #f7931a; /* BitUnlock — bitcoin */ + --c-tessera: #e2478d; /* Tessera — capability*/ + + --tile: 68px; + --edge: min(7vw, 96px); +} +@media (prefers-color-scheme: dark) { + :root:not([data-theme='light']) { + --paper: #0a0b0d; + --surface: #101217; + --ink: #f2f3f6; + --muted: #8b91a0; + --line: #23262d; + --line-soft: #191b21; + --ink-invert: #0a0b0d; + } +} +:root[data-theme='dark'] { + --paper: #0a0b0d; --surface: #101217; --ink: #f2f3f6; --muted: #8b91a0; + --line: #23262d; --line-soft: #191b21; --ink-invert: #0a0b0d; +} + +* { box-sizing: border-box; } +html { scroll-behavior: smooth; } +@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } * { animation: none !important; transition: none !important; } } +body { + margin: 0; background: var(--paper); color: var(--ink); + font-family: 'Ubuntu Sans V', system-ui, sans-serif; + font-size: 17px; line-height: 1.55; -webkit-font-smoothing: antialiased; + font-variation-settings: 'wdth' 100; +} +.mono { font-family: 'Ubuntu Sans Mono V', ui-monospace, 'SF Mono', Menlo, monospace; } +a { color: inherit; text-decoration: none; } + +/* Monumental condensed display — the parent's distinct voice. */ +.display { + font-variation-settings: 'wdth' 80; + font-weight: 800; letter-spacing: -0.02em; line-height: 0.9; text-wrap: balance; +} +.coord { + font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; + font-size: 11.5px; letter-spacing: 0.24em; text-transform: uppercase; color: var(--muted); +} + +.frame { max-width: 1280px; margin: 0 auto; padding: 0 var(--edge); } +/* Paint an explicit ground on every band so nothing relies on the body + showing through. */ +header.hero, section, footer { background: var(--paper); } +section { border-top: 1px solid var(--line); } + +/* ---------- top bar ---------- */ +.topbar { position: sticky; top: 0; z-index: 40; background: var(--paper); border-bottom: 1px solid var(--line); } +.topbar .frame { display: flex; align-items: center; gap: 24px; height: 66px; } +.wordmark { display: flex; align-items: center; gap: 12px; font-variation-settings: 'wdth' 82; font-weight: 800; font-size: 21px; letter-spacing: -0.02em; } +.logo-blocks { display: grid; grid-template-columns: repeat(2, 9px); grid-template-rows: repeat(2, 9px); gap: 2px; } +.logo-blocks i { display: block; width: 9px; height: 9px; } +.topbar nav { margin-left: auto; display: flex; gap: 26px; align-items: center; } +.topbar nav a { font-size: 14px; color: var(--muted); } +.topbar nav a:hover { color: var(--ink); } +.topbar nav a.cta { color: var(--ink); border: 1px solid var(--ink); padding: 7px 15px; } +.topbar nav a.cta:hover { background: var(--ink); color: var(--ink-invert); } +#theme { background: none; border: 1px solid var(--line); color: var(--muted); width: 32px; height: 32px; cursor: pointer; font-size: 14px; } +#theme:hover { border-color: var(--ink); color: var(--ink); } +@media (max-width: 720px) { .topbar nav a:not(.cta) { display: none; } } + +/* ---------- hero ---------- */ +.hero .frame { padding-top: clamp(56px, 9vw, 120px); padding-bottom: clamp(48px, 7vw, 96px); display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 56px; align-items: center; } +@media (max-width: 900px) { .hero .frame { grid-template-columns: 1fr; gap: 40px; } } +.hero .coord { margin-bottom: 26px; } +.hero h1 { margin: 0 0 24px; font-size: clamp(46px, 6.6vw, 92px); } +.hero h1 .own { position: relative; } +.hero h1 .own::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0.08em; height: 0.09em; background: linear-gradient(90deg, var(--c-login), var(--c-gate), var(--c-feed), var(--c-unlock), var(--c-tessera)); } +.hero p.lede { font-size: clamp(17px, 1.9vw, 20px); color: var(--muted); max-width: 46ch; margin: 0 0 30px; } +.hero .actions { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; } +.btn { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--ink); color: var(--ink); background: none; padding: 12px 22px; font: inherit; font-size: 15px; cursor: pointer; } +.btn:hover { background: var(--ink); color: var(--ink-invert); } +.btn.ghost { border-color: var(--line); color: var(--muted); } +.btn.ghost:hover { border-color: var(--ink); color: var(--ink); background: none; } + +/* the assembly — five coloured blocks locking into a foundation */ +.assembly { position: relative; } +.assembly .stack { display: flex; flex-direction: column; gap: 10px; } +.block-bar { + display: flex; align-items: center; gap: 18px; padding: 18px 22px; + background: var(--surface); border: 1px solid var(--line); position: relative; overflow: hidden; + transform: translateX(24px); opacity: 0; animation: bar-in 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) forwards; +} +.block-bar::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 5px; background: var(--bc); } +.block-bar:nth-child(1) { animation-delay: 0.15s; } +.block-bar:nth-child(2) { animation-delay: 0.30s; } +.block-bar:nth-child(3) { animation-delay: 0.45s; } +.block-bar:nth-child(4) { animation-delay: 0.60s; } +.block-bar:nth-child(5) { animation-delay: 0.75s; } +@keyframes bar-in { to { transform: translateX(0); opacity: 1; } } +@media (prefers-reduced-motion: reduce) { .block-bar { transform: none; opacity: 1; animation: none; } } +.block-bar .swatch { width: 16px; height: 16px; background: var(--bc); flex: none; } +.block-bar .bn { font-weight: 700; font-size: 16px; letter-spacing: -0.01em; } +.block-bar .bq { margin-left: auto; font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); } +.block-bar:hover { border-color: var(--bc); } +@media (max-width: 460px) { .block-bar .bq { display: none; } } + +/* ---------- thesis ---------- */ +.thesis .frame { padding: clamp(56px, 8vw, 104px) var(--edge); } +.thesis .lead { font-size: clamp(24px, 3.3vw, 40px); font-weight: 640; letter-spacing: -0.015em; line-height: 1.15; max-width: 20ch; margin: 0 0 22px; font-variation-settings: 'wdth' 92; } +.thesis .cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: 40px; margin-top: 40px; } +@media (max-width: 760px) { .thesis .cols { grid-template-columns: 1fr; } } +.thesis .cols p { color: var(--muted); margin: 0; max-width: 52ch; } +.thesis .cols .k { display: block; font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 11.5px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink); margin-bottom: 8px; } + +/* ---------- the blocks ---------- */ +.blocks .frame { padding: clamp(56px, 8vw, 100px) var(--edge); } +.section-head { display: flex; align-items: baseline; gap: 20px; margin-bottom: 48px; flex-wrap: wrap; } +.section-head h2 { margin: 0; font-size: clamp(30px, 4.4vw, 54px); font-variation-settings: 'wdth' 82; font-weight: 800; letter-spacing: -0.02em; line-height: 0.95; } +.section-head p { color: var(--muted); margin: 0; max-width: 40ch; } +.block-list { display: flex; flex-direction: column; border: 1px solid var(--line); } +.block-row { + display: grid; grid-template-columns: 200px 1fr auto; gap: 32px; align-items: center; + padding: 30px var(--tile-pad, 30px); border-bottom: 1px solid var(--line-soft); + position: relative; transition: background 0.2s; +} +.block-row:last-child { border-bottom: none; } +.block-row::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--bc); transform: scaleY(0.25); transform-origin: center; transition: transform 0.25s; } +.block-row:hover { background: color-mix(in srgb, var(--bc) 7%, transparent); } +.block-row:hover::before { transform: scaleY(1); } +.block-row .id { display: flex; align-items: center; gap: 14px; } +.block-row .id .sq { width: 22px; height: 22px; background: var(--bc); flex: none; } +.block-row .id .nm { font-size: 21px; font-weight: 720; letter-spacing: -0.015em; font-variation-settings: 'wdth' 90; } +.block-row .id .q { font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--bc); margin-top: 2px; } +.block-row .desc { color: var(--muted); font-size: 15.5px; max-width: 60ch; } +.block-row .desc b { color: var(--ink); font-weight: 600; } +.block-row .go { display: inline-flex; align-items: center; gap: 7px; font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 12px; color: var(--muted); white-space: nowrap; } +.block-row:hover .go { color: var(--bc); } +@media (max-width: 860px) { .block-row { grid-template-columns: 1fr; gap: 12px; padding: 26px 22px; } .block-row .go { justify-self: start; } } + +/* ---------- composition ---------- */ +.compose, section.compose { background: var(--surface); } +.compose .frame { padding: clamp(56px, 8vw, 100px) var(--edge); } +.flow { display: grid; grid-template-columns: repeat(5, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 12px; } +@media (max-width: 860px) { .flow { grid-template-columns: 1fr; } } +.flow .node { background: var(--surface); padding: 26px 22px; position: relative; } +.flow .node .q { font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px; } +.flow .node .sq { width: 20px; height: 20px; background: var(--bc); margin-bottom: 12px; } +.flow .node .nm { font-weight: 720; font-size: 18px; letter-spacing: -0.01em; } +.flow .node .role { color: var(--muted); font-size: 13px; margin-top: 3px; } +.compose .note { margin-top: 30px; color: var(--muted); max-width: 66ch; } +.compose .note b { color: var(--ink); font-weight: 600; } + +/* ---------- principles ---------- */ +.principles .frame { padding: clamp(56px, 8vw, 100px) var(--edge); } +.prin-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); } +@media (max-width: 860px) { .prin-grid { grid-template-columns: 1fr; } } +.prin { background: var(--paper); padding: 28px 26px; } +.prin .n { font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 12px; color: var(--muted); } +.prin h3 { margin: 14px 0 8px; font-size: 18.5px; font-weight: 680; letter-spacing: -0.01em; } +.prin p { margin: 0; color: var(--muted); font-size: 14.5px; } + +/* ---------- builders ---------- */ +.builders .frame { padding: clamp(56px, 8vw, 100px) var(--edge); display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; } +@media (max-width: 860px) { .builders .frame { grid-template-columns: 1fr; gap: 36px; } } +.builders h2 { margin: 0 0 18px; font-size: clamp(28px, 4vw, 48px); font-variation-settings: 'wdth' 82; font-weight: 800; letter-spacing: -0.02em; line-height: 0.98; } +.builders p { color: var(--muted); max-width: 50ch; margin: 0 0 22px; } +.builders .term { background: var(--ink); color: var(--ink-invert); border: 1px solid var(--ink); padding: 22px 24px; font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 13.5px; line-height: 1.9; } +.builders .term .c { opacity: 0.55; } +.builders .term .g { color: #7ee0b8; } + +/* ---------- footer ---------- */ +footer { border-top: 1px solid var(--line); } +footer .frame { padding: 46px var(--edge) 60px; display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; } +footer .fcol h4 { font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); margin: 0 0 12px; font-weight: 500; } +footer .fcol a { display: block; font-size: 14px; color: var(--muted); padding: 3px 0; } +footer .fcol a:hover { color: var(--ink); } +footer .sign { font-family: 'Ubuntu Sans Mono V', ui-monospace, monospace; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); } + +:focus-visible { outline: 2px solid var(--c-login); outline-offset: 3px; } diff --git a/assets/fonts/UbuntuSans-var.woff2 b/assets/fonts/UbuntuSans-var.woff2 new file mode 100644 index 0000000..6652d48 Binary files /dev/null and b/assets/fonts/UbuntuSans-var.woff2 differ diff --git a/assets/fonts/UbuntuSansMono-var.woff2 b/assets/fonts/UbuntuSansMono-var.woff2 new file mode 100644 index 0000000..9acabff Binary files /dev/null and b/assets/fonts/UbuntuSansMono-var.woff2 differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..cc23d58 --- /dev/null +++ b/index.html @@ -0,0 +1,217 @@ + + +
+ + +composable nostr · bitcoin infrastructure
+BitBlocks is a set of composable building blocks for apps that can't lock anyone + in — no server of record, no account to close, no algorithm you can't swap. Each block does + one thing, signs everything, and runs on open relays.
+ +§ 01 — the premise
+Every platform you use owns the four things that matter: your name, your feed, your + money, and your right to be there.
+Your identity is a row in someone's database. Your feed is an algorithm you can't read. + Your payments run through a processor that can freeze them. Your account can be closed, + and everything you built inside it goes with it. You are renting.
+BitBlocks moves each of those to open ground: a key you hold, a feed recipe you write, + money that settles cryptographically, and a presence no host can revoke. The apps become + clients over public data — replaceable, forkable, unable to hold you hostage.
+§ 02 — the blocks
+Each block is small, opinionated, and independent. Use one, or snap them together — they were + designed to compose, not to depend.
+A portable Nostr identity — a familiar username and password unlock a key + that's yours, backed by public relays with an independent recovery phrase. No account server, + no password-reset email, no database. Any app already written for a NIP-07 signer works + unchanged.
+ login.bitblocks.network → + + +A policy engine with four independent dimensions — rank, show, interact, + transact. You supply the policy; it supplies precedence, composition, and a readable + explanation of every decision. Moderation and access control without writing the machinery.
+ gate.bitblocks.network → + + +A headless feed engine. You write the algorithm as providers and a recipe; + it sources, scores, mixes, orders, and explains — and contains no recommendation logic of its + own. Swap the recipe, swap the feed. The algorithm is yours, and it's legible.
+ feed.bitblocks.network → + + +Payment-verified delivery. Every required Lightning leg settles before an + encrypted payload is released — re-encrypted to the buyer's own key. Sell digital goods, + access, and capabilities in bitcoin, with cryptographic proof instead of a payment processor.
+ bitunlock.network → + + +The capability network for agents — Agent Plugins published, curated, and + installed over Nostr, by people and by the agents themselves. Every listing is a signed event; + installs verify on your machine. Tessera is also the proof the stack composes: it's built from + the other four.
+ tessera.bitblocks.network → + +§ 03 — how they compose
+Read left to right, they answer the full lifecycle of a sovereign app. Any block can stand + alone; together they interlock.
+Tessera is the worked example. It signs users in with BitLogin, moderates + with BitGate's four dimensions, ranks its feed with BitFeed-shaped recipes, and gates paid + plugins through BitUnlock — a real application assembled entirely from the blocks. Nothing about + it is special-cased; it's just a client over public events, which is the whole point.
+§ 04 — what holds it together
+Every action is a signed event. Provenance isn't a feature bolted on — it's the storage layer, verified on your device, not taken on a server's word.
State lives on open relays. Any client can read it; no one can close your account or delete your history out from under you.
The feed, the policy, the trust graph, the price — all of it is data you write and swap. No opaque ranking, no locked-in rules.
Each block embeds in a plain static site. The code that decides anything about you runs on your side, where you can read it.
Value moves over Lightning and settles cryptographically. Payment is proof, not a promise from a processor that can reverse it.
Vendor-neutral format, vendor-neutral distribution. Fork any client; the network is the events, not the front door.
§ 05 — for builders
+Every block is open and composable, with a dependency-free core and a static build. Start with + the capability network — install its skill and let an agent search, publish, and install over + Nostr — or embed a single block in a site you already have.
+ +