carlos / carloku Public

Group plan hibernation details and align plan actions

Paul Campbell pushed by claude agent, operated by paul@keymail.dev bf2ee671bb6d0f63810608ed3cabdf10d9465095 parent f26a9ad
3 files changed, +25 −7
  • copy-review/pricing/build.mjs +4 −4
  • src/pricing/index.html +18 −1
  • src/site.css +3 −2
diff --git a/copy-review/pricing/build.mjs b/copy-review/pricing/build.mjs
index e9f0658..0feeebb 100644
--- a/copy-review/pricing/build.mjs
+++ b/copy-review/pricing/build.mjs
@@ -171,10 +171,10 @@ const bandList = Object.entries(byBand).map(([b, names]) =>
// heading (plan.team.allowances), and what Business adds beyond them
// (continuous replication, priority support) is its own list.
const planCardLists = {
- free: { plain: ["i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8"] },
+ free: { plain: ["i1", "i2", "i3", "i4", "i5"], durability: ["i6", "i7", "i8"] },
personal: { plain: ["i1", "i2", "i3", "i4"] },
community: { allowances: ["i1", "i2", "i3"] },
- business: { allowances: ["i1", "i2", "i3", "i4"], features: ["i5", "i6"] },
+ business: { allowances: ["i1", "i2", "i3", "i4"], durability: ["i5"], features: ["i6"] },
};
const priceLine = (p) => {
const id = `plan.${p}.price`;
@@ -184,13 +184,13 @@ const priceLine = (p) => {
const card = (p, featured) => {
const lists = planCardLists[p];
const items = (ids) => ids.map((i) => allowanceLi(p, i)).join("\n");
- const seen = new Set([...(lists.plain || []), ...(lists.allowances || []), ...(lists.features || [])].map((i) => `plan.${p}.${i}`));
+ const seen = new Set([...(lists.plain || []), ...(lists.allowances || []), ...(lists.features || []), ...(lists.durability || [])].map((i) => `plan.${p}.${i}`));
for (const k of Object.keys(S).filter((k) => k.startsWith(`plan.${p}.i`))) if (!seen.has(k)) throw new Error("unplaced string " + k);
return ` <article class="plan${featured ? " featured" : ""}">
${t(`plan.${p}.name`, "h3")}
<p class="price">${priceLine(p)}</p>
${S[`plan.${p}.min`] ? ` <p class="min">${t(`plan.${p}.min`)}</p>\n` : ""} <p class="for">${t(`plan.${p}.for`)}</p>
-${lists.plain ? ` <ul>\n${items(lists.plain)}\n </ul>\n` : ""}${lists.allowances ? ` <p class="allowance-heading" data-copy="plan.team.allowances">${esc(S["plan.team.allowances"])}</p>\n <ul class="allowances">\n${items(lists.allowances)}\n </ul>\n` : ""}${lists.features ? ` <ul class="plan-features">\n${items(lists.features)}\n </ul>\n` : ""} <a class="btn ${featured ? "btn-primary" : "btn-quiet"}" href="https://console.carloku.com/?plan=${p}&amp;currency=&amp;country=" data-pricing-signup data-copy="plan.${p}.cta">${esc(S[`plan.${p}.cta`])}</a>
+${lists.plain ? ` <ul>\n${items(lists.plain)}\n </ul>\n` : ""}${lists.allowances ? ` <p class="allowance-heading" data-copy="plan.team.allowances">${esc(S["plan.team.allowances"])}</p>\n <ul class="allowances">\n${items(lists.allowances)}\n </ul>\n` : ""}${` <h4 class="allowance-heading">Hibernation &amp; Replication</h4>\n <ul class="durability">\n${p === "free" ? "" : ` <li data-idle-minutes="15">${esc(S["plan.free.i6"].replace("2 minutes", "15 minutes"))}</li>\n`}${items(lists.durability || [])}\n </ul>\n`}${lists.features ? ` <ul class="plan-features">\n${items(lists.features)}\n </ul>\n` : ""} <a class="btn ${featured ? "btn-primary" : "btn-quiet"}" href="https://console.carloku.com/?plan=${p}&amp;currency=&amp;country=" data-pricing-signup data-copy="plan.${p}.cta">${esc(S[`plan.${p}.cta`])}</a>
</article>`;
};
diff --git a/src/pricing/index.html b/src/pricing/index.html
index 832ba06..a292c43 100644
--- a/src/pricing/index.html
+++ b/src/pricing/index.html
@@ -73,6 +73,9 @@
<li>100 awake hours a month</li>
<li>250 MB of storage</li>
<li>1 GB of transfer a month</li>
+ </ul>
+ <h4 class="allowance-heading">Hibernation &amp; Replication</h4>
+ <ul class="durability">
<li>Apps sleep after 2 minutes idle</li>
<li>Data stored on sleep. No data replication, no data restore.</li>
<li>Apps not visited after 90 days are archived with notice. These apps can be restored later by request.</li>
@@ -88,6 +91,11 @@
<li data-band-values="{&quot;A&quot;:&quot;85 awake hours a month&quot;,&quot;B&quot;:&quot;63.75 awake hours a month&quot;,&quot;C&quot;:&quot;42.5 awake hours a month&quot;,&quot;D&quot;:&quot;29.75 awake hours a month&quot;}">85 awake hours a month</li>
<li data-band-values="{&quot;A&quot;:&quot;2 GB of storage&quot;,&quot;B&quot;:&quot;1.5 GB of storage&quot;,&quot;C&quot;:&quot;1 GB of storage&quot;,&quot;D&quot;:&quot;0.7 GB of storage&quot;}">2 GB of storage</li>
<li data-band-values="{&quot;A&quot;:&quot;2 GB of transfer a month&quot;,&quot;B&quot;:&quot;1.5 GB of transfer a month&quot;,&quot;C&quot;:&quot;1 GB of transfer a month&quot;,&quot;D&quot;:&quot;0.7 GB of transfer a month&quot;}">2 GB of transfer a month</li>
+ </ul>
+ <h4 class="allowance-heading">Hibernation &amp; Replication</h4>
+ <ul class="durability">
+ <li data-idle-minutes="15">Apps sleep after 15 minutes idle</li>
+
</ul>
<a class="btn btn-primary" href="https://console.carloku.com/?plan=personal&amp;currency=&amp;country=" data-pricing-signup>Choose Personal</a>
</article>
@@ -101,6 +109,11 @@
<li data-band-values="{&quot;A&quot;:&quot;17 awake hours a month&quot;,&quot;B&quot;:&quot;12.75 awake hours a month&quot;,&quot;C&quot;:&quot;8.5 awake hours a month&quot;,&quot;D&quot;:&quot;5.95 awake hours a month&quot;}">17 awake hours a month</li>
<li data-band-values="{&quot;A&quot;:&quot;0.5 GB of storage&quot;,&quot;B&quot;:&quot;0.375 GB of storage&quot;,&quot;C&quot;:&quot;0.25 GB of storage&quot;,&quot;D&quot;:&quot;0.175 GB of storage&quot;}">0.5 GB of storage</li>
<li data-band-values="{&quot;A&quot;:&quot;0.4 GB of transfer a month&quot;,&quot;B&quot;:&quot;0.3 GB of transfer a month&quot;,&quot;C&quot;:&quot;0.2 GB of transfer a month&quot;,&quot;D&quot;:&quot;0.14 GB of transfer a month&quot;}">0.4 GB of transfer a month</li>
+ </ul>
+ <h4 class="allowance-heading">Hibernation &amp; Replication</h4>
+ <ul class="durability">
+ <li data-idle-minutes="15">Apps sleep after 15 minutes idle</li>
+
</ul>
<a class="btn btn-quiet" href="https://console.carloku.com/?plan=community&amp;currency=&amp;country=" data-pricing-signup>Choose Community</a>
</article>
@@ -116,8 +129,12 @@
<li data-band-values="{&quot;A&quot;:&quot;3 GB of transfer a month&quot;,&quot;B&quot;:&quot;2.25 GB of transfer a month&quot;,&quot;C&quot;:&quot;1.5 GB of transfer a month&quot;,&quot;D&quot;:&quot;1.05 GB of transfer a month&quot;}">3 GB of transfer a month</li>
<li data-band-values="{&quot;A&quot;:&quot;30,000 replication writes a month&quot;,&quot;B&quot;:&quot;22,500 replication writes a month&quot;,&quot;C&quot;:&quot;15,000 replication writes a month&quot;,&quot;D&quot;:&quot;10,500 replication writes a month&quot;}">30,000 replication writes a month</li>
</ul>
- <ul class="plan-features">
+ <h4 class="allowance-heading">Hibernation &amp; Replication</h4>
+ <ul class="durability">
+ <li data-idle-minutes="15">Apps sleep after 15 minutes idle</li>
<li>Continuous replication, with restore to an earlier moment</li>
+ </ul>
+ <ul class="plan-features">
<li>Priority support</li>
</ul>
<a class="btn btn-quiet" href="https://console.carloku.com/?plan=business&amp;currency=&amp;country=" data-pricing-signup>Choose Business</a>
diff --git a/src/site.css b/src/site.css
index 986fd16..6634d1b 100644
--- a/src/site.css
+++ b/src/site.css
@@ -405,14 +405,15 @@ article.guide .note {
.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 ul { list-style: none; padding: 0; margin: 1.1rem 0 1.4rem; flex: 0; }
.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; }
+.plan .btn { justify-content: center; margin-top: auto; }
.plans-note { margin-top: 1.5rem; color: var(--faint); font-size: 0.95rem; }
.plan .allowance-heading { margin: 1.1rem 0 0; font-size: 0.92rem; font-weight: 620; }
.plan .allowances { margin-top: 0.45rem; flex: 0; }
.plan .plan-features { margin-top: 0; }
+.plan .durability { margin-top: 0.45rem; }
.pricing-controls { padding: 0 0 1.5rem; }
.currency-form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 1.25rem; }
.currency-form .control label { display: block; font-weight: 560; margin-bottom: 0.4rem; }