feat(native): equal plan cards, mark absent features with a dash, one-line unlimited label

This commit is contained in:
Maurice
2026-11-05 23:05:56 +01:00
parent bd42661a62
commit f9e1dfe804
4 changed files with 14 additions and 6 deletions
+7 -2
View File
@@ -374,6 +374,9 @@ function planCard(plan: CloudPlan, interval: 'month' | 'year', featured: boolean
const price = interval === 'year' ? plan.yearlyCents : plan.monthlyCents;
const per = interval === 'year' ? t('native.plans.perYear') : t('native.plans.perMonth');
const feat = (text: string) => el('span', {}, icon(I.check, 16), text);
// An absent feature (e.g. a plan with no AI documents): a muted dash, not a
// green tick, so "none" never reads as a perk.
const featOff = (text: string) => el('span', { className: 'off' }, icon('M5 12h14', 16), text);
const sub = el('button', { type: 'button', className: 'btn' }, t('native.plans.subscribe'));
sub.addEventListener('click', () => subscribe(plan, interval));
return el(
@@ -390,7 +393,9 @@ function planCard(plan: CloudPlan, interval: 'month' | 'year', featured: boolean
{ className: 'plan-feats' },
feat(t('native.plans.unlimited')),
feat(t('native.plans.storage', { n: String(plan.storageGb) })),
feat(plan.aiDocuments > 0 ? t('native.plans.aiDocs', { n: String(plan.aiDocuments) }) : t('native.plans.noAi'))
plan.aiDocuments > 0
? feat(t('native.plans.aiDocs', { n: String(plan.aiDocuments) }))
: featOff(t('native.plans.noAi'))
),
sub
);
@@ -414,7 +419,7 @@ function showPlans(opts: { back?: boolean } = {}): void {
const list = plans;
if (!list) return;
content.className = 'plans';
content.replaceChildren(...list.map((p, i) => planCard(p, interval, i === list.length - 1)));
content.replaceChildren(...list.map((p) => planCard(p, interval, false)));
};
const choose = (next: 'month' | 'year') => {
if (interval === next) return;
+4
View File
@@ -849,6 +849,10 @@ a.linkbtn {
flex: none;
color: var(--ok);
}
.plan-feats .off,
.plan-feats .off svg {
color: var(--faint);
}
.plan .btn {
width: 100%;
min-height: 48px;
+1 -1
View File
@@ -51,7 +51,7 @@ const native: TranslationStrings = {
'native.plans.aiDocs': '{n} KI-Dokumente im Monat',
'native.plans.noAi': 'Keine KI-Dokumente',
'native.plans.storage': '{n} GB Speicher',
'native.plans.unlimited': 'Unbegrenzt Orte, Reisen und Personen',
'native.plans.unlimited': 'Unbegrenzt Orte, Reisen & Personen',
'native.plans.subscribe': 'Abonnieren',
'native.plans.loadError': 'Die Tarife konnten nicht geladen werden. Prüfe deine Verbindung und versuch es erneut.',
'native.plans.retry': 'Erneut versuchen',
+2 -3
View File
@@ -25,8 +25,7 @@ const native: TranslationStrings = {
'native.settings.server': 'Server',
'native.settings.serverHint': 'This app is connected to {server}.',
'native.welcome.headline': 'Your Trip.\nYour Plan.',
'native.welcome.sub':
'Plan together in real time: tours, budgets, journals, photo book — with AI. Web, phone, offline.',
'native.welcome.sub': 'Plan together in real time: tours, budgets, journals, photo book — with AI.',
'native.welcome.connect': 'Connect your TREK',
'native.welcome.connectSub': 'Open the address you already use',
'native.welcome.getCloud': 'Get TREK Cloud',
@@ -51,7 +50,7 @@ const native: TranslationStrings = {
'native.plans.aiDocs': '{n} AI documents a month',
'native.plans.noAi': 'No AI documents',
'native.plans.storage': '{n} GB storage',
'native.plans.unlimited': 'Unlimited places, trips and people',
'native.plans.unlimited': 'Unlimited places, trips & people',
'native.plans.subscribe': 'Subscribe',
'native.plans.loadError': 'Could not load the plans. Check your connection and try again.',
'native.plans.retry': 'Try again',