site-sirius-x: use the Sirius.X brand mark, drop trailing slashes
Star emoji swapped for the site's own 4-point sparkle mark — same SVG
that ships as the favicon — everywhere it appeared: the topnav brand,
the hero mark, the "you're here" pill on the family-of-.x panel, the
footer, register.html, portal.html, tld.html, market/, docs/, admin/,
brand/, storage/, theseus/, studio.html, site-footer.js. Anyone who
opens Sirius.X now sees the acid-green sparkle instead of a browser
star emoji.
Internal links normalised to no trailing slash — href="./theseus/"
became href="./theseus" (Theseus, docs, market, admin). Cleaner URLs
in the address bar and no double-slash redirect step on the mirrors.
2026-09-20 17:49:04 +02:00
<!doctype html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< title > Storage — Sirius.X (wireframe)< / title >
< meta name = "description" content = "Wireframe for the Sirius.X portal Storage tab. Per-user Sia storage on Hephaestus. Not wired to a backend." >
< link rel = "icon" href = "../assets/favicon.svg" type = "image/svg+xml" >
< link rel = "mask-icon" href = "../assets/favicon.svg" color = "#d6ff3d" >
< 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:opsz,wght@9..144,300;9..144,400;9..144,500;9..144,600;9..144,700&family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel = "stylesheet" >
< style >
:root{
--bg:#050810; --panel:#141a24; --panel2:#0a0f1c; --line:rgba(255,255,255,.06);
--sky-mid:#0a0f1c; --sky-rim:#131a2a;
--ink:#f1f4fa; --mut:#b8c2d4; --dim:#6a7488; --acid:#d6ff3d;
--chain-native:#0AC18E; --forge:#ff8c00;
--ok:#4fd1a5; --taken:#f6768a; --warn:#ffc75f;
--serif:'Fraunces',Georgia,serif;
--sans:'DM Sans','Inter',system-ui,sans-serif;
--mono:'JetBrains Mono',ui-monospace,monospace;
}
*{box-sizing:border-box}
body{margin:0;
background:radial-gradient(ellipse 1200px 600px at 50% -5%,var(--sky-rim) 0%,transparent 60%),
radial-gradient(ellipse 900px 500px at 100% 100%,var(--sky-mid) 0%,transparent 55%),
radial-gradient(ellipse 900px 500px at 0% 100%,#0c1424 0%,transparent 55%),
var(--bg);
background-attachment:fixed;
color:var(--ink);font:15px/1.55 var(--sans);min-height:100vh;font-feature-settings:"ss01","ss02"}
h1,h2,h3{font-family:var(--serif);font-feature-settings:"ss01","ss02"}
code,.mono{font-family:var(--mono)}
a{color:var(--acid);text-decoration:none}
/* topnav (matches portal) */
.topnav{position:sticky;top:0;z-index:20;display:flex;gap:2px;align-items:center;flex-wrap:wrap;
padding:10px 1.2rem;background:rgba(11,14,20,.82);backdrop-filter:blur(10px)}
.topnav .brand{font-weight:600;color:var(--ink);text-decoration:none;margin-right:14px;font-size:15px;letter-spacing:.2px}
.topnav .brand .g{color:var(--acid)}
.topnav a{color:var(--mut);text-decoration:none;padding:6px 12px;border-radius:8px;font-size:14px}
.topnav a:hover{color:var(--ink);background:var(--panel)}
.topnav a.here{color:var(--acid);background:rgba(214,255,61,.08)}
.topnav a.portal{margin-left:auto;background:rgba(214,255,61,.10);color:var(--acid);font-weight:500}
/* dashboard shell */
.dash{display:grid;grid-template-columns:236px minmax(0,1fr);gap:26px;max-width:1200px;margin:0 auto;padding:1.4rem 1.2rem 3rem}
@media (min-width:1280px){
.dash{max-width:1720px;grid-template-columns:260px minmax(0,1fr);gap:34px;padding:1.6rem 2rem 3rem}
}
@media (max-width:800px){
.dash{grid-template-columns:1fr;gap:14px}
.side{position:static}
}
.side{position:sticky;top:68px;align-self:start;display:flex;flex-direction:column;gap:4px}
.side .who{padding:12px 14px;border-radius:12px;background:var(--panel);border:1px solid var(--line);margin-bottom:8px}
.side .who .lbl{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim)}
.side .who .addr{font-family:var(--mono);font-size:12px;color:var(--ink);word-break:break-all;margin-top:4px}
.side .who .net{font-size:11.5px;color:var(--dim);margin-top:4px}
.side .grp{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim);padding:12px 14px 4px}
.side .sep{height:1px;background:var(--line);margin:8px 6px}
.side button.item,.side a.item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:9px 12px;border-radius:10px;
background:transparent;border:1px solid transparent;color:var(--mut);font:inherit;font-size:14px;cursor:pointer;text-decoration:none;transition:all .12s}
.side .item .ic{width:20px;text-align:center;flex:none;opacity:.9}
.side .item .cnt{margin-left:auto;font-family:var(--mono);font-size:11px;padding:1px 7px;border-radius:999px;background:rgba(255,255,255,.08);color:var(--ink)}
.side .item:hover{color:var(--ink);background:rgba(255,255,255,.04)}
.side .item.active{color:var(--acid);background:rgba(214,255,61,.08);border-color:rgba(214,255,61,.18)}
.side .item.active .cnt{background:rgba(214,255,61,.2);color:var(--acid)}
/* content shared */
.content{min-width:0}
.ph{display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;align-items:flex-start;margin-bottom:14px}
.ph h2{font-size:1.35rem;margin:0}
.ph p{color:var(--mut);margin:.3rem 0 0;max-width:640px}
.card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:20px 22px}
.card + .card{margin-top:14px}
.btn{display:inline-flex;align-items:center;gap:6px;text-decoration:none;padding:9px 16px;border-radius:10px;background:#4b7bec;color:#fff;font-size:14px;border:none;cursor:pointer;font-family:inherit;line-height:1.2}
.btn.ghost{background:transparent;border:1px solid var(--line);color:var(--ink)}
.btn.acid{background:var(--acid);color:#0b0e14;font-weight:600}
.btn.danger{background:rgba(246,118,138,.14);color:var(--taken);border:1px solid rgba(246,118,138,.35)}
.btn.small{padding:6px 11px;font-size:12.5px}
.btn:hover{filter:brightness(1.12)}
.btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
.badge{display:inline-block;font-size:11px;padding:2px 9px;border-radius:999px;font-weight:600;line-height:1.6}
.b-x{background:rgba(214,255,61,.14);color:var(--acid)}
.b-warn{background:rgba(255,199,95,.14);color:var(--warn)}
.b-ok{background:rgba(79,209,165,.14);color:var(--ok)}
.b-off{background:rgba(246,118,138,.14);color:var(--taken)}
.b-dim{background:rgba(255,255,255,.06);color:var(--mut)}
.b-native{background:rgba(10,193,142,.14);color:var(--chain-native)}
.b-forge{background:rgba(255,140,0,.14);color:var(--forge)}
.muted{color:var(--mut);font-size:13px}
.dim{color:var(--dim);font-size:12.5px}
.hidden{display:none !important}
/* ---------- storage layout ---------- */
.quota{display:flex;flex-direction:column;gap:14px}
.quota-hdr{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.quota-hdr .tier-name{font-family:var(--serif);font-size:1.35rem;font-weight:500}
.quota-hdr .quota-line{font-family:var(--mono);color:var(--mut);font-size:14px}
.quota-hdr .quota-line b{color:var(--ink);font-weight:500}
.quota-hdr .renew{font-size:12.5px;color:var(--dim);margin-left:auto}
.bar{width:100%;height:10px;border-radius:999px;background:rgba(255,255,255,.04);overflow:hidden;border:1px solid var(--line)}
.bar > .fill{height:100%;background:linear-gradient(90deg,var(--acid),#a8e600);border-radius:999px;transition:width .3s}
.bar.warn > .fill{background:linear-gradient(90deg,var(--warn),#f59d00)}
.bar.over > .fill{background:linear-gradient(90deg,var(--taken),#e04e4e)}
.quota-detail{display:flex;gap:20px;flex-wrap:wrap;font-size:12.5px;color:var(--dim)}
.quota-detail b{color:var(--mut);font-weight:500;font-family:var(--mono)}
/* file browser */
.browser{display:grid;grid-template-columns:180px minmax(0,1fr);gap:16px;margin-top:14px}
@media (max-width:640px){.browser{grid-template-columns:1fr}}
.folders{display:flex;flex-direction:column;gap:2px;padding:4px 0}
.folders .fh{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim);padding:6px 10px 4px}
.folders button{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:8px;background:transparent;border:1px solid transparent;color:var(--mut);font:inherit;font-size:13.5px;cursor:pointer;text-align:left;width:100%}
.folders button .ic{width:16px;text-align:center;opacity:.85}
.folders button:hover{color:var(--ink);background:rgba(255,255,255,.04)}
.folders button.active{color:var(--acid);background:rgba(214,255,61,.06);border-color:rgba(214,255,61,.15)}
.folders button .cnt{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--dim)}
.files{display:flex;flex-direction:column;gap:1px;background:var(--panel2);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.files .toolbar{display:flex;gap:8px;padding:10px 14px;border-bottom:1px solid var(--line);align-items:center;background:rgba(255,255,255,.02)}
.files .toolbar .path{font-family:var(--mono);font-size:12.5px;color:var(--mut);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.files .toolbar .path .sep{color:var(--dim);margin:0 4px}
.files .toolbar .path .lock{color:var(--acid);margin-right:6px}
.files .toolbar .path .globe{color:var(--chain-native);margin-right:6px}
.files .row{display:grid;grid-template-columns:1fr 90px 110px 40px;gap:12px;align-items:center;padding:10px 14px;transition:background .1s}
.files .row:hover{background:rgba(255,255,255,.03)}
.files .row + .row{border-top:1px solid rgba(255,255,255,.03)}
.files .row.head{color:var(--dim);font-family:var(--mono);font-size:10.5px;letter-spacing:.15em;text-transform:uppercase;padding:8px 14px}
.files .row.head:hover{background:transparent}
.files .row .name{display:flex;gap:8px;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.files .row .name .ic{width:18px;text-align:center;flex:none}
.files .row .size{font-family:var(--mono);font-size:12px;color:var(--mut);text-align:right}
.files .row .date{font-family:var(--mono);font-size:12px;color:var(--dim)}
.files .row .more{color:var(--dim);cursor:pointer;text-align:right;padding:0 4px;user-select:none}
.files .row .more:hover{color:var(--ink)}
.drop{margin:12px 14px 14px;border:1.5px dashed rgba(255,255,255,.12);border-radius:10px;padding:22px;text-align:center;color:var(--mut);font-size:13.5px;transition:all .15s}
.drop.active{border-color:var(--acid);background:rgba(214,255,61,.03);color:var(--ink)}
.drop b{color:var(--acid);font-weight:500}
.drop .k{font-family:var(--mono);color:var(--dim);font-size:12px;display:block;margin-top:4px}
/* upgrade modal */
.modal-scrim{position:fixed;inset:0;z-index:100;background:rgba(4,6,11,.72);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;padding:20px}
.modal-scrim.show{display:flex}
.modal{background:var(--panel);border:1px solid var(--line);border-radius:16px;max-width:640px;width:100%;max-height:calc(100vh - 40px);overflow:auto;padding:22px 26px}
.modal h2{margin:0 0 6px;font-size:1.4rem}
.modal .close{float:right;background:none;border:0;color:var(--dim);font-size:22px;cursor:pointer;line-height:1;padding:0 4px;margin:-4px -8px 0 0}
.modal .close:hover{color:var(--ink)}
.plans{display:flex;flex-direction:column;gap:10px;margin:14px 0 18px}
.plan{display:flex;align-items:center;gap:14px;padding:14px 16px;border-radius:12px;border:1px solid var(--line);cursor:pointer;transition:all .12s;background:var(--panel2)}
.plan:hover{border-color:rgba(214,255,61,.28)}
.plan.sel{border-color:var(--acid);background:rgba(214,255,61,.05)}
.plan .radio{width:16px;height:16px;border-radius:50%;border:1.5px solid var(--dim);flex:none;position:relative}
.plan.sel .radio{border-color:var(--acid)}
.plan.sel .radio::after{content:'';position:absolute;inset:3px;background:var(--acid);border-radius:50%}
.plan .nm{flex:1;font-family:var(--serif);font-size:1.05rem;font-weight:500}
.plan .size{font-family:var(--mono);font-size:12.5px;color:var(--mut);width:130px}
.plan .price{font-family:var(--mono);font-size:14px;color:var(--ink);font-weight:500;width:80px;text-align:right}
.plan.current{opacity:.6;cursor:default}
.plan.current .nm::after{content:' — current';color:var(--dim);font-family:var(--sans);font-size:12px;font-weight:400}
.plan .save{font-family:var(--mono);font-size:10.5px;color:var(--acid);letter-spacing:.1em;margin-left:8px}
.pay-box{padding:18px 20px;border-radius:12px;background:linear-gradient(135deg,rgba(214,255,61,.04),rgba(10,193,142,.02));border:1px solid rgba(214,255,61,.16)}
.pay-box .amt{font-family:var(--serif);font-size:2rem;color:var(--acid);font-weight:400;letter-spacing:-.02em}
.pay-box .amt sub{font-family:var(--mono);font-size:12px;color:var(--mut);letter-spacing:0;vertical-align:baseline;margin-left:6px}
.pay-box .oracle{font-family:var(--mono);font-size:11.5px;color:var(--dim);margin-top:4px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pay-box .dot{width:6px;height:6px;border-radius:50%;background:var(--ok);animation:pulse 2s infinite ease-in-out}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
.modal .actions{display:flex;gap:10px;margin-top:16px;flex-wrap:wrap;align-items:center}
.modal .actions .btn{flex:1;justify-content:center;padding:12px 18px;font-size:14.5px}
.modal .actions .btn.acid{flex:2}
.modal .alt{font-size:12px;color:var(--dim);margin-top:12px;text-align:center}
.modal .alt a{color:var(--mut)}
/* confirmation banner */
.banner{padding:14px 18px;border-radius:12px;background:rgba(79,209,165,.06);border:1px solid rgba(79,209,165,.24);color:var(--ink);margin-bottom:14px;display:flex;gap:12px;align-items:center}
.banner.warn{background:rgba(255,199,95,.06);border-color:rgba(255,199,95,.24)}
.banner.err{background:rgba(246,118,138,.06);border-color:rgba(246,118,138,.24)}
.banner .ic{font-size:20px;flex:none}
.banner .txt{flex:1;font-size:13.5px;color:var(--mut)}
.banner .txt b{color:var(--ink);font-weight:500}
.banner .close{background:none;border:0;color:var(--dim);font-size:18px;cursor:pointer;padding:0 4px}
.banner .close:hover{color:var(--ink)}
/* wireframe state picker (dev-only) */
.wf-picker{position:fixed;bottom:16px;right:16px;z-index:50;padding:8px 10px;border-radius:12px;background:rgba(20,26,36,.94);border:1px solid var(--line);font-family:var(--mono);font-size:11px;color:var(--dim);display:flex;flex-direction:column;gap:4px;backdrop-filter:blur(10px)}
.wf-picker .h{color:var(--acid);text-transform:uppercase;letter-spacing:.15em;font-size:9.5px;margin-bottom:2px}
.wf-picker button{background:transparent;border:0;color:var(--mut);cursor:pointer;font-family:inherit;font-size:11.5px;padding:3px 6px;border-radius:6px;text-align:left}
.wf-picker button:hover{color:var(--ink);background:rgba(255,255,255,.04)}
.wf-picker button.active{color:var(--acid);background:rgba(214,255,61,.08)}
< / style >
< / head >
< body >
< nav class = "topnav" >
site-sirius-x: only paint .X acid; keep Sirius white
Brand button was wrapping the whole "Sirius.X" label in <span class="g">,
so the entire name rendered acid green. Consistency across the ecosystem
is Sirius (ink) + .X (acid), like Theseus.X and Hephaestus.X. Split the
span across every page (index, tld, portal, admin, brand, docs, market,
storage, theseus/) so only the .X tail carries the acid tint.
2026-09-22 01:28:25 +02:00
< a class = "brand" href = "../" > < svg width = "18" height = "18" viewBox = "0 0 64 64" style = "vertical-align:-4px;margin-right:6px" aria-hidden = "true" > < rect width = "64" height = "64" rx = "12" fill = "#0b0e14" / > < path d = "M32 4 L36.4 27.6 L60 32 L36.4 36.4 L32 60 L27.6 36.4 L4 32 L27.6 27.6 Z" fill = "#d6ff3d" / > < / svg > Sirius< span class = "g" > .X< / span > < / a >
site-sirius-x: use the Sirius.X brand mark, drop trailing slashes
Star emoji swapped for the site's own 4-point sparkle mark — same SVG
that ships as the favicon — everywhere it appeared: the topnav brand,
the hero mark, the "you're here" pill on the family-of-.x panel, the
footer, register.html, portal.html, tld.html, market/, docs/, admin/,
brand/, storage/, theseus/, studio.html, site-footer.js. Anyone who
opens Sirius.X now sees the acid-green sparkle instead of a browser
star emoji.
Internal links normalised to no trailing slash — href="./theseus/"
became href="./theseus" (Theseus, docs, market, admin). Cleaner URLs
in the address bar and no double-slash redirect step on the mirrors.
2026-09-20 17:49:04 +02:00
< a href = "../tld.html" > 🌐 TLD< / a >
< a href = "../market/" > 🛒 Market< / a >
< a href = "../portal.html" class = "portal here" > 🔑 Storage< / a >
< / nav >
< div class = "dash" >
<!-- ============ sidebar ============ -->
< aside class = "side" aria-label = "Dashboard menu" >
< div class = "who" >
< div class = "lbl" > Signed in< / div >
< div class = "addr" > bitcoincash:qzrp…4qtx< / div >
< div class = "net" > chipnet · 42,180 sat< / div >
< / div >
< button class = "item" > < span class = "ic" > 🎨< / span > Web-Builder< / button >
< button class = "item" > < span class = "ic" > 🌐< / span > Domain names< span class = "cnt" > 3< / span > < / button >
< button class = "item" > < span class = "ic" > 🏷< / span > My TLDs< span class = "cnt" > 1< / span > < / button >
< button class = "item active" > < span class = "ic" > 📦< / span > Storage< span class = "cnt" id = "side-quota" > 120M< / span > < / button >
< div class = "sep" > < / div >
< button class = "item" > < span class = "ic" > ⚙< / span > Settings< / button >
< button class = "item" > < span class = "ic" > 🚪< / span > Sign out< / button >
< / aside >
<!-- ============ content ============ -->
< main class = "content" >
<!-- Confirmation banners appear here based on wireframe state -->
< div id = "banner-confirming" class = "banner warn hidden" >
< div class = "ic" > ⏳< / div >
< div class = "txt" > < b > Confirming payment.< / b > 0.0462 BCH received — waiting for 1 confirmation (~10 min). Your plan activates automatically.< / div >
< button class = "close" onclick = "dismissBanner(this)" > × < / button >
< / div >
< div id = "banner-upgraded" class = "banner hidden" >
< div class = "ic" > ✓< / div >
< div class = "txt" > < b > Silent Max is active.< / b > Quota bumped to 50 GB private. Renews 2026-10-20.< / div >
< button class = "close" onclick = "dismissBanner(this)" > × < / button >
< / div >
< div id = "banner-grace" class = "banner err hidden" >
< div class = "ic" > ⚠< / div >
< div class = "txt" > < b > Over quota.< / b > Files are read-only for 27 more days. Upgrade or delete files to restore write access.< / div >
< button class = "close" onclick = "dismissBanner(this)" > × < / button >
< / div >
< div class = "ph" >
< div >
< h2 > Storage< / h2 >
< p id = "hdr-sub" > Files you host on Silent Mode's Sia backend. Public files get a URL anyone can open;
private files are encrypted in your browser with a key only your wallet can derive.< / p >
< / div >
< div style = "display:flex;gap:8px;flex-wrap:wrap" >
< button class = "btn ghost small" > ↻ Refresh< / button >
< button class = "btn acid small" id = "upgrade-btn" onclick = "openModal()" > Upgrade< / button >
< / div >
< / div >
<!-- Quota card -->
< section class = "card" >
< div class = "quota" >
< div class = "quota-hdr" >
< span class = "tier-name" id = "tier-name" > Silent Free< / span >
< span class = "badge b-dim" id = "tier-badge" > Free< / span >
< span class = "quota-line" > < b id = "q-used" > 120 MB< / b > / < span id = "q-cap" > 500 MB< / span > private< / span >
< span class = "renew" id = "renew-line" style = "display:none" > renews < b id = "renew-date" > 2026-10-20< / b > < / span >
< / div >
< div class = "bar" id = "q-bar" > < div class = "fill" id = "q-fill" style = "width:24%" > < / div > < / div >
< div class = "quota-detail" >
< span > Public: < b > 2.4 GB< / b > · unlimited< / span >
< span > Files: < b > 47< / b > < / span >
< span > Encryption: < b > on< / b > for private< / span >
< span id = "credit-line" style = "display:none" > Credit: < b > $0.00< / b > < / span >
< / div >
< / div >
< / section >
<!-- File browser -->
< section class = "card" style = "padding:14px 14px 0" >
< div class = "browser" >
< nav class = "folders" >
< div class = "fh" > Folders< / div >
< button class = "active" data-folder = "private" >
< span class = "ic" style = "color:var(--acid)" > 🔒< / span > Private
< span class = "cnt" > 12< / span >
< / button >
< button data-folder = "public" >
< span class = "ic" style = "color:var(--chain-native)" > 🌐< / span > Public
< span class = "cnt" > 35< / span >
< / button >
< button data-folder = "shared" >
< span class = "ic" > 🔗< / span > Shared
< span class = "cnt" > 2< / span >
< / button >
< div class = "fh" style = "margin-top:8px" > Actions< / div >
< button > < span class = "ic" > + < / span > New folder< / button >
< button > < span class = "ic" > ↑< / span > Upload< / button >
< / nav >
< div class = "files" >
< div class = "toolbar" >
< div class = "path" >
< span class = "lock" > 🔒< / span >
< span > private< / span >
< span class = "sep" > /< / span >
< span > projects< / span >
< / div >
< button class = "btn ghost small" > Share< / button >
< / div >
< div class = "row head" >
< span > Name< / span >
< span class = "size" style = "text-align:right" > Size< / span >
< span class = "date" > Modified< / span >
< span > < / span >
< / div >
< div class = "row" >
< span class = "name" > < span class = "ic" > 📁< / span > silentmode-notes< / span >
< span class = "size" > —< / span >
< span class = "date" > 3d ago< / span >
< span class = "more" > ⋯< / span >
< / div >
< div class = "row" >
< span class = "name" > < span class = "ic" > 📁< / span > contracts< / span >
< span class = "size" > —< / span >
< span class = "date" > 1w ago< / span >
< span class = "more" > ⋯< / span >
< / div >
< div class = "row" >
< span class = "name" > < span class = "ic" > 📄< / span > hestia-outline.md< / span >
< span class = "size" > 14 KB< / span >
< span class = "date" > just now< / span >
< span class = "more" > ⋯< / span >
< / div >
< div class = "row" >
< span class = "name" > < span class = "ic" > 📄< / span > oracle-notes.txt< / span >
< span class = "size" > 4 KB< / span >
< span class = "date" > 2h ago< / span >
< span class = "more" > ⋯< / span >
< / div >
< div class = "row" >
< span class = "name" > < span class = "ic" > 🗄< / span > backup-2026-09-18.tar.gz< / span >
< span class = "size" > 86 MB< / span >
< span class = "date" > 2d ago< / span >
< span class = "more" > ⋯< / span >
< / div >
< div class = "row" >
< span class = "name" > < span class = "ic" > 🖼< / span > diagram.png< / span >
< span class = "size" > 220 KB< / span >
< span class = "date" > 4d ago< / span >
< span class = "more" > ⋯< / span >
< / div >
< div class = "row" >
< span class = "name" > < span class = "ic" > 🔑< / span > keys.json.gpg< / span >
< span class = "size" > 2 KB< / span >
< span class = "date" > 2w ago< / span >
< span class = "more" > ⋯< / span >
< / div >
< div class = "drop" id = "drop" >
Drag files here, or < b > click to browse< / b >
< span class = "k" > Encrypted in your browser before upload · max 100 MB per file on Free< / span >
< / div >
< / div >
< / div >
< / section >
<!-- CLI hint -->
< section class = "card" style = "margin-top:14px" >
< div style = "display:flex;gap:10px;align-items:baseline;justify-content:space-between;flex-wrap:wrap" >
< div >
< h3 style = "margin:0 0 4px" > CLI access< / h3 >
< p class = "muted" style = "margin:0" > Upload from a script or CI with your Silent Mode PAT.
Encryption still happens client-side.< / p >
< / div >
< span class = "badge b-dim" id = "cli-tier" > Free — via gateway< / span >
< / div >
< pre style = "margin:12px 0 0;padding:12px 14px;background:var(--panel2);border:1px solid var(--line);border-radius:10px;font-family:var(--mono);font-size:12.5px;color:var(--mut);overflow:auto;line-height:1.6" > < span style = "color:var(--dim)" > # upload a private file< / span >
curl -H "Authorization: token $HESTIA_PAT" \
--data-binary @notes.md \
https://storage.silentmode.st/u/48291/private/notes.md
< span style = "color:var(--dim)" > # list your files< / span >
curl -H "Authorization: token $HESTIA_PAT" \
https://storage.silentmode.st/u/48291/list< / pre >
< p class = "muted" id = "cli-hint" style = "margin:10px 0 0;font-size:12.5px" >
< span class = "badge b-warn" > Pro / Max< / span > get their own S3 credentials for direct
< code > rclone< / code > / < code > aws s3< / code > use.
< / p >
< / section >
< / main >
< / div >
<!-- ============ upgrade modal ============ -->
< div class = "modal-scrim" id = "modal" >
< div class = "modal" >
< button class = "close" onclick = "closeModal()" > × < / button >
< h2 > Plans< / h2 >
< p class = "muted" > Priced in USD, paid in BCH at the live oracle rate. All plans include unlimited public storage. Encryption is client-side, wallet-derived, always on for private files.< / p >
< div class = "plans" id = "plans" >
< div class = "plan current" data-tier = "free" >
< span class = "radio" > < / span >
< span class = "nm" > Silent Free< / span >
< span class = "size" > 500 MB private< / span >
< span class = "price" > $0< / span >
< / div >
< div class = "plan" data-tier = "pro" onclick = "selectPlan('pro')" >
< span class = "radio" > < / span >
< span class = "nm" > Silent Pro< / span >
< span class = "size" > 2 GB private< / span >
< span class = "price" > $3< span class = "save" > ·25% off GH< / span > < / span >
< / div >
< div class = "plan sel" data-tier = "max" onclick = "selectPlan('max')" >
< span class = "radio" > < / span >
< span class = "nm" > Silent Max< / span >
< span class = "size" > 50 GB private< / span >
< span class = "price" > $16< span class = "save" > ·24% off GH< / span > < / span >
< / div >
< / div >
< div class = "pay-box" >
< div style = "display:flex;justify-content:space-between;align-items:baseline" >
< div >
< div class = "dim" style = "font-family:var(--mono);letter-spacing:.1em;text-transform:uppercase;font-size:10px" > Pay for 1 month< / div >
< div class = "amt" id = "pay-amt" > 0.0462 BCH< sub > ≈ $16.00< / sub > < / div >
< / div >
< span class = "badge b-native" id = "pay-tier" > Silent Max< / span >
< / div >
< div class = "oracle" >
< span class = "dot" > < / span >
< span > live oracle at < b style = "color:var(--mut)" id = "oracle-rate" > $346.40< / b > / BCH< / span >
< span > ·< / span >
< span id = "oracle-age" > quoted 00:14 ago< / span >
< span > ·< / span >
< span > refreshes in < span id = "oracle-refresh" > 04:46< / span > < / span >
< / div >
< / div >
< div class = "actions" >
< button class = "btn ghost" onclick = "closeModal()" > Cancel< / button >
< button class = "btn acid" onclick = "mockPay()" > Pay from wallet →< / button >
< / div >
< div class = "alt" >
also accepts: < a href = "#" > QR code< / a > · < a href = "#" > external wallet< / a > · < a href = "#" > on-chain address< / a >
< / div >
< / div >
< / div >
<!-- ============ wireframe state picker (dev only) ============ -->
< div class = "wf-picker" >
< div class = "h" > Wireframe state< / div >
< button class = "active" onclick = "setState('free')" > Free · default< / button >
< button onclick = "setState('confirming')" > Free · confirming< / button >
< button onclick = "setState('max-fresh')" > Max · just upgraded< / button >
< button onclick = "setState('max-half')" > Max · half full< / button >
< button onclick = "setState('grace')" > Free · over quota< / button >
< / div >
< script >
const PLAN = {
free: {name:'Silent Free', badge:'Free', badgeCls:'b-dim', used:120, cap:500, capUnit:'MB', price:0, bch:0},
pro: {name:'Silent Pro', badge:'Pro', badgeCls:'b-forge', used:1200, cap:2, capUnit:'GB', price:3, bch:0.00866},
max: {name:'Silent Max', badge:'Max', badgeCls:'b-native',used:24800, cap:50, capUnit:'GB', price:16, bch:0.04620},
};
let currentTier = 'free';
let selectedTier = 'max';
function selectPlan(t){
selectedTier = t;
document.querySelectorAll('.plan').forEach(p=>p.classList.toggle('sel', p.dataset.tier === t));
const p = PLAN[t];
document.getElementById('pay-amt').innerHTML = p.bch.toFixed(5) + ' BCH< sub > ≈ $' + p.price.toFixed(2) + '< / sub > ';
document.getElementById('pay-tier').className = 'badge ' + p.badgeCls;
document.getElementById('pay-tier').textContent = p.name;
}
function openModal(){ document.getElementById('modal').classList.add('show'); }
function closeModal(){ document.getElementById('modal').classList.remove('show'); }
function dismissBanner(el){ el.parentElement.classList.add('hidden'); }
function mockPay(){
closeModal();
setState('confirming');
// fake the SSE flow: confirming → upgraded after 3s
setTimeout(() => setState('max-fresh'), 3000);
}
function fmtBytes(x, unit){
if (unit === 'MB') return x < 1024 ? x + ' MB ' : ( x / 1024 ) . toFixed ( 1 ) + ' GB ' ;
if (unit === 'GB') return x < 1 ? Math . round ( x * 1024 ) + ' MB ' : x + ' GB ' ;
return x + ' ' + unit;
}
function setState(s){
// reset banners
['confirming','upgraded','grace'].forEach(k =>
document.getElementById('banner-' + k).classList.add('hidden'));
// reset state-picker button
document.querySelectorAll('.wf-picker button').forEach(b => b.classList.remove('active'));
(document.querySelector(`.wf-picker button[onclick*="${s}"]`) || {classList:{add:()=>{}}}).classList.add('active');
let tier='free', usedMB=120, capMB=500, capLabel='500 MB', tierLabel='Silent Free',
badgeCls='b-dim', badgeLbl='Free', renew=false, credit=false, cliBadge='Free — via gateway';
if (s === 'confirming') {
document.getElementById('banner-confirming').classList.remove('hidden');
}
if (s === 'max-fresh') {
tier='max'; usedMB=120; capMB=50*1024; capLabel='50 GB'; tierLabel='Silent Max';
badgeCls='b-native'; badgeLbl='Max'; renew=true;
cliBadge='Max — direct S3';
document.getElementById('banner-upgraded').classList.remove('hidden');
}
if (s === 'max-half') {
tier='max'; usedMB=25*1024; capMB=50*1024; capLabel='50 GB'; tierLabel='Silent Max';
badgeCls='b-native'; badgeLbl='Max'; renew=true;
cliBadge='Max — direct S3';
}
if (s === 'grace') {
tier='free'; usedMB=580; capMB=500; capLabel='500 MB'; tierLabel='Silent Free';
badgeCls='b-dim'; badgeLbl='Free (over quota)'; credit=true;
document.getElementById('banner-grace').classList.remove('hidden');
}
currentTier = tier;
document.getElementById('tier-name').textContent = tierLabel;
document.getElementById('tier-badge').className = 'badge ' + badgeCls;
document.getElementById('tier-badge').textContent = badgeLbl;
const pct = Math.min(100, Math.round((usedMB / capMB) * 100));
document.getElementById('q-used').textContent = usedMB < 1024 ? usedMB + ' MB ' : ( usedMB / 1024 ) . toFixed ( 1 ) + ' GB ' ;
document.getElementById('q-cap').textContent = capLabel;
document.getElementById('q-fill').style.width = pct + '%';
document.getElementById('q-bar').className = 'bar' + (pct >= 100 ? ' over' : pct >= 85 ? ' warn' : '');
document.getElementById('side-quota').textContent = usedMB < 1024 ? usedMB + ' M ' : ( usedMB / 1024 ) . toFixed ( 1 ) + ' G ' ;
document.getElementById('renew-line').style.display = renew ? '' : 'none';
document.getElementById('credit-line').style.display = credit ? '' : 'none';
document.getElementById('cli-tier').textContent = cliBadge;
document.getElementById('cli-tier').className = 'badge ' + (tier === 'free' ? 'b-dim' : tier === 'pro' ? 'b-forge' : 'b-native');
// update available plans in modal (highlight current, remove .current from others)
document.querySelectorAll('.plan').forEach(p => {
p.classList.toggle('current', p.dataset.tier === tier);
if (p.dataset.tier === tier) p.classList.remove('sel');
});
if (tier === 'free') selectPlan('max');
else if (tier === 'pro') selectPlan('max');
else selectPlan('max');
}
// fake oracle refresh countdown (visual only)
let refreshLeft = 286;
setInterval(() => {
refreshLeft = refreshLeft > 0 ? refreshLeft - 1 : 300;
const m = Math.floor(refreshLeft / 60);
const s = refreshLeft % 60;
const el = document.getElementById('oracle-refresh');
if (el) el.textContent = String(m).padStart(2,'0') + ':' + String(s).padStart(2,'0');
}, 1000);
setState('free');
< / script >
< / body >
< / html >