index.astro
1---
2import Layout from '../layouts/Layout.astro';
3import WaitlistForm from '../components/WaitlistForm.astro';
4import HostingMap from '../components/HostingMap.astro';
5import Masthead from '../components/Masthead.astro';
6import Footer from '../components/Footer.astro';
7
8const provisions = [
9 {
10 term: 'Your domain, your passport to an ecosystem of apps',
11 body: 'Built on the Atmosphere, an open-web standard that keeps all your data securely in one place. Your email becomes your Atmosphere identity, with single sign-on to dozens of apps for your business.',
12 machine: '[email protected]',
13 },
14 {
15 term: 'Works with all your apps',
16 body: 'Use any mail app or our webmail. Speaks every protocol so you can connect anywhere.',
17 machine: 'Apple Mail · Outlook · Webmail',
18 },
19 {
20 term: 'Mail that hits the inbox',
21 body: 'Configured to fight spam. Your messages land in inboxes, not the promotions tab.',
22 machine: 'delivery: reliable',
23 },
24 {
25 term: 'Reliability baked in',
26 body: 'We know email is a critical service for your business. We expertly run it so you can worry about other things.',
27 machine: 'status: healthy',
28 },
29 {
30 term: 'No lock-in, no surveillance',
31 body: 'Open-source infrastructure built on the AT Protocol means you can never be locked in. Good service for a reasonable price, independent of the big players.',
32 machine: 'lock-in: impossible',
33 },
34];
35
36const ledger = [
37 { topic: 'Your identity', them: 'An account on their platform.', us: 'An Atmosphere identity you control.' },
38 { topic: 'Where mail lives', them: 'Wherever their data centres are.', us: 'Inside the EU, if you choose.' },
39 { topic: 'The rules', them: 'Their terms, worse for you all the time.', us: 'Open protocols and open-source software.' },
40 { topic: 'Lock-in', them: 'That\'s their business model.', us: 'Impossible by design.' },
41];
42
43// Exchange grid: identity in the centre, routes out to each kind of app.
44// Positions are 3×3 cells, row-major; 4 is the centre.
45const exchange = [
46 { key: 'mail', pos: 0, title: 'Business email', line: 'sovrn Mail, on your own domain.', live: true },
47 { key: 'blog', pos: 1, title: 'Blogging', line: 'Publish a journal or newsletter under your name.' },
48 { key: 'pod', pos: 2, title: 'Podcast production', line: 'Record, publish and keep your feed.' },
49 { key: 'chat', pos: 3, title: 'Team chat', line: 'Talk with staff and clients, no extra login.' },
50 { key: 'git', pos: 5, title: 'Git forge hosting', line: 'Host code and review changes together.' },
51 { key: 'events', pos: 6, title: 'Events & RSVPs', line: 'Invite customers and see who’s coming.' },
52 { key: 'social', pos: 7, title: 'Social publishing', line: 'Reach people on open social networks.' },
53 { key: 'photos', pos: 8, title: 'Portfolios & photos', line: 'Show your work where you choose.' },
54];
55const cellCentre = (pos: number) => ({ x: (pos % 3) * 100 + 50, y: Math.floor(pos / 3) * 100 + 50 });
56
57---
58
59<Layout>
60
61 <Masthead />
62
63 <main id="main">
64 <section class="hero" aria-labelledby="hero-title">
65 <div class="hero-field">
66 <h1 id="hero-title" class="hero-title">
67 <span>Reliable email</span>
68 <span>for independent</span>
69 <span>business.</span>
70 </h1>
71 <div class="hero-action">
72 <p class="hero-sub">
73 <span>Quality email hosting for your domain.</span>
74 <span>Declare your sovereignty from big-tech bad actors.</span>
75 </p>
76 <WaitlistForm id="hero" />
77 </div>
78 </div>
79 <div class="hero-column on-dark" aria-hidden="true">
80 <img class="speedmark" src="/plates/speedmark.png" alt="" width="1032" height="528" />
81 </div>
82 </section>
83
84 <section class="chain on-dark" aria-label="What independence means">
85 <ul class="pledges">
86 <li>
87 <strong>Your data stays yours.</strong>
88 <span>No surveillance, no lock-in. Kept secure by design.</span>
89 </li>
90 <li>
91 <strong>You decide where it lives.</strong>
92 <span>Host in the EU or choose another region near you.</span>
93 </li>
94 <li>
95 <strong>Independent infrastructure.</strong>
96 <span>No more reliance on big-tech companies that don't support your values.</span>
97 </li>
98 </ul>
99 <div class="chain-corner" aria-hidden="true"></div>
100 </section>
101
102 <section id="mail" class="schedule" aria-labelledby="mail-title">
103 <div class="schedule-head">
104 <h2 id="mail-title" class="section-title">Mail, run properly.</h2>
105 <p class="lede">
106 Hosted email for businesses that want to break free of big tech, built on a protocol that guarantees your independence.
107 </p>
108 </div>
109 <dl class="schedule-list">
110 {
111 provisions.map((p) => (
112 <div class="schedule-row">
113 <dt>{p.term}</dt>
114 <dd class="schedule-body">{p.body}</dd>
115 <dd class="schedule-machine mono">{p.machine}</dd>
116 </div>
117 ))
118 }
119 </dl>
120 </section>
121
122 <section class="ledger on-dark" aria-labelledby="ledger-title">
123 <h2 id="ledger-title" class="section-title">
124 Break free of big tech. Nothing lost, but a whole lot gained.
125 </h2>
126 <table class="ledger-table">
127 <caption class="visually-hidden">How a big-tech suite compares with sovrn</caption>
128 <thead>
129 <tr>
130 <th scope="col"><span class="visually-hidden">Topic</span></th>
131 <th scope="col">With big-tech email</th>
132 <th scope="col" class="ours">With us</th>
133 </tr>
134 </thead>
135 <tbody>
136 {
137 ledger.map((row) => (
138 <tr>
139 <th scope="row">{row.topic}</th>
140 <td>{row.them}</td>
141 <td class="ours">{row.us}</td>
142 </tr>
143 ))
144 }
145 </tbody>
146 </table>
147 </section>
148
149 <section id="eu" class="region" aria-labelledby="eu-title">
150 <div class="region-plate">
151 <HostingMap />
152 </div>
153 <div class="region-copy">
154 <h2 id="eu-title" class="section-title">Choose where your mail lives.</h2>
155 <p class="lede">
156 Pick the jurisdiction that makes sense for you. Always on independent infrastructure no matter what you choose.
157 </p>
158 <figure class="region-form" aria-label="Hosting region choice, illustrated">
159 <p class="region-form-label">Hosting region, chosen by you.</p>
160 <div class="tick is-on">
161 <span class="box" aria-hidden="true">
162 <svg viewBox="0 0 20 20"><path d="M4 4l12 12M16 4L4 16" fill="none" stroke="currentColor" stroke-width="2.25" /></svg>
163 </span>
164 <span><strong>EU</strong>Strong data-protection laws and consumer rights.</span>
165 </div>
166 <div class="tick">
167 <span class="box" aria-hidden="true"></span>
168 <span><strong>Elsewhere</strong> Outside the EU? Pick somewhere closer, still free of big tech.</span>
169 </div>
170 </figure>
171 </div>
172 </section>
173
174 <section id="atmosphere" class="atmos on-dark" aria-labelledby="atmos-title">
175 <div class="atmos-copy">
176 <h2 id="atmos-title" class="section-title">One identity. A whole ecosystem.</h2>
177 <p class="lede">
178 Every email account is also an Atmosphere account, built on the open AT Protocol. The same identity works
179 across a growing network of independent apps, and your data comes with you when you switch.
180 </p>
181 <p class="atmos-note">
182 A whole host of apps to help you run your business, integrated with single sign-on, where your data can't be locked away.
183 </p>
184 </div>
185 <div class="exchange">
186 <svg class="routes" viewBox="0 0 300 300" preserveAspectRatio="none" aria-hidden="true">
187 {
188 exchange.map((c) => {
189 const { x, y } = cellCentre(c.pos);
190 return <line class={`route route-${c.key}`} x1="150" y1="150" x2={x} y2={y} />;
191 })
192 }
193 </svg>
194 <ul class="exchange-grid">
195 {
196 exchange.map((c) => (
197 <li class:list={['cell', { live: c.live }]} style={`--col:${(c.pos % 3) + 1};--row:${Math.floor(c.pos / 3) + 1}`} data-route={c.key} tabindex="0">
198 <span class="cell-title">{c.title}</span>
199 <span class="cell-line">{c.line}</span>
200 {c.live ? <span class="cell-tag">Open for the waitlist</span> : null}
201 </li>
202 ))
203 }
204 <li class="cell hub">
205 <span class="cell-title">Your identity</span>
206 <span class="cell-line mono">@yourstudio.eu</span>
207 </li>
208 </ul>
209 </div>
210 </section>
211
212 <section class="steps" aria-labelledby="steps-title">
213 <h2 id="steps-title" class="section-title">Just three steps to a better email</h2>
214 <ol class="steps-list">
215 <li>
216 <span class="step-n" aria-hidden="true">1</span>
217 <h3>Sign in</h3>
218 <p>Use the Atmosphere account you already have, or create one with us.</p>
219 </li>
220 <li>
221 <span class="step-n" aria-hidden="true">2</span>
222 <h3>Add your domain</h3>
223 <p>Publish the DNS records we give you. We check them and tell you when each one is ready.</p>
224 <p class="record mono" aria-label="Example DNS record">
225 <span class="record-type">MX</span> yourbakery.eu
226 </p>
227 </li>
228 <li>
229 <span class="step-n" aria-hidden="true">3</span>
230 <h3>Go live</h3>
231 <p>Create mailboxes for your team and connect any mail app. Mail starts arriving.</p>
232 </li>
233 </ol>
234 </section>
235
236 <section id="join" class="close" aria-labelledby="join-title">
237 <div class="close-field">
238 <h2 id="join-title" class="close-title">Take back your sovereignty.</h2>
239 <p class="close-sub">
240 Mail is our first service. More tools for running an independent business will follow, all on the
241 same identity. Join the waitlist and we’ll send an invite when there’s room.
242 </p>
243 <WaitlistForm id="close" />
244 </div>
245 <div class="close-column on-dark" aria-hidden="true">
246 <img class="close-mark" src="/plates/speedmark.png" alt="" width="1032" height="528" loading="lazy" />
247 </div>
248 </section>
249 </main>
250
251 <Footer />
252</Layout>
253
254<style>
255 /* ——— Hero ——— */
256 .hero {
257 display: grid;
258 grid-template-columns: 1fr 24.6%;
259 min-height: clamp(34rem, min(77.6svh, 51.7vw), 54rem);
260 }
261
262 .hero-field {
263 display: flex;
264 flex-direction: column;
265 justify-content: space-between;
266 gap: 2rem;
267 padding: clamp(2rem, min(5.6svh, 3.7vw), 4rem) 2.3% clamp(1.25rem, min(3.4svh, 2.3vw), 2.5rem) var(--gutter);
268 background: var(--gold);
269 color: var(--ptt);
270 }
271
272 .hero-title {
273 font-size: clamp(2.3rem, 8.2vw, 7.9rem);
274 font-weight: 850;
275 line-height: 0.95;
276 letter-spacing: -0.042em;
277 margin-left: -0.05em;
278 }
279
280 .hero-title span,
281 .hero-sub span {
282 display: block;
283 }
284
285 .hero-action {
286 display: grid;
287 gap: 2.25rem;
288 }
289
290 .hero-sub {
291 font-size: clamp(1.35rem, 2.6vw, 2.5rem);
292 font-weight: 700;
293 line-height: 1.03;
294 letter-spacing: -0.045em;
295 }
296
297 .hero-column {
298 position: relative;
299 background: var(--ptt);
300 overflow: hidden;
301 }
302
303 .speedmark {
304 position: absolute;
305 left: 3.7%;
306 top: 24%;
307 width: 91%;
308 height: auto;
309 /* the plate's ground is a shade darker than --ptt; lighten keeps only the bars */
310 mix-blend-mode: lighten;
311 animation: dispatch 1.1s var(--ease-out) 0.15s both;
312 }
313
314 @keyframes dispatch {
315 from {
316 transform: translateX(-18%);
317 clip-path: inset(0 100% 0 0);
318 }
319 to {
320 transform: none;
321 clip-path: inset(0 0 0 0);
322 }
323 }
324
325 @media (prefers-reduced-motion: reduce) {
326 .speedmark {
327 animation: none;
328 }
329 }
330
331 /* ——— Independence strip ——— */
332 .chain {
333 display: grid;
334 grid-template-columns: 1fr 11.8%;
335 min-height: clamp(5rem, min(12.1svh, 8.1vw), 8.5rem);
336 background: var(--ptt);
337 color: var(--paper);
338 }
339
340 .pledges {
341 display: grid;
342 grid-template-columns: repeat(3, 1fr);
343 align-content: center;
344 gap: 1rem clamp(1.5rem, 3vw, 3rem);
345 padding: 1.25rem var(--gutter);
346 min-width: 0;
347 }
348
349 .pledges li {
350 display: grid;
351 align-content: start;
352 gap: 0.2rem;
353 padding-top: 0.7rem;
354 border-top: 3px solid var(--gold);
355 font-size: clamp(0.9375rem, 1vw, 1.0625rem);
356 line-height: 1.35;
357 color: var(--ptt-soft);
358 }
359
360 .pledges strong {
361 color: var(--paper);
362 font-size: clamp(1.0625rem, 1.35vw, 1.3rem);
363 font-weight: 750;
364 letter-spacing: -0.02em;
365 line-height: 1.15;
366 }
367
368 .chain-corner {
369 background: var(--signal);
370 }
371
372 /* ——— Shared section type ——— */
373 .section-title {
374 font-size: clamp(2.25rem, 5.2vw, 5rem);
375 font-weight: 850;
376 line-height: 0.95;
377 letter-spacing: -0.04em;
378 text-wrap: balance;
379 }
380
381 .lede {
382 font-size: clamp(1.125rem, 1.45vw, 1.375rem);
383 line-height: 1.45;
384 max-width: 38ch;
385 text-wrap: pretty;
386 }
387
388 /* ——— Service schedule ——— */
389 .schedule {
390 display: grid;
391 grid-template-columns: 5fr 7fr;
392 gap: 3rem var(--gutter);
393 padding: clamp(4.5rem, 10vw, 9rem) var(--gutter) clamp(4rem, 8vw, 7rem);
394 color: var(--ptt);
395 }
396
397 .schedule-head {
398 display: grid;
399 align-content: start;
400 gap: 1.75rem;
401 position: sticky;
402 top: 2rem;
403 align-self: start;
404 }
405
406 .schedule-head .lede {
407 color: var(--ink-soft);
408 }
409
410 .schedule-list {
411 border-top: 3px solid var(--ptt);
412 }
413
414 .schedule-row {
415 display: grid;
416 grid-template-columns: 1fr 1.35fr;
417 gap: 0.5rem 2rem;
418 padding: 1.75rem 0 1.85rem;
419 border-bottom: 1px solid var(--paper-rule);
420 }
421
422 .schedule-row dt {
423 grid-row: span 2;
424 font-size: clamp(1.25rem, 1.7vw, 1.6rem);
425 font-weight: 750;
426 line-height: 1.1;
427 letter-spacing: -0.025em;
428 }
429
430 .schedule-body {
431 color: var(--ink);
432 max-width: 44ch;
433 }
434
435 .schedule-machine {
436 justify-self: start;
437 margin-top: 0.5rem;
438 padding: 0.3rem 0.55rem;
439 background: var(--gold-wash);
440 color: var(--gold-ink);
441 font-size: 0.875rem;
442 font-weight: 500;
443 }
444
445 /* ——— Ledger ——— */
446 .ledger {
447 display: grid;
448 grid-template-columns: 5fr 7fr;
449 gap: 3rem var(--gutter);
450 padding: clamp(4.5rem, 9vw, 8rem) var(--gutter);
451 background: var(--ptt);
452 color: var(--paper);
453 }
454
455 .ledger .section-title {
456 align-self: start;
457 max-width: 11ch;
458 }
459
460 .ledger-table {
461 width: 100%;
462 border-collapse: collapse;
463 font-size: 1.0625rem;
464 }
465
466 .ledger-table th,
467 .ledger-table td {
468 padding: 1.15rem 1.25rem 1.2rem 0;
469 text-align: left;
470 vertical-align: top;
471 border-bottom: 1px solid color-mix(in srgb, var(--ptt-soft) 35%, transparent);
472 }
473
474 .ledger-table thead th {
475 padding-top: 0;
476 font-size: 0.9375rem;
477 font-weight: 700;
478 letter-spacing: -0.01em;
479 color: var(--ptt-soft);
480 border-bottom: 3px solid var(--paper);
481 }
482
483 .ledger-table thead th.ours {
484 color: var(--gold);
485 }
486
487 .ledger-table tbody th {
488 width: 24%;
489 font-weight: 750;
490 letter-spacing: -0.015em;
491 }
492
493 .ledger-table td {
494 color: var(--ptt-soft);
495 width: 38%;
496 }
497
498 .ledger-table td.ours {
499 color: var(--paper);
500 font-weight: 650;
501 }
502
503 /* ——— EU region ——— */
504 .region {
505 display: grid;
506 grid-template-columns: 1fr 1fr;
507 align-items: stretch;
508 background: var(--paper);
509 color: var(--ptt);
510 overflow: hidden;
511 }
512
513 /* The map is printed as a plate: inset on paper and held by a hairline
514 frame, so its blue water never runs into the blue bands around it. */
515 .region-plate {
516 display: grid;
517 align-content: center;
518 padding: clamp(3rem, 6vw, 5.5rem) var(--gutter);
519 }
520
521 .region :global(.hosting-map) {
522 aspect-ratio: 1000 / 860;
523 outline: 1px solid var(--ptt);
524 outline-offset: 0.625rem;
525 }
526
527 .region-copy {
528 display: grid;
529 align-content: center;
530 gap: 1.75rem;
531 padding: clamp(4rem, 8vw, 7.5rem) var(--gutter);
532 }
533
534 .region-copy .lede {
535 color: var(--ink);
536 }
537
538 .region-form {
539 display: grid;
540 gap: 0.9rem;
541 margin-top: 0.75rem;
542 padding-top: 1.25rem;
543 border-top: 3px solid var(--ptt);
544 max-width: 34rem;
545 }
546
547 .region-form-label {
548 font-size: 0.9375rem;
549 font-weight: 700;
550 color: var(--ink-soft);
551 }
552
553 .tick {
554 display: flex;
555 gap: 1rem;
556 align-items: flex-start;
557 color: var(--ink);
558 }
559
560 .tick strong {
561 display: block;
562 color: var(--ptt);
563 font-size: 1.25rem;
564 letter-spacing: -0.02em;
565 }
566
567 .box {
568 flex: none;
569 display: grid;
570 place-items: center;
571 width: 1.75rem;
572 height: 1.75rem;
573 margin-top: 0.15rem;
574 border: 1px solid var(--ptt);
575 color: var(--signal);
576 }
577
578 .box svg {
579 width: 1.25rem;
580 height: 1.25rem;
581 }
582
583 /* ——— Atmosphere exchange ——— */
584 .atmos {
585 display: grid;
586 grid-template-columns: 5fr 7fr;
587 gap: 3rem var(--gutter);
588 padding: clamp(4.5rem, 9vw, 8rem) var(--gutter);
589 background: var(--ptt-deep);
590 color: var(--paper);
591 }
592
593 .atmos-copy {
594 display: grid;
595 align-content: start;
596 gap: 1.75rem;
597 }
598
599 .atmos-copy .lede {
600 color: var(--ptt-soft);
601 }
602
603 .atmos-note {
604 font-size: 1rem;
605 font-weight: 700;
606 letter-spacing: -0.01em;
607 color: var(--gold);
608 }
609
610 .exchange {
611 position: relative;
612 align-self: start;
613 max-width: 44rem;
614 width: 100%;
615 justify-self: end;
616 }
617
618 .routes {
619 position: absolute;
620 inset: 0;
621 width: 100%;
622 height: 100%;
623 }
624
625 .route {
626 stroke: var(--paper);
627 stroke-opacity: 0.28;
628 stroke-width: 6;
629 vector-effect: non-scaling-stroke;
630 transition:
631 stroke 0.3s var(--ease-out),
632 stroke-opacity 0.3s var(--ease-out),
633 stroke-width 0.3s var(--ease-out);
634 }
635
636 .route-mail {
637 stroke: var(--gold);
638 stroke-opacity: 1;
639 }
640
641 .exchange-grid {
642 position: relative;
643 display: grid;
644 grid-template-columns: repeat(3, 1fr);
645 /* in an auto-height grid, 1fr rows all take the tallest row's height: one module */
646 grid-template-rows: repeat(3, 1fr);
647 gap: clamp(1.5rem, 4vw, 3.5rem);
648 }
649
650 .cell {
651 display: flex;
652 flex-direction: column;
653 justify-content: center;
654 gap: 0.4rem;
655 padding: clamp(0.75rem, 1.4vw, 1.25rem);
656 background: var(--ptt-deep);
657 border: 1px solid var(--ptt-soft);
658 color: var(--paper);
659 outline-offset: 4px;
660 transition:
661 background-color 0.3s var(--ease-out),
662 transform 0.3s var(--ease-out);
663 }
664
665 .cell {
666 grid-column: var(--col, 2);
667 grid-row: var(--row, 2);
668 }
669
670 .cell-title {
671 font-size: clamp(1rem, 1.5vw, 1.45rem);
672 font-weight: 800;
673 line-height: 1.02;
674 letter-spacing: -0.03em;
675 }
676
677 .cell-line {
678 font-size: clamp(0.8rem, 0.95vw, 0.9375rem);
679 line-height: 1.3;
680 color: var(--ptt-soft);
681 }
682
683 .cell-tag {
684 margin-top: 0.35rem;
685 font-size: 0.8125rem;
686 font-weight: 700;
687 }
688
689 .cell.live {
690 background: var(--gold);
691 border-color: var(--gold);
692 color: var(--ptt);
693 }
694
695 .cell.live .cell-line {
696 color: var(--ptt);
697 }
698
699 .cell.live .cell-tag {
700 color: var(--ptt);
701 }
702
703 .cell.hub {
704 justify-content: center;
705 background: var(--signal);
706 border-color: var(--signal);
707 color: #fff;
708 }
709
710 .cell.hub .cell-title {
711 font-size: clamp(1.25rem, 2.2vw, 2.1rem);
712 }
713
714 .cell.hub .cell-line {
715 color: var(--ink);
716 font-size: clamp(0.75rem, 0.9vw, 0.875rem);
717 overflow-wrap: anywhere;
718 }
719
720 .cell:not(.hub):hover,
721 .cell:not(.hub):focus-visible {
722 border-color: var(--signal);
723 box-shadow: inset 0 0 0 2px var(--signal);
724 }
725
726 .cell.live:hover,
727 .cell.live:focus-visible {
728 border-color: var(--signal);
729 }
730
731 /* the exchange patches a route when a line of work is pointed at */
732 .exchange:has(.cell[data-route='mail']:is(:hover, :focus-visible)) .route-mail,
733 .exchange:has(.cell[data-route='blog']:is(:hover, :focus-visible)) .route-blog,
734 .exchange:has(.cell[data-route='pod']:is(:hover, :focus-visible)) .route-pod,
735 .exchange:has(.cell[data-route='chat']:is(:hover, :focus-visible)) .route-chat,
736 .exchange:has(.cell[data-route='git']:is(:hover, :focus-visible)) .route-git,
737 .exchange:has(.cell[data-route='events']:is(:hover, :focus-visible)) .route-events,
738 .exchange:has(.cell[data-route='social']:is(:hover, :focus-visible)) .route-social,
739 .exchange:has(.cell[data-route='photos']:is(:hover, :focus-visible)) .route-photos {
740 stroke: var(--signal);
741 stroke-opacity: 1;
742 stroke-width: 10;
743 }
744
745 /* ——— Steps ——— */
746 .steps {
747 padding: clamp(4.5rem, 9vw, 8rem) var(--gutter);
748 color: var(--ptt);
749 }
750
751 .steps-list {
752 display: grid;
753 grid-template-columns: repeat(3, 1fr);
754 margin-top: clamp(2.5rem, 5vw, 4rem);
755 border-top: 3px solid var(--ptt);
756 }
757
758 .steps-list li {
759 display: grid;
760 align-content: start;
761 gap: 0.75rem;
762 padding: 1.5rem 2rem 0 0;
763 }
764
765 .steps-list li + li {
766 padding-left: 2rem;
767 border-left: 1px solid var(--paper-rule);
768 }
769
770 .step-n {
771 font-size: clamp(4.5rem, 8vw, 7.5rem);
772 font-weight: 900;
773 line-height: 0.85;
774 letter-spacing: -0.06em;
775 color: var(--ptt);
776 }
777
778 .steps-list h3 {
779 font-size: clamp(1.4rem, 2vw, 1.9rem);
780 font-weight: 800;
781 letter-spacing: -0.03em;
782 line-height: 1.05;
783 }
784
785 .steps-list p {
786 color: var(--ink);
787 max-width: 34ch;
788 }
789
790 .steps-list .record {
791 color: var(--ptt);
792 }
793
794 .record {
795 justify-self: start;
796 display: inline-flex;
797 gap: 0.75rem;
798 align-items: center;
799 margin-top: 0.25rem;
800 padding: 0.45rem 0.7rem;
801 border: 1px solid var(--ptt);
802 font-size: 0.875rem;
803
804 }
805
806 .record-type {
807 padding: 0.1rem 0.4rem;
808 background: var(--ptt);
809 color: var(--paper);
810 }
811
812 /* ——— Close ——— */
813 .close {
814 display: grid;
815 grid-template-columns: 1fr 24.6%;
816 }
817
818 .close-field {
819 display: grid;
820 gap: 2rem;
821 padding: clamp(4.5rem, 9vw, 8rem) var(--gutter);
822 background: var(--gold);
823 color: var(--ptt);
824 }
825
826 .close-title {
827 font-size: clamp(2.75rem, 7.5vw, 7.25rem);
828 font-weight: 850;
829 line-height: 0.93;
830 letter-spacing: -0.04em;
831 }
832
833 .close-sub {
834 font-size: clamp(1.125rem, 1.6vw, 1.5rem);
835 font-weight: 600;
836 line-height: 1.35;
837 letter-spacing: -0.015em;
838 max-width: 40ch;
839 margin-bottom: 0.75rem;
840 }
841
842 .close-column {
843 position: relative;
844 background: var(--ptt);
845 }
846
847 .close-mark {
848 position: absolute;
849 left: 3.7%;
850 bottom: 12%;
851 width: 91%;
852 height: auto;
853 mix-blend-mode: lighten;
854 }
855
856 /* ——— Responsive ——— */
857 @media (max-width: 1100px) {
858 /* the postmark column only earns its place beside a wide hero */
859 .hero,
860 .close {
861 grid-template-columns: 1fr;
862 }
863 .hero {
864 min-height: 0;
865 }
866 .hero-column,
867 .close-column {
868 display: none;
869 }
870 .schedule,
871 .ledger,
872 .atmos {
873 grid-template-columns: 1fr;
874 }
875 .schedule-head {
876 position: static;
877 }
878 .exchange {
879 justify-self: start;
880 }
881 .region {
882 grid-template-columns: 1fr;
883 }
884 .region-plate {
885 padding-bottom: 0;
886 }
887 .region :global(.hosting-map) {
888 max-height: 40rem;
889 }
890 }
891
892 @media (max-width: 800px) {
893 .region :global(.hosting-map) {
894 outline-offset: 0.375rem;
895 }
896 .pledges {
897 grid-template-columns: 1fr;
898 padding-block: 1.75rem;
899 gap: 1.25rem;
900 }
901 .chain {
902 grid-template-columns: 1fr 3rem;
903 }
904 .schedule-row {
905 grid-template-columns: 1fr;
906 }
907 .schedule-row dt {
908 grid-row: auto;
909 }
910 .ledger-table thead {
911 display: none;
912 }
913 .ledger-table,
914 .ledger-table tbody,
915 .ledger-table tr,
916 .ledger-table th,
917 .ledger-table td {
918 display: block;
919 width: auto;
920 }
921 .ledger-table tr {
922 padding: 1.1rem 0;
923 border-bottom: 1px solid color-mix(in srgb, var(--ptt-soft) 35%, transparent);
924 }
925 .ledger-table th,
926 .ledger-table td {
927 padding: 0.15rem 0;
928 border: 0;
929 }
930 .ledger-table tbody th {
931 width: auto;
932 padding-bottom: 0.4rem;
933 }
934 .ledger-table td::before {
935 display: block;
936 font-size: 0.8125rem;
937 font-weight: 700;
938 color: var(--ptt-soft);
939 }
940 .ledger-table td:not(.ours)::before {
941 content: 'Big-tech suite';
942 }
943 .ledger-table td.ours::before {
944 content: 'sovrn';
945 color: var(--gold);
946 }
947 .ledger-table td + td {
948 margin-top: 0.5rem;
949 }
950 .routes {
951 display: none;
952 }
953 /* mobile: a trunk runs down from the identity, one branch per line of work */
954 .exchange-grid {
955 display: flex;
956 flex-direction: column;
957 gap: 0.75rem;
958 padding-left: 1.5rem;
959 background: linear-gradient(var(--ptt-soft), var(--ptt-soft)) 0.5rem 0 / 2px calc(100% - 2.25rem) no-repeat;
960 }
961 .cell {
962 position: relative;
963 min-height: 0;
964 padding: 0.85rem 1rem;
965 }
966 .cell::before {
967 content: '';
968 position: absolute;
969 left: calc(-1rem - 1px);
970 top: 50%;
971 width: 1rem;
972 height: 2px;
973 background: var(--ptt-soft);
974 transition: background-color 0.3s var(--ease-out), transform 0.3s var(--ease-out);
975 }
976 .cell.live::before {
977 background: var(--gold);
978 }
979 .cell:not(.hub):is(:hover, :focus-visible)::before {
980 background: var(--signal);
981 transform: scaleY(2);
982 }
983 .cell.hub {
984 order: -1;
985 margin-left: -1.5rem;
986 }
987 .cell.hub::before {
988 display: none;
989 }
990 .steps-list {
991 grid-template-columns: 1fr;
992 }
993 .steps-list li,
994 .steps-list li + li {
995 padding: 1.75rem 0;
996 border-left: 0;
997 border-bottom: 1px solid var(--paper-rule);
998 }
999
1000 }
1001</style>