# CLAUDE.md — SVS MSP Calculator

---

## What This Is

**SVS MSP Calculator** — a live pricing and quote tool used by the sales team on screen during prospect calls.
HTML5 / CSS3 / JS. No frameworks, no build tools. Open `SVS-MSP-Calculator.html` in a browser — it runs.

**Status:** Active development — current focus is GUI / UI improvement.
Quote logic and pricing engine are stable. Do not touch without explicit approval.

---

## How It Works

### The Update Loop

Every input change triggers this pipeline:

```
Input event → readFormState() → calculateQuote(state, pricing) → renderQuote(quote) → mobileSync()
```

`SVS-MSP-Calculator.js` orchestrates this via `update()`. The engine is a pure function — state in, quote out. Render writes to DOM. Mobile sync clones to the mobile panel. **Any change that touches this chain affects the entire app.**

### CSS Cascade

9 modular CSS files loaded via `SVS-MSP-Calculator.css` (master import):

```
tokens.css → base.css → layout.css → components.css → responsive.css
                                                        ↕
                                          light.css / glass.css (theme overrides)
                                                        ↕
                                                    print.css
```

**Tokens are the source of truth.** 60+ semantic variables (`--ink`, `--paper`, `--accent`, `--surface-*`, `--print-*`). Changing a token ripples through all 3 themes, all components, and print output.

Themes are pure CSS variable overrides on `:root` — no HTML changes, no JS logic. `theme-manager.js` toggles a class; the cascade does the rest.

### Mobile Sync

`mobile-sync.js` physically clones the sidebar DOM into a bottom-sheet panel (`#mobileQuotePanel`) and appends `_m` to every cloned ID. It then syncs content, classes, styles, and checkbox states from desktop → mobile after each `update()`.

**If you add a new sidebar element, mobile-sync must know about it or mobile breaks silently.**

### The Sidebar Is the Product

The right column (`.sidebar`) is what the prospect stares at during the call. Hero numbers: MRR, per-user cost, annual total. Every UI change should be evaluated from: **does this make the sidebar clearer?**

### Print / PDF

`SVS-MSP-Calculator-print.css` is a parallel rendering target with its own token set (`--print-*`). At `@media print` it hides all interactive controls, forces sections open, and outputs a clean A4 document. Print is not an afterthought — it's a sales deliverable.

### localStorage

3 keys: quote state (full form data as JSON), quote reference ID, theme preference. Save/load via `quote-persistence.js`. `Ctrl+S` / `Ctrl+L` shortcuts.

---

## Invariants

Things that must be true before and after every session. Each has a verification step.

| Invariant | Verify |
|-----------|--------|
| All unit tests pass | `node tests/test-quote-engine.js` — 254/254 |
| All 3 themes render correctly | Playwright-check Dark, Light, Glass after any CSS change |
| DOM IDs unchanged | Never rename — `mobile-sync.js` maps 100+ desktop↔mobile pairs silently |
| localStorage round-trip | Save → reload → confirm all values restore |
| Print output clean | Verify after any CSS change — print has its own cascade |
| Mobile panel matches sidebar | Check mobile bottom-sheet after any sidebar change |

---

## Working Rules

How Claude behaves while working. Not testable — behavioral.

1. **Read before editing** — always inspect current code first
2. **Quote engine is locked** — no changes to `quote-engine.js`, `quote-pricing.js`, or `package-prices-data.js` without explicit approval
3. **No frameworks, no build tools** — vanilla JS by design
4. **No broad rewrites** — surgical, approved changes only
5. **Ask before assuming** — when requirements are unclear, ask

---

## Do Not Touch

| Thing | Why |
|-------|-----|
| `fontawesomekit/` | Huge vendor directory. Reference known FA icons by name when needed — never scan this directory |
| `pre-alpha/` | Legacy/experimental files. Ignore unless explicitly asked |
| Quote engine files | `quote-engine.js`, `quote-pricing.js`, `package-prices-data.js` — stable, tested, locked |

---

## Design Principles

1. **Sales clarity over visual novelty** — prospects read numbers at a glance
2. **The sidebar is the hero** — treat it like a financial summary
3. **Dark theme is flagship** — Light and Glass must meet the same bar
4. **Copy is UX** — every label and nudge is a design decision
5. **Mobile is first-class** — a sales rep on a tablet must run a full quote

---

## Architecture

### HTML Structure

6 collapsible sections in the main column, sticky sidebar in the right column:

| Section | ID | Content |
|---------|----|---------|
| I — Site Management | `#sec-01` | Admin fee, floor $650 |
| II — User Package | `#sec-02` | Per-user pricing, M365/BYOL |
| III — Endpoint Package | `#sec-03` | Device count |
| IV — Server Management | `#sec-04` | Server count |
| V — Zero Trust HaaS | `#sec-05` | Seats, routers |
| VI — VoIP UCaaS | `#sec-06` | Seats, tiers |

**Layout:** CSS Grid — `3fr | 2fr` (main | sidebar). Collapses to single column at 1100px. Mobile pill + bottom-sheet panel below 1100px.

**Z-index stack:** 400 (modals) → 300 (mobile panel) → 200 (mobile pill) → 100 (top bar) → 10 (sidebar)

### JS Files

| File | Role |
|------|------|
| `SVS-MSP-Calculator.js` | Orchestrator — `update()` loop, form reading, event wiring |
| `quote-engine.js` | Pure calculation — `calculateQuote(state, pricing)` → quote object |
| `quote-pricing.js` | Pricing defaults (32 rates/fees) — `SVSQuotePricing.getSnapshot()` |
| `package-prices-data.js` | External pricing data (optional override) |
| `quote-render.js` | Writes calculated quote to DOM elements |
| `quote-persistence.js` | localStorage save/load + `Ctrl+S`/`Ctrl+L` |
| `quote-export.js` | Printable/exportable quote HTML generation |
| `quote-import.js` | Load saved quotes from JSON |
| `mobile-sync.js` | Clones sidebar → mobile panel, syncs on every `update()` |
| `theme-manager.js` | Dark/Light/Glass toggle, persists preference |

### CSS Files

| File | Role |
|------|------|
| `SVS-MSP-Calculator.css` | Master import — loads all modules |
| `*-tokens.css` | Design tokens — 60+ semantic variables, source of truth |
| `*-base.css` | Body, top bar, theme toggle |
| `*-layout.css` | Grid, page layout, sidebar, modals |
| `*-components.css` | Section cards, buttons, icons, form controls |
| `*-responsive.css` | Media queries — 1100px and 600px breakpoints |
| `*-light.css` | Light theme — `:root` variable overrides only |
| `*-glass.css` | Glass theme — gradients, blur, `color-scheme: dark` |
| `*-print.css` | Print/PDF — own token set, aggressive cleanup, A4-ready |

### Tests

254 tests across 47 groups. Custom minimal harness (no framework). Covers:
pricing, discounts, add-ons, VoIP tiers, HST, contract terms, edge cases, admin fees.

Run: `node tests/test-quote-engine.js`

---

## Tools & When to Use Them

| Tool | Use when |
|------|----------|
| **Playwright** | Visual verification — viewing HTML/CSS across themes |
| **ui-ux-pro-max** | Any design decision — invoke before touching CSS |
| **superpowers** | Planning, parallel agents, debugging, TDD, branch/commit |
| **frontend-design** | Building or modifying UI components |
| **code-review** | Before marking any task complete |
| **code-simplifier** | After implementation — clean up without changing behavior |
| **context-mode** | Large output (>20 lines) — routes through sandbox to protect context window. Use `ctx_batch_execute` for multi-command research, `ctx_search` for follow-up queries, `ctx_execute`/`ctx_execute_file` for data processing, `ctx_fetch_and_index` for URL fetching |
| **accesslint** | Accessibility and colour contrast checking. Use `contrast-checker` for WCAG ratio checks on hex pairs, `use-of-color` to flag colour-only indicators, `reviewer` for full component audits. Minimum standard: WCAG 2.1 AA (4.5:1 normal text, 3:1 large text). Suggest replacement hex values on failure. |

---

## Session Start

1. Read `docs/SESSION-HANDOFF.md` — current state of the project
2. Run `node tests/test-quote-engine.js` — confirm 254/254
3. Ask the user what they want — do not assume, do not start changing things

Read other docs only when the task requires them:
- `docs/QUICK-REF.md` — file map, DOM IDs, pricing constants
- `docs/quote-rules.md` — pricing / business logic
- `docs/DECISION-LOG.md` — has this decision already been made?
- `docs/KNOWN-ISSUES.md` — is this bug already tracked?

---

## Session End

1. Run `node tests/test-quote-engine.js` — all 254 must pass
2. Update `docs/SESSION-HANDOFF.md` as a **current state snapshot**:
   - What is the state of the project right now (not a history log)
   - What files are in what state
   - What is next
3. Commit if approved by user — one concern per commit
