8.6 KiB
8.6 KiB
Quick Reference — SVS MSP CALC
Stack
Vanilla HTML5/CSS3/JS (ES5-compatible). No frameworks, no npm, no build tools. Open HTML in browser to run.
Project Status
Design & Sales Optimization: COMPLETE (2026-03-16)
- 22 tasks executed across 5 chunks
- 3 themes: Dark (flagship), Light, Glass — Retro removed
- 254 engine tests passing
- All responsive breakpoints verified
File Map
JS Runtime
| File | Purpose | Key Functions |
|---|---|---|
SVS-MSP-Calculator.js |
Orchestration, event binding | update(), calcQuote(), stepInput(), initQuote(), toggleSection() |
quote-engine.js |
Pure math (DO NOT TOUCH without tests) | calculateQuote(state, pricing), readFormState(), getPricingConfig() |
quote-pricing.js |
Pricing defaults (34 keys), JSON loader | getSnapshot(), globals |
quote-render.js |
DOM rendering + animated counters | renderSidebar(), animateValue(), setSummary(), renderNudge(), buildNudges() |
quote-persistence.js |
localStorage save/restore | saveState(), restoreState(), resetState() |
quote-export.js |
Print/PDF + JSON export | Respects HST toggle, schema v1.0 |
quote-import.js |
JSON import + schema migration | Additive migrations only |
theme-manager.js |
3-theme cycle + persistence | toggleTheme(), applyTheme(), initTheme() — cycle: Dark → Light → Glass |
mobile-sync.js |
Mobile panel dual-render | Clones sidebar, wraps update() for _m ID sync |
package-prices-data.js |
Pricing source (DO NOT MOVE) | Single source of truth for all rates |
CSS (load order via manifest SVS-MSP-Calculator.css)
| File | Purpose | Key Tokens/Classes |
|---|---|---|
*-tokens.css |
Design tokens — colors, spacing, radii, typography, shadows | --shadow-card/hover/open, --sidebar-zone-*, --text-money-hero |
*-base.css |
Resets, top bar chrome | Global typography |
*-layout.css |
Grid: .outer, .main-col, .side-col |
Section gap: clamp(12px, 1.2vw, 20px) |
*-components.css |
Sections, steppers, badges, sidebar, VS table, pitch bar | .sec-active, .suffix-mo, stepper-pulse keyframe, tabular-nums |
*-responsive.css |
Breakpoints: 1920+, ≤1350, ≤1100, ≤900, ≤600, 780L | Mobile: sidebar hidden, floating MRR badge |
*-print.css |
Print overrides | Strips shadows, animations, forces expand |
*-light.css |
Light theme token overrides | Softer shadows, inverted zone tints |
*-glass.css |
Glass theme (frosted blur) | Stronger shadows, translucent backgrounds |
HTML Structure (section display order)
| Order | ID | Numeral | Title | Has Stepper |
|---|---|---|---|---|
| 1 | sec-02 | I | User Package | userCount |
| 2 | sec-03 | II | Endpoint Package | endpointCount |
| 3 | sec-01 | III | Site Management | — (badges only) |
| 4 | sec-04 | IV | Server Management | serverCount |
| 5 | sec-05 | V | Zero Trust Networking (HaaS) | ztNetSeats |
| 6 | sec-06 | VI | VoIP / Unified Communications (UCaaS) | voipSeats |
Key DOM IDs (do not rename — mobile sync depends on these)
- Inputs:
userCount,endpointCount,serverCount,ztNetSeats,ztNetRouters,voipSeats - Summaries:
sec01-summarythroughsec06-summary - Admin:
adminFeeDisplay,adminWaived,feeBreakdown - Sidebar values:
sl-users-val,sl-endpoints-val,sl-servers-val,sl-zt-val,sl-voip-val - Hero:
mrrDisplay,annualDisplay,sl-monthly-total-val - Progress:
floorBar,floorNote
Design System (post-optimization)
Animations
| Animation | Duration | Trigger | Implementation |
|---|---|---|---|
| Number counter (sidebar + badges) | 350ms ease-out | Value change | animateValue() in quote-render.js |
| Stepper pulse | 150ms ease-out | +/- click | CSS @keyframes stepper-pulse + .pulse class in JS |
| Section expand/collapse | ~250ms | Click header | JS animateSection() + CSS height/opacity |
| Chevron rotate | --transition-medium |
Section toggle | CSS transform: rotate(180deg) on .sec-open |
| Sidebar line hover | --transition-fast |
Mouse hover | CSS border-left accent + padding shift |
| Progress bar | 300ms ease-out | Value change | CSS transition: width on .progress-fill |
| Term tile selection | 200ms ease | Click tile | CSS transitions on .tier-seg |
Typography Hierarchy
- Bold (700-800): Section titles, hero MRI number, monthly total value
- Semi-bold (600): Sidebar
.valamounts, line item labels - Medium (500):
.sidebar-group-title, uppercase labels - Regular (400): Descriptions, subtitles, meta text
Shadow Tokens (per theme)
--shadow-card— base elevation on.section--shadow-card-hover— combined with--section-hover-shadow(left accent glow)--shadow-card-open— combined with--section-open-shadow(stronger glow)
Active Section System
.sec-activeclass toggled inupdate()based on section count > 0- CSS: 3px left accent border via
color-mix(in srgb, var(--accent) 50%, transparent) .sec-active .section-num— numeral turns accent-blue
Sidebar Zones
.sidebar-group--monthly— rounded container,--sidebar-zone-servicestint.sidebar-group--invoice—--sidebar-zone-invoicetint.sidebar-group--value— green-tinted--sidebar-zone-value.sidebar-line:hover— accent border slides in left, background tints blue
Pricing Defaults (from quote-pricing.js)
Users: M365 $140 (m2m) / $130 (annual) | BYOL $110 | ExtHrs +$25 | 1PWM +$9 | INKY +$8 | ZT +$55
Endpoints: $35/ea | USB +$4 | BMB +$25
Servers: $120/ea
ZT Net: $25/seat | $100/router
Admin: Floor $150 | Threshold $650 | ZT +$250 | 1PWM 10%
VoIP: Basic $28 | Standard $35 | Premium $45 | Phone +$15 | Fax +$10
Discounts: m2m 0% | 12mo 3% + 50% off onboarding | 24mo 5% + complimentary onboarding
HST: 13% (Ontario)
Tests
node svsmspcalc/tests/test-quote-engine.js
254 tests, zero dependencies. Run after any pricing/engine/render changes.
Danger Zones
- DOM IDs → mobile sync breaks silently if renamed
quote-engine.jsmath → run tests after any change- Print CSS → sensitive to component class changes
update()call chain → side effects cascade (calcQuote → render → sidebar → nudges → summaries → sec-active toggle → save)- localStorage key:
svs-msp-quote-v1 animateValue()targets both desktop element AND_mmobile clone.suffix-mospan inside monthly total value — set viainnerHTMLnottextContent
Directory Layout
svsmspcalc/
├── SVS-MSP-Calculator.html # Main HTML shell
├── SVS-MSP-Calculator.css # CSS import manifest
├── SVS-MSP-Calculator.js # Orchestration + event binding
├── SVS-MSP-Calculator-tokens.css # Design tokens (shadows, zones, colors)
├── SVS-MSP-Calculator-base.css # Resets, typography
├── SVS-MSP-Calculator-layout.css # Grid system, section gap
├── SVS-MSP-Calculator-components.css # All UI components (~2100 lines)
├── SVS-MSP-Calculator-responsive.css # Breakpoints
├── SVS-MSP-Calculator-print.css # Print overrides
├── SVS-MSP-Calculator-light.css # Light theme overrides
├── SVS-MSP-Calculator-glass.css # Glass theme overrides
├── quote-engine.js # Pure math (254 tests)
├── quote-render.js # Rendering + animateValue()
├── quote-pricing.js # Pricing config
├── quote-persistence.js # localStorage
├── quote-export.js # Print/PDF + JSON export
├── quote-import.js # JSON import + migration
├── theme-manager.js # 3-theme cycle
├── mobile-sync.js # Mobile dual-render
├── package-prices-data.js # PRICING SOURCE
├── M365icons/ # Microsoft 365 icons
├── fontawesomekit/ # Font Awesome icons
├── pre-alpha/ # READ-ONLY archived reference
├── tests/
│ └── test-quote-engine.js # 254 engine tests
└── docs/
├── QUICK-REF.md # THIS FILE — architecture + file map
├── SESSION-HANDOFF.md # Current status + next steps
├── CHECKPOINT.md # Historical checkpoint
├── MASTER-SESSION-PROMPT.md # Master rebuild prompt
├── STAGE3-11 prompts # Historical stage prompts
├── quote-rules.md # Business logic rules
└── regression-checklist.md # QA checklist