carlos / carloku Public

Add the pricing page (draft copy under review)

/pricing/ is rendered from copy-review/pricing/strings.json by
copy-review/pricing/build.mjs, which also writes the review preview. The
page lists the four plans, the country bands, the overage rates, the
half-price code, the review promise, tax and cancellation, in the site's
existing style; Pricing joins the top navigation on both hand-written
pages and src/pricing passes through the Eleventy build. Every string is
draft copy awaiting the copy review; nothing here is approved yet.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 35f29d833e3bc33125faa8c35b10e31cc3e3a855 parent a71ce06
9 files changed, +3075 −0
  • .gitignore +2 −0
  • copy-review/pricing/build.mjs +185 −0
  • copy-review/pricing/countries.json +2030 −0
  • copy-review/pricing/strings.json +611 −0
  • eleventy.config.js +1 −0
  • src/get-started/index.html +1 −0
  • src/index.html +1 −0
  • src/pricing/index.html +194 −0
  • src/site.css +50 −0
diff --git a/.gitignore b/.gitignore
index 3a799fb..d13615c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
node_modules/
_site/
+writing/
+copy-review/preview/
diff --git a/copy-review/pricing/build.mjs b/copy-review/pricing/build.mjs
new file mode 100644
index 0000000..ec98cc9
--- /dev/null
+++ b/copy-review/pricing/build.mjs
@@ -0,0 +1,185 @@
+// 🤖 Renders the pricing page from copy-review/pricing/strings.json.
+// Writes copy-review/pricing/preview/index.html (with data-copy bindings, for
+// the review server) and src/pricing/index.html (the same page, bindings
+// stripped, assets absolute). Re-run after an approved review is applied to
+// strings.json; never edit the rendered files by hand.
+import fs from "node:fs";
+import path from "node:path";
+const here = path.dirname(new URL(import.meta.url).pathname);
+const root = path.resolve(here, "..", "..");
+const strings = JSON.parse(fs.readFileSync(path.join(here, "strings.json"), "utf8"));
+const S = Object.fromEntries(strings.map((s) => [s.id, s.text]));
+const esc = (t) => t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
+const t = (id, tag = "span", cls = "") => {
+ if (!(id in S)) throw new Error("missing string " + id);
+ return `<${tag}${cls ? ` class="${cls}"` : ""} data-copy="${id}">${esc(S[id])}</${tag}>`;
+};
+const li = (id) => ` <li data-copy="${id}">${esc(S[id])}</li>`;
+const countries = JSON.parse(fs.readFileSync(path.join(here, "countries.json"), "utf8"));
+const recs = (countries.countries || countries.records || []).slice().sort((a, b) => a.name.localeCompare(b.name));
+const byBand = { A: [], B: [], C: [], D: [] };
+for (const r of recs) byBand[r.band].push(r.name);
+const bandList = Object.entries(byBand).map(([b, names]) =>
+ ` <div class="band-col"><h3>Band ${b}</h3><p>${names.map(esc).join(", ")}</p></div>`).join("\n");
+
+const card = (p, featured) => ` <article class="plan${featured ? " featured" : ""}">
+ ${t(`plan.${p}.name`, "h3")}
+ <p class="price">${t(`plan.${p}.price`)}</p>
+${S[`plan.${p}.min`] ? ` <p class="min">${t(`plan.${p}.min`)}</p>\n` : ""} <p class="for">${t(`plan.${p}.for`)}</p>
+ <ul>
+${Object.keys(S).filter((k) => k.startsWith(`plan.${p}.i`)).map(li).join("\n")}
+ </ul>
+ <a class="btn ${featured ? "btn-primary" : "btn-quiet"}" href="https://console.carloku.com" data-copy="plan.${p}.cta">${esc(S[`plan.${p}.cta`])}</a>
+ </article>`;
+
+const page = `<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title data-copy="meta.title">${esc(S["meta.title"])}</title>
+<meta name="description" content="🤖 ${esc(S["meta.description"])}">
+<meta property="og:title" content="${esc(S["meta.title"])}">
+<meta property="og:description" content="${esc(S["meta.description"])}">
+<meta property="og:type" content="website">
+<meta property="og:url" content="https://carloku.com/pricing/">
+<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
+<meta name="theme-color" content="#0e0c13" media="(prefers-color-scheme: dark)">
+<link rel="icon" href="/favicon.svg" type="image/svg+xml">
+<link rel="preload" href="/fonts/Geist-Variable.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/GeistMono-Variable.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="stylesheet" href="/site.css">
+</head>
+<body>
+<a class="skip" href="#main">Skip to content</a>
+<header class="site-head">
+ <div class="wrap">
+ <a class="brand" href="/"><svg class="mark" viewBox="0 0 64 64" aria-hidden="true"><rect width="64" height="64" rx="14" fill="#5b3e96"/><circle cx="30" cy="32" r="17" fill="none" stroke="#ffffff" stroke-width="8" stroke-linecap="round" stroke-dasharray="88.8 18" stroke-dashoffset="-9"/><circle cx="51" cy="44" r="5" fill="#c9b2f7"/></svg>Carloku</a>
+ <nav aria-label="Site">
+ <a href="/#workflow">How it works</a>
+ <a href="/#open">Open source</a>
+ <a href="/pricing/" aria-current="page" data-copy="nav.pricing">${esc(S["nav.pricing"])}</a>
+ <a href="/get-started/">Get started</a>
+ </nav>
+ <a class="head-cta" href="https://console.carloku.com">Dashboard</a>
+ </div>
+</header>
+<main id="main">
+ <div class="page-hero">
+ <div class="wrap narrow">
+ <h1><span data-copy="hero.title">${esc(S["hero.title"])}</span><span class="dot">.</span></h1>
+ <p class="lede" data-copy="hero.lede">${esc(S["hero.lede"])}</p>
+ <p class="hero-note" data-copy="hero.new">${esc(S["hero.new"])}</p>
+ </div>
+ </div>
+ <section class="plans-section">
+ <div class="wrap">
+ ${t("plans.heading", "h2")}
+ <div class="plans">
+${card("free", false)}
+${card("personal", true)}
+${card("community", false)}
+${card("business", false)}
+ </div>
+ <p class="plans-note" data-copy="plans.note">${esc(S["plans.note"])}</p>
+ </div>
+ </section>
+ <section class="tint">
+ <div class="wrap narrow prose">
+ ${t("member.heading", "h2")}
+ <p data-copy="member.p1">${esc(S["member.p1"])}</p>
+ <p data-copy="member.p2">${esc(S["member.p2"])}</p>
+ </div>
+ </section>
+ <section>
+ <div class="wrap narrow prose">
+ ${t("bands.heading", "h2")}
+ <p data-copy="bands.p1">${esc(S["bands.p1"])}</p>
+ <ul>
+${["a", "b", "c", "d"].map((b) => li("bands." + b)).join("\n")}
+ </ul>
+ <table class="price-table">
+ <thead><tr><th scope="col"><span class="visually-hidden">Plan</span></th><th scope="col">A</th><th scope="col">B</th><th scope="col">C</th><th scope="col">D</th></tr></thead>
+ <tbody>
+ <tr><th scope="row" data-copy="bands.table.personal">${esc(S["bands.table.personal"])}</th><td>€24</td><td>€18</td><td>€12</td><td>€8.40</td></tr>
+ <tr><th scope="row" data-copy="bands.table.community">${esc(S["bands.table.community"])}</th><td>€5</td><td>€3.75</td><td>€2.50</td><td>€1.75</td></tr>
+ <tr><th scope="row" data-copy="bands.table.business">${esc(S["bands.table.business"])}</th><td>€50</td><td>€37.50</td><td>€25</td><td>€17.50</td></tr>
+ </tbody>
+ </table>
+ <p data-copy="bands.p2">${esc(S["bands.p2"])}</p>
+ <p data-copy="bands.p3">${esc(S["bands.p3"])}</p>
+ <details class="bands-all">
+ <summary data-copy="bands.list.summary">${esc(S["bands.list.summary"])}</summary>
+${bandList}
+ </details>
+ </div>
+ </section>
+ <section class="tint">
+ <div class="wrap narrow prose">
+ ${t("over.heading", "h2")}
+ <p data-copy="over.p1">${esc(S["over.p1"])}</p>
+ <table class="price-table rates">
+ <tbody>
+ <tr><th scope="row" data-copy="over.table.awake">${esc(S["over.table.awake"])}</th><td data-copy="over.rate.awake">${esc(S["over.rate.awake"])}</td></tr>
+ <tr><th scope="row" data-copy="over.table.storage">${esc(S["over.table.storage"])}</th><td data-copy="over.rate.storage">${esc(S["over.rate.storage"])}</td></tr>
+ <tr><th scope="row" data-copy="over.table.transfer">${esc(S["over.table.transfer"])}</th><td data-copy="over.rate.transfer">${esc(S["over.rate.transfer"])}</td></tr>
+ <tr><th scope="row" data-copy="over.table.writes">${esc(S["over.table.writes"])}</th><td data-copy="over.rate.writes">${esc(S["over.rate.writes"])}</td></tr>
+ </tbody>
+ </table>
+ <p data-copy="over.p2">${esc(S["over.p2"])}</p>
+ <p data-copy="over.p3">${esc(S["over.p3"])}</p>
+ </div>
+ </section>
+ <section class="band">
+ <div class="wrap">
+ ${t("half.heading", "h2")}
+ <p data-copy="half.p1">${esc(S["half.p1"])}</p>
+ </div>
+ </section>
+ <section>
+ <div class="wrap narrow prose">
+ ${t("promise.heading", "h2")}
+ <p data-copy="promise.p1">${esc(S["promise.p1"])}</p>
+ ${t("pay.heading", "h2")}
+ <p data-copy="pay.p1">${esc(S["pay.p1"])}</p>
+ <p data-copy="pay.p2">${esc(S["pay.p2"])}</p>
+ <p data-copy="pay.p3">${esc(S["pay.p3"])}</p>
+ <p data-copy="pay.p4">${esc(S["pay.p4"])}</p>
+ </div>
+ </section>
+ <section class="close-cta">
+ <div class="wrap">
+ <h2><span data-copy="start.heading">${esc(S["start.heading"])}</span><span class="dot">.</span></h2>
+ <p data-copy="start.p1">${esc(S["start.p1"])}</p>
+ <div class="cta">
+ <a class="btn btn-primary" href="https://console.carloku.com" data-copy="start.cta.console">${esc(S["start.cta.console"])}</a>
+ <a class="btn btn-quiet" href="/get-started/" data-copy="start.cta.guide">${esc(S["start.cta.guide"])}</a>
+ </div>
+ </div>
+ </section>
+</main>
+<footer>
+ <div class="wrap">
+ <p>🤖 Written by an LLM (Claude), on the ideas, instruction, and editing of humans.
+ AI-written text here is always marked and always disclosed; see
+ <a href="https://11factor.org/#x">factor X</a>.</p>
+ <p><a href="/">← carloku.com</a> · <a href="https://github.com/carlosframework/carloku">Source on GitHub</a>.</p>
+ </div>
+</footer>
+<script src="/site.js" defer></script>
+</body>
+</html>
+`;
+fs.mkdirSync(path.join(root, "src", "pricing"), { recursive: true });
+fs.writeFileSync(path.join(root, "src", "pricing", "index.html"), page.replace(/ data-copy(?:-title)?="[^"]*"/g, ""));
+const prev = path.join(here, "preview");
+fs.mkdirSync(path.join(prev, "fonts"), { recursive: true });
+for (const f of ["site.css", "favicon.svg"]) fs.copyFileSync(path.join(root, "src", f), path.join(prev, f));
+for (const f of fs.readdirSync(path.join(root, "src", "fonts"))) fs.copyFileSync(path.join(root, "src", "fonts", f), path.join(prev, "fonts", f));
+let previewHtml = page
+ .replace(/href="\/site\.css"/, 'href="site.css"')
+ .replace(/href="\/fonts\//g, 'href="fonts/"'.slice(0, -1))
+ .replace(/href="\/favicon\.svg"/, 'href="favicon.svg"')
+ .replace(/<script src="\/site\.js" defer><\/script>\n/, "");
+fs.writeFileSync(path.join(prev, "index.html"), previewHtml);
+console.log("wrote src/pricing/index.html and copy-review/pricing/preview/index.html", strings.length, "strings");
diff --git a/copy-review/pricing/countries.json b/copy-review/pricing/countries.json
new file mode 100644
index 0000000..2b3fe0d
--- /dev/null
+++ b/copy-review/pricing/countries.json
@@ -0,0 +1,2030 @@
+{
+ "version": "2026-09-17-countries-v1",
+ "requested_indicator": "PA.NUS.PPPC.RF",
+ "requested_indicator_status": "archived: World Bank source 57 (WDI Database Archives). GET /v2/country/{iso}/indicator/PA.NUS.PPPC.RF returns \"The indicator was not found. It may have been deleted or archived.\" for every country tried, including USA, on 2026-09-17. Its bulk CSV download exists but fails the indicator's own base-country-equals-100 definition (USA values of 20/14/5 for 2022-2024) and was rejected as untrustworthy rather than parsed further.",
+ "current_indicator": "PA.NUS.GDP.PLI",
+ "current_indicator_name": "Price level index (GDP)",
+ "current_indicator_source": "World Development Indicators, World Bank (source id 2)",
+ "current_indicator_source_note": "The price level index (PLI) is the ratio of a purchasing power parity (PPP) conversion factor to the corresponding market exchange rate between two countries, expressed relative to a base country that is set equal to 100. For this series the base country is the United States. It provides a measure of the differences in price level between the country and the United States by indicating the number of units of the common currency (US dollars) needed to buy the same volume of the aggregation level in each country. At the level of GDP, the price level ratio provides a measure of the differences in the general price levels of countries.",
+ "current_indicator_last_updated": "2026-07-13",
+ "transformation": "ratio = current_indicator raw value / 100. The current indicator is expressed on a 0-100 scale with base country United States = 100; the retired indicator was expressed as a direct ratio (United States = 1.0) of the same underlying measure (PPP conversion factor to market exchange rate, base United States) per both indicators' own sourceNote text. Dividing by 100 restores the ratio scale the band thresholds below assume.",
+ "source_url": "https://api.worldbank.org/v2/country/all/indicator/PA.NUS.GDP.PLI?format=json&date=2022:2024&per_page=20000",
+ "retrieved_date": "2026-09-17",
+ "band_thresholds": {
+ "a_min": "0.875",
+ "b_min": "0.625",
+ "c_min": "0.425"
+ },
+ "overrides": [
+ "AT",
+ "AU",
+ "BE",
+ "CA",
+ "DE",
+ "DK",
+ "ES",
+ "FI",
+ "FR",
+ "GB",
+ "GR",
+ "IE",
+ "IT",
+ "LU",
+ "NL",
+ "PT",
+ "SE",
+ "US"
+ ],
+ "countries": [
+ {
+ "iso2": "AD",
+ "name": "Andorra",
+ "observation_year": 2024,
+ "raw_index_value": "65.4652562217967",
+ "ratio": "0.654652562217967",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "AE",
+ "name": "United Arab Emirates",
+ "observation_year": 2024,
+ "raw_index_value": "63.3616309451431",
+ "ratio": "0.633616309451431",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "AF",
+ "name": "Afghanistan",
+ "observation_year": 2024,
+ "raw_index_value": "18.6419514830207",
+ "ratio": "0.186419514830207",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "AG",
+ "name": "Antigua and Barbuda",
+ "observation_year": 2024,
+ "raw_index_value": "69.1416294107689",
+ "ratio": "0.691416294107689",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "AL",
+ "name": "Albania",
+ "observation_year": 2024,
+ "raw_index_value": "42.5964673371086",
+ "ratio": "0.425964673371086",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "AM",
+ "name": "Armenia",
+ "observation_year": 2024,
+ "raw_index_value": "37.4347758374219",
+ "ratio": "0.374347758374219",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "AO",
+ "name": "Angola",
+ "observation_year": 2024,
+ "raw_index_value": "27.3076165287256",
+ "ratio": "0.273076165287256",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "AR",
+ "name": "Argentina",
+ "observation_year": 2024,
+ "raw_index_value": "45.8395601723183",
+ "ratio": "0.458395601723183",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "AT",
+ "name": "Austria",
+ "observation_year": 2024,
+ "raw_index_value": "76.8978286403906",
+ "ratio": "0.768978286403906",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "AU",
+ "name": "Australia",
+ "observation_year": 2024,
+ "raw_index_value": "89.5894112849615",
+ "ratio": "0.895894112849615",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "AW",
+ "name": "Aruba",
+ "observation_year": 2024,
+ "raw_index_value": "74.6257169517821",
+ "ratio": "0.746257169517821",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "AZ",
+ "name": "Azerbaijan",
+ "observation_year": 2024,
+ "raw_index_value": "29.0087435497411",
+ "ratio": "0.290087435497411",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BA",
+ "name": "Bosnia and Herzegovina",
+ "observation_year": 2024,
+ "raw_index_value": "37.3703858381207",
+ "ratio": "0.373703858381207",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BB",
+ "name": "Barbados",
+ "observation_year": 2024,
+ "raw_index_value": "109.607215877638",
+ "ratio": "1.09607215877638",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "BD",
+ "name": "Bangladesh",
+ "observation_year": 2024,
+ "raw_index_value": "26.8447911723453",
+ "ratio": "0.268447911723453",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BE",
+ "name": "Belgium",
+ "observation_year": 2024,
+ "raw_index_value": "76.2307575575",
+ "ratio": "0.762307575575",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "BF",
+ "name": "Burkina Faso",
+ "observation_year": 2024,
+ "raw_index_value": "33.8669020372191",
+ "ratio": "0.338669020372191",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BG",
+ "name": "Bulgaria",
+ "observation_year": 2024,
+ "raw_index_value": "41.9277731040122",
+ "ratio": "0.419277731040122",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BH",
+ "name": "Bahrain",
+ "observation_year": 2024,
+ "raw_index_value": "44.202139294112",
+ "ratio": "0.44202139294112",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "BI",
+ "name": "Burundi",
+ "observation_year": 2024,
+ "raw_index_value": "18.1245208127752",
+ "ratio": "0.181245208127752",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BJ",
+ "name": "Benin",
+ "observation_year": 2024,
+ "raw_index_value": "33.4469422526318",
+ "ratio": "0.334469422526318",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BM",
+ "name": "Bermuda",
+ "observation_year": 2024,
+ "raw_index_value": "119.812062185577",
+ "ratio": "1.19812062185577",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "BN",
+ "name": "Brunei Darussalam",
+ "observation_year": 2024,
+ "raw_index_value": "36.8331451477285",
+ "ratio": "0.368331451477285",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BO",
+ "name": "Bolivia",
+ "observation_year": 2024,
+ "raw_index_value": "34.2823399681983",
+ "ratio": "0.342823399681983",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BR",
+ "name": "Brazil",
+ "observation_year": 2024,
+ "raw_index_value": "46.0890723998018",
+ "ratio": "0.460890723998018",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "BS",
+ "name": "Bahamas, The",
+ "observation_year": 2024,
+ "raw_index_value": "95.6315655509349",
+ "ratio": "0.956315655509349",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "BT",
+ "name": "Bhutan",
+ "observation_year": 2024,
+ "raw_index_value": "23.8033697006015",
+ "ratio": "0.238033697006015",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BW",
+ "name": "Botswana",
+ "observation_year": 2024,
+ "raw_index_value": "37.1125511242075",
+ "ratio": "0.371125511242075",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BY",
+ "name": "Belarus",
+ "observation_year": 2024,
+ "raw_index_value": "25.946783525077",
+ "ratio": "0.25946783525077",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "BZ",
+ "name": "Belize",
+ "observation_year": 2024,
+ "raw_index_value": "53.463178010533",
+ "ratio": "0.53463178010533",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "CA",
+ "name": "Canada",
+ "observation_year": 2024,
+ "raw_index_value": "84.0153207747759",
+ "ratio": "0.840153207747759",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "CD",
+ "name": "Congo, Dem. Rep.",
+ "observation_year": 2024,
+ "raw_index_value": "38.0023246917053",
+ "ratio": "0.380023246917053",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "CF",
+ "name": "Central African Republic",
+ "observation_year": 2024,
+ "raw_index_value": "40.8052824372795",
+ "ratio": "0.408052824372795",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "CG",
+ "name": "Congo, Rep.",
+ "observation_year": 2024,
+ "raw_index_value": "35.4421573076285",
+ "ratio": "0.354421573076285",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "CH",
+ "name": "Switzerland",
+ "observation_year": 2024,
+ "raw_index_value": "110.500213434747",
+ "ratio": "1.10500213434747",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "CI",
+ "name": "Cote d'Ivoire",
+ "observation_year": 2024,
+ "raw_index_value": "35.5177366478691",
+ "ratio": "0.355177366478691",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "CL",
+ "name": "Chile",
+ "observation_year": 2024,
+ "raw_index_value": "46.1839558478626",
+ "ratio": "0.461839558478626",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "CM",
+ "name": "Cameroon",
+ "observation_year": 2024,
+ "raw_index_value": "32.6956331885356",
+ "ratio": "0.326956331885356",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "CN",
+ "name": "China",
+ "observation_year": 2024,
+ "raw_index_value": "48.9806640888522",
+ "ratio": "0.489806640888522",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "CO",
+ "name": "Colombia",
+ "observation_year": 2024,
+ "raw_index_value": "35.4335953368221",
+ "ratio": "0.354335953368221",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "CR",
+ "name": "Costa Rica",
+ "observation_year": 2024,
+ "raw_index_value": "59.752769551419",
+ "ratio": "0.59752769551419",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "CV",
+ "name": "Cabo Verde",
+ "observation_year": 2024,
+ "raw_index_value": "46.2256093985824",
+ "ratio": "0.462256093985824",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "CW",
+ "name": "Curacao",
+ "observation_year": 2024,
+ "raw_index_value": "69.7384115740955",
+ "ratio": "0.697384115740955",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "CY",
+ "name": "Cyprus",
+ "observation_year": 2024,
+ "raw_index_value": "61.3812036809463",
+ "ratio": "0.613812036809463",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "CZ",
+ "name": "Czechia",
+ "observation_year": 2024,
+ "raw_index_value": "55.2324548998213",
+ "ratio": "0.552324548998213",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "DE",
+ "name": "Germany",
+ "observation_year": 2024,
+ "raw_index_value": "75.8599340089062",
+ "ratio": "0.758599340089062",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "DJ",
+ "name": "Djibouti",
+ "observation_year": 2024,
+ "raw_index_value": "45.4218272384726",
+ "ratio": "0.454218272384726",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "DK",
+ "name": "Denmark",
+ "observation_year": 2024,
+ "raw_index_value": "87.7544028964132",
+ "ratio": "0.877544028964132",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "DM",
+ "name": "Dominica",
+ "observation_year": 2024,
+ "raw_index_value": "48.7786632480818",
+ "ratio": "0.487786632480818",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "DO",
+ "name": "Dominican Republic",
+ "observation_year": 2024,
+ "raw_index_value": "39.4307724218955",
+ "ratio": "0.394307724218955",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "DZ",
+ "name": "Algeria",
+ "observation_year": 2024,
+ "raw_index_value": "32.6016226560324",
+ "ratio": "0.326016226560324",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "EC",
+ "name": "Ecuador",
+ "observation_year": 2024,
+ "raw_index_value": "43.0740974308494",
+ "ratio": "0.430740974308494",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "EE",
+ "name": "Estonia",
+ "observation_year": 2024,
+ "raw_index_value": "62.3630825157812",
+ "ratio": "0.623630825157812",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "EG",
+ "name": "Egypt, Arab Rep.",
+ "observation_year": 2024,
+ "raw_index_value": "17.4589245118373",
+ "ratio": "0.174589245118373",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "ES",
+ "name": "Spain",
+ "observation_year": 2024,
+ "raw_index_value": "60.8413638147656",
+ "ratio": "0.608413638147656",
+ "computed_band": "C",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "ET",
+ "name": "Ethiopia",
+ "observation_year": 2024,
+ "raw_index_value": "34.4403481534475",
+ "ratio": "0.344403481534475",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "FI",
+ "name": "Finland",
+ "observation_year": 2024,
+ "raw_index_value": "81.6055342511718",
+ "ratio": "0.816055342511718",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "FJ",
+ "name": "Fiji",
+ "observation_year": 2024,
+ "raw_index_value": "41.5294419627777",
+ "ratio": "0.415294419627777",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "FM",
+ "name": "Micronesia, Fed. Sts.",
+ "observation_year": 2024,
+ "raw_index_value": "95.4938228573462",
+ "ratio": "0.954938228573462",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "FO",
+ "name": "Faroe Islands",
+ "observation_year": 2024,
+ "raw_index_value": "90.3592706473352",
+ "ratio": "0.903592706473352",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "FR",
+ "name": "France",
+ "observation_year": 2024,
+ "raw_index_value": "73.7359788150781",
+ "ratio": "0.737359788150781",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "GA",
+ "name": "Gabon",
+ "observation_year": 2024,
+ "raw_index_value": "38.2056821319162",
+ "ratio": "0.382056821319162",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "GB",
+ "name": "United Kingdom",
+ "observation_year": 2024,
+ "raw_index_value": "84.8850489420597",
+ "ratio": "0.848850489420597",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "GD",
+ "name": "Grenada",
+ "observation_year": 2024,
+ "raw_index_value": "57.9250112245574",
+ "ratio": "0.579250112245574",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "GE",
+ "name": "Georgia",
+ "observation_year": 2024,
+ "raw_index_value": "32.6252979324882",
+ "ratio": "0.326252979324882",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "GH",
+ "name": "Ghana",
+ "observation_year": 2024,
+ "raw_index_value": "30.0483620676612",
+ "ratio": "0.300483620676612",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "GL",
+ "name": "Greenland",
+ "observation_year": 2023,
+ "raw_index_value": "74.1379389303593",
+ "ratio": "0.741379389303593",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "GM",
+ "name": "Gambia, The",
+ "observation_year": 2024,
+ "raw_index_value": "25.0337661522703",
+ "ratio": "0.250337661522703",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "GN",
+ "name": "Guinea",
+ "observation_year": 2024,
+ "raw_index_value": "37.0730399547107",
+ "ratio": "0.370730399547107",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "GQ",
+ "name": "Equatorial Guinea",
+ "observation_year": 2024,
+ "raw_index_value": "41.0227579253373",
+ "ratio": "0.410227579253373",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "GR",
+ "name": "Greece",
+ "observation_year": 2024,
+ "raw_index_value": "55.7519026126562",
+ "ratio": "0.557519026126562",
+ "computed_band": "C",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "GT",
+ "name": "Guatemala",
+ "observation_year": 2024,
+ "raw_index_value": "42.7351634524949",
+ "ratio": "0.427351634524949",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "GW",
+ "name": "Guinea-Bissau",
+ "observation_year": 2024,
+ "raw_index_value": "32.2737120150547",
+ "ratio": "0.322737120150547",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "GY",
+ "name": "Guyana",
+ "observation_year": 2024,
+ "raw_index_value": "36.9686348516584",
+ "ratio": "0.369686348516584",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "HK",
+ "name": "Hong Kong SAR, China",
+ "observation_year": 2024,
+ "raw_index_value": "72.0381353471007",
+ "ratio": "0.720381353471007",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "HN",
+ "name": "Honduras",
+ "observation_year": 2024,
+ "raw_index_value": "45.5305411801063",
+ "ratio": "0.455305411801063",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "HR",
+ "name": "Croatia",
+ "observation_year": 2024,
+ "raw_index_value": "48.5359280064149",
+ "ratio": "0.485359280064149",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "HT",
+ "name": "Haiti",
+ "observation_year": 2024,
+ "raw_index_value": "65.0184454399522",
+ "ratio": "0.650184454399522",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "HU",
+ "name": "Hungary",
+ "observation_year": 2024,
+ "raw_index_value": "48.0127126511694",
+ "ratio": "0.480127126511694",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "ID",
+ "name": "Indonesia",
+ "observation_year": 2024,
+ "raw_index_value": "29.9009965374497",
+ "ratio": "0.299009965374497",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "IE",
+ "name": "Ireland",
+ "observation_year": 2024,
+ "raw_index_value": "80.1929195014063",
+ "ratio": "0.801929195014063",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "IL",
+ "name": "Israel",
+ "observation_year": 2024,
+ "raw_index_value": "94.6552801717158",
+ "ratio": "0.946552801717158",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "IN",
+ "name": "India",
+ "observation_year": 2024,
+ "raw_index_value": "24.1821996879637",
+ "ratio": "0.241821996879637",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "IQ",
+ "name": "Iraq",
+ "observation_year": 2024,
+ "raw_index_value": "41.9294035030357",
+ "ratio": "0.419294035030357",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "IR",
+ "name": "Iran, Islamic Rep.",
+ "observation_year": 2024,
+ "raw_index_value": "26.0776525211842",
+ "ratio": "0.260776525211842",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "IS",
+ "name": "Iceland",
+ "observation_year": 2024,
+ "raw_index_value": "102.754522612876",
+ "ratio": "1.02754522612876",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "IT",
+ "name": "Italy",
+ "observation_year": 2024,
+ "raw_index_value": "64.9024553335156",
+ "ratio": "0.649024553335156",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "JM",
+ "name": "Jamaica",
+ "observation_year": 2024,
+ "raw_index_value": "60.0652274740972",
+ "ratio": "0.600652274740972",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "JO",
+ "name": "Jordan",
+ "observation_year": 2024,
+ "raw_index_value": "42.5794458019025",
+ "ratio": "0.425794458019025",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "JP",
+ "name": "Japan",
+ "observation_year": 2024,
+ "raw_index_value": "62.4066284421693",
+ "ratio": "0.624066284421693",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "KE",
+ "name": "Kenya",
+ "observation_year": 2024,
+ "raw_index_value": "32.0836821224238",
+ "ratio": "0.320836821224238",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "KG",
+ "name": "Kyrgyz Republic",
+ "observation_year": 2024,
+ "raw_index_value": "30.6384165083671",
+ "ratio": "0.306384165083671",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "KH",
+ "name": "Cambodia",
+ "observation_year": 2024,
+ "raw_index_value": "32.9246007591304",
+ "ratio": "0.329246007591304",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "KI",
+ "name": "Kiribati",
+ "observation_year": 2024,
+ "raw_index_value": "68.4269474577724",
+ "ratio": "0.684269474577724",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "KM",
+ "name": "Comoros",
+ "observation_year": 2024,
+ "raw_index_value": "45.8965499644165",
+ "ratio": "0.458965499644165",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "KN",
+ "name": "St. Kitts and Nevis",
+ "observation_year": 2024,
+ "raw_index_value": "68.6606554429293",
+ "ratio": "0.686606554429293",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "KR",
+ "name": "Korea, Rep.",
+ "observation_year": 2024,
+ "raw_index_value": "59.3576396809388",
+ "ratio": "0.593576396809388",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "KW",
+ "name": "Kuwait",
+ "observation_year": 2024,
+ "raw_index_value": "61.8526081806483",
+ "ratio": "0.618526081806483",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "KY",
+ "name": "Cayman Islands",
+ "observation_year": 2024,
+ "raw_index_value": "113.114611542503",
+ "ratio": "1.13114611542503",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "KZ",
+ "name": "Kazakhstan",
+ "observation_year": 2024,
+ "raw_index_value": "34.565379764769",
+ "ratio": "0.34565379764769",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "LA",
+ "name": "Lao PDR",
+ "observation_year": 2024,
+ "raw_index_value": "21.6953379615205",
+ "ratio": "0.216953379615205",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "LB",
+ "name": "Lebanon",
+ "observation_year": 2024,
+ "raw_index_value": "37.5354730523133",
+ "ratio": "0.375354730523133",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "LC",
+ "name": "St. Lucia",
+ "observation_year": 2024,
+ "raw_index_value": "51.5480960699244",
+ "ratio": "0.515480960699244",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "LK",
+ "name": "Sri Lanka",
+ "observation_year": 2024,
+ "raw_index_value": "28.9493268335141",
+ "ratio": "0.289493268335141",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "LR",
+ "name": "Liberia",
+ "observation_year": 2024,
+ "raw_index_value": "45.443232675685",
+ "ratio": "0.45443232675685",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "LS",
+ "name": "Lesotho",
+ "observation_year": 2024,
+ "raw_index_value": "33.315216652006",
+ "ratio": "0.33315216652006",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "LT",
+ "name": "Lithuania",
+ "observation_year": 2024,
+ "raw_index_value": "53.1492105375",
+ "ratio": "0.531492105375",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "LU",
+ "name": "Luxembourg",
+ "observation_year": 2024,
+ "raw_index_value": "88.2766780322656",
+ "ratio": "0.882766780322656",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "LV",
+ "name": "Latvia",
+ "observation_year": 2024,
+ "raw_index_value": "53.74322093875",
+ "ratio": "0.5374322093875",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "LY",
+ "name": "Libya",
+ "observation_year": 2024,
+ "raw_index_value": "45.8593775827166",
+ "ratio": "0.458593775827166",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "MA",
+ "name": "Morocco",
+ "observation_year": 2024,
+ "raw_index_value": "39.8187429322033",
+ "ratio": "0.398187429322033",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MD",
+ "name": "Moldova",
+ "observation_year": 2024,
+ "raw_index_value": "40.6121529420174",
+ "ratio": "0.406121529420174",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "ME",
+ "name": "Montenegro",
+ "observation_year": 2024,
+ "raw_index_value": "38.9579629904049",
+ "ratio": "0.389579629904049",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MG",
+ "name": "Madagascar",
+ "observation_year": 2024,
+ "raw_index_value": "29.1411678327008",
+ "ratio": "0.291411678327008",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MH",
+ "name": "Marshall Islands",
+ "observation_year": 2024,
+ "raw_index_value": "92.137924629206",
+ "ratio": "0.92137924629206",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "MK",
+ "name": "North Macedonia",
+ "observation_year": 2024,
+ "raw_index_value": "34.4199931672268",
+ "ratio": "0.344199931672268",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "ML",
+ "name": "Mali",
+ "observation_year": 2024,
+ "raw_index_value": "32.9136616120769",
+ "ratio": "0.329136616120769",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MM",
+ "name": "Myanmar",
+ "observation_year": 2024,
+ "raw_index_value": "22.6275455292655",
+ "ratio": "0.226275455292655",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MN",
+ "name": "Mongolia",
+ "observation_year": 2024,
+ "raw_index_value": "35.2099084532892",
+ "ratio": "0.352099084532892",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MO",
+ "name": "Macao SAR, China",
+ "observation_year": 2024,
+ "raw_index_value": "56.6323026330055",
+ "ratio": "0.566323026330055",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "MR",
+ "name": "Mauritania",
+ "observation_year": 2024,
+ "raw_index_value": "28.518946575825",
+ "ratio": "0.28518946575825",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MT",
+ "name": "Malta",
+ "observation_year": 2024,
+ "raw_index_value": "62.8344430674925",
+ "ratio": "0.628344430674925",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "MU",
+ "name": "Mauritius",
+ "observation_year": 2024,
+ "raw_index_value": "37.8301877532205",
+ "ratio": "0.378301877532205",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MV",
+ "name": "Maldives",
+ "observation_year": 2024,
+ "raw_index_value": "51.0257023769908",
+ "ratio": "0.510257023769908",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "MW",
+ "name": "Malawi",
+ "observation_year": 2024,
+ "raw_index_value": "28.0793988763421",
+ "ratio": "0.280793988763421",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MX",
+ "name": "Mexico",
+ "observation_year": 2024,
+ "raw_index_value": "54.1744819872408",
+ "ratio": "0.541744819872408",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "MY",
+ "name": "Malaysia",
+ "observation_year": 2024,
+ "raw_index_value": "30.5761388170918",
+ "ratio": "0.305761388170918",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "MZ",
+ "name": "Mozambique",
+ "observation_year": 2024,
+ "raw_index_value": "38.457809833667",
+ "ratio": "0.38457809833667",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "NA",
+ "name": "Namibia",
+ "observation_year": 2024,
+ "raw_index_value": "38.4841786748317",
+ "ratio": "0.384841786748317",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "NE",
+ "name": "Niger",
+ "observation_year": 2024,
+ "raw_index_value": "35.7064163597851",
+ "ratio": "0.357064163597851",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "NG",
+ "name": "Nigeria",
+ "observation_year": 2024,
+ "raw_index_value": "11.9140216830737",
+ "ratio": "0.119140216830737",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "NI",
+ "name": "Nicaragua",
+ "observation_year": 2024,
+ "raw_index_value": "32.6558777413895",
+ "ratio": "0.326558777413895",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "NL",
+ "name": "Netherlands",
+ "observation_year": 2024,
+ "raw_index_value": "79.1675804833594",
+ "ratio": "0.791675804833594",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "NO",
+ "name": "Norway",
+ "observation_year": 2024,
+ "raw_index_value": "85.0761659557971",
+ "ratio": "0.850761659557971",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "NP",
+ "name": "Nepal",
+ "observation_year": 2024,
+ "raw_index_value": "25.4154636392294",
+ "ratio": "0.254154636392294",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "NR",
+ "name": "Naoero",
+ "observation_year": 2024,
+ "raw_index_value": "103.20398133498",
+ "ratio": "1.0320398133498",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "NZ",
+ "name": "New Zealand",
+ "observation_year": 2024,
+ "raw_index_value": "88.5979916984826",
+ "ratio": "0.885979916984826",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "OM",
+ "name": "Oman",
+ "observation_year": 2024,
+ "raw_index_value": "48.5283415027085",
+ "ratio": "0.485283415027085",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "PA",
+ "name": "Panama",
+ "observation_year": 2024,
+ "raw_index_value": "46.2501709276174",
+ "ratio": "0.462501709276174",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "PE",
+ "name": "Peru",
+ "observation_year": 2024,
+ "raw_index_value": "47.6812398965343",
+ "ratio": "0.476812398965343",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "PG",
+ "name": "Papua New Guinea",
+ "observation_year": 2024,
+ "raw_index_value": "59.6024232390472",
+ "ratio": "0.596024232390472",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "PH",
+ "name": "Philippines",
+ "observation_year": 2024,
+ "raw_index_value": "33.7342146257315",
+ "ratio": "0.337342146257315",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "PK",
+ "name": "Pakistan",
+ "observation_year": 2024,
+ "raw_index_value": "23.6218009724264",
+ "ratio": "0.236218009724264",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "PL",
+ "name": "Poland",
+ "observation_year": 2024,
+ "raw_index_value": "48.9706129869663",
+ "ratio": "0.489706129869663",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "PR",
+ "name": "Puerto Rico (US)",
+ "observation_year": 2024,
+ "raw_index_value": "78.1857550769963",
+ "ratio": "0.781857550769963",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "PS",
+ "name": "West Bank and Gaza",
+ "observation_year": 2024,
+ "raw_index_value": "63.4768249928382",
+ "ratio": "0.634768249928382",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "PT",
+ "name": "Portugal",
+ "observation_year": 2024,
+ "raw_index_value": "55.8500745211719",
+ "ratio": "0.558500745211719",
+ "computed_band": "C",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "PW",
+ "name": "Palau",
+ "observation_year": 2024,
+ "raw_index_value": "86.2764636970531",
+ "ratio": "0.862764636970531",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "PY",
+ "name": "Paraguay",
+ "observation_year": 2024,
+ "raw_index_value": "34.6539863235716",
+ "ratio": "0.346539863235716",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "QA",
+ "name": "Qatar",
+ "observation_year": 2024,
+ "raw_index_value": "59.7297323281739",
+ "ratio": "0.597297323281739",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "RO",
+ "name": "Romania",
+ "observation_year": 2024,
+ "raw_index_value": "40.91596217684",
+ "ratio": "0.4091596217684",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "RS",
+ "name": "Serbia",
+ "observation_year": 2024,
+ "raw_index_value": "41.6595551113114",
+ "ratio": "0.416595551113114",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "RU",
+ "name": "Russian Federation",
+ "observation_year": 2024,
+ "raw_index_value": "31.3758271750097",
+ "ratio": "0.313758271750097",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "RW",
+ "name": "Rwanda",
+ "observation_year": 2024,
+ "raw_index_value": "28.003896131296",
+ "ratio": "0.28003896131296",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "SA",
+ "name": "Saudi Arabia",
+ "observation_year": 2024,
+ "raw_index_value": "49.3878755915459",
+ "ratio": "0.493878755915459",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "SB",
+ "name": "Solomon Islands",
+ "observation_year": 2024,
+ "raw_index_value": "72.1712593006936",
+ "ratio": "0.721712593006936",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "SC",
+ "name": "Seychelles",
+ "observation_year": 2024,
+ "raw_index_value": "55.0834007153095",
+ "ratio": "0.550834007153095",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "SD",
+ "name": "Sudan",
+ "observation_year": 2024,
+ "raw_index_value": "46.4681102309262",
+ "ratio": "0.464681102309262",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "SE",
+ "name": "Sweden",
+ "observation_year": 2024,
+ "raw_index_value": "80.3442193781319",
+ "ratio": "0.803442193781319",
+ "computed_band": "B",
+ "band": "A",
+ "overridden": true
+ },
+ {
+ "iso2": "SG",
+ "name": "Singapore",
+ "observation_year": 2024,
+ "raw_index_value": "61.9586274931098",
+ "ratio": "0.619586274931098",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "SI",
+ "name": "Slovenia",
+ "observation_year": 2024,
+ "raw_index_value": "59.5808235208594",
+ "ratio": "0.595808235208594",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "SK",
+ "name": "Slovak Republic",
+ "observation_year": 2024,
+ "raw_index_value": "54.3250004407031",
+ "ratio": "0.543250004407031",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "SL",
+ "name": "Sierra Leone",
+ "observation_year": 2024,
+ "raw_index_value": "22.868112275854",
+ "ratio": "0.22868112275854",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "SM",
+ "name": "San Marino",
+ "observation_year": 2023,
+ "raw_index_value": "75.9688772792505",
+ "ratio": "0.759688772792505",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "SN",
+ "name": "Senegal",
+ "observation_year": 2024,
+ "raw_index_value": "34.1112278534369",
+ "ratio": "0.341112278534369",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "SO",
+ "name": "Somalia, Fed. Rep.",
+ "observation_year": 2024,
+ "raw_index_value": "39.2409379309328",
+ "ratio": "0.392409379309328",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "SR",
+ "name": "Suriname",
+ "observation_year": 2024,
+ "raw_index_value": "31.8877332610461",
+ "ratio": "0.318877332610461",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "ST",
+ "name": "Sao Tome and Principe",
+ "observation_year": 2024,
+ "raw_index_value": "55.8244140238529",
+ "ratio": "0.558244140238529",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "SV",
+ "name": "El Salvador",
+ "observation_year": 2024,
+ "raw_index_value": "41.5072277055406",
+ "ratio": "0.415072277055406",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "SX",
+ "name": "Sint Maarten (Dutch part)",
+ "observation_year": 2024,
+ "raw_index_value": "77.0196742700397",
+ "ratio": "0.770196742700397",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "SY",
+ "name": "Syrian Arab Republic",
+ "observation_year": 2022,
+ "raw_index_value": "21.5443381716821",
+ "ratio": "0.215443381716821",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "SZ",
+ "name": "Eswatini",
+ "observation_year": 2024,
+ "raw_index_value": "33.0675101001167",
+ "ratio": "0.330675101001167",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TC",
+ "name": "Turks and Caicos Islands",
+ "observation_year": 2024,
+ "raw_index_value": "98.6773622391009",
+ "ratio": "0.986773622391009",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "TD",
+ "name": "Chad",
+ "observation_year": 2024,
+ "raw_index_value": "35.4418114316956",
+ "ratio": "0.354418114316956",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TG",
+ "name": "Togo",
+ "observation_year": 2024,
+ "raw_index_value": "33.1885302706371",
+ "ratio": "0.331885302706371",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TH",
+ "name": "Thailand",
+ "observation_year": 2024,
+ "raw_index_value": "29.6542171651989",
+ "ratio": "0.296542171651989",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TJ",
+ "name": "Tajikistan",
+ "observation_year": 2024,
+ "raw_index_value": "25.1582580825485",
+ "ratio": "0.251582580825485",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TL",
+ "name": "Timor-Leste",
+ "observation_year": 2024,
+ "raw_index_value": "30.0724727908055",
+ "ratio": "0.300724727908055",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TM",
+ "name": "Turkmenistan",
+ "observation_year": 2024,
+ "raw_index_value": "28.0809595166141",
+ "ratio": "0.280809595166141",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TN",
+ "name": "Tunisia",
+ "observation_year": 2024,
+ "raw_index_value": "28.7966783770144",
+ "ratio": "0.287966783770144",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TO",
+ "name": "Tonga",
+ "observation_year": 2024,
+ "raw_index_value": "76.0352947890093",
+ "ratio": "0.760352947890093",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "TR",
+ "name": "Turkiye",
+ "observation_year": 2024,
+ "raw_index_value": "35.2209289675403",
+ "ratio": "0.352209289675403",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "TT",
+ "name": "Trinidad and Tobago",
+ "observation_year": 2024,
+ "raw_index_value": "51.4919077038928",
+ "ratio": "0.514919077038928",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "TV",
+ "name": "Tuvalu",
+ "observation_year": 2024,
+ "raw_index_value": "92.4241076186729",
+ "ratio": "0.924241076186729",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "TZ",
+ "name": "Tanzania",
+ "observation_year": 2024,
+ "raw_index_value": "28.2145133562566",
+ "ratio": "0.282145133562566",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "UA",
+ "name": "Ukraine",
+ "observation_year": 2024,
+ "raw_index_value": "28.931009728974",
+ "ratio": "0.28931009728974",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "UG",
+ "name": "Uganda",
+ "observation_year": 2024,
+ "raw_index_value": "32.8830360936683",
+ "ratio": "0.328830360936683",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "US",
+ "name": "United States",
+ "observation_year": 2024,
+ "raw_index_value": "100",
+ "ratio": "1",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "UY",
+ "name": "Uruguay",
+ "observation_year": 2024,
+ "raw_index_value": "66.4224894928745",
+ "ratio": "0.664224894928745",
+ "computed_band": "B",
+ "band": "B",
+ "overridden": false
+ },
+ {
+ "iso2": "UZ",
+ "name": "Uzbekistan",
+ "observation_year": 2024,
+ "raw_index_value": "26.6603264677911",
+ "ratio": "0.266603264677911",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "VC",
+ "name": "St. Vincent and the Grenadines",
+ "observation_year": 2024,
+ "raw_index_value": "53.9888329440389",
+ "ratio": "0.539888329440389",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "VI",
+ "name": "Virgin Islands (U.S.)",
+ "observation_year": 2022,
+ "raw_index_value": "89.0243717259396",
+ "ratio": "0.890243717259396",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "VN",
+ "name": "Viet Nam",
+ "observation_year": 2024,
+ "raw_index_value": "28.7813411512511",
+ "ratio": "0.287813411512511",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "VU",
+ "name": "Vanuatu",
+ "observation_year": 2024,
+ "raw_index_value": "90.6601569574162",
+ "ratio": "0.906601569574162",
+ "computed_band": "A",
+ "band": "A",
+ "overridden": false
+ },
+ {
+ "iso2": "WS",
+ "name": "Samoa",
+ "observation_year": 2024,
+ "raw_index_value": "61.6284821519096",
+ "ratio": "0.616284821519096",
+ "computed_band": "C",
+ "band": "C",
+ "overridden": false
+ },
+ {
+ "iso2": "XK",
+ "name": "Kosovo",
+ "observation_year": 2024,
+ "raw_index_value": "39.2764526470122",
+ "ratio": "0.392764526470122",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "ZA",
+ "name": "South Africa",
+ "observation_year": 2024,
+ "raw_index_value": "40.4892452728896",
+ "ratio": "0.404892452728896",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "ZM",
+ "name": "Zambia",
+ "observation_year": 2024,
+ "raw_index_value": "28.1237977812003",
+ "ratio": "0.281237977812003",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ },
+ {
+ "iso2": "ZW",
+ "name": "Zimbabwe",
+ "observation_year": 2024,
+ "raw_index_value": "42.073314558067",
+ "ratio": "0.42073314558067",
+ "computed_band": "D",
+ "band": "D",
+ "overridden": false
+ }
+ ]
+}
diff --git a/copy-review/pricing/strings.json b/copy-review/pricing/strings.json
new file mode 100644
index 0000000..c4ece3c
--- /dev/null
+++ b/copy-review/pricing/strings.json
@@ -0,0 +1,611 @@
+[
+ {
+ "id": "meta.title",
+ "section": "Page",
+ "label": "Browser tab title",
+ "text": "Pricing — Carloku",
+ "context": "The browser tab title and the title shown when the page is shared. Follows the pattern of the other pages: Get started — Carloku."
+ },
+ {
+ "id": "meta.description",
+ "section": "Page",
+ "label": "Search description",
+ "text": "Four plans, priced per year in euro. Start on Free. Personal, Community and Business add room and continuous replication. Usage beyond the inclusions is billed monthly at published rates.",
+ "context": "The description search engines and link previews show under the page title. Not visible on the page itself."
+ },
+ {
+ "id": "nav.pricing",
+ "section": "Navigation",
+ "label": "Menu link",
+ "text": "Pricing",
+ "context": "The link to this page in the site's top menu, on every page, between How it works, Open source and Get started."
+ },
+ {
+ "id": "hero.title",
+ "section": "Opening",
+ "label": "Page heading",
+ "text": "Pricing",
+ "context": "The big heading at the top of the page."
+ },
+ {
+ "id": "hero.lede",
+ "section": "Opening",
+ "label": "Lede",
+ "text": "Four plans, priced per year in euro before VAT. Start on Free. When you want more room, pick a paid plan from your account's Billing page.",
+ "context": "The two or three sentences under the heading. They say what the page holds and how buying works."
+ },
+ {
+ "id": "hero.new",
+ "section": "Opening",
+ "label": "New notice",
+ "text": "Paid plans and usage billing are new on Carloku.",
+ "context": "A quiet one-line note under the lede. It says once that this is new, without apology."
+ },
+ {
+ "id": "plans.heading",
+ "section": "The plans",
+ "label": "Section heading",
+ "text": "The plans",
+ "context": "Heading over the four plan cards."
+ },
+ {
+ "id": "plan.free.name",
+ "section": "The plans",
+ "label": "Free plan name",
+ "text": "Free",
+ "context": "The name on the first card and on the console's billing page."
+ },
+ {
+ "id": "plan.free.price",
+ "section": "The plans",
+ "label": "Free price",
+ "text": "€0",
+ "context": "The price line on the Free card."
+ },
+ {
+ "id": "plan.free.for",
+ "section": "The plans",
+ "label": "Free, who it is for",
+ "text": "For trying Carloku, or for a small app you never want to pay for.",
+ "context": "One sentence under the price on the Free card."
+ },
+ {
+ "id": "plan.free.i1",
+ "section": "The plans",
+ "label": "Free inclusion 1",
+ "text": "One member",
+ "context": "First item in the Free card's list."
+ },
+ {
+ "id": "plan.free.i2",
+ "section": "The plans",
+ "label": "Free inclusion 2",
+ "text": "3 apps",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.free.i3",
+ "section": "The plans",
+ "label": "Free inclusion 3",
+ "text": "100 awake hours a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.free.i4",
+ "section": "The plans",
+ "label": "Free inclusion 4",
+ "text": "250 MB of storage",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.free.i5",
+ "section": "The plans",
+ "label": "Free inclusion 5",
+ "text": "1 GB of transfer a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.free.i6",
+ "section": "The plans",
+ "label": "Free inclusion 6",
+ "text": "Apps sleep after 2 minutes idle",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.free.i7",
+ "section": "The plans",
+ "label": "Free inclusion 7",
+ "text": "Your data is saved when an app sleeps. There is no continuous replication and no restore to an earlier moment.",
+ "context": "The durability line on the Free card. It has to be honest about what Free does not get without sounding reckless."
+ },
+ {
+ "id": "plan.free.i8",
+ "section": "The plans",
+ "label": "Free inclusion 8",
+ "text": "An app nobody visits for 90 days is archived: its address stops answering and its data is kept, compressed, and restored on request. You get an email at 60 and 80 days. Nothing is ever deleted.",
+ "context": "The dormancy line on the Free card."
+ },
+ {
+ "id": "plan.free.cta",
+ "section": "The plans",
+ "label": "Free button",
+ "text": "Create an account",
+ "context": "The button at the foot of the Free card. It goes to the console, where sign-in creates the account."
+ },
+ {
+ "id": "plan.personal.name",
+ "section": "The plans",
+ "label": "Personal plan name",
+ "text": "Personal",
+ "context": "The name on the second card, on Stripe's checkout page and on invoices."
+ },
+ {
+ "id": "plan.personal.price",
+ "section": "The plans",
+ "label": "Personal price",
+ "text": "€24 a year",
+ "context": "The price line on the Personal card."
+ },
+ {
+ "id": "plan.personal.for",
+ "section": "The plans",
+ "label": "Personal, who it is for",
+ "text": "For one person running a few apps.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.personal.i1",
+ "section": "The plans",
+ "label": "Personal inclusion 1",
+ "text": "One member",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.personal.i2",
+ "section": "The plans",
+ "label": "Personal inclusion 2",
+ "text": "85 awake hours a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.personal.i3",
+ "section": "The plans",
+ "label": "Personal inclusion 3",
+ "text": "2 GB of storage",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.personal.i4",
+ "section": "The plans",
+ "label": "Personal inclusion 4",
+ "text": "2 GB of transfer a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.personal.cta",
+ "section": "The plans",
+ "label": "Personal button",
+ "text": "Choose Personal",
+ "context": "The button at the foot of the Personal card. It goes to the console's billing page."
+ },
+ {
+ "id": "plan.community.name",
+ "section": "The plans",
+ "label": "Community plan name",
+ "text": "Community",
+ "context": "The name on the third card, on Stripe's checkout page and on invoices."
+ },
+ {
+ "id": "plan.community.price",
+ "section": "The plans",
+ "label": "Community price",
+ "text": "€5 per member a year",
+ "context": "The price line on the Community card."
+ },
+ {
+ "id": "plan.community.min",
+ "section": "The plans",
+ "label": "Community minimum",
+ "text": "Minimum 10 members, so €50 a year to start.",
+ "context": "Small print under the Community price."
+ },
+ {
+ "id": "plan.community.for",
+ "section": "The plans",
+ "label": "Community, who it is for",
+ "text": "For a group sharing one account: a club, a class, an open-source project.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.community.i1",
+ "section": "The plans",
+ "label": "Community inclusion 1",
+ "text": "Each member adds 17 awake hours a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.community.i2",
+ "section": "The plans",
+ "label": "Community inclusion 2",
+ "text": "Each member adds 0.5 GB of storage",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.community.i3",
+ "section": "The plans",
+ "label": "Community inclusion 3",
+ "text": "Each member adds 0.4 GB of transfer a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.community.cta",
+ "section": "The plans",
+ "label": "Community button",
+ "text": "Choose Community",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.name",
+ "section": "The plans",
+ "label": "Business plan name",
+ "text": "Business",
+ "context": "The name on the fourth card, on Stripe's checkout page and on invoices."
+ },
+ {
+ "id": "plan.business.price",
+ "section": "The plans",
+ "label": "Business price",
+ "text": "€50 per member a year",
+ "context": "The price line on the Business card."
+ },
+ {
+ "id": "plan.business.min",
+ "section": "The plans",
+ "label": "Business minimum",
+ "text": "Minimum 10 members, so €500 a year to start.",
+ "context": "Small print under the Business price."
+ },
+ {
+ "id": "plan.business.for",
+ "section": "The plans",
+ "label": "Business, who it is for",
+ "text": "For teams that need continuous replication and restore.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.i1",
+ "section": "The plans",
+ "label": "Business inclusion 1",
+ "text": "Each member adds 170 awake hours a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.i2",
+ "section": "The plans",
+ "label": "Business inclusion 2",
+ "text": "Each member adds 5 GB of storage",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.i3",
+ "section": "The plans",
+ "label": "Business inclusion 3",
+ "text": "Each member adds 3 GB of transfer a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.i4",
+ "section": "The plans",
+ "label": "Business inclusion 4",
+ "text": "Each member adds 30,000 replication writes a month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.i5",
+ "section": "The plans",
+ "label": "Business inclusion 5",
+ "text": "Continuous replication, with restore to an earlier moment",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.i6",
+ "section": "The plans",
+ "label": "Business inclusion 6",
+ "text": "Priority support",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plan.business.cta",
+ "section": "The plans",
+ "label": "Business button",
+ "text": "Choose Business",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "plans.note",
+ "section": "The plans",
+ "label": "Under the cards",
+ "text": "Paid plans are never archived, however quiet the app.",
+ "context": "One line under the four cards."
+ },
+ {
+ "id": "member.heading",
+ "section": "What a member is",
+ "label": "Section heading",
+ "text": "What a member is",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "member.p1",
+ "section": "What a member is",
+ "label": "Paragraph 1",
+ "text": "A member is a person with access to the account in the console. People who use the apps you deploy are never counted and never priced.",
+ "context": "The sentence that stops a reader pricing their app's users as members."
+ },
+ {
+ "id": "member.p2",
+ "section": "What a member is",
+ "label": "Paragraph 2",
+ "text": "Inclusions are per member, per month. They are pooled across the account and do not roll over.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.heading",
+ "section": "Prices where you live",
+ "label": "Section heading",
+ "text": "Prices where you live",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.p1",
+ "section": "Prices where you live",
+ "label": "Paragraph 1",
+ "text": "Prices are indexed to local affordability, using a World Bank price-level measure for your billing country. There are four bands.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.a",
+ "section": "Prices where you live",
+ "label": "Band A line",
+ "text": "Band A pays the full price and gets the full inclusions.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.b",
+ "section": "Prices where you live",
+ "label": "Band B line",
+ "text": "Band B pays 75% and gets 75% of the inclusions.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.c",
+ "section": "Prices where you live",
+ "label": "Band C line",
+ "text": "Band C pays 50% and gets 50%.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.d",
+ "section": "Prices where you live",
+ "label": "Band D line",
+ "text": "Band D pays 35% and gets 35%.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.table.personal",
+ "section": "Prices where you live",
+ "label": "Table row, Personal",
+ "text": "Personal, a year",
+ "context": "Row label in the price-by-band table. The figures in the row are €24, €18, €12, €8.40."
+ },
+ {
+ "id": "bands.table.community",
+ "section": "Prices where you live",
+ "label": "Table row, Community",
+ "text": "Community, per member a year",
+ "context": "Row label. Figures: €5, €3.75, €2.50, €1.75."
+ },
+ {
+ "id": "bands.table.business",
+ "section": "Prices where you live",
+ "label": "Table row, Business",
+ "text": "Business, per member a year",
+ "context": "Row label. Figures: €50, €37.50, €25, €17.50."
+ },
+ {
+ "id": "bands.p2",
+ "section": "Prices where you live",
+ "label": "Paragraph 2",
+ "text": "Ireland, the EU-15, the US, the UK, Australia and Canada are band A. Your billing country sets the band at checkout. Usage beyond the inclusions costs the same in every band.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.p3",
+ "section": "Prices where you live",
+ "label": "Paragraph 3",
+ "text": "Checkout can show the price in your local currency. The euro price is what is charged.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "bands.list.summary",
+ "section": "Prices where you live",
+ "label": "Country list toggle",
+ "text": "Every country and its band",
+ "context": "The clickable label of a folded list of all 199 countries with their bands. The list itself is data, not copy."
+ },
+ {
+ "id": "over.heading",
+ "section": "Going past what's included",
+ "label": "Section heading",
+ "text": "Going past what's included",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "over.p1",
+ "section": "Going past what's included",
+ "label": "Paragraph 1",
+ "text": "Usage beyond the pooled inclusions is billed monthly, from our own usage statements.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "over.table.awake",
+ "section": "Going past what's included",
+ "label": "Table row, awake",
+ "text": "Awake time",
+ "context": "Row label. The rate shown is €0.010 per hour."
+ },
+ {
+ "id": "over.table.storage",
+ "section": "Going past what's included",
+ "label": "Table row, storage",
+ "text": "Storage",
+ "context": "Row label. Rate: €0.106 per GB per month."
+ },
+ {
+ "id": "over.table.transfer",
+ "section": "Going past what's included",
+ "label": "Table row, transfer",
+ "text": "Transfer",
+ "context": "Row label. Rate: €0.414 per GB."
+ },
+ {
+ "id": "over.table.writes",
+ "section": "Going past what's included",
+ "label": "Table row, writes",
+ "text": "Replication writes",
+ "context": "Row label. Rate: €0.023 per 1,000."
+ },
+ {
+ "id": "over.rate.awake",
+ "section": "Going past what's included",
+ "label": "Rate, awake",
+ "text": "€0.010 per hour",
+ "context": "The rate cell next to Awake time."
+ },
+ {
+ "id": "over.rate.storage",
+ "section": "Going past what's included",
+ "label": "Rate, storage",
+ "text": "€0.106 per GB per month",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "over.rate.transfer",
+ "section": "Going past what's included",
+ "label": "Rate, transfer",
+ "text": "€0.414 per GB",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "over.rate.writes",
+ "section": "Going past what's included",
+ "label": "Rate, writes",
+ "text": "€0.023 per 1,000",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "over.p2",
+ "section": "Going past what's included",
+ "label": "Paragraph 2",
+ "text": "A month under €1 is not billed. We bill only usage we measured completely. If our measurement of a meter is incomplete for a month, that meter is not billed for that month.",
+ "context": "The completeness promise. It is what lets us hold billing when evidence is missing instead of guessing."
+ },
+ {
+ "id": "over.p3",
+ "section": "Going past what's included",
+ "label": "Paragraph 3",
+ "text": "Apps can serve files straight from their storage bucket. For that transfer we count only what Amazon Web Services (AWS) charges us for. If that count is wrong, it is wrong in your favour.",
+ "context": "The object-storage transfer contract Paul settled: only transfer AWS charges Team Tito for."
+ },
+ {
+ "id": "half.heading",
+ "section": "Half price for anyone",
+ "label": "Section heading",
+ "text": "Half price for anyone",
+ "context": "Heading of the dark full-width band."
+ },
+ {
+ "id": "half.p1",
+ "section": "Half price for anyone",
+ "label": "Paragraph",
+ "text": "Use the code HALF at checkout for 50% off the subscription, forever. No form, no proof. The inclusions are not halved.",
+ "context": "The code word HALF is a placeholder until the promotion code is created in Stripe. Edit it here and the same word will be created."
+ },
+ {
+ "id": "promise.heading",
+ "section": "What we promise",
+ "label": "Section heading",
+ "text": "What we promise",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "promise.p1",
+ "section": "What we promise",
+ "label": "Paragraph",
+ "text": "Your price is fixed for the year you bought. Rates and country bands are reviewed once a year, in public. Any tightening applies to new subscriptions only. Existing accounts keep the deal they signed up for until they choose to change it.",
+ "context": "The review promise from the pricing design."
+ },
+ {
+ "id": "pay.heading",
+ "section": "Tax, paying and cancelling",
+ "label": "Section heading",
+ "text": "Tax, paying and cancelling",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "pay.p1",
+ "section": "Tax, paying and cancelling",
+ "label": "Tax",
+ "text": "Prices exclude value-added tax (VAT). VAT is added at checkout according to your billing country and shown before you pay. The merchant is Team Tito Limited, Dublin, Ireland.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "pay.p2",
+ "section": "Tax, paying and cancelling",
+ "label": "Paying and cancelling",
+ "text": "You pay by card through Stripe. From your account's Billing page you can change your card, download invoices and cancel. Cancelling keeps the plan running until the end of the year you paid for.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "pay.p3",
+ "section": "Tax, paying and cancelling",
+ "label": "Team changes",
+ "text": "Adding a member to Community or Business charges the rest of the current year for that member straight away, prorated to the day. A member who leaves comes off the bill at renewal.",
+ "context": "This states the proration decision. 'Straight away' (charged when added) is the recommendation; the alternative is 'on your next invoice'. Whatever you approve here is what the billing worker will do."
+ },
+ {
+ "id": "pay.p4",
+ "section": "Tax, paying and cancelling",
+ "label": "Privacy",
+ "text": "We keep no card details, billing name or billing address on our side.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "start.heading",
+ "section": "Start",
+ "label": "Closing heading",
+ "text": "Start",
+ "context": "Heading of the closing call to action."
+ },
+ {
+ "id": "start.p1",
+ "section": "Start",
+ "label": "Closing text",
+ "text": "Create an account at console.carloku.com. You sign in with a passkey through Keymail, so there is no password. Every new account starts on Free, and no card is needed. When you want more, open your account's Billing page, choose a plan and pay.",
+ "context": "One line in the plan card's list of what the plan includes."
+ },
+ {
+ "id": "start.cta.console",
+ "section": "Start",
+ "label": "Primary button",
+ "text": "Create an account",
+ "context": "The purple button in the closing section. Goes to the console."
+ },
+ {
+ "id": "start.cta.guide",
+ "section": "Start",
+ "label": "Secondary button",
+ "text": "Read the setup guide",
+ "context": "The quiet button beside it. Goes to /get-started/."
+ }
+]
\ No newline at end of file
diff --git a/eleventy.config.js b/eleventy.config.js
index 05d185a..2ef1098 100644
--- a/eleventy.config.js
+++ b/eleventy.config.js
@@ -47,6 +47,7 @@ function sameFence(closing, opening) {
export default function (eleventyConfig) {
eleventyConfig.addPassthroughCopy({ "src/index.html": "index.html" });
eleventyConfig.addPassthroughCopy({ "src/get-started": "get-started" });
+ eleventyConfig.addPassthroughCopy({ "src/pricing": "pricing" });
eleventyConfig.addPassthroughCopy({ "src/site.css": "site.css" });
eleventyConfig.addPassthroughCopy({ "src/docs.css": "docs.css" });
eleventyConfig.addPassthroughCopy({ "src/site.js": "site.js" });
diff --git a/src/get-started/index.html b/src/get-started/index.html
index e3088fc..6f4e860 100644
--- a/src/get-started/index.html
+++ b/src/get-started/index.html
@@ -24,6 +24,7 @@
<nav aria-label="Site">
<a href="/#workflow">How it works</a>
<a href="/#open">Open source</a>
+ <a href="/pricing/">Pricing</a>
<a href="/get-started/">Get started</a>
</nav>
<a class="head-cta" href="https://console.carloku.com">Dashboard</a>
diff --git a/src/index.html b/src/index.html
index 56ff07f..7df92cd 100644
--- a/src/index.html
+++ b/src/index.html
@@ -39,6 +39,7 @@ the verdict, and DESIGN.md.
<nav aria-label="Site">
<a href="#workflow">How it works</a>
<a href="#open">Open source</a>
+ <a href="/pricing/">Pricing</a>
<a href="/get-started/">Get started</a>
</nav>
<a class="head-cta" href="https://console.carloku.com">Dashboard</a>
diff --git a/src/pricing/index.html b/src/pricing/index.html
new file mode 100644
index 0000000..223c0f2
--- /dev/null
+++ b/src/pricing/index.html
@@ -0,0 +1,194 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Pricing — Carloku</title>
+<meta name="description" content="🤖 Four plans, priced per year in euro. Start on Free. Personal, Community and Business add room and continuous replication. Usage beyond the inclusions is billed monthly at published rates.">
+<meta property="og:title" content="Pricing — Carloku">
+<meta property="og:description" content="Four plans, priced per year in euro. Start on Free. Personal, Community and Business add room and continuous replication. Usage beyond the inclusions is billed monthly at published rates.">
+<meta property="og:type" content="website">
+<meta property="og:url" content="https://carloku.com/pricing/">
+<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
+<meta name="theme-color" content="#0e0c13" media="(prefers-color-scheme: dark)">
+<link rel="icon" href="/favicon.svg" type="image/svg+xml">
+<link rel="preload" href="/fonts/Geist-Variable.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/GeistMono-Variable.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="stylesheet" href="/site.css">
+</head>
+<body>
+<a class="skip" href="#main">Skip to content</a>
+<header class="site-head">
+ <div class="wrap">
+ <a class="brand" href="/"><svg class="mark" viewBox="0 0 64 64" aria-hidden="true"><rect width="64" height="64" rx="14" fill="#5b3e96"/><circle cx="30" cy="32" r="17" fill="none" stroke="#ffffff" stroke-width="8" stroke-linecap="round" stroke-dasharray="88.8 18" stroke-dashoffset="-9"/><circle cx="51" cy="44" r="5" fill="#c9b2f7"/></svg>Carloku</a>
+ <nav aria-label="Site">
+ <a href="/#workflow">How it works</a>
+ <a href="/#open">Open source</a>
+ <a href="/pricing/" aria-current="page">Pricing</a>
+ <a href="/get-started/">Get started</a>
+ </nav>
+ <a class="head-cta" href="https://console.carloku.com">Dashboard</a>
+ </div>
+</header>
+<main id="main">
+ <div class="page-hero">
+ <div class="wrap narrow">
+ <h1><span>Pricing</span><span class="dot">.</span></h1>
+ <p class="lede">Four plans, priced per year in euro before VAT. Start on Free. When you want more room, pick a paid plan from your account's Billing page.</p>
+ <p class="hero-note">Paid plans and usage billing are new on Carloku.</p>
+ </div>
+ </div>
+ <section class="plans-section">
+ <div class="wrap">
+ <h2>The plans</h2>
+ <div class="plans">
+ <article class="plan">
+ <h3>Free</h3>
+ <p class="price"><span>€0</span></p>
+ <p class="for"><span>For trying Carloku, or for a small app you never want to pay for.</span></p>
+ <ul>
+ <li>One member</li>
+ <li>3 apps</li>
+ <li>100 awake hours a month</li>
+ <li>250 MB of storage</li>
+ <li>1 GB of transfer a month</li>
+ <li>Apps sleep after 2 minutes idle</li>
+ <li>Your data is saved when an app sleeps. There is no continuous replication and no restore to an earlier moment.</li>
+ <li>An app nobody visits for 90 days is archived: its address stops answering and its data is kept, compressed, and restored on request. You get an email at 60 and 80 days. Nothing is ever deleted.</li>
+ </ul>
+ <a class="btn btn-quiet" href="https://console.carloku.com">Create an account</a>
+ </article>
+ <article class="plan featured">
+ <h3>Personal</h3>
+ <p class="price"><span>€24 a year</span></p>
+ <p class="for"><span>For one person running a few apps.</span></p>
+ <ul>
+ <li>One member</li>
+ <li>85 awake hours a month</li>
+ <li>2 GB of storage</li>
+ <li>2 GB of transfer a month</li>
+ </ul>
+ <a class="btn btn-primary" href="https://console.carloku.com">Choose Personal</a>
+ </article>
+ <article class="plan">
+ <h3>Community</h3>
+ <p class="price"><span>€5 per member a year</span></p>
+ <p class="min"><span>Minimum 10 members, so €50 a year to start.</span></p>
+ <p class="for"><span>For a group sharing one account: a club, a class, an open-source project.</span></p>
+ <ul>
+ <li>Each member adds 17 awake hours a month</li>
+ <li>Each member adds 0.5 GB of storage</li>
+ <li>Each member adds 0.4 GB of transfer a month</li>
+ </ul>
+ <a class="btn btn-quiet" href="https://console.carloku.com">Choose Community</a>
+ </article>
+ <article class="plan">
+ <h3>Business</h3>
+ <p class="price"><span>€50 per member a year</span></p>
+ <p class="min"><span>Minimum 10 members, so €500 a year to start.</span></p>
+ <p class="for"><span>For teams that need continuous replication and restore.</span></p>
+ <ul>
+ <li>Each member adds 170 awake hours a month</li>
+ <li>Each member adds 5 GB of storage</li>
+ <li>Each member adds 3 GB of transfer a month</li>
+ <li>Each member adds 30,000 replication writes a month</li>
+ <li>Continuous replication, with restore to an earlier moment</li>
+ <li>Priority support</li>
+ </ul>
+ <a class="btn btn-quiet" href="https://console.carloku.com">Choose Business</a>
+ </article>
+ </div>
+ <p class="plans-note">Paid plans are never archived, however quiet the app.</p>
+ </div>
+ </section>
+ <section class="tint">
+ <div class="wrap narrow prose">
+ <h2>What a member is</h2>
+ <p>A member is a person with access to the account in the console. People who use the apps you deploy are never counted and never priced.</p>
+ <p>Inclusions are per member, per month. They are pooled across the account and do not roll over.</p>
+ </div>
+ </section>
+ <section>
+ <div class="wrap narrow prose">
+ <h2>Prices where you live</h2>
+ <p>Prices are indexed to local affordability, using a World Bank price-level measure for your billing country. There are four bands.</p>
+ <ul>
+ <li>Band A pays the full price and gets the full inclusions.</li>
+ <li>Band B pays 75% and gets 75% of the inclusions.</li>
+ <li>Band C pays 50% and gets 50%.</li>
+ <li>Band D pays 35% and gets 35%.</li>
+ </ul>
+ <table class="price-table">
+ <thead><tr><th scope="col"><span class="visually-hidden">Plan</span></th><th scope="col">A</th><th scope="col">B</th><th scope="col">C</th><th scope="col">D</th></tr></thead>
+ <tbody>
+ <tr><th scope="row">Personal, a year</th><td>€24</td><td>€18</td><td>€12</td><td>€8.40</td></tr>
+ <tr><th scope="row">Community, per member a year</th><td>€5</td><td>€3.75</td><td>€2.50</td><td>€1.75</td></tr>
+ <tr><th scope="row">Business, per member a year</th><td>€50</td><td>€37.50</td><td>€25</td><td>€17.50</td></tr>
+ </tbody>
+ </table>
+ <p>Ireland, the EU-15, the US, the UK, Australia and Canada are band A. Your billing country sets the band at checkout. Usage beyond the inclusions costs the same in every band.</p>
+ <p>Checkout can show the price in your local currency. The euro price is what is charged.</p>
+ <details class="bands-all">
+ <summary>Every country and its band</summary>
+ <div class="band-col"><h3>Band A</h3><p>Australia, Austria, Bahamas, The, Barbados, Belgium, Bermuda, Canada, Cayman Islands, Denmark, Faroe Islands, Finland, France, Germany, Greece, Iceland, Ireland, Israel, Italy, Luxembourg, Marshall Islands, Micronesia, Fed. Sts., Naoero, Netherlands, New Zealand, Portugal, Spain, Sweden, Switzerland, Turks and Caicos Islands, Tuvalu, United Kingdom, United States, Vanuatu, Virgin Islands (U.S.)</p></div>
+ <div class="band-col"><h3>Band B</h3><p>Andorra, Antigua and Barbuda, Aruba, Curacao, Greenland, Haiti, Hong Kong SAR, China, Kiribati, Malta, Norway, Palau, Puerto Rico (US), San Marino, Sint Maarten (Dutch part), Solomon Islands, St. Kitts and Nevis, Tonga, United Arab Emirates, Uruguay, West Bank and Gaza</p></div>
+ <div class="band-col"><h3>Band C</h3><p>Albania, Argentina, Bahrain, Belize, Brazil, Cabo Verde, Chile, China, Comoros, Costa Rica, Croatia, Cyprus, Czechia, Djibouti, Dominica, Ecuador, Estonia, Grenada, Guatemala, Honduras, Hungary, Jamaica, Japan, Jordan, Korea, Rep., Kuwait, Latvia, Liberia, Libya, Lithuania, Macao SAR, China, Maldives, Mexico, Oman, Panama, Papua New Guinea, Peru, Poland, Qatar, Samoa, Sao Tome and Principe, Saudi Arabia, Seychelles, Singapore, Slovak Republic, Slovenia, St. Lucia, St. Vincent and the Grenadines, Sudan, Trinidad and Tobago</p></div>
+ <div class="band-col"><h3>Band D</h3><p>Afghanistan, Algeria, Angola, Armenia, Azerbaijan, Bangladesh, Belarus, Benin, Bhutan, Bolivia, Bosnia and Herzegovina, Botswana, Brunei Darussalam, Bulgaria, Burkina Faso, Burundi, Cambodia, Cameroon, Central African Republic, Chad, Colombia, Congo, Dem. Rep., Congo, Rep., Cote d'Ivoire, Dominican Republic, Egypt, Arab Rep., El Salvador, Equatorial Guinea, Eswatini, Ethiopia, Fiji, Gabon, Gambia, The, Georgia, Ghana, Guinea, Guinea-Bissau, Guyana, India, Indonesia, Iran, Islamic Rep., Iraq, Kazakhstan, Kenya, Kosovo, Kyrgyz Republic, Lao PDR, Lebanon, Lesotho, Madagascar, Malawi, Malaysia, Mali, Mauritania, Mauritius, Moldova, Mongolia, Montenegro, Morocco, Mozambique, Myanmar, Namibia, Nepal, Nicaragua, Niger, Nigeria, North Macedonia, Pakistan, Paraguay, Philippines, Romania, Russian Federation, Rwanda, Senegal, Serbia, Sierra Leone, Somalia, Fed. Rep., South Africa, Sri Lanka, Suriname, Syrian Arab Republic, Tajikistan, Tanzania, Thailand, Timor-Leste, Togo, Tunisia, Turkiye, Turkmenistan, Uganda, Ukraine, Uzbekistan, Viet Nam, Zambia, Zimbabwe</p></div>
+ </details>
+ </div>
+ </section>
+ <section class="tint">
+ <div class="wrap narrow prose">
+ <h2>Going past what's included</h2>
+ <p>Usage beyond the pooled inclusions is billed monthly, from our own usage statements.</p>
+ <table class="price-table rates">
+ <tbody>
+ <tr><th scope="row">Awake time</th><td>€0.010 per hour</td></tr>
+ <tr><th scope="row">Storage</th><td>€0.106 per GB per month</td></tr>
+ <tr><th scope="row">Transfer</th><td>€0.414 per GB</td></tr>
+ <tr><th scope="row">Replication writes</th><td>€0.023 per 1,000</td></tr>
+ </tbody>
+ </table>
+ <p>A month under €1 is not billed. We bill only usage we measured completely. If our measurement of a meter is incomplete for a month, that meter is not billed for that month.</p>
+ <p>Apps can serve files straight from their storage bucket. For that transfer we count only what Amazon Web Services (AWS) charges us for. If that count is wrong, it is wrong in your favour.</p>
+ </div>
+ </section>
+ <section class="band">
+ <div class="wrap">
+ <h2>Half price for anyone</h2>
+ <p>Use the code HALF at checkout for 50% off the subscription, forever. No form, no proof. The inclusions are not halved.</p>
+ </div>
+ </section>
+ <section>
+ <div class="wrap narrow prose">
+ <h2>What we promise</h2>
+ <p>Your price is fixed for the year you bought. Rates and country bands are reviewed once a year, in public. Any tightening applies to new subscriptions only. Existing accounts keep the deal they signed up for until they choose to change it.</p>
+ <h2>Tax, paying and cancelling</h2>
+ <p>Prices exclude value-added tax (VAT). VAT is added at checkout according to your billing country and shown before you pay. The merchant is Team Tito Limited, Dublin, Ireland.</p>
+ <p>You pay by card through Stripe. From your account's Billing page you can change your card, download invoices and cancel. Cancelling keeps the plan running until the end of the year you paid for.</p>
+ <p>Adding a member to Community or Business charges the rest of the current year for that member straight away, prorated to the day. A member who leaves comes off the bill at renewal.</p>
+ <p>We keep no card details, billing name or billing address on our side.</p>
+ </div>
+ </section>
+ <section class="close-cta">
+ <div class="wrap">
+ <h2><span>Start</span><span class="dot">.</span></h2>
+ <p>Create an account at console.carloku.com. You sign in with a passkey through Keymail, so there is no password. Every new account starts on Free, and no card is needed. When you want more, open your account's Billing page, choose a plan and pay.</p>
+ <div class="cta">
+ <a class="btn btn-primary" href="https://console.carloku.com">Create an account</a>
+ <a class="btn btn-quiet" href="/get-started/">Read the setup guide</a>
+ </div>
+ </div>
+ </section>
+</main>
+<footer>
+ <div class="wrap">
+ <p>🤖 Written by an LLM (Claude), on the ideas, instruction, and editing of humans.
+ AI-written text here is always marked and always disclosed; see
+ <a href="https://11factor.org/#x">factor X</a>.</p>
+ <p><a href="/">← carloku.com</a> · <a href="https://github.com/carlosframework/carloku">Source on GitHub</a>.</p>
+ </div>
+</footer>
+<script src="/site.js" defer></script>
+</body>
+</html>
diff --git a/src/site.css b/src/site.css
index 929a181..a8c0933 100644
--- a/src/site.css
+++ b/src/site.css
@@ -386,3 +386,53 @@ article.guide .note {
html { scroll-behavior: auto; }
*, *::before, *::after { animation: none !important; transition: none !important; }
}
+
+/* ---- Pricing ---- */
+.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
+.plans-section { padding-top: 2rem; }
+.plans {
+ margin-top: 2.25rem;
+ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 1.25rem; align-items: stretch;
+}
+.plan {
+ display: flex; flex-direction: column;
+ border: 1px solid var(--line-strong); border-radius: 0.85rem;
+ padding: 1.5rem 1.4rem 1.4rem; background: var(--bg);
+}
+.plan.featured { border-color: var(--accent); box-shadow: var(--shadow); }
+.plan h3 { font-size: 1.12rem; font-weight: 620; letter-spacing: -0.01em; }
+.plan .price { margin-top: 0.6rem; font-size: 1.55rem; font-weight: 650; letter-spacing: -0.02em; line-height: 1.2; }
+.plan .min { margin-top: 0.25rem; font-size: 0.86rem; color: var(--faint); }
+.plan .for { margin-top: 0.8rem; color: var(--muted); font-size: 0.96rem; min-height: 3.1em; }
+.plan ul { list-style: none; padding: 0; margin: 1.1rem 0 1.4rem; flex: 1; }
+.plan li { font-size: 0.92rem; color: var(--muted); padding: 0.42rem 0 0.42rem 1.25rem; position: relative; border-top: 1px solid var(--line); }
+.plan li::before { content: ""; position: absolute; left: 0; top: 0.95rem; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--accent); opacity: 0.7; }
+.plan .btn { justify-content: center; }
+.plans-note { margin-top: 1.5rem; color: var(--faint); font-size: 0.95rem; }
+.prose h2 { font-size: 1.45rem; margin-bottom: 1rem; }
+.prose h2 + h2, .prose p + h2, .prose table + h2 { margin-top: 2.6rem; }
+.prose p, .prose ul { color: var(--muted); max-width: 42rem; margin-bottom: 1rem; }
+.prose ul { padding-left: 1.2rem; }
+.prose li + li { margin-top: 0.4rem; }
+.prose a { color: var(--accent); text-decoration: none; }
+.prose a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
+.price-table { border-collapse: collapse; width: 100%; max-width: 42rem; margin: 1.25rem 0 1.4rem; font-size: 0.95rem; font-variant-numeric: tabular-nums; }
+.price-table th, .price-table td { text-align: left; padding: 0.6rem 0.75rem 0.6rem 0; border-bottom: 1px solid var(--line); vertical-align: top; }
+.price-table thead th { color: var(--faint); font-weight: 560; font-size: 0.85rem; }
+.price-table tbody th { font-weight: 520; color: var(--ink); }
+.price-table td { color: var(--muted); }
+.bands-all { margin-top: 1.25rem; }
+.bands-all summary { cursor: pointer; color: var(--accent); font-weight: 520; }
+.bands-all summary::marker { color: var(--accent); }
+.band-col { margin-top: 1rem; }
+.band-col h3 { font-size: 0.95rem; font-weight: 620; margin-bottom: 0.3rem; }
+.band-col p { font-size: 0.9rem; color: var(--faint); max-width: 42rem; }
+.band .cta { margin-top: 0; }
+@media (max-width: 62rem) {
+ .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); }
+}
+@media (max-width: 44rem) {
+ .plans { grid-template-columns: 1fr; }
+ .plan .for { min-height: 0; }
+}