PageSourceSearch

https://armada.buzz/

html armada.buzz collected 2026-10-02 00:26:29 UTC 13,570 bytes, 159 lines download raw bytes

1<!doctype html>
2<html lang="en" class="dark">
3  <head>
4    <meta charset="UTF-8" />
5    <!-- Content Security Policy, delivered as a meta tag so it applies on every
6         platform. The hosted web build also gets it as a response header from
7         nginx.conf; the two INTERSECT per directive, so a directive loosened
8         here alone still has no effect there. Native has no header at all —
9         Capacitor serves the bundle from https://localhost (Android) and
10         capacitor://localhost (iOS), and Electron from app://armada — so this
11         tag is the whole policy in those builds.
12         Notes on individual directives:
13         - 'unsafe-inline' in style-src is required, not incidental: the boot
14           splash below is built out of style= attributes, and fontLoader.ts
15           injects a <style> element for theme @font-face rules at runtime.
16         - https://www.youtube.com in script-src is the iframe player API
17           (src/lib/youtubeApi.ts); the embed itself is a frame-src entry.
18         - blob: in worker-src/media-src carries bundled web workers and
19           decrypted attachment playback respectively.
20         - frame-ancestors is ignored in a meta-delivered policy, so the
21           clickjacking defense lives in nginx.conf only. -->
22    <meta http-equiv="content-security-policy" content="default-src 'none'; script-src 'self' 'wasm-unsafe-eval' https://www.youtube.com; worker-src 'self' blob:; child-src 'self' blob:; style-src 'self' 'unsafe-inline'; frame-src 'self' https://www.youtube-nocookie.com https://open.spotify.com https://platform.twitter.com https://www.instagram.com https://streamable.com https://*.iframe.diy; object-src 'none'; font-src 'self' https: data:; base-uri 'self'; manifest-src 'self'; connect-src 'self' blob: https: wss:; img-src 'self' data: blob: https:; media-src 'self' blob: https:" />
23    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
24    <link rel="icon" type="image/png" sizes="256x256" href="/favicon.png" />
25    <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
26    <link rel="manifest" href="/manifest.webmanifest" />
27    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover, interactive-widget=resizes-content" />
28    <!-- YouTube requires an HTTP Referer for embedded playback. The browser
29         supplies this deployment's own origin, including on self-hosts. -->
30    <meta name="referrer" content="strict-origin-when-cross-origin" />
31    <meta name="theme-color" content="#100b15" media="(prefers-color-scheme: dark)" />
32    <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
33    <!-- Standalone/home-screen behavior comes from manifest.webmanifest alone
34         (display: standalone). Deliberately NO legacy apple-mobile-web-app-*
35         meta tags: with apple-mobile-web-app-capable + black-translucent
36         present, iOS (observed on iOS 26 / iPhone 16 Pro) takes the legacy
37         home-screen layout path and sizes the standalone webview to
38         screen-minus-status-bar while anchoring it at the top, leaving a
39         dead ~62pt letterbox band below the page that no in-page CSS can
40         remove. Manifest-only (Ditto's config) sizes the window correctly.
41         apple-mobile-web-app-capable was also tried as a fix for iOS Web Push
42         being unavailable in the installed PWA (window.Notification undefined);
43         it made no difference on iOS 26.2.1, so it stays out. -->
44    <title>Armada</title>
45    <!-- Stamped per build (armada-build-stamp Vite plugin); lets a device's
46         running bundle be identified when debugging stale-PWA issues. -->
47    <meta name="build" content="2026-10-01 20:23:55Z" />
48    <meta name="description" content="The open-source, encrypted Discord alternative. Unbannable communities with channels, voice, and DMs — no host required. Your keys, your fleet." />
49
50    <!-- Open Graph / social. og:image/twitter:image MUST be absolute URLs —
51         most crawlers (X, Discord, Slack, iMessage) do not resolve relative
52         ones and the card renders with no image. https://armada.buzz is stamped
53         at build time from PUBLIC_WEB_ORIGIN so a build points its card at
54         the host it is actually served from: an absolute URL on some OTHER
55         origin is only as good as that origin, and when it can't be fetched
56         the preview degrades to the platform's generic placeholder icon. -->
57    <meta property="og:type" content="website" />
58    <meta property="og:title" content="Armada" />
59    <meta property="og:description" content="The open-source, encrypted Discord alternative. Unbannable communities with channels, voice, and DMs — no host required. Your keys, your fleet." />
60    <meta property="og:image" content="https://armada.buzz/og.png" />
61    <meta property="og:image:type" content="image/png" />
62    <meta property="og:image:width" content="1200" />
63    <meta property="og:image:height" content="630" />
64    <meta property="og:url" content="https://armada.buzz" />
65    <meta property="og:site_name" content="Armada" />
66    <meta name="twitter:card" content="summary_large_image" />
67    <meta name="twitter:title" content="Armada" />
68    <meta name="twitter:description" content="The open-source, encrypted Discord alternative. Unbannable communities with channels, voice, and DMs — no host required. Your keys, your fleet." />
69    <meta name="twitter:image" content="https://armada.buzz/og.png" />
70
71    <!-- Marks home-screen (standalone PWA) launches on <html> before first
72         paint so CSS can scroll-lock the shell (see index.css). External
73         because the policy above permits no inline script. -->
74    
74<script src="/standalone.js"></script>
74
75    
75<script src="/theme.js"></script>
75
76    
76<script type="module" crossorigin src="/assets/index-D6uL_aXl.js"></script>
76
77    <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-QTnfLwEv.js">
78    <link rel="modulepreload" crossorigin href="/assets/lucide-icons-GmG7O7nz.js">
79    <link rel="modulepreload" crossorigin href="/assets/vendor-nostr-B8luZNPL.js">
80    <link rel="modulepreload" crossorigin href="/assets/vendor-radix-BdOCIdXO.js">
81    <link rel="modulepreload" crossorigin href="/assets/vendor-react-Cj-tKOwh.js">
82    <link rel="modulepreload" crossorigin href="/assets/dist-BcvA-GRa.js">
83    <link rel="modulepreload" crossorigin href="/assets/kvCache-DmzGwgBm.js">
84    <link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-CZLUN3pe.js">
85    <link rel="modulepreload" crossorigin href="/assets/useToast-BaojZlzQ.js">
86    <link rel="modulepreload" crossorigin href="/assets/platform-CX72QBWD.js">
87    <link rel="modulepreload" crossorigin href="/assets/useCurrentUser-D4QnF4TO.js">
88    <link rel="modulepreload" crossorigin href="/assets/protocol-Cbby3CJU.js">
89    <link rel="modulepreload" crossorigin href="/assets/useAppContext-Dheo3zbF.js">
90    <link rel="modulepreload" crossorigin href="/assets/publishOutbox-eA4L7GmU.js">
91    <link rel="modulepreload" crossorigin href="/assets/useNostrPublish-DaUWpAsr.js">
92    <link rel="modulepreload" crossorigin href="/assets/useMuteList-DSGedOi-.js">
93    <link rel="modulepreload" crossorigin href="/assets/mediaPolicy-D2mJJ8_m.js">
94    <link rel="modulepreload" crossorigin href="/assets/useBlossomServers-BenlNkdZ.js">
95    <link rel="modulepreload" crossorigin href="/assets/useRemoveRailKey-BCWvLUGJ.js">
96    <link rel="modulepreload" crossorigin href="/assets/silentPaymentsCore-BQkvFdYF.js">
97    <link rel="modulepreload" crossorigin href="/assets/nostrId-CuDCNeUw.js">
98    <link rel="modulepreload" crossorigin href="/assets/resolvePubkey-ObgiCMT-.js">
99    <link rel="modulepreload" crossorigin href="/assets/shareOrigin-CkUxYn2H.js">
100    <link rel="stylesheet" crossorigin href="/assets/index-BwiPh5Lt.css">
101  
101<script type="module" async src="/_npanel/script.js?v=52264416a644aff8"></script>
101</head>
102  <body>
103    <!-- Static boot splash: the same animated Armada crest as BootSplash.tsx,
104         inlined so it paints on the very first frame — before the JS bundle
105         parses, the provider tree mounts, and the first lazy route chunk loads.
106         Without it, an APK cold start (logged in) showed a blank themed
107         background for a few seconds until React could render its own splash.
108         React's createRoot(#root).render() replaces these children on mount,
109         so it disappears the moment the app paints. Uses the CSS vars theme.js
110         set on :root before this markup, so it matches the persisted theme. -->
111    <div id="root">
112      <div id="boot-splash" role="status" aria-label="Loading" style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:hsl(var(--background, 260 22% 9%));">
113        <!-- Hidden until the script below decides this launch isn't headed for
114             /welcome. A display:none element doesn't animate, so revealing it
115             starts the draw at frame one rather than mid-stroke. -->
116        <svg id="boot-mark" width="96" height="96" viewBox="0 0 128 128" fill="none" role="img" aria-label="Armada logo" style="display:none;filter:drop-shadow(0 8px 24px hsl(var(--primary, 330 90% 62%) / 0.25));">
117          <!-- Wake: each line sweeps open from the centerline (x=64, also every
118               line's own midpoint), then scans slowly in and out on its own
119               loop. Both are scaleX about that centerline, split across the
120               wrapper and the path so they don't fight over one transform. -->
121          <g fill="hsl(var(--accent2, 180 90% 55%))">
122            <g style="transform-origin:64px 0;animation:armada-wake 6s ease-in-out 0.9s infinite;">
123              <path d="M95.4 104.865H32.59c-1.18 0-2.14-.96-2.14-2.14s.96-2.14 2.14-2.14H95.4c1.18 0 2.14.96 2.14 2.14s-.96 2.14-2.14 2.14z" style="transform-origin:64px 0;animation:armada-sweep 0.52s cubic-bezier(0.22,1,0.36,1) both;"></path>
124            </g>
125            <g style="transform-origin:64px 0;animation:armada-wake 6s ease-in-out 1.5s infinite;">
126              <path d="M83.98 115.565H44.01a1.43 1.43 0 1 1 0-2.86h39.97a1.43 1.43 0 1 1 0 2.86z" style="transform-origin:64px 0;animation:armada-sweep 0.52s cubic-bezier(0.22,1,0.36,1) 0.07s both;"></path>
127            </g>
128            <g style="transform-origin:64px 0;animation:armada-wake 6s ease-in-out 2.1s infinite;">
129              <path d="M73.99 123.775H54.01a1.071 1.071 0 0 1 0-2.14h19.98a1.071 1.071 0 0 1 0 2.14z" style="transform-origin:64px 0;animation:armada-sweep 0.52s cubic-bezier(0.22,1,0.36,1) 0.14s both;"></path>
130            </g>
131          </g>
132          <!-- Sail, drawn in three stacked copies: halo sheen, fill, and the
133               hairline trace on top (pathLength="1" normalizes the dash). -->
134          <path d="M64 4.225l-39.97 88.5h17.13l2.31-5.2 2.76-6.22-2.22-1.43-1.42-12.84h9.99l4.89-11.01L64 41.335l11.42 25.7h9.99l-1.43 12.84-2.22 1.43 2.77 6.22 2.31 5.2h17.13z" fill="hsl(var(--primary, 330 90% 62%))" style="opacity:0;filter:drop-shadow(0 0 10px hsl(var(--primary, 330 90% 62%) / 0.6));animation:armada-sheen 0.9s ease-in-out 0.64s both;"></path>
135          <path d="M64 4.225l-39.97 88.5h17.13l2.31-5.2 2.76-6.22-2.22-1.43-1.42-12.84h9.99l4.89-11.01L64 41.335l11.42 25.7h9.99l-1.43 12.84-2.22 1.43 2.77 6.22 2.31 5.2h17.13z" fill="hsl(var(--primary, 330 90% 62%))" style="animation:armada-ink 0.42s ease-out 0.4s both;"></path>
136          <path d="M64 4.225l-39.97 88.5h17.13l2.31-5.2 2.76-6.22-2.22-1.43-1.42-12.84h9.99l4.89-11.01L64 41.335l11.42 25.7h9.99l-1.43 12.84-2.22 1.43 2.77 6.22 2.31 5.2h17.13z" pathLength="1" fill="none" stroke="hsl(var(--primary, 330 90% 62%))" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="opacity:0;stroke-dasharray:1;animation:armada-trace 0.78s cubic-bezier(0.65,0,0.35,1) 0.08s both;"></path>
137          <!-- Waterline caret, inked in last. -->
138          <path d="M76.84 79.165c-.15 0-.31-.05-.44-.15l-12.41-9.65-12.41 9.65c-.31.24-.76.19-1-.13a.706.706 0 0 1 .13-1l12.85-9.99c.26-.2.62-.2.88 0l12.85 9.99a.715.715 0 0 1-.43 1.28z" fill="hsl(var(--primary, 330 90% 62%))" fill-opacity="0.85" style="animation:armada-ink 0.32s ease-out 0.86s both;"></path>
139        </svg>
140      </div>
141    </div>
142    <!-- Reveals the mark above unless this launch is headed for /welcome (see
143         the file for why). Must stay HERE, after the splash markup it reads.
144         External because the policy above permits no inline script. -->
145    
145<script src="/boot-splash.js"></script>
145
146    <style>
147      /* Keep in sync with ArmadaCrestKeyframes in src/components/brand/ArmadaCrest.tsx.
148         Every element's base style is its final resting state and the keyframes
149         supply only the entrance, so killing them below lands on the finished
150         mark rather than a half-drawn one. */
151      @keyframes armada-trace { 0% { opacity: 1; stroke-dashoffset: 1; } 76% { opacity: 1; stroke-dashoffset: 0; } 100% { opacity: 0; stroke-dashoffset: 0; } }
152      @keyframes armada-ink { from { opacity: 0; } to { opacity: 1; } }
153      @keyframes armada-sheen { 0%, 100% { opacity: 0; } 45% { opacity: 1; } }
154      @keyframes armada-sweep { from { opacity: 0; transform: scaleX(0.15); } to { opacity: 1; transform: scaleX(1); } }
155      @keyframes armada-wake { 0%, 100% { transform: scaleX(1); } 50% { transform: scaleX(0.78); } }
156      @media (prefers-reduced-motion: reduce) { #boot-splash [style*="animation"] { animation: none !important; } }
157    </style>
158  </body>
159</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.