Cowork Cost Calculator Playbook¶
Why this playbook exists
The /cowork-cost-calculator/ tool was rebuilt v1→v6 over one long session (18 Jun 2026, session ce18cacd) — from a broken non-Zen scaffold into a polished "meter" instrument, then extended with a credit-check widget + a /cost screenshot. Two things are easy to get wrong and expensive to rediscover: (1) the cost-model calibration (my first numbers were ~6× too low until I pinned them to Microsoft's public estimator) and (2) the Zen-template contract (a missing body class silently kills light/dark). This captures both so the next session that touches Cowork costing starts from the right place.
Read this first before touching static/js/cowork-cost-calculator.js · static/css/cowork-cost-calculator.css · layouts/cowork-cost-calculator/list.html · the Cowork pricing-spoke/hub credit copy · or any "what does Cowork cost" number on the site.
TL;DR¶
/cowork-cost-calculator/ (Hugo section: content/cowork-cost-calculator/_index.md + layouts/cowork-cost-calculator/list.html)
3 tabs: Calculator · Compare & control · FAQ
Calculator panel order: framing line → meter card (controls left | readout right)
→ credit-check widget (credits×runs=$) → habit strip → disclaimer
Engine static/js/cowork-cost-calculator.js:
compute() main estimate (USAGE bands × users × CREDIT_COST + seats × SEAT)
computeCredit() credit-check (credits × runs × CREDIT_COST) ← DOM-independent of compute()
animateMeter() count-up (tracks module-level meterCurrent + meterRAF, cancels prior frame)
5 currencies: USD GBP EUR AUD NZD (rate table in CURRENCIES)
Default reading (50 users / Balanced): seat + meter ≈ $10,500/mo (range $7,500–$15,000). Per-user ≈ $120–410/mo across light→heavy.
🔴 The cost model — and the calibration story (most important section)¶
The numbers are the product. Get them wrong and the tool is worse than useless — it misleads a paying audience.
Constants (in cowork-cost-calculator.js):
- CREDIT_COST = 0.01 — $0.01 per Copilot Credit (PayGo, public)
- SEAT = 30 — $30 Microsoft 365 Copilot enterprise seat (see "$30 vs $19.99" below)
- HEAVY_TASK_CREDITS = 2500 — one heavy run, used by the habit strip + credit-check default
USAGE bands — credits/user/month [low, mid, high]:
| Level | low | mid | high |
|---|---|---|---|
| Light | 6,000 | 9,000 | 13,000 |
| Balanced | 15,000 | 21,000 | 30,000 |
| Heavy | 32,000 | 40,000 | 52,000 |
How these were calibrated (the ~6× lesson)¶
- v4 and earlier were ~6× too low. I'd guessed ~20/100/400 credits per prompt. When I studied Jukka Niiranen's public
cost-of-cowork.htmland Microsoft's own estimator, the real per-prompt figures were ~125/500/2500 — and real users run many prompts/tasks a month. - The fix: stop guessing per-prompt, calibrate per-user-per-month against a public anchor. I pinned the bands so the per-user output lands in the ~$120–410/user/month envelope that Microsoft's public Customer Cowork Estimator produces (
aka.ms/CustomerCoworkEstimator→adoption.microsoft.com). - Rule for future edits: if you change a band, re-check the per-user output still sits in that public envelope. Never widen the model on a hunch — anchor it to a public Microsoft source and say so.
$30 vs $19.99 (recurring subconscious false-flag)¶
The subconscious inbox keeps flagging "$19.99 M365 Premium." That's the consumer SKU. This tool targets enterprise admins → the $30 M365 Copilot seat is correct. Jukka (the licensing authority) uses $30; Sush explicitly confirmed "$30 OK" more than once. Keep $30. Ignore the $19.99 flag.
The design — "the meter", not a form¶
Sush's two hard notes drove the design: "less knobs, every text earns its place" and "it doesn't even look like a tool" (vs Jukka's instrument). Result:
- One unified card: controls (users number + Light/Balanced/Heavy pills) on the left, a count-up meter readout on the right. Inputs folded INTO the card (no separate input layer).
- Seat-vs-meter split bar — visually shows how much of the bill is the predictable seat vs the variable credit burn.
- Verdict line ("Nx your seat") + habit strip (one run → weekly → daily → team escalation) to make the "cost is in the repeats" point.
- Widened by dropping the right companion rail (606→972px):
body.page-cowork-cost-calculator .zt-reading--tool-detail > .zt-companion { display:none }+ grid250px minmax(0,1fr)at@media(min-width:1024px). Base.zt-readingcollapses to1fr≤1024px — clean handoff, no gap.
The credit-check widget (Sush's idea)¶
For people who already know a task's exact cost: credits × runs = $ (currency-aware, reads the same currency selector). computeCredit() touches a disjoint DOM set (#cc-credits, #cc-runs, #cc-cost, #cc-sub) from the main estimate — they never interfere. Default 2500×20 = $500.
The /cost integration (verified Cowork feature)¶
/cost is a real Cowork slash-command: type it in a task window after a task and Cowork replies e.g. "379.6 credits used for this task so far." (confirmed by Sush's own screenshot, 18 Jun 2026). This is the perfect input for the credit-check widget — run a task → /cost → exact credits → ×frequency → real monthly $. The tool's credit-check tip links to the pricing spoke "see it in action"; the spoke + hub carry the screenshot (static/images/blog/cowork/cost-command-credits.webp, 1300×282).
Zen-template contract — the gotchas that bite¶
- Body needs the
zen-migratedclass (added via the chain inlayouts/_default/baseof.html). Miss it and the page is force-dark with a dead light/dark toggle. This was the original v1 bug. - White-on-accent buttons/pills MUST use
var(--accent-strong)(#4F46E5) — passes WCAG in BOTH modes.var(--accent)is #818CF8 in dark and fails contrast on the active pill (2.98:1). This was a pre-deploy review fix. - No undefined tokens. v1 used
--indigo-600/--slate-50/--amber-50/--green-600(don't exist) → broken colours. Use canonical Zen tokens only. - No gradients/glows — solid
--bg-elevated/--accent-subtle; one indigo accent. - The
.cowcalc-cc-tipcallout uses--accent-subtlebg +var(--accent)left border — both-mode safe (verified dark: text 11:1, link 6.3:1, code 17:1).
QA traps (don't chase ghosts)¶
naturalWidth === 0on blog images is a lazy-load artifact, not a bug.loading="lazy"images don't fetch bytes until near-viewport. To truly check decode: setimg.loading='eager',scrollIntoView(), awaitonload, then readnaturalWidth. (Live webp decodes 1300×282.)- Count-up mid-animation false fail. Reading
#out-meterright after a pill/currency change catches the count-up at ~480ms. Wait ≥700ms before asserting, or it's a timing artifact. - Playwright dark-mode: the site toggles via
document.documentElement.setAttribute('data-theme','dark')(seestatic/js/switcher.js). If you set it then click the toggle, you flip it back to light. Set the attribute and DON'T click. - Playwright + ESM: the QA script must live inside the repo tree (copy a temp
_qa-*.mjsto repo root, run, delete) —import { chromium }won't resolve from the session-state folder.
Cross-link map (blog ↔ tool, both ways)¶
- Hub
microsoft-copilot-cowork-complete-guide.md:> 💸calculator callout in Licensing +/costcallout & screenshot in "What Cowork actually looks like". - Pricing spoke
microsoft-copilot-cowork-pricing-cost-management.md: calculator link in "Who runs Cowork" + the "Know your exact per-task cost — the/costcommand" section (screenshot + "make the case for your own seat" angle + credit-check link). In-page anchor id:know-your-exact-per-task-cost--the-cost-command. - Tool ecosystem grid + FAQ link back to the Cowork blogs; credit-check tip → pricing spoke.
Registration + deploy¶
- OG image: add the slug to
data/tool_colours.tomlFIRST (it's the OG generator's canonical gate, NOT toolkit_nav), thennode scripts/og-generator-tool/make.mjs. Icon colour comes fromdata/toolkit_nav.tomlcolor(#6366F1). Outputstatic/images/og/cowork-cost-calculator.jpg. - Registry:
data/toolkit_nav.toml(feeds header subtitle + /free-tools + ecosystem card). - cache_version: bump
hugo.tomlon any CSS/JS change. - SEO gate (
check-seo-lengths.ps1 -Strict): title ≤60 (currently 59), description ≤155 (148), OG ≤50KB. - Build:
pwsh -NoProfile -File scripts\hugo-safe.ps1(auto-runscheck-blog-html.mjswhen content/blog changed). - Deploy: Cloudflare Pages rebuilds Hugo from source on push to
main.mainis a separate worktree (C:\ssClawy\_atgc-main) — do NOTgit checkout main. Publish from wip:git fetch→git merge origin/main(resolvelayouts/blog/list.htmlcluster registry if it conflicts — keep all clusters) →git push origin HEAD:main. Re-fetch right before push (bots commit often). Verify live with HTTP markers + a Playwright decode check.
File map¶
| File | Role |
|---|---|
content/cowork-cost-calculator/_index.md |
Frontmatter (title 59c / desc 148c) + FAQ array + images: ["images/og/cowork-cost-calculator.jpg"] |
layouts/cowork-cost-calculator/list.html |
3-tab layout; Calculator panel markup (meter card, credit-check widget, habit strip) |
static/css/cowork-cost-calculator.css |
.cowcalc-* styles (meter card grid, split bar, pills, credit-check, .cowcalc-cc-tip) |
static/js/cowork-cost-calculator.js |
compute / computeCredit / animateMeter, USAGE bands, CURRENCIES, tabs |
data/tool_colours.toml |
OG generator canonical slug gate |
data/toolkit_nav.toml |
tool registry |
static/images/blog/cowork/cost-command-credits.webp |
the /cost screenshot (1300×282) |
Built 18 Jun 2026, session ce18cacd. Live commit 8cf9f978.