waybetter-for-x/apps/web/store/index.html
2026-10-01 06:01:13 +07:00

192 lines
12 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- seo -->
<meta name="theme-color" content="#07080c" />
<link rel="icon" type="image/svg+xml" href="/brand/wb-icon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/brand/wb-icon-32.png" />
<link rel="apple-touch-icon" href="/brand/wb-icon-256.png" />
<script>document.documentElement.classList.add('js');</script>
<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=Geist:wght@300..900&family=Geist+Mono:wght@400;500;600&family=Instrument+Serif:ital@1&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="../src/base.css" />
<link rel="stylesheet" href="../src/gallery.css" />
<link rel="stylesheet" href="../src/store.css" />
</head>
<body>
<a data-i18n="site.store.page.skipToTheStore" class="skip" href="#browse">Skip to the Store</a>
<header class="top">
<div class="wrap top-row">
<a class="mark" href="./" aria-label="wayBetter Store">
<img class="wb" src="/brand/wb-mark-simple.svg" alt="" width="43" height="24" />
<span class="mark-name" translate="no">wayBetter <span class="mark-sub">Store</span></span>
</a>
<nav data-i18n-aria-label="site.common.primary" class="top-nav" aria-label="Primary">
<a href="../" class="keep keep-sm nav-family">wayBetter</a>
<a data-i18n="site.common.store" href="./" aria-current="page">Store</a>
<a data-i18n="site.common.themes" href="./?kind=theme" data-store-link="theme">Themes</a>
<a data-i18n="site.common.plugins" href="./?kind=plugin" data-store-link="plugin">Plugins</a>
<a data-i18n="site.common.isItSafe" href="#installing">Is it safe?</a>
<a href="../x/">wayBetter for X</a>
<a data-i18n="site.common.publishYours" class="top-cta keep" href="submit/">Publish<span class="cta-more"> yours</span></a>
</nav>
<!-- lang:top -->
</div>
<div class="top-progress" aria-hidden="true"></div>
</header>
<main id="main">
<section class="st-hero">
<div class="st-hero-wash" aria-hidden="true"></div>
<div class="st-hero-dots" aria-hidden="true"></div>
<div class="wrap st-hero-grid">
<div class="st-hero-copy">
<p data-i18n="site.store.hero.waybetterStoreOneSignedCatalog" class="kicker"><span class="kicker-dot"></span><span class="foss" translate="no">(FOSS)</span> wayBetter Store &middot; one signed catalog</p>
<h1>
<span data-i18n="site.store.hero.makeEveryApp" class="h1-line">Make every app</span>
<span class="h1-line"><em data-i18n="site.store.hero.yours" class="grad">yours.</em></span>
</h1>
<p data-i18n="site.store.hero.themesAndPluginsForWaybetter" class="st-lede">
Themes and plugins for wayBetter apps. Every file is in one signed catalog, every
plugin says what it uses, and you read the code before anything installs. Free, open
source, no account.
</p>
<dl class="st-stats">
<div><dt data-i18n="site.common.themes">Themes</dt><dd><!-- store:total:theme --></dd></div>
<div><dt data-i18n="site.common.plugins">Plugins</dt><dd><!-- store:total:plugin --></dd></div>
<div><dt data-i18n="site.store.hero.apps">Apps</dt><dd><!-- store:total:apps --></dd></div>
<div><dt data-i18n="site.store.hero.signed">Signed</dt><dd class="st-stat-text">Ed25519</dd></div>
</dl>
</div>
<div class="st-art" aria-hidden="true"><!-- store:art --></div>
</div>
</section>
<section data-i18n-aria-label="site.store.browse.browseTheStore" class="st-browse" id="browse" aria-label="Browse the Store">
<div class="st-bar-wrap" data-store-sticky>
<div class="wrap">
<!-- store:bar -->
</div>
</div>
<div class="wrap">
<div data-store-shelves>
<!-- store:areas -->
<!-- store:featured -->
<!-- store:latest -->
</div>
<header class="st-shelf-head st-all-head">
<h2 data-i18n="site.store.browse.everything" class="st-h" data-store-heading>Everything</h2>
<p data-i18n="site.store.browse.items" aria-live="polite" data-store-count><!-- store:total:all --> items</p>
</header>
<div class="gal-grid" data-store-grid>
<!-- store:grid -->
</div>
<div class="st-empty" data-store-empty hidden>
<p class="st-empty-mark" aria-hidden="true">&empty;</p>
<h3 data-i18n="site.store.browse.nothingMatches" data-store-empty-title>Nothing matches.</h3>
<p data-i18n="site.store.browse.tryAnotherWordOrFewer">Try another word or fewer filters. If it does not exist yet, it can: a theme is one JSON file and a plugin is one JavaScript file.</p>
<div class="ctas">
<button data-i18n="site.store.browse.clearSearchAndFilters" class="btn btn-solid btn-sm" type="button" data-store-reset>Clear search and filters</button>
<a data-i18n="site.common.publishYourOwn" class="btn btn-ghost btn-sm" href="submit/">Publish your own</a>
</div>
</div>
<p data-i18n="site.store.browse.catalogUpdatedItemsTodayAre" class="gal-note">Catalog updated <!-- store:generated -->. Items today are for <!-- store:apps -->; every wayBetter app reads this same catalog and shows only its own.</p>
</div>
</section>
<section class="section section-tight st-safe" id="installing">
<div class="wrap">
<header class="sec-head">
<p data-i18n="site.store.installing.trustHowInstallingWorks" class="chapter"><b>Trust</b> How installing works</p>
<h2 data-i18n="site.store.installing.oneClickThenYouDecide" class="title">One click, then <em class="grad">you decide.</em></h2>
<p data-i18n="site.store.installing.nothingOnThisSiteCan" class="lead">Nothing on this site can install anything. A button here opens the app; the app checks the file and shows it to you; you confirm there, or you don&rsquo;t.</p>
</header>
<ol class="st-steps">
<li>
<span class="n">i.</span>
<h3 data-i18n="site.store.installing.aLinkNotAnInstaller">A link, not an installer</h3>
<p data-i18n="site.store.installing.installIsALinkIt">&ldquo;Install&rdquo; is a <code>waybetter://</code> link. It opens the app and proposes an item. Web pages, and tabs inside the app, cannot install anything.</p>
</li>
<li>
<span class="n">ii.</span>
<h3 data-i18n="site.store.installing.theAppChecksTheFile">The app checks the file</h3>
<p data-i18n="site.store.installing.itDownloadsTheFileItself">It downloads the file itself, verifies the catalog&rsquo;s Ed25519 signature with the key compiled into the app, then the file&rsquo;s size and SHA-256 against the catalog.</p>
</li>
<li>
<span class="n">iii.</span>
<h3 data-i18n="site.store.installing.youReadItThenConfirm">You read it, then confirm</h3>
<p data-i18n="site.store.installing.theInstallScreenShowsThe">The install screen shows the name, author, version, source, SHA-256, the permissions a plugin declares and the code or theme file. Nothing is written until you press Install.</p>
</li>
</ol>
<div class="st-honest">
<h3 data-i18n="site.store.installing.whatThisDoesNotPromise">What this does not promise</h3>
<p data-i18n="site.store.installing.aPluginIsJavascriptRunning">A plugin is JavaScript running inside the app&rsquo;s page, with the page&rsquo;s own access. Its permissions are a declaration and a guard rail, not a sandbox: they limit what the wayBetter API hands a plugin, and code that wants to get around a check can. A scan cannot see through minified code either. Install what you would trust as a browser extension.</p>
<p data-i18n="site.store.installing.themesAreDataSanitizedField">Themes are data, sanitized field by field; only a theme&rsquo;s optional CSS runs in the page, with the same trust as your own custom CSS. Anything in the signed catalog is vouched for by the Store key, which is kept offline.</p>
</div>
<div class="st-noapp" id="no-app">
<div>
<h3 data-i18n="site.store.noApp.noAppYet">No app yet?</h3>
<p data-i18n="site.store.noApp.oneClickInstallNeedsWaybetter">One-click install needs wayBetter for X <!-- store:since --> or newer. Without it, download an item&rsquo;s file from its page and drag it onto the wayBetter window: you get the same install screen.</p>
</div>
<a data-i18n="site.common.getWaybetterForX" class="btn btn-brush" href="../x/">
Get wayBetter for X
<svg class="arrow" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 8h9M8.5 4.5 12 8l-3.5 3.5" /></svg>
</a>
</div>
</div>
</section>
<section class="section section-tight st-publish">
<div class="wrap">
<div class="next-cta">
<div>
<h3 data-i18n="site.store.page.madeSomethingPublishIt">Made something? <em class="grad">Publish it.</em></h3>
<p data-i18n="site.store.page.oneFolderInOnePull">One folder in one pull request adds a theme or a plugin to the Store, or send the file in an issue. The checks run on your machine; a maintainer signs the catalog after the merge. All it takes is a free %FORGE_HOST% account.</p>
</div>
<div class="ctas">
<a data-i18n="site.store.page.howToPublish" class="btn btn-solid" href="submit/">
How to publish
<svg class="arrow" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 8h9M8.5 4.5 12 8l-3.5 3.5" /></svg>
</a>
<button data-i18n-aria-label="site.store.page.copyTheCommandNpmCreate" class="inline-cmd" type="button" data-copy="npm create waybetter" aria-label="Copy the command: npm create waybetter">
<span class="ps" aria-hidden="true">$</span> <span translate="no">npm create waybetter</span>
<span data-i18n="site.common.copy" class="copy-btn" aria-hidden="true" data-copy-label>Copy</span>
</button>
</div>
</div>
</div>
</section>
</main>
<footer class="foot">
<div class="wrap foot-row">
<a data-i18n-aria-label="site.common.waybetterHome" class="mark mark-sm" href="../" aria-label="wayBetter home">
<img class="wb" src="/brand/wb-mark-simple.svg" alt="" width="43" height="24" loading="lazy" />
<span class="mark-name" translate="no">wayBetter</span>
</a>
<p data-i18n="site.common.madeByCrtkafaGpl3" class="foot-legal">
Made by <a href="https://x.com/CRTkafa">@CRTkafa</a> &middot; GPL-3.0-or-later &middot;
Not affiliated with the apps it extends.
</p>
<nav data-i18n-aria-label="site.common.footer" class="foot-nav" aria-label="Footer">
<a data-i18n="site.common.store" href="./">Store</a>
<a data-i18n="site.common.publishYourOwn" href="submit/">Publish your own</a>
<a href="../x/">wayBetter for X</a>
<a href="catalog.json">catalog.json</a>
<a data-i18n="site.common.source" data-i18n-aria-label="site.common.sourceOn" class="src-link" href="%REPO_URL%" aria-label="Source on %FORGE_HOST%"><img class="src-logo" src="/git-crt-logo.svg" alt="" width="16" height="16" />Source</a>
</nav>
<!-- lang:foot -->
</div>
</footer>
<script type="module" src="../src/store.ts"></script>
</body>
</html>