removed fp6 from shop
All checks were successful
Deploy / build-deploy (push) Successful in 5m35s

This commit is contained in:
Jorijn van der Graaf 2026-09-05 18:38:39 +02:00
commit 25805a093a
20 changed files with 788 additions and 805 deletions

View file

@ -289,8 +289,8 @@ export RenderedPage RenderHome(std::span<const Project> projects,
R"("founder":{"@type":"Person","@id":"https://catcrafts.net/about#person",)"
R"("name":"Jorijn van der Graaf","url":"https://catcrafts.net/about"},)"
R"("description":"Catcrafts makes accessible, open-source software and hardware: )"
R"(the Crafter C++ suite, the imsd IMS/VoLTE implementation, and Fairphone )"
R"((Gen. 6) handsets sold with postmarketOS preinstalled.",)"
R"(the Crafter C++ suite, the imsd IMS/VoLTE implementation, and mainline )"
R"(Linux support for mobile hardware.",)"
R"("sameAs":["https://forgejo.catcrafts.net/Catcrafts/"]},)"
R"({"@type":"WebSite","@id":"https://catcrafts.net/#website",)"
R"("name":"Catcrafts","alternateName":["Catcrafts.net","CatCrafts"],)"
@ -676,8 +676,8 @@ export RenderedPage RenderShop(std::span<const Product> products, const Rates& r
RenderedPage page;
page.meta.title = "Shop — Catcrafts";
page.meta.description =
"Fairphone (Gen. 6) and (Gen. 6+) handsets reflashed to run postmarketOS, "
"with the IMS/VoLTE stack Catcrafts maintains.";
"Hardware that runs the open-source software Catcrafts maintains, and a "
"donation item that funds the work directly.";
page.meta.canonical = "/shop";
page.meta.geoPriceHint = true;
// The category page as typed data: an ItemList naming each product page.
@ -704,10 +704,9 @@ export RenderedPage RenderShop(std::span<const Product> products, const Rates& r
page.main = Format(
R"(<header class="page-header">)"
R"(<h1 class="page-header__title">Shop</h1>)"
R"(<p class="page-header__lede">Hardware that runs the software from the )"
R"(projects page. Assembled to order and flashed. Please allow up to a )"
R"(week before dispatch. Or fund the work directly: the donation item )"
R"(takes any amount.)"
R"(<p class="page-header__lede">Everything sold here funds the open-source )"
R"(work on the projects page. Or fund the work directly: the donation )"
R"(item takes any amount.)"
R"(</header>)"
R"(<div class="product-grid">{}</div>)",
cards.empty() ? Raw(R"(<p class="empty">No products listed.</p>)") : Join(cards));
@ -1362,18 +1361,19 @@ export RenderedPage RenderProduct(const Product& product,
// donation has neither a spec sheet nor a warranty, and an empty table
// under a manufacturer-specific lede would be nonsense on its page.
//
// The lede names the BRAND, never a model. It used to say "Fairphone
// (Gen. 6)" in the markup, which read true while the catalogue held one
// phone and went silently false the moment it held two — a spec sheet
// introduced as some other device's sheet is worse than no lede at all.
// The lede names the BRAND, never a model. It used to hardcode one model
// name, which read true while the catalogue held one device and went
// silently false the moment it held two — a spec sheet introduced as some
// other device's sheet is worse than no lede at all. It also claims
// nothing about the software on the device: that is the product's own
// summary's job, and this renderer serves whatever the catalogue lists.
// A spec sheet with no brand to name is a content bug, asserted against in
// ShouldShipContent rather than papered over with a second sentence here.
const SafeHtml specsSection = product.specs.empty() ? SafeHtml{} : Format(
R"(<section class="section">)"
R"(<h2 class="section__title">Specifications</h2>)"
R"(<p class="section__lede">The hardware is a stock {}, unmodified. )"
R"({}'s spec sheet is this product's spec sheet, )"
R"(and all of it works under postmarketOS.</p>)"
R"({}'s spec sheet is this product's spec sheet.</p>)"
R"(<table class="spec-table"><tbody>{}</tbody></table>)"
R"(</section>)",
Escape(product.brand), Escape(product.brand), Join(specRows));
@ -1671,7 +1671,7 @@ export RenderedPage RenderOrderStatus(const OrderView& o, std::string_view indic
R"(</section>)")
: Format(
R"(<section class="section"><h2 class="section__title">What happens now</h2>)"
R"(<p>The device is ordered, flashed and tested, then shipped. Allow up )"
R"(<p>Your order is sourced, prepared and tested, then shipped. Allow up )"
R"(to a week before dispatch. Updates land in your email.</p>)"
R"(<p><a class="btn btn--primary"{} download>Download invoice (.md)</a></p>)"
R"(<p class="order__note">GPG-clearsigned markdown. It verifies with )"