fixes to the calculator

This commit is contained in:
2026-10-20 08:32:39 -06:00
parent a9cccf4226
commit 99bf23ecf1
15 changed files with 155 additions and 116 deletions
+42 -39
View File
@@ -232,7 +232,7 @@ sections:
barsTitle: "What our users pay each month" barsTitle: "What our users pay each month"
bars: bars:
- name: "Federated" - name: "Federated"
amount: 120 amount: 159
highlight: true highlight: true
- name: "Google" - name: "Google"
amount: 575 amount: 575
@@ -240,45 +240,48 @@ sections:
amount: 940 amount: 940
- name: "Zoom" - name: "Zoom"
amount: 1450 amount: 1450
federatedAnnual: 2900 federatedPlans:
calcNote: "Savings compare the retail price of the apps you pick with our Best plan billed annually ($2,900/year). Prices are typical list prices per person per month, or per month for flat-fee apps." - { name: "Good", tier: "good", annual: 700 }
- { name: "Better", tier: "better", annual: 1450 }
- { name: "Best", tier: "best", annual: 2900 }
calcNote: "Savings compare the retail price of the apps you pick with the smallest hosted plan that replaces all of them, billed annually (Good $700, Better $1,450, or Best $2,900 a year). Prices are typical list prices per person per month, or per month for flat-fee apps."
apps: apps:
- { name: "1Password", cost: 8, perSeat: true } - { name: "1Password", cost: 8, tier: "good", perSeat: true }
- { name: "Airtable", cost: 20, perSeat: true } - { name: "Airtable", cost: 20, tier: "best", perSeat: true }
- { name: "Asana", cost: 15, perSeat: true } - { name: "Asana", cost: 15, tier: "best", perSeat: true }
- { name: "Box", cost: 15, perSeat: true } - { name: "Box", cost: 15, tier: "good", perSeat: true }
- { name: "Calendly", cost: 10, perSeat: true } - { name: "Calendly", cost: 10, tier: "better", perSeat: true }
- { name: "ClickUp", cost: 12, perSeat: true } - { name: "ClickUp", cost: 12, tier: "best", perSeat: true }
- { name: "Confluence", cost: 9, perSeat: true } - { name: "Confluence", cost: 9, tier: "best", perSeat: true }
- { name: "Constant Contact", cost: 80, perSeat: false } - { name: "Constant Contact", cost: 80, tier: "good", perSeat: false }
- { name: "Doodle", cost: 7, perSeat: true } - { name: "Doodle", cost: 7, tier: "better", perSeat: true }
- { name: "Dropbox", cost: 10, perSeat: true } - { name: "Dropbox", cost: 10, tier: "good", perSeat: true }
- { name: "Fastmail", cost: 5, perSeat: true } - { name: "Fastmail", cost: 5, tier: "good", perSeat: true }
- { name: "Freshdesk", cost: 15, perSeat: true } - { name: "Freshdesk", cost: 15, tier: "best", perSeat: true }
- { name: "Front", cost: 29, perSeat: true } - { name: "Front", cost: 29, tier: "best", perSeat: true }
- { name: "GitHub", cost: 4, perSeat: true } - { name: "GitHub", cost: 4, tier: "good", perSeat: true }
- { name: "GitLab", cost: 29, perSeat: true } - { name: "GitLab", cost: 29, tier: "good", perSeat: true }
- { name: "Google Workspace", cost: 13, perSeat: true, selected: true } - { name: "Google Workspace", cost: 13, tier: "good", perSeat: true, selected: true }
- { name: "HubSpot", cost: 20, perSeat: true } - { name: "HubSpot", cost: 20, tier: "better", perSeat: true }
- { name: "Intercom", cost: 29, perSeat: true } - { name: "Intercom", cost: 29, tier: "better", perSeat: true }
- { name: "Jira", cost: 12, perSeat: true } - { name: "Jira", cost: 12, tier: "best", perSeat: true }
- { name: "Mailchimp", cost: 135, perSeat: false } - { name: "Mailchimp", cost: 135, tier: "good", perSeat: false }
- { name: "Microsoft 365", cost: 14, perSeat: true } - { name: "Microsoft 365", cost: 14, tier: "good", perSeat: true }
- { name: "Microsoft Teams", cost: 8, perSeat: true } - { name: "Microsoft Teams", cost: 8, tier: "better", perSeat: true }
- { name: "Monday.com", cost: 12, perSeat: true } - { name: "Monday.com", cost: 12, tier: "best", perSeat: true }
- { name: "Notion", cost: 12, perSeat: true } - { name: "Notion", cost: 12, tier: "best", perSeat: true }
- { name: "Odoo", cost: 25, perSeat: true } - { name: "Odoo", cost: 25, tier: "best", perSeat: true }
- { name: "Proton", cost: 13, perSeat: true } - { name: "Proton", cost: 13, tier: "good", perSeat: true }
- { name: "Salesforce", cost: 25, perSeat: true } - { name: "Salesforce", cost: 25, tier: "better", perSeat: true }
- { name: "Shopify", cost: 79, perSeat: false } - { name: "Shopify", cost: 79, tier: "good", perSeat: false }
- { name: "Slack", cost: 9, perSeat: true, selected: true } - { name: "Slack", cost: 9, tier: "better", perSeat: true, selected: true }
- { name: "Squarespace", cost: 65, perSeat: false, selected: true } - { name: "Squarespace", cost: 65, tier: "good", perSeat: false, selected: true }
- { name: "Tailscale", cost: 6, perSeat: true } - { name: "Tailscale", cost: 6, tier: "good", perSeat: true }
- { name: "Trello", cost: 11, perSeat: true } - { name: "Trello", cost: 11, tier: "best", perSeat: true }
- { name: "Wix", cost: 36, perSeat: false } - { name: "Wix", cost: 36, tier: "good", perSeat: false }
- { name: "Zendesk", cost: 19, perSeat: true } - { name: "Zendesk", cost: 19, tier: "best", perSeat: true }
- { name: "Zoho", cost: 29, perSeat: true } - { name: "Zoho", cost: 29, tier: "good", perSeat: true }
- { name: "Zoom", cost: 13, perSeat: true } - { name: "Zoom", cost: 13, tier: "better", perSeat: true }
- type: faq - type: faq
id: "faq" id: "faq"
+3
View File
@@ -3,6 +3,9 @@
<title>{{ if .IsHome }}{{ .Site.Title }} — {{ .Site.Params.tagline }}{{ else }}{{ .Title }} · {{ .Site.Title }}{{ end }}</title> <title>{{ if .IsHome }}{{ .Site.Title }} — {{ .Site.Params.tagline }}{{ else }}{{ .Title }} · {{ .Site.Title }}{{ end }}</title>
<meta name="description" content="{{ if .Description }}{{ .Description }}{{ else }}{{ .Site.Params.tagline }}{{ end }}"> <meta name="description" content="{{ if .Description }}{{ .Description }}{{ else }}{{ .Site.Params.tagline }}{{ end }}">
<meta name="theme-color" content="#001a2b"> <meta name="theme-color" content="#001a2b">
<link rel="icon" href="{{ "favicon.ico" | relURL }}" sizes="32x32">
<link rel="icon" href="{{ "favicon.svg" | relURL }}" type="image/svg+xml">
<link rel="apple-touch-icon" href="{{ "apple-touch-icon.png" | relURL }}">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
+13 -9
View File
@@ -1,19 +1,20 @@
{{/* {{/*
The savings calculator: pick the apps you pay for today and your team The savings calculator: pick the apps you pay for today and your team
size, and compare their yearly retail cost with Federated's annual price. size, and compare their yearly retail cost with the smallest Federated plan
Input: dict with "key" (unique id), "apps" (name, cost, perSeat, selected), that replaces every app picked (the highest `tier` among them).
"annual", optional "note", "compact" (one result, no cost breakdown) and Input: dict with "key" (unique id), "apps" (name, cost, tier, perSeat,
selected), "plans" (name, tier, annual; cheapest first), optional "note", "compact" (one result, no cost breakdown) and
"more" (a link to the full calculator). The totals need JS; without it, "more" (a link to the full calculator). The totals need JS; without it,
the app list still shows each app's retail price. the app list still shows each app's retail price.
*/}} */}}
{{ $key := .key }} {{ $key := .key }}
<form class="savings-calc{{ if .compact }} is-compact{{ end }}" id="{{ $key }}-calc" data-annual="{{ .annual }}" onsubmit="return false"> <form class="savings-calc{{ if .compact }} is-compact{{ end }}" id="{{ $key }}-calc" data-plans="{{ .plans | jsonify }}" onsubmit="return false">
<fieldset class="calc-apps"> <fieldset class="calc-apps">
<legend class="plan-subhead">{{ if .compact }}Which of these do you pay for?{{ else }}Which apps do you pay for today?{{ end }}</legend> <legend class="plan-subhead">{{ if .compact }}Which of these do you pay for?{{ else }}Which apps do you pay for today?{{ end }}</legend>
<div class="calc-app-grid"> <div class="calc-app-grid">
{{ range .apps }} {{ range .apps }}
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="{{ .cost }}" data-per-seat="{{ .perSeat }}"{{ if .selected }} checked{{ end }}> <input type="checkbox" value="{{ .cost }}" data-tier="{{ .tier }}" data-per-seat="{{ .perSeat }}"{{ if .selected }} checked{{ end }}>
<span class="calc-app-name">{{ .name }}</span> <span class="calc-app-name">{{ .name }}</span>
<span class="calc-app-cost">${{ .cost }}{{ if .perSeat }}/person{{ else }} flat{{ end }}</span> <span class="calc-app-cost">${{ .cost }}{{ if .perSeat }}/person{{ else }} flat{{ end }}</span>
</label> </label>
@@ -34,7 +35,7 @@
<div class="calc-stat"><span class="calc-stat-label">Apps replaced</span><span class="calc-stat-value" data-out="count">0</span></div> <div class="calc-stat"><span class="calc-stat-label">Apps replaced</span><span class="calc-stat-value" data-out="count">0</span></div>
<div class="calc-stat"><span class="calc-stat-label">Their retail cost</span><span class="calc-stat-value" data-out="cost">$0</span><span class="calc-stat-unit">/year</span></div> <div class="calc-stat"><span class="calc-stat-label">Their retail cost</span><span class="calc-stat-value" data-out="cost">$0</span><span class="calc-stat-unit">/year</span></div>
{{ end }} {{ end }}
<div class="calc-stat is-highlight"><span class="calc-stat-label">You'd save</span><span class="calc-stat-value" data-out="savings">$0</span><span class="calc-stat-unit">/year</span></div> <div class="calc-stat is-highlight"><span class="calc-stat-label">You save</span><span class="calc-stat-value" data-out="savings">$0</span><span class="calc-stat-unit">/year on the <span data-out="plan">Good</span> plan</span></div>
{{ with .more }}<a class="more calc-more" href="{{ .url | relURL }}">{{ .label }}<span class="arrow" aria-hidden="true">→</span></a>{{ end }} {{ with .more }}<a class="more calc-more" href="{{ .url | relURL }}">{{ .label }}<span class="arrow" aria-hidden="true">→</span></a>{{ end }}
</div> </div>
{{ with .note }}<p class="plan-note">{{ . | markdownify }}</p>{{ end }} {{ with .note }}<p class="plan-note">{{ . | markdownify }}</p>{{ end }}
@@ -43,7 +44,7 @@
(function () { (function () {
var form = document.getElementById('{{ $key }}-calc'); var form = document.getElementById('{{ $key }}-calc');
if (!form) return; if (!form) return;
var annual = +form.dataset.annual || 0; var plans = JSON.parse(form.dataset.plans || '[]');
var range = form.querySelector('input[type=range]'); var range = form.querySelector('input[type=range]');
var shown = form.querySelector('.calc-users-value'); var shown = form.querySelector('.calc-users-value');
var fmt = function (n) { return '$' + Math.round(n).toLocaleString('en-US'); }; var fmt = function (n) { return '$' + Math.round(n).toLocaleString('en-US'); };
@@ -56,16 +57,19 @@
return 1000 + (step - 20) * 500; return 1000 + (step - 20) * 500;
} }
function update() { function update() {
var n = users(+range.value), count = 0, cost = 0; var n = users(+range.value), count = 0, cost = 0, need = 0;
shown.textContent = n.toLocaleString('en-US') + (+range.value === +range.max ? '+' : ''); shown.textContent = n.toLocaleString('en-US') + (+range.value === +range.max ? '+' : '');
range.setAttribute('aria-valuetext', shown.textContent + ' people'); range.setAttribute('aria-valuetext', shown.textContent + ' people');
form.querySelectorAll('.calc-app input:checked').forEach(function (box) { form.querySelectorAll('.calc-app input:checked').forEach(function (box) {
count++; count++;
need = Math.max(need, plans.findIndex(function (p) { return p.tier === box.dataset.tier; }));
cost += +box.value * (box.dataset.perSeat === 'true' ? n : 1) * 12; cost += +box.value * (box.dataset.perSeat === 'true' ? n : 1) * 12;
}); });
out('count', count); out('count', count);
out('cost', fmt(cost)); out('cost', fmt(cost));
out('savings', fmt(Math.max(0, cost - annual))); var plan = plans[need] || plans[plans.length - 1] || { name: '', annual: 0 };
out('savings', fmt(Math.max(0, cost - plan.annual)));
out('plan', plan.name);
} }
form.addEventListener('input', update); form.addEventListener('input', update);
update(); update();
+2 -2
View File
@@ -49,12 +49,12 @@
{{ $apps := slice }} {{ $apps := slice }}
{{ range $name := $cfg.apps }} {{ range $name := $cfg.apps }}
{{ range $src.apps }}{{ if eq .name $name }} {{ range $src.apps }}{{ if eq .name $name }}
{{ $apps = $apps | append (dict "name" .name "cost" .cost "perSeat" .perSeat "selected" (in ($cfg.selected | default slice) $name)) }} {{ $apps = $apps | append (dict "name" .name "cost" .cost "tier" .tier "perSeat" .perSeat "selected" (in ($cfg.selected | default slice) $name)) }}
{{ end }}{{ end }} {{ end }}{{ end }}
{{ end }} {{ end }}
<div class="said-savings"> <div class="said-savings">
{{ with $cfg.headline }}<h3 class="said-savings-title">{{ . }}</h3>{{ end }} {{ with $cfg.headline }}<h3 class="said-savings-title">{{ . }}</h3>{{ end }}
{{ partial "savings-calc.html" (dict "key" (printf "%s-savings" (partial "section-id.html" $s)) "apps" $apps "annual" $src.federatedAnnual "compact" true "more" $cfg.more) }} {{ partial "savings-calc.html" (dict "key" (printf "%s-savings" (partial "section-id.html" $s)) "apps" $apps "plans" $src.federatedPlans "compact" true "more" $cfg.more) }}
</div> </div>
{{ else }} {{ else }}
{{ errorf "quote section: savings.from page %q not found" $cfg.from }} {{ errorf "quote section: savings.from page %q not found" $cfg.from }}
+3 -3
View File
@@ -1,7 +1,7 @@
{{/* {{/*
Savings — an optional bar comparison (`bars`: name, amount, highlight) and Savings — an optional bar comparison (`bars`: name, amount, highlight) and
a savings calculator (`apps`: name, cost, perSeat, selected; compared with a savings calculator (`apps`: name, cost, tier, perSeat, selected; compared
`federatedAnnual`), rendered by partials/savings-calc.html. with the smallest of `federatedPlans`: name, tier, annual), rendered by partials/savings-calc.html.
*/}} */}}
{{ $s := . }} {{ $s := . }}
{{ $key := partial "section-id.html" $s | default "savings" }} {{ $key := partial "section-id.html" $s | default "savings" }}
@@ -26,6 +26,6 @@
{{ end }} {{ end }}
{{ with $s.apps }} {{ with $s.apps }}
{{ partial "savings-calc.html" (dict "key" $key "apps" . "annual" $s.federatedAnnual "note" $s.calcNote) }} {{ partial "savings-calc.html" (dict "key" $key "apps" . "plans" $s.federatedPlans "note" $s.calcNote) }}
{{ end }} {{ end }}
{{ if $s.ctas }}<div class="cta-row mt-2">{{ partial "sections/ctas.html" $s.ctas }}</div>{{ end }} {{ if $s.ctas }}<div class="cta-row mt-2">{{ partial "sections/ctas.html" $s.ctas }}</div>{{ end }}
+1 -1
View File
@@ -139,7 +139,7 @@ main:focus { outline: none; }
.site-head.is-scrolled { background: #001a2bf2; backdrop-filter: blur(12px); } .site-head.is-scrolled { background: #001a2bf2; backdrop-filter: blur(12px); }
.head-bar { display: flex; align-items: center; gap: 32px; height: var(--head-h); } .head-bar { display: flex; align-items: center; gap: 32px; height: var(--head-h); }
.brand { display: inline-flex; flex: none; } .brand { display: inline-flex; flex: none; }
.brand-logo { width: 148px; height: auto; filter: invert(1); } .brand-logo { width: 148px; height: auto; filter: invert(1); translate: 0 -3px; } /* lifts the wordmark baseline onto the nav text baseline */
.head-nav { display: flex; align-items: center; gap: 2px; margin-right: auto; } .head-nav { display: flex; align-items: center; gap: 2px; margin-right: auto; }
.nav-item { position: relative; } .nav-item { position: relative; }
+23 -17
View File
@@ -6,6 +6,9 @@
<title>Federated Computer — The Computer for your business — and the AI that runs on it.</title> <title>Federated Computer — The Computer for your business — and the AI that runs on it.</title>
<meta name="description" content="The open-source operating system for your business — and the private AI that runs on it. Unlimited users, one low price, and agentic AI that never leaves your building."> <meta name="description" content="The open-source operating system for your business — and the private AI that runs on it. Unlimited users, one low price, and agentic AI that never leaves your building.">
<meta name="theme-color" content="#001a2b"> <meta name="theme-color" content="#001a2b">
<link rel="icon" href="./favicon.ico" sizes="32x32">
<link rel="icon" href="./favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="./apple-touch-icon.png">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
@@ -1441,79 +1444,79 @@
<h3 class="said-savings-title">What would your business save?</h3> <h3 class="said-savings-title">What would your business save?</h3>
<form class="savings-calc is-compact" id="customers-savings-calc" data-annual="2900" onsubmit="return false"> <form class="savings-calc is-compact" id="customers-savings-calc" data-plans="[{&#34;annual&#34;:700,&#34;name&#34;:&#34;Good&#34;,&#34;tier&#34;:&#34;good&#34;},{&#34;annual&#34;:1450,&#34;name&#34;:&#34;Better&#34;,&#34;tier&#34;:&#34;better&#34;},{&#34;annual&#34;:2900,&#34;name&#34;:&#34;Best&#34;,&#34;tier&#34;:&#34;best&#34;}]" onsubmit="return false">
<fieldset class="calc-apps"> <fieldset class="calc-apps">
<legend class="plan-subhead">Which of these do you pay for?</legend> <legend class="plan-subhead">Which of these do you pay for?</legend>
<div class="calc-app-grid"> <div class="calc-app-grid">
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="13" data-per-seat="true" checked> <input type="checkbox" value="13" data-tier="good" data-per-seat="true" checked>
<span class="calc-app-name">Google Workspace</span> <span class="calc-app-name">Google Workspace</span>
<span class="calc-app-cost">$13/person</span> <span class="calc-app-cost">$13/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="14" data-per-seat="true"> <input type="checkbox" value="14" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Microsoft 365</span> <span class="calc-app-name">Microsoft 365</span>
<span class="calc-app-cost">$14/person</span> <span class="calc-app-cost">$14/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="9" data-per-seat="true" checked> <input type="checkbox" value="9" data-tier="better" data-per-seat="true" checked>
<span class="calc-app-name">Slack</span> <span class="calc-app-name">Slack</span>
<span class="calc-app-cost">$9/person</span> <span class="calc-app-cost">$9/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="13" data-per-seat="true"> <input type="checkbox" value="13" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Zoom</span> <span class="calc-app-name">Zoom</span>
<span class="calc-app-cost">$13/person</span> <span class="calc-app-cost">$13/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="10" data-per-seat="true"> <input type="checkbox" value="10" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Dropbox</span> <span class="calc-app-name">Dropbox</span>
<span class="calc-app-cost">$10/person</span> <span class="calc-app-cost">$10/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="8" data-per-seat="true"> <input type="checkbox" value="8" data-tier="good" data-per-seat="true">
<span class="calc-app-name">1Password</span> <span class="calc-app-name">1Password</span>
<span class="calc-app-cost">$8/person</span> <span class="calc-app-cost">$8/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="25" data-per-seat="true"> <input type="checkbox" value="25" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Salesforce</span> <span class="calc-app-name">Salesforce</span>
<span class="calc-app-cost">$25/person</span> <span class="calc-app-cost">$25/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="20" data-per-seat="true"> <input type="checkbox" value="20" data-tier="better" data-per-seat="true">
<span class="calc-app-name">HubSpot</span> <span class="calc-app-name">HubSpot</span>
<span class="calc-app-cost">$20/person</span> <span class="calc-app-cost">$20/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="19" data-per-seat="true"> <input type="checkbox" value="19" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Zendesk</span> <span class="calc-app-name">Zendesk</span>
<span class="calc-app-cost">$19/person</span> <span class="calc-app-cost">$19/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="135" data-per-seat="false"> <input type="checkbox" value="135" data-tier="good" data-per-seat="false">
<span class="calc-app-name">Mailchimp</span> <span class="calc-app-name">Mailchimp</span>
<span class="calc-app-cost">$135 flat</span> <span class="calc-app-cost">$135 flat</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="65" data-per-seat="false" checked> <input type="checkbox" value="65" data-tier="good" data-per-seat="false" checked>
<span class="calc-app-name">Squarespace</span> <span class="calc-app-name">Squarespace</span>
<span class="calc-app-cost">$65 flat</span> <span class="calc-app-cost">$65 flat</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="12" data-per-seat="true"> <input type="checkbox" value="12" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Jira</span> <span class="calc-app-name">Jira</span>
<span class="calc-app-cost">$12/person</span> <span class="calc-app-cost">$12/person</span>
</label> </label>
@@ -1531,7 +1534,7 @@
<div class="calc-result" aria-live="polite"> <div class="calc-result" aria-live="polite">
<div class="calc-stat is-highlight"><span class="calc-stat-label">You'd save</span><span class="calc-stat-value" data-out="savings">$0</span><span class="calc-stat-unit">/year</span></div> <div class="calc-stat is-highlight"><span class="calc-stat-label">You save</span><span class="calc-stat-value" data-out="savings">$0</span><span class="calc-stat-unit">/year on the <span data-out="plan">Good</span> plan</span></div>
<a class="more calc-more" href="./pricing/#savings">Try the full calculator<span class="arrow" aria-hidden="true">→</span></a> <a class="more calc-more" href="./pricing/#savings">Try the full calculator<span class="arrow" aria-hidden="true">→</span></a>
</div> </div>
@@ -1540,7 +1543,7 @@
(function () { (function () {
var form = document.getElementById('customers-savings-calc'); var form = document.getElementById('customers-savings-calc');
if (!form) return; if (!form) return;
var annual = +form.dataset.annual || 0; var plans = JSON.parse(form.dataset.plans || '[]');
var range = form.querySelector('input[type=range]'); var range = form.querySelector('input[type=range]');
var shown = form.querySelector('.calc-users-value'); var shown = form.querySelector('.calc-users-value');
var fmt = function (n) { return '$' + Math.round(n).toLocaleString('en-US'); }; var fmt = function (n) { return '$' + Math.round(n).toLocaleString('en-US'); };
@@ -1553,16 +1556,19 @@
return 1000 + (step - 20) * 500; return 1000 + (step - 20) * 500;
} }
function update() { function update() {
var n = users(+range.value), count = 0, cost = 0; var n = users(+range.value), count = 0, cost = 0, need = 0;
shown.textContent = n.toLocaleString('en-US') + (+range.value === +range.max ? '+' : ''); shown.textContent = n.toLocaleString('en-US') + (+range.value === +range.max ? '+' : '');
range.setAttribute('aria-valuetext', shown.textContent + ' people'); range.setAttribute('aria-valuetext', shown.textContent + ' people');
form.querySelectorAll('.calc-app input:checked').forEach(function (box) { form.querySelectorAll('.calc-app input:checked').forEach(function (box) {
count++; count++;
need = Math.max(need, plans.findIndex(function (p) { return p.tier === box.dataset.tier; }));
cost += +box.value * (box.dataset.perSeat === 'true' ? n : 1) * 12; cost += +box.value * (box.dataset.perSeat === 'true' ? n : 1) * 12;
}); });
out('count', count); out('count', count);
out('cost', fmt(cost)); out('cost', fmt(cost));
out('savings', fmt(Math.max(0, cost - annual))); var plan = plans[need] || plans[plans.length - 1] || { name: '', annual: 0 };
out('savings', fmt(Math.max(0, cost - plan.annual)));
out('plan', plan.name);
} }
form.addEventListener('input', update); form.addEventListener('input', update);
update(); update();
+50 -44
View File
@@ -6,6 +6,9 @@
<title>Pricing · Federated Computer</title> <title>Pricing · Federated Computer</title>
<meta name="description" content="Run Federated Computer on your own infrastructure or let us host it. Self-hosted plans start free; hosted plans start at $70/month with unlimited users."> <meta name="description" content="Run Federated Computer on your own infrastructure or let us host it. Self-hosted plans start free; hosted plans start at $70/month with unlimited users.">
<meta name="theme-color" content="#001a2b"> <meta name="theme-color" content="#001a2b">
<link rel="icon" href="../favicon.ico" sizes="32x32">
<link rel="icon" href="../favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="../apple-touch-icon.png">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
@@ -615,8 +618,8 @@
<li class="bar-row is-highlight"> <li class="bar-row is-highlight">
<span class="bar-name">Federated</span> <span class="bar-name">Federated</span>
<span class="bar-track"><span class="bar-fill" style="width: 8.275862068965518%"></span></span> <span class="bar-track"><span class="bar-fill" style="width: 10.96551724137931%"></span></span>
<span class="bar-value">$120</span> <span class="bar-value">$159</span>
</li> </li>
<li class="bar-row"> <li class="bar-row">
@@ -645,223 +648,223 @@
<form class="savings-calc" id="savings-calc" data-annual="2900" onsubmit="return false"> <form class="savings-calc" id="savings-calc" data-plans="[{&#34;annual&#34;:700,&#34;name&#34;:&#34;Good&#34;,&#34;tier&#34;:&#34;good&#34;},{&#34;annual&#34;:1450,&#34;name&#34;:&#34;Better&#34;,&#34;tier&#34;:&#34;better&#34;},{&#34;annual&#34;:2900,&#34;name&#34;:&#34;Best&#34;,&#34;tier&#34;:&#34;best&#34;}]" onsubmit="return false">
<fieldset class="calc-apps"> <fieldset class="calc-apps">
<legend class="plan-subhead">Which apps do you pay for today?</legend> <legend class="plan-subhead">Which apps do you pay for today?</legend>
<div class="calc-app-grid"> <div class="calc-app-grid">
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="8" data-per-seat="true"> <input type="checkbox" value="8" data-tier="good" data-per-seat="true">
<span class="calc-app-name">1Password</span> <span class="calc-app-name">1Password</span>
<span class="calc-app-cost">$8/person</span> <span class="calc-app-cost">$8/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="20" data-per-seat="true"> <input type="checkbox" value="20" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Airtable</span> <span class="calc-app-name">Airtable</span>
<span class="calc-app-cost">$20/person</span> <span class="calc-app-cost">$20/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="15" data-per-seat="true"> <input type="checkbox" value="15" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Asana</span> <span class="calc-app-name">Asana</span>
<span class="calc-app-cost">$15/person</span> <span class="calc-app-cost">$15/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="15" data-per-seat="true"> <input type="checkbox" value="15" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Box</span> <span class="calc-app-name">Box</span>
<span class="calc-app-cost">$15/person</span> <span class="calc-app-cost">$15/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="10" data-per-seat="true"> <input type="checkbox" value="10" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Calendly</span> <span class="calc-app-name">Calendly</span>
<span class="calc-app-cost">$10/person</span> <span class="calc-app-cost">$10/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="12" data-per-seat="true"> <input type="checkbox" value="12" data-tier="best" data-per-seat="true">
<span class="calc-app-name">ClickUp</span> <span class="calc-app-name">ClickUp</span>
<span class="calc-app-cost">$12/person</span> <span class="calc-app-cost">$12/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="9" data-per-seat="true"> <input type="checkbox" value="9" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Confluence</span> <span class="calc-app-name">Confluence</span>
<span class="calc-app-cost">$9/person</span> <span class="calc-app-cost">$9/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="80" data-per-seat="false"> <input type="checkbox" value="80" data-tier="good" data-per-seat="false">
<span class="calc-app-name">Constant Contact</span> <span class="calc-app-name">Constant Contact</span>
<span class="calc-app-cost">$80 flat</span> <span class="calc-app-cost">$80 flat</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="7" data-per-seat="true"> <input type="checkbox" value="7" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Doodle</span> <span class="calc-app-name">Doodle</span>
<span class="calc-app-cost">$7/person</span> <span class="calc-app-cost">$7/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="10" data-per-seat="true"> <input type="checkbox" value="10" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Dropbox</span> <span class="calc-app-name">Dropbox</span>
<span class="calc-app-cost">$10/person</span> <span class="calc-app-cost">$10/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="5" data-per-seat="true"> <input type="checkbox" value="5" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Fastmail</span> <span class="calc-app-name">Fastmail</span>
<span class="calc-app-cost">$5/person</span> <span class="calc-app-cost">$5/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="15" data-per-seat="true"> <input type="checkbox" value="15" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Freshdesk</span> <span class="calc-app-name">Freshdesk</span>
<span class="calc-app-cost">$15/person</span> <span class="calc-app-cost">$15/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="29" data-per-seat="true"> <input type="checkbox" value="29" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Front</span> <span class="calc-app-name">Front</span>
<span class="calc-app-cost">$29/person</span> <span class="calc-app-cost">$29/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="4" data-per-seat="true"> <input type="checkbox" value="4" data-tier="good" data-per-seat="true">
<span class="calc-app-name">GitHub</span> <span class="calc-app-name">GitHub</span>
<span class="calc-app-cost">$4/person</span> <span class="calc-app-cost">$4/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="29" data-per-seat="true"> <input type="checkbox" value="29" data-tier="good" data-per-seat="true">
<span class="calc-app-name">GitLab</span> <span class="calc-app-name">GitLab</span>
<span class="calc-app-cost">$29/person</span> <span class="calc-app-cost">$29/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="13" data-per-seat="true" checked> <input type="checkbox" value="13" data-tier="good" data-per-seat="true" checked>
<span class="calc-app-name">Google Workspace</span> <span class="calc-app-name">Google Workspace</span>
<span class="calc-app-cost">$13/person</span> <span class="calc-app-cost">$13/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="20" data-per-seat="true"> <input type="checkbox" value="20" data-tier="better" data-per-seat="true">
<span class="calc-app-name">HubSpot</span> <span class="calc-app-name">HubSpot</span>
<span class="calc-app-cost">$20/person</span> <span class="calc-app-cost">$20/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="29" data-per-seat="true"> <input type="checkbox" value="29" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Intercom</span> <span class="calc-app-name">Intercom</span>
<span class="calc-app-cost">$29/person</span> <span class="calc-app-cost">$29/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="12" data-per-seat="true"> <input type="checkbox" value="12" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Jira</span> <span class="calc-app-name">Jira</span>
<span class="calc-app-cost">$12/person</span> <span class="calc-app-cost">$12/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="135" data-per-seat="false"> <input type="checkbox" value="135" data-tier="good" data-per-seat="false">
<span class="calc-app-name">Mailchimp</span> <span class="calc-app-name">Mailchimp</span>
<span class="calc-app-cost">$135 flat</span> <span class="calc-app-cost">$135 flat</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="14" data-per-seat="true"> <input type="checkbox" value="14" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Microsoft 365</span> <span class="calc-app-name">Microsoft 365</span>
<span class="calc-app-cost">$14/person</span> <span class="calc-app-cost">$14/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="8" data-per-seat="true"> <input type="checkbox" value="8" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Microsoft Teams</span> <span class="calc-app-name">Microsoft Teams</span>
<span class="calc-app-cost">$8/person</span> <span class="calc-app-cost">$8/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="12" data-per-seat="true"> <input type="checkbox" value="12" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Monday.com</span> <span class="calc-app-name">Monday.com</span>
<span class="calc-app-cost">$12/person</span> <span class="calc-app-cost">$12/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="12" data-per-seat="true"> <input type="checkbox" value="12" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Notion</span> <span class="calc-app-name">Notion</span>
<span class="calc-app-cost">$12/person</span> <span class="calc-app-cost">$12/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="25" data-per-seat="true"> <input type="checkbox" value="25" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Odoo</span> <span class="calc-app-name">Odoo</span>
<span class="calc-app-cost">$25/person</span> <span class="calc-app-cost">$25/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="13" data-per-seat="true"> <input type="checkbox" value="13" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Proton</span> <span class="calc-app-name">Proton</span>
<span class="calc-app-cost">$13/person</span> <span class="calc-app-cost">$13/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="25" data-per-seat="true"> <input type="checkbox" value="25" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Salesforce</span> <span class="calc-app-name">Salesforce</span>
<span class="calc-app-cost">$25/person</span> <span class="calc-app-cost">$25/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="79" data-per-seat="false"> <input type="checkbox" value="79" data-tier="good" data-per-seat="false">
<span class="calc-app-name">Shopify</span> <span class="calc-app-name">Shopify</span>
<span class="calc-app-cost">$79 flat</span> <span class="calc-app-cost">$79 flat</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="9" data-per-seat="true" checked> <input type="checkbox" value="9" data-tier="better" data-per-seat="true" checked>
<span class="calc-app-name">Slack</span> <span class="calc-app-name">Slack</span>
<span class="calc-app-cost">$9/person</span> <span class="calc-app-cost">$9/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="65" data-per-seat="false" checked> <input type="checkbox" value="65" data-tier="good" data-per-seat="false" checked>
<span class="calc-app-name">Squarespace</span> <span class="calc-app-name">Squarespace</span>
<span class="calc-app-cost">$65 flat</span> <span class="calc-app-cost">$65 flat</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="6" data-per-seat="true"> <input type="checkbox" value="6" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Tailscale</span> <span class="calc-app-name">Tailscale</span>
<span class="calc-app-cost">$6/person</span> <span class="calc-app-cost">$6/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="11" data-per-seat="true"> <input type="checkbox" value="11" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Trello</span> <span class="calc-app-name">Trello</span>
<span class="calc-app-cost">$11/person</span> <span class="calc-app-cost">$11/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="36" data-per-seat="false"> <input type="checkbox" value="36" data-tier="good" data-per-seat="false">
<span class="calc-app-name">Wix</span> <span class="calc-app-name">Wix</span>
<span class="calc-app-cost">$36 flat</span> <span class="calc-app-cost">$36 flat</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="19" data-per-seat="true"> <input type="checkbox" value="19" data-tier="best" data-per-seat="true">
<span class="calc-app-name">Zendesk</span> <span class="calc-app-name">Zendesk</span>
<span class="calc-app-cost">$19/person</span> <span class="calc-app-cost">$19/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="29" data-per-seat="true"> <input type="checkbox" value="29" data-tier="good" data-per-seat="true">
<span class="calc-app-name">Zoho</span> <span class="calc-app-name">Zoho</span>
<span class="calc-app-cost">$29/person</span> <span class="calc-app-cost">$29/person</span>
</label> </label>
<label class="calc-app"> <label class="calc-app">
<input type="checkbox" value="13" data-per-seat="true"> <input type="checkbox" value="13" data-tier="better" data-per-seat="true">
<span class="calc-app-name">Zoom</span> <span class="calc-app-name">Zoom</span>
<span class="calc-app-cost">$13/person</span> <span class="calc-app-cost">$13/person</span>
</label> </label>
@@ -882,16 +885,16 @@
<div class="calc-stat"><span class="calc-stat-label">Apps replaced</span><span class="calc-stat-value" data-out="count">0</span></div> <div class="calc-stat"><span class="calc-stat-label">Apps replaced</span><span class="calc-stat-value" data-out="count">0</span></div>
<div class="calc-stat"><span class="calc-stat-label">Their retail cost</span><span class="calc-stat-value" data-out="cost">$0</span><span class="calc-stat-unit">/year</span></div> <div class="calc-stat"><span class="calc-stat-label">Their retail cost</span><span class="calc-stat-value" data-out="cost">$0</span><span class="calc-stat-unit">/year</span></div>
<div class="calc-stat is-highlight"><span class="calc-stat-label">You'd save</span><span class="calc-stat-value" data-out="savings">$0</span><span class="calc-stat-unit">/year</span></div> <div class="calc-stat is-highlight"><span class="calc-stat-label">You save</span><span class="calc-stat-value" data-out="savings">$0</span><span class="calc-stat-unit">/year on the <span data-out="plan">Good</span> plan</span></div>
</div> </div>
<p class="plan-note">Savings compare the retail price of the apps you pick with our Best plan billed annually ($2,900/year). Prices are typical list prices per person per month, or per month for flat-fee apps.</p> <p class="plan-note">Savings compare the retail price of the apps you pick with the smallest hosted plan that replaces all of them, billed annually (Good $700, Better $1,450, or Best $2,900 a year). Prices are typical list prices per person per month, or per month for flat-fee apps.</p>
</form> </form>
<script> <script>
(function () { (function () {
var form = document.getElementById('savings-calc'); var form = document.getElementById('savings-calc');
if (!form) return; if (!form) return;
var annual = +form.dataset.annual || 0; var plans = JSON.parse(form.dataset.plans || '[]');
var range = form.querySelector('input[type=range]'); var range = form.querySelector('input[type=range]');
var shown = form.querySelector('.calc-users-value'); var shown = form.querySelector('.calc-users-value');
var fmt = function (n) { return '$' + Math.round(n).toLocaleString('en-US'); }; var fmt = function (n) { return '$' + Math.round(n).toLocaleString('en-US'); };
@@ -904,16 +907,19 @@
return 1000 + (step - 20) * 500; return 1000 + (step - 20) * 500;
} }
function update() { function update() {
var n = users(+range.value), count = 0, cost = 0; var n = users(+range.value), count = 0, cost = 0, need = 0;
shown.textContent = n.toLocaleString('en-US') + (+range.value === +range.max ? '+' : ''); shown.textContent = n.toLocaleString('en-US') + (+range.value === +range.max ? '+' : '');
range.setAttribute('aria-valuetext', shown.textContent + ' people'); range.setAttribute('aria-valuetext', shown.textContent + ' people');
form.querySelectorAll('.calc-app input:checked').forEach(function (box) { form.querySelectorAll('.calc-app input:checked').forEach(function (box) {
count++; count++;
need = Math.max(need, plans.findIndex(function (p) { return p.tier === box.dataset.tier; }));
cost += +box.value * (box.dataset.perSeat === 'true' ? n : 1) * 12; cost += +box.value * (box.dataset.perSeat === 'true' ? n : 1) * 12;
}); });
out('count', count); out('count', count);
out('cost', fmt(cost)); out('cost', fmt(cost));
out('savings', fmt(Math.max(0, cost - annual))); var plan = plans[need] || plans[plans.length - 1] || { name: '', annual: 0 };
out('savings', fmt(Math.max(0, cost - plan.annual)));
out('plan', plan.name);
} }
form.addEventListener('input', update); form.addEventListener('input', update);
update(); update();
+3
View File
@@ -6,6 +6,9 @@
<title>Agent Sandbox · Federated Computer</title> <title>Agent Sandbox · Federated Computer</title>
<meta name="description" content="Thousands of AI agents running on one machine, zero risk. High-density, instant-wake AI agents that run entire teams of specialized workers, safely isolated."> <meta name="description" content="Thousands of AI agents running on one machine, zero risk. High-density, instant-wake AI agents that run entire teams of specialized workers, safely isolated.">
<meta name="theme-color" content="#001a2b"> <meta name="theme-color" content="#001a2b">
<link rel="icon" href="../../favicon.ico" sizes="32x32">
<link rel="icon" href="../../favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="../../apple-touch-icon.png">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
@@ -6,6 +6,9 @@
<title>Software Library · Federated Computer</title> <title>Software Library · Federated Computer</title>
<meta name="description" content="100&#43; open-source business apps — Nextcloud, Discourse, EspoCRM, and more — every one AI-ready out of the box via native MCP."> <meta name="description" content="100&#43; open-source business apps — Nextcloud, Discourse, EspoCRM, and more — every one AI-ready out of the box via native MCP.">
<meta name="theme-color" content="#001a2b"> <meta name="theme-color" content="#001a2b">
<link rel="icon" href="../../favicon.ico" sizes="32x32">
<link rel="icon" href="../../favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="../../apple-touch-icon.png">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
@@ -6,6 +6,9 @@
<title>Open-Source Apps · Federated Computer</title> <title>Open-Source Apps · Federated Computer</title>
<meta name="description" content="Every app your business needs — files, email, chat, CRM, support — as integrated, managed open-source software. Unlimited users, one low price, no AI project required."> <meta name="description" content="Every app your business needs — files, email, chat, CRM, support — as integrated, managed open-source software. Unlimited users, one low price, no AI project required.">
<meta name="theme-color" content="#001a2b"> <meta name="theme-color" content="#001a2b">
<link rel="icon" href="../../favicon.ico" sizes="32x32">
<link rel="icon" href="../../favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="../../apple-touch-icon.png">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

+1 -1
View File
@@ -139,7 +139,7 @@ main:focus { outline: none; }
.site-head.is-scrolled { background: #001a2bf2; backdrop-filter: blur(12px); } .site-head.is-scrolled { background: #001a2bf2; backdrop-filter: blur(12px); }
.head-bar { display: flex; align-items: center; gap: 32px; height: var(--head-h); } .head-bar { display: flex; align-items: center; gap: 32px; height: var(--head-h); }
.brand { display: inline-flex; flex: none; } .brand { display: inline-flex; flex: none; }
.brand-logo { width: 148px; height: auto; filter: invert(1); } .brand-logo { width: 148px; height: auto; filter: invert(1); translate: 0 -3px; } /* lifts the wordmark baseline onto the nav text baseline */
.head-nav { display: flex; align-items: center; gap: 2px; margin-right: auto; } .head-nav { display: flex; align-items: center; gap: 2px; margin-right: auto; }
.nav-item { position: relative; } .nav-item { position: relative; }
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB