/** * build-docs.js — renders doc/*.md into real pages under /docs/. * * The documentation was already written and already good; it just was not on the web. * It shipped in the image as raw Markdown, served as application/octet-stream, and * robots.txt disallowed /doc/ — so the only text the site owned that answers a real * question ("how does SecureBit do key exchange", "what does SAS actually verify") * was invisible to search. Meanwhile the site's entire indexable surface was one * address repeated in thirteen languages, which is why every category query lands on * page three or worse. * * So each document gets its own URL, its own
([\s\S]*?)<\/p>/); if (!match) return ''; const text = match[1].replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim(); if (text.length <= 155) return text; const cut = text.slice(0, 155); return `${cut.slice(0, cut.lastIndexOf(' ')).replace(/[,;:.]$/, '')}…`; } // Self-contained and script-free. The CSP below is stricter than the app's for the // same reason the page has no bundle: nothing here needs to execute. const STYLE = ` :root { color-scheme: dark; } * { box-sizing: border-box; } body { margin: 0; background: #0f0f11; color: #d6d6dc; font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif; font-size: 16px; line-height: 1.68; } .wrap { max-width: 46rem; margin: 0 auto; padding: 28px 24px 90px; } .top { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: baseline; padding-bottom: 16px; margin-bottom: 40px; border-bottom: 1px solid rgba(255,255,255,.08); font-size: 13.5px; } .top a { color: #8a8a92; text-decoration: none; } .top a:hover, .top a:focus-visible { color: #f0892a; } .top .brand { color: #f0892a; font-weight: 700; letter-spacing: .04em; } .top .here { color: #d6d6dc; margin-inline-start: auto; } h1 { font-size: clamp(28px, 5vw, 36px); font-weight: 800; letter-spacing: -1px; line-height: 1.14; color: #f4f4f6; margin: 0 0 24px; } h2 { font-size: 22px; font-weight: 700; letter-spacing: -.4px; color: #f4f4f6; margin: 46px 0 12px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,.07); } h3 { font-size: 17.5px; font-weight: 700; color: #e8e8eb; margin: 30px 0 8px; } h4 { font-size: 15.5px; font-weight: 700; color: #e8e8eb; margin: 22px 0 6px; } p, li { color: #a9a9b3; } p { margin: 0 0 16px; } ul, ol { padding-inline-start: 22px; margin: 0 0 16px; } li { margin: 5px 0; } a { color: #f0892a; text-underline-offset: 2px; } strong { color: #e8e8eb; } code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: .88em; background: #17171c; border: 1px solid rgba(255,255,255,.07); border-radius: 4px; padding: 1px 5px; color: #e8e8eb; } pre { background: #0b0b0e; border: 1px solid rgba(255,255,255,.08); border-radius: 8px; padding: 14px 16px; overflow-x: auto; margin: 0 0 18px; } pre code { background: none; border: 0; padding: 0; font-size: 13px; line-height: 1.62; color: #c9c9d1; } .tablewrap { overflow-x: auto; margin: 0 0 20px; } table { border-collapse: collapse; width: 100%; font-size: 14.5px; min-width: 30rem; } th { text-align: start; color: #8a8a92; font-weight: 600; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; padding: 0 14px 8px 0; border-bottom: 1px solid rgba(255,255,255,.12); } td { padding: 9px 14px 9px 0; border-bottom: 1px solid rgba(255,255,255,.06); vertical-align: top; color: #a9a9b3; } td:first-child, th:first-child { padding-inline-start: 0; } blockquote { margin: 0 0 18px; padding: 2px 0 2px 16px; border-inline-start: 3px solid rgba(240,137,42,.4); color: #8a8a92; } hr { border: 0; border-top: 1px solid rgba(255,255,255,.08); margin: 34px 0; } img { max-width: 100%; height: auto; } a:focus-visible { outline: 2px solid #f0892a; outline-offset: 2px; border-radius: 2px; } .more { margin-top: 64px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.08); } .more h2 { font-size: 13px; letter-spacing: .12em; text-transform: uppercase; color: #6b6b73; border: 0; margin: 0 0 12px; padding: 0; font-weight: 700; } .more ul { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 4px 24px; } .more li { margin: 0; padding: 7px 0; border-bottom: 1px solid rgba(255,255,255,.05); font-size: 14.5px; } @media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } } `; /** * FAQ markup, built from the document's own