just being crazy honestly
5
.claude/settings.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"enabledPlugins": {
|
||||||
|
"context-mode@context-mode": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,22 @@
|
|||||||
"Bash(git checkout*)",
|
"Bash(git checkout*)",
|
||||||
"Read(//c/Users/JohnOReilly/OneDrive - Silicon Valley Services/Documents/Projects VS CODE/SVS MSP Calculator/**)",
|
"Read(//c/Users/JohnOReilly/OneDrive - Silicon Valley Services/Documents/Projects VS CODE/SVS MSP Calculator/**)",
|
||||||
"mcp__plugin_playwright_playwright__browser_evaluate",
|
"mcp__plugin_playwright_playwright__browser_evaluate",
|
||||||
"mcp__plugin_playwright_playwright__browser_run_code"
|
"mcp__plugin_playwright_playwright__browser_run_code",
|
||||||
|
"Bash(node:*)",
|
||||||
|
"Bash(bun --version)",
|
||||||
|
"Read(//c/Users/JohnOReilly/AppData/Roaming/npm/node_modules/bun/**)",
|
||||||
|
"Read(//c/Users/JohnOReilly/**)",
|
||||||
|
"mcp__plugin_context-mode_context-mode__ctx_batch_execute",
|
||||||
|
"mcp__plugin_context-mode_context-mode__ctx_doctor",
|
||||||
|
"mcp__plugin_context-mode_context-mode__ctx_fetch_and_index",
|
||||||
|
"mcp__plugin_context-mode_context-mode__ctx_execute_file",
|
||||||
|
"mcp__plugin_context-mode_context-mode__ctx_execute",
|
||||||
|
"mcp__plugin_playwright_playwright__browser_take_screenshot",
|
||||||
|
"mcp__plugin_playwright_playwright__browser_click",
|
||||||
|
"mcp__plugin_accesslint_accesslint__analyze_color_pair"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"enabledPlugins": {
|
||||||
|
"context-mode@context-mode": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
.claude/skills/ui-ux-pro-max
Submodule
8
.mcp.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"accesslint": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "@accesslint/mcp"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.playwright-mcp/console-2026-03-18T20-08-48-067Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 816ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:8765/favicon.ico:0
|
||||||
1
.playwright-mcp/console-2026-03-18T20-27-17-867Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 442ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:8766/favicon.ico:0
|
||||||
1
.playwright-mcp/console-2026-03-18T20-43-11-414Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 254ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8765/favicon.ico:0
|
||||||
1
.playwright-mcp/console-2026-03-18T20-53-05-347Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 433ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8765/favicon.ico:0
|
||||||
1
.playwright-mcp/console-2026-03-18T21-06-29-639Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 557ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8766/favicon.ico:0
|
||||||
203
CLAUDE-beta.md
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
# 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
|
||||||
59
CLAUDE-nextsteps.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Next Steps — SVS MSP Calculator
|
||||||
|
|
||||||
|
**Updated:** 2026-03-18
|
||||||
|
**Purpose:** Resume guide for next session.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Just Completed (2026-03-18, committed as 4c53af9)
|
||||||
|
|
||||||
|
Sidebar UX polish pass:
|
||||||
|
- Unified dividers → one `--sidebar-rule` token, dashed everywhere
|
||||||
|
- Letter-spacing → `--text-spacing-money: 0.05em` token
|
||||||
|
- Font floor → 11px minimum (6 locations bumped)
|
||||||
|
- Contrast → muted colors darkened to 6.5:1+ on all themes
|
||||||
|
- Opacity → removed from 9 double-muted text elements
|
||||||
|
- Total line border → scoped to monthly breakdown only
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Next Session: Google Fonts + GUI Polish
|
||||||
|
|
||||||
|
### Step 1: Google Fonts Selection
|
||||||
|
- **Approved:** up to 3 fonts (preferred), 4 hard cap
|
||||||
|
- **Currently loaded:** Poppins (hero numbers), DM Mono (monospace values)
|
||||||
|
- **Need:** A clean sans-serif for body text, labels, and UI copy
|
||||||
|
- **Candidates to evaluate:** Inter, IBM Plex Sans, Source Sans 3, Outfit, or similar
|
||||||
|
- **Approach:** Pick font → load from Google Fonts CDN → apply to body/labels → verify all 3 themes
|
||||||
|
|
||||||
|
### Step 2: GUI Polish List A
|
||||||
|
- Contract Term pills — more vertical padding on unselected
|
||||||
|
- Section card collapsed headers — slightly tight vertically
|
||||||
|
- "MANAGED IT SERVICES (SECTIONS I, II, III)" label — low contrast
|
||||||
|
- Insight carousel text — more line-height
|
||||||
|
- "QUOTE NOTES" label spacing — inconsistent with other section labels
|
||||||
|
|
||||||
|
### Step 3: Typography Token Pass
|
||||||
|
- Tokenize remaining hardcoded letter-spacing (~20 locations)
|
||||||
|
- Tokenize hardcoded font-sizes
|
||||||
|
- Move sidebar typography tokens from components.css → tokens.css
|
||||||
|
- Phase 4: icon/button sizing tokens
|
||||||
|
- Phase 6: responsive breakpoint font-sizes (optional)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tools Available — USE THEM
|
||||||
|
|
||||||
|
| Tool | When |
|
||||||
|
|------|------|
|
||||||
|
| **Playwright MCP** | Visual verification across Dark/Light/Glass |
|
||||||
|
| **accesslint** | Contrast checking on any color changes |
|
||||||
|
| **superpowers** | Planning, parallel agents, TDD, debugging |
|
||||||
|
| **context-mode** | Large output processing (>20 lines) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resume Prompt
|
||||||
|
|
||||||
|
Tell Claude:
|
||||||
|
> "Read docs/SESSION-HANDOFF.md. Pick up at Google Fonts selection, then GUI polish list A."
|
||||||
359
CLAUDE.md
@@ -1,248 +1,203 @@
|
|||||||
# CLAUDE.md — SVS MSP Calculator
|
# CLAUDE.md — SVS MSP Calculator
|
||||||
|
|
||||||
> Master instruction set for Claude Code. This is the SINGLE file to read on session start.
|
---
|
||||||
> It references deeper docs — do not duplicate them here.
|
|
||||||
|
|
||||||
## Project Identity
|
## What This Is
|
||||||
|
|
||||||
**App:** SVS MSP Calculator — a live quote/pricing calculator for SVS Managed Services.
|
**SVS MSP Calculator** — a live pricing and quote tool used by the sales team on screen during prospect calls.
|
||||||
**Used by:** Sales team, live on screen with prospects during discovery calls.
|
HTML5 / CSS3 / JS. No frameworks, no build tools. Open `SVS-MSP-Calculator.html` in a browser — it runs.
|
||||||
**Tech:** Vanilla HTML5 / CSS3 / JS (ES5-compatible). No frameworks, no npm, no build tools. Open `SVS-MSP-Calculator.html` in a browser — it runs.
|
|
||||||
**Status:** Alpha-ready, pushing to Beta.
|
|
||||||
**Tests:** 254 passing (`node tests/test-quote-engine.js`)
|
|
||||||
**Themes:** 3 — Dark (flagship), Light, Glass
|
|
||||||
|
|
||||||
For full architecture, file maps, DOM IDs, and pricing constants see `docs/QUICK-REF.md`.
|
**Status:** Active development — current focus is GUI / UI improvement.
|
||||||
For business logic and pricing rules see `docs/quote-rules.md`.
|
Quote logic and pricing engine are stable. Do not touch without explicit approval.
|
||||||
For the complete architecture brief see `docs/MASTER-SESSION-PROMPT.md`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Session Start Protocol
|
## How It Works
|
||||||
|
|
||||||
On every new conversation, execute in order:
|
### The Update Loop
|
||||||
|
|
||||||
1. **Read context** (parallel):
|
Every input change triggers this pipeline:
|
||||||
- `docs/SESSION-HANDOFF.md` — what happened last, what is next
|
|
||||||
- `docs/QUICK-REF.md` — file map, DOM IDs, pricing, danger zones
|
|
||||||
2. **Run baseline tests:** `node tests/test-quote-engine.js` — confirm 254/254 pass
|
|
||||||
3. **Ask the user** what they want to work on. Do not assume. Do not start changing things.
|
|
||||||
4. **Read task-specific docs only when needed:**
|
|
||||||
- `docs/quote-rules.md` — pricing or business logic work
|
|
||||||
- `docs/regression-checklist.md` — validation work
|
|
||||||
- `docs/MASTER-SESSION-PROMPT.md` — unfamiliar areas, full architecture
|
|
||||||
- `docs/DECISION-LOG.md` — check if a relevant decision was already made
|
|
||||||
- `docs/KNOWN-ISSUES.md` — check if the issue is already tracked
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Session End Protocol
|
|
||||||
|
|
||||||
Before ending any session:
|
|
||||||
|
|
||||||
1. **Run full test suite:** `node tests/test-quote-engine.js` — all 254 must pass
|
|
||||||
2. **Update `docs/SESSION-HANDOFF.md`** with:
|
|
||||||
- What was done (brief, specific)
|
|
||||||
- Files modified (table format)
|
|
||||||
- Test status (pass count)
|
|
||||||
- What is next (prioritized)
|
|
||||||
3. **Update `docs/CHECKPOINT.md`** if structural work was completed
|
|
||||||
4. **Update `docs/DECISION-LOG.md`** if any decisions were made
|
|
||||||
5. **Use `superpowers:finishing-a-development-branch`** for commit and cleanup
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Orchestration Engine — Superpowers
|
|
||||||
|
|
||||||
Use the **superpowers** plugin as the execution backbone for all non-trivial work.
|
|
||||||
|
|
||||||
### Workflow Selection
|
|
||||||
|
|
||||||
| Situation | Superpowers Skill to Use |
|
|
||||||
|-----------|--------------------------|
|
|
||||||
| Planning any feature or multi-step work | `superpowers:writing-plans` |
|
|
||||||
| Executing a plan with review gates | `superpowers:subagent-driven-development` |
|
|
||||||
| 2+ independent tasks (e.g., fix CSS in all 3 themes) | `superpowers:dispatching-parallel-agents` |
|
|
||||||
| Investigating a bug or failure | `superpowers:systematic-debugging` |
|
|
||||||
| Writing or modifying quote engine logic | `superpowers:test-driven-development` |
|
|
||||||
| Final checks before marking work done | `superpowers:verification-before-completion` |
|
|
||||||
| Committing, branch cleanup, merge prep | `superpowers:finishing-a-development-branch` |
|
|
||||||
| Visual brainstorming for design or UX | `superpowers:brainstorming` |
|
|
||||||
|
|
||||||
### Subagent-Driven Development Flow
|
|
||||||
|
|
||||||
For any plan with 2+ tasks, use `superpowers:subagent-driven-development`:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Per task:
|
Input event → readFormState() → calculateQuote(state, pricing) → renderQuote(quote) → mobileSync()
|
||||||
1. Dispatch implementer subagent (with role-specific model — see below)
|
|
||||||
2. Spec compliance review (did it match requirements?)
|
|
||||||
3. Code quality review (is it well-built?)
|
|
||||||
4. Mark task complete
|
|
||||||
After all tasks:
|
|
||||||
Final code review → superpowers:finishing-a-development-branch
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
`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.**
|
||||||
|
|
||||||
## Agent Roles & Model Routing
|
### CSS Cascade
|
||||||
|
|
||||||
When dispatching subagents (via superpowers or directly), route to the right role and model.
|
9 modular CSS files loaded via `SVS-MSP-Calculator.css` (master import):
|
||||||
|
|
||||||
### Frontend Coder — Opus (default)
|
|
||||||
**When:** JS logic, CSS changes, HTML structure, bug fixes, refactoring.
|
|
||||||
**How:** Surgical precision. Read the file first, make the minimal change.
|
|
||||||
**Post-change:** Run the full validation pipeline.
|
|
||||||
|
|
||||||
### UI/UX Designer — Opus + ui-ux-pro-max Skill
|
|
||||||
**When:** Design decisions — palettes, typography, spacing, layout, visual hierarchy, component styling.
|
|
||||||
**How:** Invoke the ui-ux-pro-max skill BEFORE implementation. Feed design system output to the implementer subagent.
|
|
||||||
**Sub-skills:** banner-design, brand, design-system, design, slides, ui-styling
|
|
||||||
**Constraint:** Translate all output to vanilla CSS — this project has no framework.
|
|
||||||
|
|
||||||
### Copywriter — Sonnet Model
|
|
||||||
**When:** ALL user-facing text — button labels, section descriptions, nudge messages, tooltip copy, sidebar labels, sales language, feature descriptions, comparison text, pitch bar copy.
|
|
||||||
**How:** Dispatch Agent with `model: "sonnet"`. Provide context about:
|
|
||||||
- The sales use case (live on calls with prospects)
|
|
||||||
- The specific UI element being written for
|
|
||||||
- The current text (if revising)
|
|
||||||
**Tone:** Confident, concise, client-facing. Not marketing fluff. This is a tool used live.
|
|
||||||
**Rule:** Copy is UX. Every label guides behavior. Every nudge drives a decision.
|
|
||||||
|
|
||||||
### Calculation Validator — Opus
|
|
||||||
**When:** After ANY change to `quote-engine.js`, `quote-pricing.js`, `package-prices-data.js`, or sidebar render values.
|
|
||||||
**How:**
|
|
||||||
1. Run `node tests/test-quote-engine.js` — all 254 must pass
|
|
||||||
2. Manually verify 2+ quote configs against the verification matrix in `docs/MASTER-SESSION-PROMPT.md` (Priority 4)
|
|
||||||
3. Cross-check sidebar display values against engine output
|
|
||||||
4. Verify admin fee floor/threshold logic at edge cases (0 users, 1 endpoint)
|
|
||||||
|
|
||||||
### QA / Regression Tester — Opus
|
|
||||||
**When:** After any visual, structural, or behavioral change.
|
|
||||||
**How:** Run the validation pipeline below. Use Playwright MCP for visual verification.
|
|
||||||
**Reference:** `docs/regression-checklist.md` for full manual QA procedures.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Validation Pipeline
|
|
||||||
|
|
||||||
After every change, validate in order. Stop and fix at the first failure.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
1. TESTS node tests/test-quote-engine.js (254/254 must pass)
|
tokens.css → base.css → layout.css → components.css → responsive.css
|
||||||
2. SYNTAX No console errors on fresh browser load
|
↕
|
||||||
3. THEMES Playwright: verify Dark, Light, Glass all render correctly
|
light.css / glass.css (theme overrides)
|
||||||
4. MOBILE Playwright: verify at 375px — floating MRR pill, bottom sheet, sync
|
↕
|
||||||
5. PRINT If CSS touched: verify print output is unaffected
|
print.css
|
||||||
6. PERSISTENCE If state/form touched: save → reload → verify all values restore
|
|
||||||
7. EXPORT If export touched: JSON export valid, version field present
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
**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.
|
||||||
|
|
||||||
## Hard Constraints
|
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.
|
||||||
|
|
||||||
These are inviolable. Every change must preserve them.
|
### Mobile Sync
|
||||||
|
|
||||||
| # | Constraint |
|
`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()`.
|
||||||
|---|-----------|
|
|
||||||
| 1 | **DOM IDs are a contract.** `mobile-sync.js` maps 100+ ID pairs (desktop ↔ `_m` suffix). Renaming breaks sync silently. |
|
**If you add a new sidebar element, mobile-sync must know about it or mobile breaks silently.**
|
||||||
| 2 | **Quote math is sacred.** Any `quote-engine.js` or `quote-pricing.js` change requires test validation. |
|
|
||||||
| 3 | **localStorage round-trip must work.** Key: `svs-msp-quote-v1`. Verify after form/state changes. |
|
### The Sidebar Is the Product
|
||||||
| 4 | **All 3 themes must work.** Dark (flagship), Light, Glass. Token/component changes cascade to all. |
|
|
||||||
| 5 | **Mobile parity maintained.** Sidebar clone in mobile panel must stay in sync. Usable at 375px. |
|
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?**
|
||||||
| 6 | **Print/PDF tested after CSS changes.** Print CSS is sensitive to component class changes. |
|
|
||||||
| 7 | **No framework or build-tool migration.** Vanilla JS by design. |
|
### Print / PDF
|
||||||
| 8 | **No broad rewrites.** Surgical, approved changes only. |
|
|
||||||
| 9 | **Read before editing.** Always inspect current code before making changes. |
|
`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.
|
||||||
| 10 | **Ask before assuming.** When requirements are ambiguous, ask the user. |
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Regression Hotspots
|
## Invariants
|
||||||
|
|
||||||
| Area | Risk | Why |
|
Things that must be true before and after every session. Each has a verification step.
|
||||||
|------|------|-----|
|
|
||||||
| `quote-engine.js` math | Critical | Wrong quotes in real sales calls |
|
| Invariant | Verify |
|
||||||
| localStorage round-trip | High | Silent failures lose configured quotes |
|
|-----------|--------|
|
||||||
| Mobile sync ID map | High | 100+ pairs desync silently if IDs change |
|
| All unit tests pass | `node tests/test-quote-engine.js` — 254/254 |
|
||||||
| Print/PDF CSS | Medium | Separate cascade, sensitive to class changes |
|
| All 3 themes render correctly | Playwright-check Dark, Light, Glass after any CSS change |
|
||||||
| Theme switching | Medium | All 3 themes affected by token changes |
|
| DOM IDs unchanged | Never rename — `mobile-sync.js` maps 100+ desktop↔mobile pairs silently |
|
||||||
| `update()` call chain | Medium | Side effects cascade: calc → render → sidebar → nudges → summaries → save |
|
| 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 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Installed Plugins & Skills
|
## Working Rules
|
||||||
|
|
||||||
### Plugins (use when applicable)
|
How Claude behaves while working. Not testable — behavioral.
|
||||||
|
|
||||||
| Plugin | When to Use |
|
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
|
||||||
| `superpowers` | Orchestration: planning, agents, reviews, TDD, debugging, branch mgmt |
|
3. **No frameworks, no build tools** — vanilla JS by design
|
||||||
| `frontend-design` | Frontend design patterns and implementation |
|
4. **No broad rewrites** — surgical, approved changes only
|
||||||
| `code-review` | Structured code review |
|
5. **Ask before assuming** — when requirements are unclear, ask
|
||||||
| `code-simplifier` | Simplification and cleanup passes |
|
|
||||||
| `playwright` | Browser automation, visual verification, screenshot comparison |
|
|
||||||
| `claude-md-management` | Maintaining this CLAUDE.md file |
|
|
||||||
| `skill-creator` | Creating new custom skills for this project |
|
|
||||||
|
|
||||||
### Skills (ui-ux-pro-max)
|
|
||||||
|
|
||||||
| Skill | When to Use |
|
|
||||||
|-------|-------------|
|
|
||||||
| `ui-ux-pro-max` | Main design intelligence — styles, colors, typography, UX rules |
|
|
||||||
| `design-system` | Token architecture, component specs |
|
|
||||||
| `brand` | Voice, visual identity, messaging consistency |
|
|
||||||
| `ui-styling` | Component styling (translate to vanilla CSS) |
|
|
||||||
| `design` | Logo, icons, visual assets |
|
|
||||||
| `banner-design` | Marketing banners and heroes |
|
|
||||||
| `slides` | HTML presentations |
|
|
||||||
|
|
||||||
**Search command** (requires Python 3):
|
|
||||||
```bash
|
|
||||||
python3 .claude/skills/ui-ux-pro-max/src/ui-ux-pro-max/scripts/search.py "<query>" --domain <domain>
|
|
||||||
```
|
|
||||||
Domains: `style`, `color`, `typography`, `product`, `landing`, `chart`, `ux`
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Commit Protocol
|
## Do Not Touch
|
||||||
|
|
||||||
- One concern per commit. Do not bundle unrelated changes.
|
| Thing | Why |
|
||||||
- Message format: `<area>: <what> — <why>`
|
|-------|-----|
|
||||||
- Examples: `css: fix glass theme sidebar blur — backdrop-filter not applying at 900px`
|
| `fontawesomekit/` | Huge vendor directory. Reference known FA icons by name when needed — never scan this directory |
|
||||||
- Examples: `engine: correct admin fee at zero users — floor logic was bypassed`
|
| `pre-alpha/` | Legacy/experimental files. Ignore unless explicitly asked |
|
||||||
- Do not commit temp files or `.bak-focusmode` files.
|
| Quote engine files | `quote-engine.js`, `quote-pricing.js`, `package-prices-data.js` — stable, tested, locked |
|
||||||
- Run validation pipeline before committing.
|
|
||||||
- Use `superpowers:finishing-a-development-branch` for final commit + cleanup.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Design Principles
|
## Design Principles
|
||||||
|
|
||||||
1. **Sales clarity over visual novelty.** Prospects must read numbers at a glance.
|
1. **Sales clarity over visual novelty** — prospects read numbers at a glance
|
||||||
2. **Trust through polish.** Misaligned inputs erode prospect confidence.
|
2. **The sidebar is the hero** — treat it like a financial summary
|
||||||
3. **Progressive disclosure.** Lead with MRR total. Detail unfolds on demand.
|
3. **Dark theme is flagship** — Light and Glass must meet the same bar
|
||||||
4. **Feedback immediacy.** Every input change updates sidebar within 1 frame.
|
4. **Copy is UX** — every label and nudge is a design decision
|
||||||
5. **Dark theme is the flagship.** Light and Glass must meet the same bar.
|
5. **Mobile is first-class** — a sales rep on a tablet must run a full quote
|
||||||
6. **The sidebar is the hero.** Design it like a financial summary, not a DOM dump.
|
|
||||||
7. **Copy is UX.** Labels, nudges, and button text are design decisions.
|
|
||||||
8. **Mobile is first-class.** A sales rep on a tablet must run a full quote.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## File Reference
|
## Architecture
|
||||||
|
|
||||||
See `docs/QUICK-REF.md` for the complete file map, DOM IDs, and pricing constants.
|
### HTML Structure
|
||||||
|
|
||||||
| Category | Key Files |
|
6 collapsible sections in the main column, sticky sidebar in the right column:
|
||||||
|----------|-----------|
|
|
||||||
| Orchestration | `SVS-MSP-Calculator.js`, `SVS-MSP-Calculator.html` |
|
| Section | ID | Content |
|
||||||
| Quote Engine | `quote-engine.js`, `quote-pricing.js`, `package-prices-data.js` |
|
|---------|----|---------|
|
||||||
| Rendering | `quote-render.js`, `mobile-sync.js`, `theme-manager.js` |
|
| I — Site Management | `#sec-01` | Admin fee, floor $650 |
|
||||||
| Persistence | `quote-persistence.js`, `quote-export.js`, `quote-import.js` |
|
| II — User Package | `#sec-02` | Per-user pricing, M365/BYOL |
|
||||||
| CSS Tokens | `SVS-MSP-Calculator-tokens.css` (source of truth for design tokens) |
|
| III — Endpoint Package | `#sec-03` | Device count |
|
||||||
| CSS Themes | `*-light.css`, `*-glass.css` |
|
| IV — Server Management | `#sec-04` | Server count |
|
||||||
| CSS Layout | `*-layout.css`, `*-components.css`, `*-responsive.css`, `*-print.css` |
|
| V — Zero Trust HaaS | `#sec-05` | Seats, routers |
|
||||||
| Tests | `tests/test-quote-engine.js` (254 tests, zero deps) |
|
| VI — VoIP UCaaS | `#sec-06` | Seats, tiers |
|
||||||
| Docs | `docs/QUICK-REF.md`, `docs/SESSION-HANDOFF.md`, `docs/MASTER-SESSION-PROMPT.md`, `docs/quote-rules.md`, `docs/DECISION-LOG.md`, `docs/KNOWN-ISSUES.md` |
|
|
||||||
|
**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
|
||||||
|
|||||||
BIN
dark-footnote-after.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
dark-sidebar-after.png
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
dark-theme-full.png
Normal file
|
After Width: | Height: | Size: 256 KiB |
@@ -1,400 +0,0 @@
|
|||||||
# SVS MSP CALC — Beta Build Checkpoint
|
|
||||||
|
|
||||||
**Date:** 2026-03-15
|
|
||||||
**Status:** Phases 1–8 + Stage 8 complete. Beta + a11y/perf audit + code quality passes I & II + test expansion + print enhancements done.
|
|
||||||
**Tests:** 254/254 passing
|
|
||||||
**Build Prompt:** .claude/plans/STAGE2-BUILD-PROMPT.md
|
|
||||||
**Previous Stage Prompt:** docs/STAGE3-SESSION-PROMPT.md
|
|
||||||
**Previous Stage Prompt:** docs/STAGE5-SESSION-PROMPT.md
|
|
||||||
**Previous Stage Prompt:** docs/STAGE6-SESSION-PROMPT.md
|
|
||||||
**Previous Stage Prompt:** docs/STAGE7-SESSION-PROMPT.md
|
|
||||||
**Previous Stage Prompt:** docs/STAGE8-SESSION-PROMPT.md
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Completed
|
|
||||||
|
|
||||||
### Phase 1: Bug Fixes (6/6)
|
|
||||||
|
|
||||||
| # | Issue | File | Change |
|
|
||||||
|---|-------|------|--------|
|
|
||||||
| 1.1 | ADDON_INKY default $5 → $8 | quote-pricing.js:12 | `ADDON_INKY: 5` → `8` |
|
|
||||||
| 1.2 | Onboarding fee loses manual override on term switch | SVS-MSP-Calculator.js:41-70 | Store manual value in `data-manual-value` before 24mo clears it; restore on switch back to m2m/12mo |
|
|
||||||
| 1.3 | VoIP fax CSV comment misleading | package-prices.csv:18 | "Flat/mo" → "Per seat/mo" |
|
|
||||||
| 1.4 | Print forces HST on regardless of user toggle | quote-export.js:12 | Removed `state.hstEnabled = true;` — print now respects user's HST toggle |
|
|
||||||
| 1.5 | JSON export missing schema version | quote-export.js:229 | Added `version: '1.0'` as first field in payload |
|
|
||||||
| 1.6 | ZT admin supplement triggers with no warning | quote-render.js:494-499 | New amber nudge when `ztActive` warns about $250 admin supplement |
|
|
||||||
|
|
||||||
Test expectations updated in test-quote-engine.js for INKY $8 (4 values changed).
|
|
||||||
|
|
||||||
### Phase 2: Visual Polish (Sections I–III)
|
|
||||||
|
|
||||||
| # | Issue | File | Change |
|
|
||||||
|---|-------|------|--------|
|
|
||||||
| 2.1a | Hardcoded `#e06070` danger icon | components.css:41 | → `var(--text-danger)` — adapts per theme |
|
|
||||||
| 2.1b | Hardcoded `#86efac` pill-savings on checked state | components.css:442 | → `var(--text-pill-savings-active)` — new token |
|
|
||||||
| — | Token added to all 4 themes | tokens.css, light.css, glass.css, 70retro.css | Dark: `#86efac`, Light: `#d4f5e0`, Glass: `#a8f0c8`, Retro: `#e0f0d0` |
|
|
||||||
| 2.1c | QUICK-REF.md outdated | docs/QUICK-REF.md | Updated INKY $8, export desc, theme list, test count |
|
|
||||||
|
|
||||||
**Audit findings (no action needed):**
|
|
||||||
- All 4 themes fully token-covered for Sections I–III
|
|
||||||
- Glass theme uses `!important` selector overrides (valid for glassmorphism effects)
|
|
||||||
- Sidebar focus-toggle white rgba values sit on colored header — correct everywhere
|
|
||||||
- No remaining hardcoded colors in Sections I–III component CSS
|
|
||||||
- Sidebar renders correctly across all 4 themes at all breakpoints
|
|
||||||
|
|
||||||
### Phase 3: UX Hardening (Sections I–III)
|
|
||||||
|
|
||||||
#### 3.1 Interaction Refinements
|
|
||||||
|
|
||||||
| # | Change | Files | Details |
|
|
||||||
|---|--------|-------|---------|
|
|
||||||
| 3.1a | Smooth theme-switch transition | tokens.css, theme-manager.js | `body.theme-transitioning` class enables 0.25s color/bg/border fade; applied for 300ms during `toggleTheme()` |
|
|
||||||
| 3.1b | Nudge crossfade on rotation/nav | components.css, quote-render.js | `.nudge-fading` class fades opacity to 0; `cycleNudge()` does fade-out → swap → fade-in (180ms); auto-rotation now uses `cycleNudge(1)` for consistency |
|
|
||||||
| 3.1c | Summary badge fade-in on collapse | components.css | `@keyframes badgeFadeIn` — 0.25s opacity + translateY animation on `.sec-summary-badge` |
|
|
||||||
| 3.1d | Addon toggle micro-feedback | components.css | `@keyframes addonPulse` — 0.2s scale(1.015) pulse on `.addon-row.selected` |
|
|
||||||
|
|
||||||
#### 3.2 Responsive Edge Cases
|
|
||||||
|
|
||||||
| # | Change | Files | Details |
|
|
||||||
|---|--------|-------|---------|
|
|
||||||
| 3.2a | Touch targets ≥44px on mobile | responsive.css | `.mobile-panel-close-btn` 36→44px, `.nudge-nav-btn` 34→44px at ≤1100px; `.collapsible-header` and `.section-toggle` min-height 44px at ≤600px |
|
|
||||||
| 3.2b | Container query fallback verified | — | `@container (max-width: 760px)` for addon rows has adequate fallback via ≤600px media query; no change needed |
|
|
||||||
|
|
||||||
#### 3.3 Mobile Experience Completeness
|
|
||||||
|
|
||||||
| # | Change | Files | Details |
|
|
||||||
|---|--------|-------|---------|
|
|
||||||
| 3.3a | Focus trap in mobile panel | mobile-sync.js | `trapFocus()` function keeps Tab cycling within open panel; focus moves to close button on open, returns to pill on close |
|
|
||||||
| 3.3b | Safe-area insets for notch phones | responsive.css | `padding-bottom: env(safe-area-inset-bottom)` on `.mobile-panel-sheet`; `right: max(14px, env(safe-area-inset-right))` on `.mobile-quote-pill` |
|
|
||||||
|
|
||||||
**GATE: 88/88 tests pass. All JS syntax-checked. CSS brace balance verified.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 4: Documentation & QA
|
|
||||||
|
|
||||||
| # | Task | Status |
|
|
||||||
|---|------|--------|
|
|
||||||
| 4.1 | Update all docs (README, code-verification, quote-rules, phase-roadmap, QUICK-REF, MASTER-SESSION-PROMPT, ai-session-brief) | COMPLETE |
|
|
||||||
| 4.2 | Full regression checklist walkthrough | COMPLETE — 88/88 automated, 15/15 manual items verified in code |
|
|
||||||
| 4.3 | Beta definition of done verification | COMPLETE — all 13 criteria pass |
|
|
||||||
|
|
||||||
**Docs updated:**
|
|
||||||
- README.md — phase status, 88 tests, 4 themes, export description, file map (70retro.css added)
|
|
||||||
- code-verification.md — date, test count, all Phase 1-3 changes as known-good baseline
|
|
||||||
- quote-rules.md — onboarding manual override persistence, HST print behavior, JSON export rules, admin nudge
|
|
||||||
- phase-roadmap.md — Phases 1-4 status, 88 tests
|
|
||||||
- QUICK-REF.md — test count in "Remind User", 70retro.css in CSS file map
|
|
||||||
- MASTER-SESSION-PROMPT.md — 88 tests (3 occurrences), 4 themes (6 occurrences), 70retro.css in tree, 4 theme override layers
|
|
||||||
- ai-session-brief.md — test count updated
|
|
||||||
|
|
||||||
**Regression checklist results:**
|
|
||||||
- Automated: 88/88 pass
|
|
||||||
- Manual: All 15 items verified via source code review (admin waive displays, term/onboarding logic, manual override persistence, sidebar sync, mobile panel sync, persistence round-trip, reset behavior, print HST, JSON export, section headers, theme transitions, nudge crossfade, focus trap, safe-area insets, touch targets)
|
|
||||||
|
|
||||||
**Beta Definition of Done: ALL 13 CRITERIA PASS**
|
|
||||||
|
|
||||||
**GATE: PASSED — Beta build for Sections I–III is complete.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 5: Performance & Accessibility Audit
|
|
||||||
|
|
||||||
| # | Fix | File(s) | Details |
|
|
||||||
|---|-----|---------|---------|
|
|
||||||
| A2 | `aria-expanded` on section & collapsible toggles | HTML, SVS-MSP-Calculator.js | Added `aria-expanded="false"` to 12 toggle elements; JS updates dynamically on toggle |
|
|
||||||
| A3 | Focus trap on reset confirm modal | quote-persistence.js | `trapFocusInModal()` — Tab cycles within modal when open |
|
|
||||||
| A4 | `aria-label` on stepper buttons | HTML | All 12 step-btn elements have descriptive labels (e.g. "Decrease users") |
|
|
||||||
| P1 | Glass theme scroll jank on mobile | glass.css | `background-attachment: scroll` at ≤1100px — avoids fixed-bg repaint on iOS |
|
|
||||||
| P2 | Skip mobile sync on desktop | mobile-sync.js | Guard skips 35+ element sync when panel closed on desktop; forces full sync on `openMobilePanel()` |
|
|
||||||
| M1 | `sidebarFocusClientName` not in sync map | mobile-sync.js | Added to html sync list — client name now updates in mobile panel |
|
|
||||||
| M2 | `sl-discount-detail` + `sl-value-onboarding-label` not in sync map | mobile-sync.js | Added to html sync list — contract term label and onboarding label now sync |
|
|
||||||
|
|
||||||
**Not flagged (clean):** Token coverage, `:focus-visible`, mobile focus trap, escape handling, touch targets, `will-change` usage, print CSS isolation, no unused JS.
|
|
||||||
|
|
||||||
**GATE: 88/88 tests pass. All fixes verified.**
|
|
||||||
|
|
||||||
### Font Awesome Icon Fix
|
|
||||||
|
|
||||||
| # | Fix | File | Details |
|
|
||||||
|---|-----|------|---------|
|
|
||||||
| FA1 | Icons invisible on `file://` protocol | components.css:44-79 | All 36 FA Sharp Solid SVG file references converted to inline `data:image/svg+xml` URIs — eliminates CORS/`file://` restriction on `mask-image: url()` |
|
|
||||||
|
|
||||||
**Root cause:** CSS `mask-image: url("fontawesomekit/svgs/...")` is blocked by browser security on the `file://` protocol. Inline data URIs bypass this completely.
|
|
||||||
|
|
||||||
**GATE: 88/88 tests pass. Icons render on local file open.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 6: Code Quality Pass (Stage 3)
|
|
||||||
|
|
||||||
| # | Fix | File(s) | Details |
|
|
||||||
|---|-----|---------|---------|
|
|
||||||
| CQ1 | New `--sky` color token | tokens.css, light.css, glass.css, 70retro.css | Per-theme sky/info accent: Dark `#38bdf8`, Light `#0e7490`, Glass `#7dd3fc`, Retro `#a34a14` |
|
|
||||||
| CQ2 | New `--transition-fast` token | tokens.css | `0.15s` — replaces hardcoded timing in layout.css button transitions |
|
|
||||||
| CQ3 | Consolidated duplicate button CSS | layout.css:25-47 | `.btn-reset-quote` and `.btn-import-quote` shared 10 identical properties → merged into grouped selector |
|
|
||||||
| CQ4 | Hardcoded amber hover → token-derived | layout.css:43-46 | `rgba(232,146,15,…)` → `color-mix(in srgb, var(--amber) …%, transparent)` |
|
|
||||||
| CQ5 | Hardcoded sky blue hover → token-derived | layout.css:47-50, light.css, glass.css, 70retro.css | All `rgba(56,189,248,…)` / `#38bdf8` / `#7dd3fc` / `#a34a14` → `var(--sky)` + `color-mix()` |
|
|
||||||
| CQ6 | Dead null-check removed | quote-render.js:533 | `nudgeIndex == null ||` removed — `nudgeIndex` is always initialized to `0` |
|
|
||||||
|
|
||||||
**Audit findings (no action taken — documented for future):**
|
|
||||||
- `fmt()` duplicated in quote-render.js and quote-export.js (both inside IIFEs — intentional isolation, one-liner)
|
|
||||||
- Spacing magic numbers (14px/16px/20px) used 95+ times — too many touchpoints for surgical migration
|
|
||||||
- `console.warn()` statements in pricing/persistence/import are intentional error reporting
|
|
||||||
- No dead functions, no unreachable code, no unused exports across all 8 JS modules
|
|
||||||
|
|
||||||
**GATE: 88/88 tests pass. All 4 themes verified tokenized.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 7: Test Coverage Expansion (Stage 4)
|
|
||||||
|
|
||||||
| # | Test Group | Count | Details |
|
|
||||||
|---|-----------|-------|---------|
|
|
||||||
| T1 | Pricing DEFAULTS integrity | 34 | All required keys exist, types correct, values match spec, frozen, ordering invariants |
|
|
||||||
| T2 | Engine edge cases & boundaries | 55 | Admin fee thresholds, large counts (100u/100ep), string coercion, invalid inputs (NaN/null/empty), servers-only, VoIP-only, VoIP edge cases, ZT without user addon, admin waived, all addons combined, BYOL term independence, discount rounding |
|
|
||||||
| T3 | Export JSON schema validation | 18 | Payload structure, field types, version field, contract term labels, licensing labels, pricing sub-object, voip tier null handling |
|
|
||||||
| T4 | Persistence state shape | 6 | JSON round-trip for strings/numbers/booleans, engine compatibility, zero-state |
|
|
||||||
| T5 | Import payload mapping | 12 | Contract term reverse-map, full export→import→engine round-trip (MRR, effectiveMrr, mrrWithHst, userTotal, endpointTotal, voipTotal, adminFeeNet, effectiveAnnual) |
|
|
||||||
| T6 | Quote output invariants | 24 | 6 configs × 4 invariants (effectiveMrr, effectiveAnnual, mrrWithHst, non-negative values) |
|
|
||||||
|
|
||||||
**Total: 88 → 250 tests (162 new). All passing.**
|
|
||||||
|
|
||||||
**GATE: 250/250 tests pass.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 8: Enhanced Print/PDF (Stage 4)
|
|
||||||
|
|
||||||
| # | Enhancement | File(s) | Details |
|
|
||||||
|---|------------|---------|---------|
|
|
||||||
| P1 | Quote notes field | HTML:920, components.css, quote-persistence.js, quote-export.js, quote-import.js | `<textarea id="quoteNotes">` in sidebar, persisted in localStorage, included in JSON export/import, rendered on print invoice |
|
|
||||||
| P2 | Explicit validity date | quote-export.js | Computes 30-day expiry: "Valid until [date]" in print footer instead of generic "30 days" |
|
|
||||||
| P3 | Page break control | quote-export.js (inline CSS) | `page-break-inside:avoid` on table rows + `.tots-wrap`; `break-inside:avoid` on notes section |
|
|
||||||
| P4 | Rep name field | HTML:100, layout.css, quote-persistence.js, quote-export.js, quote-import.js | `<input id="repName">` below client name, persisted, in JSON export/import, shown in print header + footer |
|
|
||||||
| P5 | CYA "Not Included" section | quote-export.js | Print splits config into "Your Service Configuration" (active) + "Services Not Included in This Quote" (excluded, muted, smaller) |
|
|
||||||
|
|
||||||
**Additional changes:**
|
|
||||||
- JSON export schema version bumped to `1.1` (new `repName`, `quoteNotes` fields)
|
|
||||||
- JSON import handles new fields gracefully (backward-compatible with `1.0` exports)
|
|
||||||
- Print CSS hides notes + rep inputs on `@media print` (main page path)
|
|
||||||
- 4 new tests added (repName/quoteNotes in export schema + persistence)
|
|
||||||
|
|
||||||
**GATE: 254/254 tests pass.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Key Files to Read on Resume
|
|
||||||
|
|
||||||
1. `docs/MASTER-SESSION-PROMPT.md` — full architecture and constraints
|
|
||||||
2. `docs/QUICK-REF.md` — compact file map, IDs, pricing
|
|
||||||
3. `docs/regression-checklist.md` — test procedures
|
|
||||||
4. `.claude/plans/STAGE2-BUILD-PROMPT.md` — the build prompt driving this work
|
|
||||||
5. This file — checkpoint status
|
|
||||||
|
|
||||||
### Stage 5 / Phase 9: Visual QA + Retro Theme Overhaul
|
|
||||||
|
|
||||||
**Visual QA:** 3 breakpoints (mobile ~375px, desktop ~1100-1400px, wide ~1800px+) × 4 themes.
|
|
||||||
|
|
||||||
| Theme | Mobile | Desktop | Wide | Result |
|
|
||||||
|-------|--------|---------|------|--------|
|
|
||||||
| Dark | Clean | Clean | Clean | PASS |
|
|
||||||
| Light | Clean | Clean | Clean | PASS |
|
|
||||||
| Glass | Clean | Clean | Clean | PASS |
|
|
||||||
| Retro | Overhauled | — | — | REWORKED |
|
|
||||||
|
|
||||||
**Retro theme overhaul:**
|
|
||||||
- **Problem:** Original 70s wood-panel brown palette had low contrast, muddy colors, invisible logo (black SVG on brown header)
|
|
||||||
- **Solution:** Warm paper base + neon-warm cyberpunk accents
|
|
||||||
- Accent: hot rose `#e11d48` (warm neon, harmonizes with cream)
|
|
||||||
- Green/Sky: warm teal `#0d9488`
|
|
||||||
- Header: warm charcoal `#1c1317` with rose neon border
|
|
||||||
- Logo: `.top-bar-logo path { fill: #f0e4d0 }` — overrides hardcoded `#0c0c0c` SVG fills
|
|
||||||
- Progress bar: rose → teal gradient
|
|
||||||
- Paper texture: warm brown scanlines (unchanged from original)
|
|
||||||
- **Status:** Functional, user notes full design pass deferred to later
|
|
||||||
|
|
||||||
**Remaining QA not yet done:** Retro theme at all viewport widths, landscape orientation.
|
|
||||||
|
|
||||||
**GATE: 254/254 tests pass. No visual bugs found on Dark/Light/Glass.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Stage 6 / Phase 10: Elastic Responsive Foundation
|
|
||||||
|
|
||||||
**Problem:** 5 fixed breakpoints (1350, 1100, 900, 600, 780px landscape) with hardcoded px overrides at each step. Max width capped at 1800px — wasted space on 1440p+ monitors.
|
|
||||||
|
|
||||||
**Solution:** Fluid `clamp()` tokens replace discrete breakpoint steps. Only structural breakpoints remain.
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| E1 | Fluid layout tokens | tokens.css | `--page-max-width: clamp(1200px, 92vw, 2400px)`, `--page-gutter-x: clamp(16px, 3vw, 80px)`, `--layout-column-gap: clamp(24px, 3vw, 56px)`, sidebar min 400→360px |
|
|
||||||
| E2 | Fluid section tokens | tokens.css | `--section-offset: clamp(52px, 7vw, 104px)`, `--section-num-width/size` fluid, `--section-padding-*` fluid |
|
|
||||||
| E3 | Eliminated 1350px breakpoint | responsive.css | Removed — fluid tokens handle narrow desktop scaling |
|
|
||||||
| E4 | Eliminated 900px breakpoint | responsive.css | Removed — fluid tokens handle tablet spacing/numerals |
|
|
||||||
| E5 | Fluid logo margin | base.css | `margin-left: clamp(26px, 5.2vw, 78px)` replaces hardcoded 78px + breakpoint overrides |
|
|
||||||
| E6 | Fluid main-col gap | layout.css | `gap: clamp(16px, 1.5vw, 24px)` replaces hardcoded 24px + breakpoint override |
|
|
||||||
| E7 | Fluid client-bar padding | layout.css | `clamp()` on vertical padding, `var(--section-offset)` for left |
|
|
||||||
|
|
||||||
**Breakpoint reduction:** 5 → 3 (1100px structural, 600px phone layout, 780px landscape orientation)
|
|
||||||
|
|
||||||
**Width scaling:**
|
|
||||||
- 1080p (1920px): content fills ~1766px (92vw)
|
|
||||||
- 1440p (2560px): content fills ~2355px (92vw)
|
|
||||||
- 4K (3840px): content caps at 2400px max
|
|
||||||
|
|
||||||
**GATE: 254/254 tests pass.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Stage 7 / Phase 11: Feature Work (Option A)
|
|
||||||
|
|
||||||
#### 11.1 Keyboard Shortcuts
|
|
||||||
|
|
||||||
| Shortcut | Action | File | Details |
|
|
||||||
|----------|--------|------|---------|
|
|
||||||
| Ctrl+P | Print invoice | SVS-MSP-Calculator.js | `preventDefault()` blocks browser print dialog; calls `printInvoice()` |
|
|
||||||
| Ctrl+E | Export JSON | SVS-MSP-Calculator.js | Calls `exportQuoteJSON()` |
|
|
||||||
| Ctrl+R | Reset quote | SVS-MSP-Calculator.js | Opens confirm modal via `openResetConfirm()` — not a hard reset |
|
|
||||||
| Escape | Close overlays | mobile-sync.js (existing) | Already handled — closes sidebar focus + mobile panel |
|
|
||||||
|
|
||||||
All shortcuts are suppressed when focus is in an `<input>`, `<textarea>`, or `<select>` to avoid hijacking normal typing.
|
|
||||||
|
|
||||||
#### 11.2 New Contextual Nudges
|
|
||||||
|
|
||||||
| # | Nudge | Color | Trigger |
|
|
||||||
|---|-------|-------|---------|
|
|
||||||
| N1 | Users set but no endpoints | amber | `users > 0 && endpoints === 0` |
|
|
||||||
| N2 | VoIP seats ≠ user count | amber | `voipSeats > 0 && users > 0 && voipSeats !== users` |
|
|
||||||
| N3 | High admin-to-MRR ratio | amber | `adminFeeNet > MRR * 0.25` (and not waived) |
|
|
||||||
| N4 | Extended Hours upsell | green | `!addExtHours && users > 0` |
|
|
||||||
|
|
||||||
Added after existing nudges in `buildNudges()` in quote-render.js (lines 524–551).
|
|
||||||
|
|
||||||
**GATE: 254/254 tests pass.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Stage 8 / Phase 12: Code Quality Pass II
|
|
||||||
|
|
||||||
#### 8.1 `--transition-fast` / `--transition-medium` Token Adoption
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| T1 | New `--transition-medium` token | tokens.css | `0.25s` — for chevron/collapsible/nudge transforms |
|
|
||||||
| T2 | 10× `0.15s` → `var(--transition-fast)` | components.css | pill-toggle, tier-seg, addon-preview-pill, addon checkbox, sidebar-focus-toggle, nudge-nav-btn, btn-toggle-all, quote-notes-input, btn-export |
|
|
||||||
| T3 | 3× `0.25s` → `var(--transition-medium)` | components.css | sec-chevron transform, collapsible-toggle transform, nudge-banner bg/border |
|
|
||||||
| T4 | 1× `0.15s` → `var(--transition-fast)` | base.css | theme-toggle-btn |
|
|
||||||
| T5 | 2× `0.15s` → `var(--transition-fast)` | responsive.css | mobile-quote-pill, mobile-panel-close-btn |
|
|
||||||
|
|
||||||
**Left as-is:** 0.12s (stepper/addon micro-interactions), 0.18s (term tile tuned), 0.2s (switch/section/overlay), 0.3s (progress bar/accordion), 0.34s (section-body tuned bezier). No `0.15s` hardcodes remain outside the token definition.
|
|
||||||
|
|
||||||
#### 8.2 CSS Selector Specificity Audit
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| S1 | `.sec-open` → `.section.sec-open` | components.css | Removed 2× `!important` — specificity now beats `.section:hover` via class count |
|
|
||||||
| S2 | Documented intentional `!important` | components.css | Added comments to `.qs-discount-sub`, sidebar utility classes (`.sl-muted`, `.sl-discount-val`, `.sl-hst-val`), and VS value classes |
|
|
||||||
|
|
||||||
**Audit findings (no action — all legitimate):**
|
|
||||||
- components.css: 13 remaining `!important` — all utility `display: none` or color overrides that must beat compound parent selectors
|
|
||||||
- 70retro.css: 37 `!important` — theme override pattern (same as glass.css with 97)
|
|
||||||
- responsive.css: 8 `!important` — mobile sidebar embedding
|
|
||||||
- tokens.css: 1 `!important` — `body.theme-transitioning` (intentional, per spec)
|
|
||||||
- print.css: All `!important` — standard `@media print` override pattern
|
|
||||||
- No overly-qualified selectors found (element-qualified patterns are all necessary)
|
|
||||||
|
|
||||||
#### 8.3 Print CSS Hardening
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| P1 | Hide 4 missing interactive elements | print.css | Added `display: none !important` for `.sidebar-focus-toggle`, `.sidebar-utility`, `.qs-switch`, `.confirm-modal` |
|
|
||||||
| P2 | Theme-independent callout borders | tokens.css, print.css | New `--print-callout-green-border` and `--print-callout-red-border` tokens replace theme-variable `var(--green)` and `var(--surface-danger-border)` in print context |
|
|
||||||
|
|
||||||
**Verification:**
|
|
||||||
- All `--print-*` tokens defined only in `:root` (tokens.css) — no theme overrides
|
|
||||||
- Page-break rules unaffected by fluid layout tokens (`.outer` forced to `display: block; max-width: 100%` in print)
|
|
||||||
- Print invoice (separate window) uses inline CSS — not affected by main page changes
|
|
||||||
|
|
||||||
#### 8.4 (Stretch) Spacing Token Consolidation — Deferred
|
|
||||||
|
|
||||||
**Assessment:** 150+ magic-number spacing values across components.css (10px: 36, 12px: 35, 14px: 36, 16px: 24, 20px: 19). Existing `--space-stack-*` tokens used only 4× out of 150+. Migration scope too broad for surgical approach. Deferred to a dedicated spacing-focused stage.
|
|
||||||
|
|
||||||
**GATE: 254/254 tests pass.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Stage 8 Feature Fixes
|
|
||||||
|
|
||||||
#### F1: Fullscreen Live Quote View — Print Only
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| F1a | Hide Reset + Import in focus mode | components.css | `.export-wrap` and `.sidebar-utility` now `display: none` in sidebar-focus-open |
|
|
||||||
| F1b | Print button inside sidebar header | HTML, components.css | New `.sidebar-focus-print-btn` in `.sidebar-header-row` — hidden by default, `display: inline-flex` in focus mode |
|
|
||||||
| F1c | Print button hidden in print/mobile | print.css, components.css | `display: none !important` in `@media print` and `.mobile-panel-sheet` |
|
|
||||||
|
|
||||||
**Before:** Focus mode hid Print/Export JSON, showed Reset/Import
|
|
||||||
**After:** Focus mode shows a Print button in the header bar (next to collapse icon), hides all other action buttons
|
|
||||||
|
|
||||||
#### F2: Toggle Switch 2-State Theme Colors
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| F2a | New `--surface-switch-off` / `--surface-switch-on` tokens | tokens.css | Dark: off `#4a4540`, on `var(--green)` |
|
|
||||||
| F2b | Light theme switch tokens | light.css | Off `#b5ad9f`, on `var(--green)` |
|
|
||||||
| F2c | Glass theme switch tokens | glass.css | Off `rgba(255,255,255,0.15)`, on `var(--green)` |
|
|
||||||
| F2d | Retro theme switch tokens | 70retro.css | Off `#c0b4a0`, on `var(--green)` |
|
|
||||||
| F2e | Component CSS uses tokens | components.css | `.qs-switch` bg → `var(--surface-switch-off)`, checked → `var(--surface-switch-on)` |
|
|
||||||
| F2f | Glass checked override | glass.css | Added `.qs-toggle-row input:checked ~ .qs-switch { background: var(--surface-switch-on) }` |
|
|
||||||
|
|
||||||
**Before:** Off = `--border` (barely visible), On = `--accent` (theme accent)
|
|
||||||
**After:** Off = distinct muted track per theme, On = `--green` (universally "enabled")
|
|
||||||
|
|
||||||
**GATE: 254/254 tests pass.**
|
|
||||||
|
|
||||||
#### F1 Fix: Print Button Visibility in Focus Mode
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| F1d | Print button inside sidebar header | HTML:697 | New `.sidebar-focus-print-btn` button in `.sidebar-header-row`, between title and collapse icon |
|
|
||||||
| F1e | Focus-only visibility | components.css | `display: none` by default; `display: inline-flex` when `body.sidebar-focus-open` |
|
|
||||||
| F1f | Hidden in print + mobile | print.css, components.css | `display: none !important` in `@media print` and `.mobile-panel-sheet` |
|
|
||||||
|
|
||||||
**Root cause:** `.sidebar-utility` is a sibling of `.sidebar`, not inside it. When `.sidebar` becomes `position: fixed`, the utility div is left behind the backdrop.
|
|
||||||
|
|
||||||
#### F3: Pricing CSV → JSON Migration
|
|
||||||
|
|
||||||
| # | Change | File(s) | Details |
|
|
||||||
|---|--------|---------|---------|
|
|
||||||
| F3a | New JSON pricing file | package-prices.json | Structured by category with `{ key: { value, description } }` format — human-readable + machine-parseable |
|
|
||||||
| F3b | Script-loaded pricing | package-prices-data.js, HTML | `window.SVS_PRICING_DATA` set via `<script>` tag — works on `file://` protocol, no web server needed |
|
|
||||||
| F3c | Loader updated | quote-pricing.js | `loadPricing()` checks `SVS_PRICING_DATA` global first (script path), then `fetch()` fallback (web server), then built-in defaults |
|
|
||||||
| F3d | CSV retained | package-prices.csv | Original CSV kept for reference; no longer loaded at runtime |
|
|
||||||
|
|
||||||
**How to update pricing:** Edit `package-prices-data.js` — change the `value` field for any key. No web server needed. The file is loaded via `<script>` tag before the pricing engine initializes.
|
|
||||||
|
|
||||||
**JSON format example:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"user_packages": {
|
|
||||||
"RATE_M365": { "value": 130, "description": "Per-user/mo rate — M365 included" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**GATE: 254/254 tests pass.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Hard Constraints (reminder)
|
|
||||||
|
|
||||||
1. DOM IDs are a contract — no renaming
|
|
||||||
2. 254 tests must pass: `node svsmspcalc/tests/test-quote-engine.js`
|
|
||||||
3. localStorage keys unchanged
|
|
||||||
4. All 4 themes must work after every change
|
|
||||||
5. Mobile parity maintained
|
|
||||||
6. No frameworks, no npm — vanilla only
|
|
||||||
7. Surgical changes only
|
|
||||||
8. Sections IV–VI unchanged (deferred)
|
|
||||||
@@ -1,415 +0,0 @@
|
|||||||
# SVS MSP CALC — Master Session Prompt
|
|
||||||
### Pre-Alpha → Beta Optimization Brief
|
|
||||||
**Version:** 1.0 | **Date:** 2026-03-14 | **Audience:** Senior Engineers + UI/UX Leads
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## WHO YOU ARE (Team Persona)
|
|
||||||
|
|
||||||
You are a cross-functional senior engineering and design team operating with full production standards:
|
|
||||||
|
|
||||||
- **Senior Frontend Engineer** — Deep HTML/CSS/JS expertise. Minimal safe changes. Surgical precision. Strong regression awareness. No casual hacks, no premature abstractions, no over-engineering.
|
|
||||||
- **UI/UX Architect** — Masters-level understanding of design systems, visual hierarchy, information architecture, interaction design, and accessibility. Fluent in tokenized CSS design systems. Makes layouts feel inevitable, not assembled.
|
|
||||||
- **Sales Enablement Lead** — Understands this tool is used live on sales calls with prospects. Every UX decision must serve the sales conversation. Copy must be confident, concise, and client-facing.
|
|
||||||
- **QA Engineer** — Regression-aware. Knows where the landmines are (mobile sync, quote math, persistence, print/PDF). Validates behavior before marking work done.
|
|
||||||
|
|
||||||
You do not introduce change for its own sake. You improve with purpose, validate your work, and leave the codebase healthier than you found it.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PROJECT OVERVIEW
|
|
||||||
|
|
||||||
**App:** SVS MSP CALC — A live quote/pricing calculator for SVS Managed Services.
|
|
||||||
**Type:** Static HTML + Vanilla JS + Modular CSS (no frameworks, no build tools, no npm)
|
|
||||||
**Used by:** SVS sales team, live on screen with prospects during discovery calls
|
|
||||||
**Goal of this session:** Advance from pre-alpha to a solid, ship-ready **beta build**
|
|
||||||
|
|
||||||
### What "Beta" Means Here
|
|
||||||
- All active sections (I–III) are visually polished and production-quality
|
|
||||||
- All three themes (Dark, Light, Glass) are consistent, tested, and professional
|
|
||||||
- Mobile experience is smooth, reliable, and parity-complete with desktop
|
|
||||||
- Print/PDF invoice is clean, branded, and pixel-accurate
|
|
||||||
- Quote math, persistence, and export are verified and regression-safe
|
|
||||||
- UX hierarchy is clear: users know exactly what to do without instructions
|
|
||||||
- No known bugs in active scope
|
|
||||||
- Sections IV–VI (Zero Trust Networking, VoIP) are ready to activate — code is solid and UX frameworks are in place, even if content is still gated
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ARCHITECTURE SNAPSHOT
|
|
||||||
|
|
||||||
```
|
|
||||||
svsmspcalc/
|
|
||||||
├── SVS-MSP-Calculator.html # Stable HTML shell (65KB, inline handlers)
|
|
||||||
├── SVS-MSP-Calculator.js # Master orchestration (310 lines)
|
|
||||||
├── quote-engine.js # Pure quote math (196 lines)
|
|
||||||
├── quote-pricing.js # Pricing defaults + JSON override (134 lines)
|
|
||||||
├── quote-render.js # DOM rendering + nudge engine (662 lines)
|
|
||||||
├── quote-persistence.js # localStorage save/restore (212 lines)
|
|
||||||
├── quote-export.js # Print/PDF + JSON export (295 lines)
|
|
||||||
├── theme-manager.js # Dark/Light/Glass switching (110 lines)
|
|
||||||
├── mobile-sync.js # Mobile panel + 100+ element sync (236 lines)
|
|
||||||
├── SVS-MSP-Calculator.css # Manifest: @imports all CSS files
|
|
||||||
├── SVS-MSP-Calculator-tokens.css # Design tokens + CSS vars
|
|
||||||
├── SVS-MSP-Calculator-base.css # Global chrome
|
|
||||||
├── SVS-MSP-Calculator-layout.css # Grid, header, main/sidebar split
|
|
||||||
├── SVS-MSP-Calculator-components.css # All section cards, controls, sidebar (66KB)
|
|
||||||
├── SVS-MSP-Calculator-responsive.css # Viewport/container overrides (16KB)
|
|
||||||
├── SVS-MSP-Calculator-print.css # Print-specific rules
|
|
||||||
├── SVS-MSP-Calculator-light.css # Light theme overrides
|
|
||||||
├── SVS-MSP-Calculator-glass.css # Glass theme (glassmorphism)
|
|
||||||
├── package-prices.json # Overrideable pricing (JSON, categorized with descriptions)
|
|
||||||
├── package-prices.csv # Legacy pricing reference (no longer loaded at runtime)
|
|
||||||
├── tests/
|
|
||||||
│ └── test-quote-engine.js # Automated quote engine tests (88 tests, Node.js)
|
|
||||||
└── docs/
|
|
||||||
├── README.md
|
|
||||||
├── ai-session-brief.md
|
|
||||||
├── phase-roadmap.md
|
|
||||||
├── code-verification.md
|
|
||||||
├── quote-rules.md
|
|
||||||
├── regression-checklist.md
|
|
||||||
└── MASTER-SESSION-PROMPT.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tech Stack Facts
|
|
||||||
- **No frameworks.** Vanilla JS (ES5-compatible), HTML5, CSS3.
|
|
||||||
- **No build tools.** Open the HTML in a browser — it runs.
|
|
||||||
- **No npm.** No webpack, Vite, Rollup, Parcel, or transpilation.
|
|
||||||
- **No TypeScript.** Plain `.js` files.
|
|
||||||
- **CSS architecture:** Tokenized custom properties. Modular files. Three theme override layers (Dark, Light, Glass).
|
|
||||||
- **State:** localStorage only. Key: `svs-msp-quote-v1`.
|
|
||||||
- **Fonts:** Google Fonts (Cinzel, Poppins, Lato, DM Mono).
|
|
||||||
- **Icons:** Font Awesome 7 Sharp (local SVGs), M365 icon set (local).
|
|
||||||
|
|
||||||
### Initialization Flow
|
|
||||||
```
|
|
||||||
initTheme() → restore saved theme (dark/light/glass)
|
|
||||||
initQuote() → load JSON pricing, set quote ref, restore localStorage, call update()
|
|
||||||
update() → calcQuote() → renderQuoteUi() → renderSidebar() → nudges → savings → summaries
|
|
||||||
debouncedSave() → auto-save to localStorage (debounced 400ms)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Automated Testing
|
|
||||||
```
|
|
||||||
node svsmspcalc/tests/test-quote-engine.js
|
|
||||||
```
|
|
||||||
254 tests, zero dependencies. Tests the pure `calculateQuote(state, pricing)` function against known-good expected values using default pricing. Covers: rates, add-ons, admin fee logic, discounts, HST, VoIP, ZT networking, edge cases, MRR integrity, export schema, persistence shape, import mapping, and quote output invariants.
|
|
||||||
|
|
||||||
Run after any change to `quote-engine.js`, `quote-pricing.js`, or pricing JSON values.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ACTIVE SECTIONS (I–VI) — All Structurally Active
|
|
||||||
|
|
||||||
| # | Section | Display Order | Key Logic |
|
|
||||||
|---|---------|---------------|-----------|
|
|
||||||
| I | User Package | 1st | M365 Included ($130/user) vs BYOL ($110/user); 4 add-ons |
|
|
||||||
| II | Endpoint Package | 2nd | $35/endpoint; USB Blocking + Bare Metal Backup add-ons |
|
|
||||||
| III | Site Management | 3rd | Floor + minimum threshold; ZT supplement; 1PWM surcharge; waivable |
|
|
||||||
| IV | Server Management | 4th | $120/server |
|
|
||||||
| V | Zero Trust Networking (HaaS) | 5th | ZT seats + routers |
|
|
||||||
| VI | VoIP / Unified Communications (UCaaS) | 6th | 3 tiers + desk phone + eFax |
|
|
||||||
| — | Contract & Onboarding | Settings bar | M2M / 12mo (3%) / 24mo (5%); onboarding auto-calc or manual; HST 13% |
|
|
||||||
|
|
||||||
All sections use unified `sec-controls-row` header layout: stepper + label badge + price badge.
|
|
||||||
Sections default to collapsed. Inner collapsibles default to collapsed.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## KEY PRICING CONSTANTS
|
|
||||||
|
|
||||||
```js
|
|
||||||
RATE_M365: 130 // per user/mo — M365 Included license
|
|
||||||
RATE_BYOL: 110 // per user/mo — Bring Your Own License
|
|
||||||
RATE_ENDPOINT: 35 // per endpoint/mo
|
|
||||||
RATE_SERVER: 120 // per server/mo
|
|
||||||
ADMIN_FEE_FLOOR: 150
|
|
||||||
ADMIN_FEE_MINIMUM: 650
|
|
||||||
DISCOUNT_12MO: 0.03 // 3%
|
|
||||||
DISCOUNT_24MO: 0.05 // 5%
|
|
||||||
HST_RATE: 0.13 // Ontario
|
|
||||||
VOIP_RATE_BASIC: 28 // per seat/mo
|
|
||||||
VOIP_RATE_STANDARD: 35
|
|
||||||
VOIP_RATE_PREMIUM: 45
|
|
||||||
```
|
|
||||||
|
|
||||||
Pricing can be overridden at runtime via `package-prices.json`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## NON-NEGOTIABLES (Hard Constraints)
|
|
||||||
|
|
||||||
These are inviolable. Every change must preserve them:
|
|
||||||
|
|
||||||
1. **HTML shell is stable.** DOM IDs are a contract. Mobile sync maps 100+ ID pairs (desktop ↔ `_m` suffix). Renaming an ID breaks sync silently and catastrophically.
|
|
||||||
2. **Quote math is correct.** Any change to `quote-engine.js` requires before/after validation of all outputs. Do not "clean up" math without proving equivalence.
|
|
||||||
3. **localStorage persistence is intact.** `saveState()` and `restoreState()` must round-trip cleanly. Verify after any form/state changes.
|
|
||||||
4. **All three themes must work.** Dark (default), Light (soft khaki), Glass (glassmorphism). Changes to tokens or components cascade to all three.
|
|
||||||
5. **Mobile parity is maintained.** The sidebar clone in the mobile panel must stay in sync. Mobile UX must be usable on a 375px viewport.
|
|
||||||
6. **Print/PDF export must be tested after CSS changes.** Print CSS lives in a separate file but is sensitive to component class changes.
|
|
||||||
7. **No framework or build-tool migration.** This is vanilla JS by design.
|
|
||||||
8. **No broad rewrites.** Surgical, approved changes only.
|
|
||||||
9. **Sections IV–VI remain deferred** unless explicitly reopened.
|
|
||||||
10. **Read before editing.** Always inspect the current code before making changes.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## BETA WORK PRIORITIES
|
|
||||||
|
|
||||||
Work in this order unless directed otherwise. Each priority includes UX, code, and QA dimensions.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 1 — Visual Design System Audit & Elevation
|
|
||||||
|
|
||||||
**Goal:** Achieve visual cohesion and professional polish across all themes that rivals a SaaS product.
|
|
||||||
|
|
||||||
**UI/UX Audit Checklist:**
|
|
||||||
- [ ] Typography hierarchy — Is Cinzel/Poppins/Lato used consistently? Are font sizes, weights, and line-heights harmonious across sections?
|
|
||||||
- [ ] Spacing system — Is padding/margin using tokens consistently? Are section cards visually balanced?
|
|
||||||
- [ ] Color usage — Are `--accent`, `--green`, `--amber`, `--muted` used purposefully, not decoratively?
|
|
||||||
- [ ] Interactive states — Do all buttons, inputs, toggles, and checkboxes have clear hover/focus/active states in all three themes?
|
|
||||||
- [ ] Card hierarchy — Is there a clear visual distinction between level-1 containers, level-2 cards, and level-3 controls?
|
|
||||||
- [ ] Icon consistency — Are Font Awesome icons used at consistent sizes, weights, and optical alignment?
|
|
||||||
- [ ] Section header design — Are the numbered section headers (I, II, III) visually strong and scannable?
|
|
||||||
- [ ] Sidebar layout — Does the sidebar feel like a polished financial summary panel, not a DOM dump?
|
|
||||||
- [ ] Progress bars — Are the progress bars in Section I legible and purposeful?
|
|
||||||
- [ ] Nudge panel — Does the nudge carousel feel like a smart sales assistant, not a popup?
|
|
||||||
|
|
||||||
**CSS Architecture Health:**
|
|
||||||
- [ ] Are there redundant/conflicting rules in `components.css` vs `responsive.css`?
|
|
||||||
- [ ] Are design tokens being used everywhere they should be, or are magic numbers scattered?
|
|
||||||
- [ ] Is the Glass theme consistent and not broken at any viewport?
|
|
||||||
- [ ] Is the Light theme soft and readable without feeling washed out?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 2 — Interaction Design & UX Flow
|
|
||||||
|
|
||||||
**Goal:** The tool should feel intuitive, responsive, and professionally crafted to a prospect sitting across the table.
|
|
||||||
|
|
||||||
**Interaction Audit:**
|
|
||||||
- [ ] **Onboarding flow clarity** — When a user opens the tool fresh, is the first action obvious?
|
|
||||||
- [ ] **Section collapse/expand** — Is the animation smooth? Are collapsed section summaries accurate and helpful?
|
|
||||||
- [ ] **Add-on toggle behavior** — Does toggling add-ons give clear feedback (visual state + sidebar update)?
|
|
||||||
- [ ] **Stepper inputs** — Do +/- steppers feel snappy? Is there clear min/max clamping behavior?
|
|
||||||
- [ ] **Contract term selection** — Is the 3-option selector clearly communicating the discount impact?
|
|
||||||
- [ ] **Onboarding fee override** — Is the manual override UX clear (placeholder, lock icon, restore-to-auto)?
|
|
||||||
- [ ] **Admin fee waiver** — Is the waiver checkbox prominent enough? Is the consequence visible immediately?
|
|
||||||
- [ ] **Sidebar update speed** — Is the live update fast enough to feel real-time?
|
|
||||||
- [ ] **Nudge carousel** — Is the 30-second rotation appropriate? Does it feel helpful or distracting?
|
|
||||||
- [ ] **Theme toggle** — Is the toggle clearly labeled for current/next state? Is the transition smooth?
|
|
||||||
- [ ] **Reset confirmation modal** — Is it clear what gets destroyed? Is the secondary action (cancel) prominent?
|
|
||||||
- [ ] **Export buttons** — Are Print and JSON export clearly labeled and discoverable?
|
|
||||||
|
|
||||||
**Keyboard & Accessibility:**
|
|
||||||
- [ ] All interactive elements reachable via Tab in logical order
|
|
||||||
- [ ] Focus ring visible in all themes
|
|
||||||
- [ ] ARIA labels accurate and present on all form controls
|
|
||||||
- [ ] Color contrast ratios pass WCAG AA in Light theme (most at-risk)
|
|
||||||
- [ ] Screen reader order matches visual order
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 3 — Responsive Design Hardening
|
|
||||||
|
|
||||||
**Goal:** The layout should feel elastically fluid at every breakpoint, not brittle or hacked together.
|
|
||||||
|
|
||||||
**Breakpoint Audit:**
|
|
||||||
- [ ] 1800px+ — Does the max-width container feel appropriately constrained?
|
|
||||||
- [ ] 1400-1800px — Desktop sweet spot. Is the 3:2 main/sidebar split balanced?
|
|
||||||
- [ ] 1100-1400px — Narrower desktop. Do section cards reflow without overlapping?
|
|
||||||
- [ ] 780-1100px — Tablet. Does the layout gracefully switch to sidebar-as-panel?
|
|
||||||
- [ ] 480-780px — Mobile-landscape/small tablet. Single column, all controls accessible?
|
|
||||||
- [ ] 375-480px — Small mobile. Is the floating MRR pill positioned correctly? Does the bottom sheet open cleanly?
|
|
||||||
- [ ] 320px — Edge case. Does anything catastrophically break?
|
|
||||||
|
|
||||||
**Responsive Rules:**
|
|
||||||
- Prefer `clamp()`, container queries, and token-based adjustments over stacked `@media` hacks
|
|
||||||
- Section cards should never clip or overflow their container
|
|
||||||
- Contract/onboarding settings must adapt before content gets squeezed
|
|
||||||
- Touch targets must be ≥44px on mobile
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 4 — Quote Engine & Business Logic Verification
|
|
||||||
|
|
||||||
**Goal:** Every line-item and total in the sidebar is mathematically correct and matches what the invoice shows.
|
|
||||||
|
|
||||||
**Verification Matrix (test each combination):**
|
|
||||||
|
|
||||||
| Test | What to Verify |
|
|
||||||
|------|---------------|
|
|
||||||
| 0 users, 1 endpoint | Admin fee floor triggers correctly |
|
|
||||||
| 5 users M365, 3 endpoints, no add-ons | Base MRR matches manual calculation |
|
|
||||||
| 5 users BYOL + 1Password + Zero Trust | Add-on stacking is correct |
|
|
||||||
| 12-month term | 3% discount applied to base MRR only (not admin or HST) |
|
|
||||||
| 24-month term | 5% discount; onboarding auto-waived |
|
|
||||||
| Manual onboarding override | Auto-calc disabled; manual value preserved on save/restore |
|
|
||||||
| HST toggle | 13% applied only to MRR+onboarding (not before); first invoice total correct |
|
|
||||||
| Admin fee waiver | Admin fee = $0; "Value Unlocked" reflects waived amount |
|
|
||||||
| VoIP Basic 3 seats + 2 desk phones | VoIP cost correct; eFax add-on stacks |
|
|
||||||
| Full configuration (all add-ons, 24mo, HST) | All components sum correctly; no double-counting |
|
|
||||||
| Save → Reload | All values restore exactly; no drift |
|
|
||||||
| Export JSON → parse | All keys present; math cross-checks against UI |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 5 — Mobile Experience Completeness
|
|
||||||
|
|
||||||
**Goal:** A salesperson can hand their phone to a prospect and the quote tool is fully usable.
|
|
||||||
|
|
||||||
**Mobile Audit:**
|
|
||||||
- [ ] Floating MRR pill — correct value, correct position, visible in all themes
|
|
||||||
- [ ] Bottom sheet panel opens smoothly (slide-up animation clean)
|
|
||||||
- [ ] Scroll lock applied correctly when panel open (body doesn't scroll behind)
|
|
||||||
- [ ] All sidebar elements clone correctly into mobile panel (100+ pairs)
|
|
||||||
- [ ] HST toggle syncs bidirectionally (desktop ↔ mobile)
|
|
||||||
- [ ] Quote values in mobile panel match desktop exactly
|
|
||||||
- [ ] Close gestures (× button, Escape key, backdrop tap) all work
|
|
||||||
- [ ] Print/Export buttons accessible from mobile panel
|
|
||||||
- [ ] No clipped text or overflowing elements in mobile panel
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 6 — Print/PDF Invoice Quality
|
|
||||||
|
|
||||||
**Goal:** The printed invoice looks like it came from a professional MSP's billing system, not an HTML form.
|
|
||||||
|
|
||||||
**Print Audit:**
|
|
||||||
- [ ] Logo renders correctly (embedded SVG, not broken)
|
|
||||||
- [ ] Client name, quote ref, and date are on every page header
|
|
||||||
- [ ] All line items appear with correct labels and amounts
|
|
||||||
- [ ] Feature checklist is legible and cleanly formatted
|
|
||||||
- [ ] Totals section is visually prominent
|
|
||||||
- [ ] Value unlocked section is formatted correctly
|
|
||||||
- [ ] Comparison (vs. in-house IT) is present and readable
|
|
||||||
- [ ] No phantom scrollbars or UI chrome bleeds into print
|
|
||||||
- [ ] Page breaks don't split line-item rows awkwardly
|
|
||||||
- [ ] Fonts render in print (or fallback gracefully)
|
|
||||||
- [ ] All themes produce same print output (print CSS is theme-independent)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 7 — Sections IV–VI: Beta-Ready Scaffolding
|
|
||||||
|
|
||||||
**Goal:** Even if Sections IV–VI remain content-gated, their code, UX framework, and CSS should be clean enough to activate with minimal effort.
|
|
||||||
|
|
||||||
**Audit:**
|
|
||||||
- [ ] Section IV (Zero Trust Networking) — Is the HTML structure complete? Are inputs wired to `readFormState()`? Does the engine include ZT costs?
|
|
||||||
- [ ] Section V (VoIP/UCaaS) — Are all 3 tier selectors functional? Desk phone HaaS wired? eFax add-on wired? Savings comparison functional?
|
|
||||||
- [ ] Section VI — Is it a clean placeholder with no broken references?
|
|
||||||
- [ ] Deferred section CSS — Are styles isolated so activating them doesn't cause layout contamination?
|
|
||||||
- [ ] Quote engine — Does it calculate ZT/VoIP costs when those inputs are present, even if sections are hidden?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PRIORITY 8 — Code Quality & Documentation Sync
|
|
||||||
|
|
||||||
**Goal:** Any engineer should be able to pick up this codebase in 10 minutes and understand what's happening.
|
|
||||||
|
|
||||||
**Code Quality Checklist:**
|
|
||||||
- [ ] No dead code in active modules (check for unused functions, unreachable branches)
|
|
||||||
- [ ] No magic numbers — pricing constants should reference `DEFAULTS` keys, not hardcoded values
|
|
||||||
- [ ] No duplicate logic between `quote-engine.js` and `quote-render.js`
|
|
||||||
- [ ] `mobile-sync.js` sync map is clean — no stale ID pairs for removed elements
|
|
||||||
- [ ] CSS custom properties used consistently — no redundant fallback values where tokens are sufficient
|
|
||||||
- [ ] `quote-export.js` HTML template is clean — no CSS class references that no longer exist
|
|
||||||
- [ ] `SVS-MSP-Calculator.js` `update()` function is linear and readable — no side effects that aren't obvious
|
|
||||||
|
|
||||||
**Documentation Sync:**
|
|
||||||
- [ ] `docs/README.md` reflects current file structure and phase status
|
|
||||||
- [ ] `docs/code-verification.md` has been updated with latest known-good state
|
|
||||||
- [ ] `docs/regression-checklist.md` covers all active sections and export paths
|
|
||||||
- [ ] `docs/quote-rules.md` reflects current pricing and business rule implementation
|
|
||||||
- [ ] `docs/phase-roadmap.md` is updated to reflect beta completion criteria
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## WORKING PROTOCOL FOR THIS SESSION
|
|
||||||
|
|
||||||
### Before Making Any Change
|
|
||||||
1. Read the relevant file(s) first — do not edit from memory
|
|
||||||
2. Identify the minimal change that achieves the goal
|
|
||||||
3. Check if the change touches any of the regression hotspots (see below)
|
|
||||||
4. Confirm the change won't break mobile sync, theme cascade, or persistence
|
|
||||||
|
|
||||||
### Regression Hotspots — Extra Caution Required
|
|
||||||
| Area | Risk | Why |
|
|
||||||
|------|------|-----|
|
|
||||||
| `quote-engine.js` math | Critical | Business-critical; errors generate wrong quotes in real sales calls |
|
|
||||||
| localStorage round-trip | High | Silent failures; user loses configured quote |
|
|
||||||
| Mobile sync ID map | High | 100+ pairs; silently desyncs if IDs change |
|
|
||||||
| Print/PDF CSS | Medium | Separate cascade; component class changes cascade here |
|
|
||||||
| Theme switching | Medium | All four themes affected by token/component changes |
|
|
||||||
| `update()` call chain | Medium | Side effects in render sequence can cascade silently |
|
|
||||||
|
|
||||||
### After Making Changes
|
|
||||||
1. Verify syntax (especially JS — no console errors on load)
|
|
||||||
2. Check all three themes render correctly
|
|
||||||
3. Check mobile panel renders correctly at ≤780px
|
|
||||||
4. Verify sidebar totals are mathematically correct for a test quote
|
|
||||||
5. If CSS touched: verify print output is unaffected
|
|
||||||
6. Update `docs/code-verification.md` if a known-good state changes
|
|
||||||
|
|
||||||
### Commit Protocol
|
|
||||||
- Commits should be small and focused (one concern per commit)
|
|
||||||
- Commit messages should state what changed and why (not just "fix css")
|
|
||||||
- Do not combine unrelated changes in one commit
|
|
||||||
- Do not commit `.bak-focusmode` files
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## UX/UI DESIGN PRINCIPLES FOR THIS PROJECT
|
|
||||||
|
|
||||||
These principles guide every UI decision:
|
|
||||||
|
|
||||||
1. **Sales clarity over visual novelty.** If a prospect can't read a number at a glance, the design failed.
|
|
||||||
2. **Trust through polish.** A janky tooltip or misaligned input erodes prospect confidence. Every pixel matters.
|
|
||||||
3. **Progressive disclosure.** Lead with the total MRR. Let detail unfold as needed (collapsed sections, sidebar).
|
|
||||||
4. **Reduce cognitive load.** Group related controls. Use spacing and color to indicate hierarchy, not decoration.
|
|
||||||
5. **Feedback immediacy.** Every input change must visibly update the sidebar within 1 frame. No lag.
|
|
||||||
6. **Consistency as reliability.** Spacing, typography, and color behavior should be predictable. Surprises feel like bugs.
|
|
||||||
7. **Dark theme is the flagship.** Light and Glass must meet the same bar. No theme should feel like a degraded experience.
|
|
||||||
8. **Mobile is a first-class use case.** A sales rep on a tablet or phone must be able to run a full quote.
|
|
||||||
9. **The sidebar is the hero.** It's where the value proposition lives. Design it with the weight of a financial summary.
|
|
||||||
10. **Copy is UI.** Labels, nudges, section headers, and button text are all UX. Make them purposeful and confident.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FILE READ ORDER FOR NEW SESSIONS
|
|
||||||
|
|
||||||
To resume efficiently, read in this order:
|
|
||||||
1. `docs/README.md` — current project state
|
|
||||||
2. `docs/phase-roadmap.md` — approved work and constraints
|
|
||||||
3. `docs/code-verification.md` — known-good baseline
|
|
||||||
4. `docs/MASTER-SESSION-PROMPT.md` — this file (if not already loaded)
|
|
||||||
5. Then only the source files relevant to the specific task
|
|
||||||
|
|
||||||
For business logic questions: `docs/quote-rules.md`
|
|
||||||
For manual QA: `docs/regression-checklist.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## BETA DEFINITION OF DONE
|
|
||||||
|
|
||||||
The build is ready to call "beta" when:
|
|
||||||
|
|
||||||
- [ ] All Sections I–III are visually polished and functionally complete
|
|
||||||
- [ ] All three themes pass a full visual review at all major breakpoints
|
|
||||||
- [ ] Print/PDF invoice is clean and professionally branded
|
|
||||||
- [ ] Mobile panel is fully synced and usable at 375px
|
|
||||||
- [ ] Quote math passes all combinations in the verification matrix
|
|
||||||
- [ ] localStorage save/restore is tested and clean
|
|
||||||
- [ ] JSON export is valid and complete
|
|
||||||
- [ ] All nudges fire correctly for their trigger conditions
|
|
||||||
- [ ] Section collapse/expand summaries are accurate
|
|
||||||
- [ ] Comparison (vs. in-house IT) and VoIP savings panels show correct values
|
|
||||||
- [ ] No console errors on fresh load in any theme
|
|
||||||
- [ ] All docs are updated and accurate
|
|
||||||
- [ ] Sections IV–VI are scaffolded cleanly, ready to activate on demand
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*This document is the canonical session brief for the SVS MSP CALC beta push. Update it when constraints, priorities, or decisions change.*
|
|
||||||
@@ -1,86 +1,67 @@
|
|||||||
# Session Handoff — SVS MSP CALC
|
# Session Handoff — SVS MSP CALC
|
||||||
|
|
||||||
**Last updated:** 2026-03-16
|
**Last updated:** 2026-03-18
|
||||||
**Session:** Spacing Token Consolidation + Docs Cleanup + Phase 4-6 Research
|
**Session:** Sidebar UX Polish + Readability Pass
|
||||||
**Status:** COMMITTED — token consolidation + docs cleanup merged. Phase 4-6 research complete, design not started.
|
**Status:** Sidebar dividers unified, letter-spacing improved, contrast & font floor applied. Committed.
|
||||||
**Tests:** 254/254 passing
|
**Tests:** 254/254 passing
|
||||||
|
|
||||||
## What Was Done This Session
|
## Current State
|
||||||
|
|
||||||
### Spacing Token Consolidation (Phases 1-3) — COMMITTED
|
### What's Committed
|
||||||
Commit `786a850`: `css: tokenize borders, spacing, and radii — spacing audit pass 4`
|
- **Sidebar divider unification** — one `--sidebar-rule` token + `dashed` style everywhere. Old tokens removed: `--sidebar-line-rule`, `--sidebar-line-rule-style`, `--sidebar-total-rule`, `--sidebar-total-rule-style`
|
||||||
- Phase 1: border widths (76 replacements), Phase 2: spacing tokens (18), Phase 3: border-radius (16)
|
- **Total line scoped** — border-top only on `.sidebar-group--monthly .sidebar-line-total`, removed from invoice/value/summary
|
||||||
- 110 replacements + 7 new tokens across 7 CSS files
|
- **Letter-spacing token** — `--text-spacing-money: 0.05em` (was hardcoded 0.02em), applied to `.val`, `.sl-sub`, `.suffix-mo`
|
||||||
- Playwright verified: 9 screenshots (3 themes x 3 viewports) — zero regressions
|
- **Font size floor** — 6 locations bumped from 8px/10px/0.625rem → 0.6875rem (11px min)
|
||||||
|
- **Muted contrast improved** — Dark `#9e9588`→`#b0a99f` (6.6:1), Light `#6a6157`→`#554e46` (6.5:1)
|
||||||
|
- **Opacity cleanup** — removed opacity from 9 text elements that were double-muting with `--muted`
|
||||||
|
- **Sidebar fine-print line-height** — `.vs-footnote` 1.75, `.sidebar-note-mono` 1.65, responsive 1.7
|
||||||
|
|
||||||
### Docs Cleanup — COMMITTED
|
### What's NOT Committed (still modified)
|
||||||
Commit `a42ce66`: removed 11 outdated files (1,480 lines)
|
- `CLAUDE.md` — updated from beta
|
||||||
- 8 STAGE*-SESSION-PROMPT.md files, ai-session-brief.md, code-verification.md, phase-roadmap.md
|
- `CLAUDE-nextsteps.md` — resume guide
|
||||||
- Updated QUICK-REF.md directory listing
|
- `docs/SESSION-HANDOFF.md` — this file
|
||||||
|
- `.claude/` config files, `.mcp.json`
|
||||||
|
- Various screenshot PNGs (can be cleaned up)
|
||||||
|
- Deleted docs: `CHECKPOINT.md`, `MASTER-SESSION-PROMPT.md`, `regression-checklist.md`
|
||||||
|
|
||||||
### Phase 4-6 Research — NOT COMMITTED (findings below)
|
### Accesslint Contrast Audit Results
|
||||||
Deep exploration of remaining token consolidation + sidebar UX issues. Ready to brainstorm into design.
|
All sidebar text passes WCAG AA across all 3 themes:
|
||||||
|
| Theme | Weakest Pair | Ratio |
|
||||||
|
|-------|-------------|-------|
|
||||||
|
| Dark | muted on card | 6.64:1 |
|
||||||
|
| Light | muted on sidebar-body | 6.54:1 |
|
||||||
|
| Glass | muted on card | 8.73:1 |
|
||||||
|
|
||||||
## Research Findings: Remaining Token Consolidation (Phases 4-6)
|
## What's Next
|
||||||
|
|
||||||
### Phase 4: Icon/Button Sizing (~12 locations)
|
### Priority 1: Google Fonts (approved, max 3)
|
||||||
Hardcoded icon/button sizes scattered across components.css:
|
- Google Fonts are on the table — user approved up to 3 (prefer), 4 hard cap
|
||||||
- 14px (export icon), 15px (sidebar icon), 16px (nudge nav), 18px (addon checkbox)
|
- Currently using: Poppins (hero numbers), DM Mono (values/mono), system sans-serif (body)
|
||||||
- 20px (HST toggle), 22px (M365 icon), 28px (mobile pill), 34px (chevron/toggle buttons)
|
- Explore: clean sans-serif for body/labels to improve readability at small sizes
|
||||||
- **Missing tokens:** `--icon-size-xs` through `--icon-size-xl`, `--control-icon-size`
|
- Consider: Inter, IBM Plex Sans, Source Sans 3, or similar
|
||||||
|
|
||||||
### Phase 5: Typography Scale (~36 locations)
|
### Priority 2: GUI Polish List A
|
||||||
**Letter-spacing (26+ occurrences, no tokens):**
|
- Contract Term pills — more vertical padding on unselected
|
||||||
- 0.02em (price values), 0.04em (meta labels), 0.06em (waive labels)
|
- Section card collapsed headers — slightly tight vertically
|
||||||
- 0.07em (badges/floor notes), 0.08em (buttons/badges), 0.1em (section titles)
|
- "MANAGED IT SERVICES (SECTIONS I, II, III)" label — low contrast
|
||||||
- 0.12em (labels/headings), 0.14em (nav), 0.18em (uppercase kickers), -0.02em (MRR hero)
|
- Insight carousel text — more line-height
|
||||||
- **Missing tokens:** `--text-spacing-tight/compact/normal/loose` etc.
|
- "QUOTE NOTES" label spacing — inconsistent with other section labels
|
||||||
|
|
||||||
**Font-size (hardcoded, not using tokens):**
|
### Priority 3: Typography Token Pass
|
||||||
- 8px (best value badge), 10px (mobile pill label), 12px (various labels)
|
- Tokenize remaining hardcoded letter-spacing values (~20 locations)
|
||||||
- 13px (sublabels), 14px (addon name, fee table), 15px (section meta)
|
- Tokenize hardcoded font-sizes not yet on tokens
|
||||||
- 16px (input label), 18px (sidebar hero responsive), 20px (modal icon)
|
- Move sidebar typography tokens from components.css to tokens.css
|
||||||
|
- Phase 4: icon/button sizing (~12 hardcoded values)
|
||||||
|
- Phase 6: responsive breakpoint font-sizes (optional)
|
||||||
|
|
||||||
**Sidebar typography tokens defined in components.css (should be in tokens.css):**
|
### Priority 4: Sections IV-VI Activation
|
||||||
- `--sidebar-copy-size`, `--sidebar-copy-line`, `--sidebar-note-size`, `--sidebar-mono-size`, `--sidebar-mrr-size` (components.css lines 1019-1023)
|
### Priority 5: Mobile Panel UX Enhancements
|
||||||
|
|
||||||
### Phase 6: Responsive Breakpoints (optional)
|
## Key References
|
||||||
Hardcoded responsive font-sizes in @media rules:
|
- Token file: `SVS-MSP-Calculator-tokens.css`
|
||||||
- 1.375rem, 1.125rem, 1.1rem (mobile text), 2.25rem/1.875rem (sidebar MRR at breakpoints)
|
- Sidebar styles: `SVS-MSP-Calculator-components.css`
|
||||||
- Could benefit from `--text-size-responsive-*` tokens
|
- Theme overrides: `SVS-MSP-Calculator-light.css`, `SVS-MSP-Calculator-glass.css`
|
||||||
|
- Tests: `node tests/test-quote-engine.js` — 254/254
|
||||||
## Research Findings: Sidebar UX Issues
|
|
||||||
|
|
||||||
### Divider/Line Inconsistency Across Themes
|
|
||||||
Sidebar divider tokens exist but values differ per theme:
|
|
||||||
- **Dark:** `color-mix(in srgb, var(--border) 88%, transparent)` — dashed
|
|
||||||
- **Light:** `color-mix(in srgb, var(--border) 70%, transparent)` — lighter
|
|
||||||
- **Glass:** `rgba(143, 183, 221, 0.12)` — very light
|
|
||||||
- **Risk:** Extra/mismatched horizontal lines visible on some themes. Needs Playwright visual audit.
|
|
||||||
|
|
||||||
### Price Value Letter-Spacing
|
|
||||||
- Current: `letter-spacing: 0.02em` on `.sidebar-line .val` (components.css ~line 1211)
|
|
||||||
- User feedback: prices ($x.xx) look "bunched" — needs more breathing room
|
|
||||||
- `font-variant-numeric: tabular-nums` IS applied globally (good)
|
|
||||||
- Consider bumping to 0.04em-0.06em and tokenizing as `--text-spacing-money`
|
|
||||||
|
|
||||||
### Sidebar Line Variants
|
|
||||||
| Element | Style | Notes |
|
|
||||||
|---------|-------|-------|
|
|
||||||
| `.sidebar-line` | dashed bottom border | Uses `--sidebar-line-rule-style` |
|
|
||||||
| `.sidebar-line-opportunity` | dotted | No token for line-style |
|
|
||||||
| `.sidebar-line-discount` | dashed, opacity 0.8 | Hardcoded opacity |
|
|
||||||
| `.sidebar-line-hst` | double top border | Uses token |
|
|
||||||
| `.sidebar-line-total` | solid top border | Uses `--sidebar-total-rule` (good) |
|
|
||||||
|
|
||||||
## Files Modified (this session)
|
|
||||||
|
|
||||||
| File | Change |
|
|
||||||
|------|--------|
|
|
||||||
| 7 CSS files | Token consolidation (committed) |
|
|
||||||
| 11 docs files | Deleted (committed) |
|
|
||||||
| `docs/QUICK-REF.md` | Updated directory listing (committed) |
|
|
||||||
| `docs/SESSION-HANDOFF.md` | Updated (committed) |
|
|
||||||
|
|
||||||
## Test Status
|
## Test Status
|
||||||
```
|
```
|
||||||
@@ -88,62 +69,18 @@ Sidebar divider tokens exist but values differ per theme:
|
|||||||
node tests/test-quote-engine.js
|
node tests/test-quote-engine.js
|
||||||
```
|
```
|
||||||
|
|
||||||
## What's Next
|
|
||||||
|
|
||||||
**Priority 1 (next session):** Sidebar UX fine-tune + Phase 4-6 token consolidation
|
|
||||||
- Brainstorm into design (was about to start — visual companion offered, user paused)
|
|
||||||
- Use `superpowers:brainstorming` → design spec → `superpowers:writing-plans`
|
|
||||||
- Dispatch UI/UX designer (Opus + ui-ux-pro-max) for sidebar line/spacing decisions
|
|
||||||
- Use Playwright MCP for visual comparison across themes
|
|
||||||
|
|
||||||
**Priority 2:** Sections IV-VI activation
|
|
||||||
**Priority 3:** Mobile panel UX enhancements
|
|
||||||
**Priority 4:** Beta readiness audit
|
|
||||||
|
|
||||||
## Continuation Prompt
|
## Continuation Prompt
|
||||||
|
|
||||||
```
|
```
|
||||||
Read docs/SESSION-HANDOFF.md then docs/QUICK-REF.md.
|
Read docs/SESSION-HANDOFF.md and CLAUDE-nextsteps.md.
|
||||||
3 themes: Dark, Light, Glass.
|
3 themes: Dark, Light, Glass.
|
||||||
254 tests must pass: node tests/test-quote-engine.js
|
254 tests must pass: node tests/test-quote-engine.js
|
||||||
|
|
||||||
## Resume Point: Sidebar UX Fine-Tune + Token Consolidation (Phases 4-6)
|
## Resume Point: Google Fonts + GUI Polish
|
||||||
|
|
||||||
Research is DONE (see SESSION-HANDOFF.md "Research Findings" sections).
|
Google Fonts approved (max 3). Currently: Poppins, DM Mono, system sans-serif.
|
||||||
Design has NOT started yet. Pick up at brainstorming.
|
Pick a body/label font, then continue with polish list A items.
|
||||||
|
|
||||||
### Two workstreams to combine into one design:
|
Use Playwright MCP for visual verification across all 3 themes.
|
||||||
|
Use accesslint for contrast checking on any color changes.
|
||||||
**1. Sidebar UX fine-tune (user-reported issues):**
|
|
||||||
- Extra horizontal lines in sidebar that don't match across Dark/Light/Glass themes
|
|
||||||
- Price values ($x.xx) look "bunched" — need more letter-spacing
|
|
||||||
- Divider opacity/color differs per theme (Dark 88%, Light 70%, Glass 12% rgba)
|
|
||||||
- Use Playwright MCP to screenshot sidebar across all 3 themes for visual comparison
|
|
||||||
- Dispatch UI/UX designer (Opus + ui-ux-pro-max skill) for design decisions
|
|
||||||
|
|
||||||
**2. Token consolidation Phases 4-6:**
|
|
||||||
- Phase 4: icon/button sizing (~12 hardcoded values → --icon-size-* tokens)
|
|
||||||
- Phase 5: typography scale (~36 locations — letter-spacing + font-size + move sidebar tokens to tokens.css)
|
|
||||||
- Phase 6: responsive breakpoints (optional — hardcoded rem values in @media)
|
|
||||||
|
|
||||||
### Action: Start with superpowers:brainstorming
|
|
||||||
- Project context: ALREADY EXPLORED (skip step 1 of brainstorming checklist)
|
|
||||||
- Offer visual companion (Playwright) — user was offered, hadn't accepted yet
|
|
||||||
- Then clarifying questions → approaches → design → spec → plan
|
|
||||||
|
|
||||||
## Key References
|
|
||||||
- Token file: SVS-MSP-Calculator-tokens.css
|
|
||||||
- Sidebar styles: SVS-MSP-Calculator-components.css (lines 1019-1023 sidebar tokens, 1183-1250 sidebar lines)
|
|
||||||
- Theme overrides: SVS-MSP-Calculator-light.css (lines 122-123), SVS-MSP-Calculator-glass.css (lines 194-195)
|
|
||||||
|
|
||||||
## Plugins Available — USE THEM
|
|
||||||
- **superpowers** — planning, subagent-driven development, parallel agents, TDD, debugging
|
|
||||||
- **ui-ux-pro-max** — design intelligence (palettes, typography, styles)
|
|
||||||
- **playwright** — visual verification in real browser
|
|
||||||
- **frontend-design**, **code-review**, **code-simplifier**
|
|
||||||
|
|
||||||
## Clear up DOCS folder
|
|
||||||
- clean up docs, remove old phases no longer under considertation, old instructions that no longer apply
|
|
||||||
|
|
||||||
Budget: stay under 60% context. Checkpoint before ending.
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
# Regression Checklist
|
|
||||||
|
|
||||||
Use this when a change could affect runtime behavior. It is not required reading for every session.
|
|
||||||
|
|
||||||
## Automated tests (run first)
|
|
||||||
|
|
||||||
```
|
|
||||||
node svsmspcalc/tests/test-quote-engine.js
|
|
||||||
```
|
|
||||||
|
|
||||||
This covers all core quote math, admin fee logic, discounts, HST, VoIP, ZT, and MRR integrity. If all 88 tests pass, the items marked **[AUTO]** below are verified.
|
|
||||||
|
|
||||||
## Core quote math
|
|
||||||
|
|
||||||
- **[AUTO]** Verify M365 Included and BYOL base rates
|
|
||||||
- **[AUTO]** Verify each user add-on changes MRR correctly
|
|
||||||
- **[AUTO]** Verify endpoint count affects endpoint pricing
|
|
||||||
- **[AUTO]** Verify server count affects server pricing
|
|
||||||
- **[AUTO]** Verify Zero Trust Networking seat and HaaS counts affect MRR correctly
|
|
||||||
- **[AUTO]** Verify VoIP tier changes pricing correctly
|
|
||||||
- **[AUTO]** Verify desk phone and eFax add-ons change pricing correctly
|
|
||||||
|
|
||||||
## Site admin fee
|
|
||||||
|
|
||||||
- **[AUTO]** Verify admin fee floor at low subtotal
|
|
||||||
- **[AUTO]** Verify admin fee reduces as base subtotal rises
|
|
||||||
- **[AUTO]** Verify admin fee stops reducing at the configured floor
|
|
||||||
- **[AUTO]** Verify Zero Trust supplement appears when Zero Trust is active
|
|
||||||
- **[AUTO]** Verify 1Password admin surcharge appears when 1Password is selected
|
|
||||||
- **[AUTO]** Verify admin fee waive excludes fee from MRR
|
|
||||||
- [MANUAL] Verify admin fee waive state updates all relevant displays
|
|
||||||
|
|
||||||
## Contract term and onboarding
|
|
||||||
|
|
||||||
- **[AUTO]** Verify month-to-month has no discount
|
|
||||||
- **[AUTO]** Verify 12-month applies 3% discount
|
|
||||||
- **[AUTO]** Verify 24-month applies 5% discount
|
|
||||||
- [MANUAL] Verify 12-month auto-waives onboarding
|
|
||||||
- [MANUAL] Verify 24-month auto-waives onboarding
|
|
||||||
- [MANUAL] Verify switching back to month-to-month restores editable onboarding behavior
|
|
||||||
- [MANUAL] Verify manual onboarding override persists until reset by waiver logic
|
|
||||||
|
|
||||||
## Tax and totals
|
|
||||||
|
|
||||||
- **[AUTO]** Verify HST toggle applies 13% to discounted MRR
|
|
||||||
- **[AUTO]** Verify HST disabled = $0
|
|
||||||
- **[AUTO]** Verify HST applied after contract discount (not before)
|
|
||||||
- **[AUTO]** Verify annual projection matches effective MRR * 12
|
|
||||||
- **[AUTO]** Verify per-user effective cost is 0 when users = 0
|
|
||||||
|
|
||||||
## Sidebar and mobile parity
|
|
||||||
|
|
||||||
- [MANUAL] Verify desktop sidebar values match configured quote
|
|
||||||
- [MANUAL] Verify mobile pill MRR matches headline MRR
|
|
||||||
- [MANUAL] Verify mobile panel content matches desktop sidebar
|
|
||||||
- [MANUAL] Verify mobile HST toggle syncs back to desktop state
|
|
||||||
- [MANUAL] Verify nudge banner content and state match on desktop and mobile
|
|
||||||
|
|
||||||
## Persistence and reset
|
|
||||||
|
|
||||||
- [MANUAL] Verify quote state restores after reload
|
|
||||||
- [MANUAL] Verify theme preference restores after reload
|
|
||||||
- [MANUAL] Verify quote reference persists within the intended window
|
|
||||||
- [MANUAL] Verify reset clears quote state
|
|
||||||
- [MANUAL] Verify reset preserves theme preference
|
|
||||||
|
|
||||||
## Export and print
|
|
||||||
|
|
||||||
- [MANUAL] Verify Print / Save PDF opens the formatted print view
|
|
||||||
- [MANUAL] Verify print respects user's HST toggle state
|
|
||||||
- [MANUAL] Verify print view uses the expected totals, discount, onboarding, and HST states
|
|
||||||
- [MANUAL] Verify JSON export downloads a file
|
|
||||||
- [MANUAL] Verify JSON export copies content to clipboard when supported
|
|
||||||
- [MANUAL] Verify JSON payload matches the visible quote configuration
|
|
||||||
- [MANUAL] Verify JSON export includes `"version": "1.0"` field
|
|
||||||
|
|
||||||
## Section header layout
|
|
||||||
|
|
||||||
- [MANUAL] Verify all 6 sections show numeral + title + chevron on row 1
|
|
||||||
- [MANUAL] Verify controls row (stepper + badge + price) on row 2
|
|
||||||
- [MANUAL] Verify subtitle appears on row 3 only when expanded
|
|
||||||
- [MANUAL] Verify small-screen stacking at ≤600px / container ≤520px
|
|
||||||
- [MANUAL] Verify all elements span full width when stacked
|
|
||||||
|
|
||||||
## UX interactions (Phase 3)
|
|
||||||
|
|
||||||
- [MANUAL] Verify theme switch transitions smoothly (no flash)
|
|
||||||
- [MANUAL] Verify nudge banner crossfades on rotation and manual nav
|
|
||||||
- [MANUAL] Verify section summary badge fades in on collapse
|
|
||||||
- [MANUAL] Verify addon row shows subtle pulse on toggle
|
|
||||||
- [MANUAL] Verify touch targets ≥44px at ≤600px (close btn, nudge nav, section toggles)
|
|
||||||
- [MANUAL] Verify mobile panel traps focus (Tab cycles within panel)
|
|
||||||
- [MANUAL] Verify focus returns to pill on panel close
|
|
||||||
- [MANUAL] Verify safe-area insets respected on notch phones (pill position, panel padding)
|
|
||||||
|
|
||||||
## Accessibility (Phase 5)
|
|
||||||
|
|
||||||
- [MANUAL] Verify `aria-expanded` toggles on section headers when opening/closing
|
|
||||||
- [MANUAL] Verify `aria-expanded` toggles on collapsible headers when opening/closing
|
|
||||||
- [MANUAL] Verify reset modal traps focus (Tab cycles within modal, cannot reach background)
|
|
||||||
- [MANUAL] Verify stepper buttons announce descriptive labels via screen reader
|
|
||||||
- [MANUAL] Verify Glass theme scrolls smoothly on mobile (no jank from fixed backgrounds)
|
|
||||||
- [MANUAL] Verify mobile panel gets full sync on open (client name, discount label visible)
|
|
||||||
- [MANUAL] Verify mobile sync skips on desktop when panel is closed (performance)
|
|
||||||
BIN
glass-theme-full.png
Normal file
|
After Width: | Height: | Size: 594 KiB |
BIN
light-theme-full.png
Normal file
|
After Width: | Height: | Size: 270 KiB |
BIN
sidebar-dark-after.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
sidebar-dark.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
sidebar-glass-after.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
sidebar-glass.png
Normal file
|
After Width: | Height: | Size: 216 KiB |
BIN
sidebar-light-after.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
sidebar-light.png
Normal file
|
After Width: | Height: | Size: 120 KiB |
BIN
sidebar-zones-dark.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
sidebar-zones-detail.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
this-is-the-area-with-extra-lines.png
Normal file
|
After Width: | Height: | Size: 29 KiB |