Files
svsmspcalc/SVS-MSP-Calculator-tokens.css
John OReilly 4c53af96a9 style: sidebar UX polish — unified dividers, letter-spacing, contrast, font floor
- Unify sidebar dividers: one dashed style + --sidebar-rule token (replaces 4 old tokens)
- Remove total-line border from invoice/value/summary groups (keep monthly only)
- Add --text-spacing-money: 0.05em token (was hardcoded 0.02em) for price readability
- Bump 6 font sizes from 8-10px to 0.6875rem (11px minimum floor)
- Darken --muted: Dark #9e9588→#b0a99f (6.6:1), Light #6a6157→#554e46 (6.5:1)
- Remove opacity on 9 text elements that were double-muting with --muted color
- Normalize divider weight across themes: Dark/Light 75%, Glass 0.16

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:35:31 -04:00

286 lines
13 KiB
CSS

/* SVS MSP Calculator - Tokens */
/* Extracted during Phase 5 to keep the HTML shell stable while splitting the monolithic stylesheet. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* ── THEME TRANSITION ─────────────────────────────────────────
Brief color fade when switching themes so the swap feels smooth
instead of a jarring flash. Applied to body so it cascades.
transition-duration kept short (0.25s) to feel snappy.
─────────────────────────────────────────────────────────────── */
body.theme-transitioning,
body.theme-transitioning *,
body.theme-transitioning *::before,
body.theme-transitioning *::after {
transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease !important;
}
/* ── FOCUS VISIBLE ──────────────────────────────────────────────
Single rule covers all interactive elements — native inputs,
custom div toggles (section headers, collapsible headers),
addon rows, tier segments, and the theme toggle button.
Uses :focus-visible so mouse clicks don't show the ring.
─────────────────────────────────────────────────────────────── */
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* Suppress the default outline on elements we've styled explicitly */
.num-input:focus-visible,
.client-input:focus-visible,
.qs-fee-input:focus-visible,
.savings-input-row input:focus-visible {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 2px var(--focus-ring-soft);
}
/* ── DESIGN TOKENS ─────────────────────────────────────────────
Single source of truth for all colours. Edit here, not inline.
─────────────────────────────────────────────────────────────── */
html {
font-size: calc(16px * var(--font-scale, 1));
}
:root {
--font-scale: 1.03;
--page-max-width: clamp(1200px, 92vw, 2400px);
--page-gutter-x: clamp(16px, 3vw, 80px);
--layout-main-col: minmax(0, 3fr);
--layout-side-col: minmax(360px, 2fr);
--layout-column-gap: clamp(24px, 3vw, 56px);
--section-offset: clamp(52px, 7vw, 104px);
--section-num-width: clamp(44px, 5.5vw, 84px);
--section-num-size: clamp(2.625rem, 3.4vw, 4.125rem);
--section-padding-x: clamp(18px, 2.5vw, 40px);
--section-padding-top: clamp(20px, 2vw, 28px);
--section-padding-bottom: clamp(24px, 2.2vw, 32px);
--space-xs: 4px;
--space-sm: 8px;
--space-stack-tight: 10px;
--space-md: 12px;
--space-stack: 14px;
--space-stack-roomy: 16px;
--space-lg: 18px;
--space-xl: 20px;
--space-2xl: 24px;
--space-3xl: 28px;
--space-4xl: 32px;
--border-thin: 1px;
--border-medium: 2px;
--border-thick: 3px;
--radius-sm: 4px;
--radius-control: 6px;
--radius-md: 8px;
--radius-lg: 10px;
--radius-card: 12px;
--radius-pill: 999px;
--control-min-height: 46px;
--control-pad-y: 10px;
--control-pad-x: 16px;
--control-pad-y-tight: 6px;
--control-pad-x-tight: 10px;
--content-measure: 68ch;
--text-body-size: 1.03125rem;
--text-body-line: 1.72;
--text-meta-size: 0.75rem;
--text-label-size: 0.75rem;
--text-copy-size: 0.9375rem;
--text-copy-line: 1.76;
--text-compact-line: 1.58;
--text-title-line: 1.24;
--text-spacing-money: 0.05em;
--ink: #e8e3da; /* warm beige-white — brighter for legibility */
--paper: #1c1a17; /* darker base — widens gap vs card for panel float */
--accent: #3d8aba; /* lifted blue — pops on dark backgrounds */
--muted: #b0a99f; /* softer secondary — clearly subordinate but readable (6.6:1) */
--border: #35322c; /* subtler dividers */
--border-soft: var(--border);
--card: #272420; /* elevated surface — clear separation from paper */
--green: #3ab870;
--amber: #e8920f;
--sky: #38bdf8;
--transition-fast: 0.15s;
--transition-medium: 0.25s;
--focus-ring-soft: rgba(45,122,168,0.25);
--top-bar-bg: var(--ink);
--top-bar-border: var(--accent);
--top-bar-meta: var(--muted);
--top-bar-shadow: 0 10px 24px rgba(0,0,0,0.08);
--theme-chip-bg: rgba(0, 0, 0, 0.1);
--theme-chip-hover: rgba(0, 0, 0, 0.17);
--theme-chip-active: rgba(0, 0, 0, 0.23);
--theme-chip-fg: #3a3632;
--theme-chip-border: transparent;
--theme-chip-shadow: none;
--surface-section: var(--card);
--surface-feature: var(--card);
--surface-settings: var(--card);
--surface-settings-divider: var(--border);
--surface-input: var(--card);
--surface-term-wrap: var(--surface-input);
--surface-term-tile: transparent;
--surface-term-tile-hover: var(--surface-accent-soft);
--surface-term-tile-active: linear-gradient(180deg, color-mix(in srgb, var(--accent) 60%, white 12%), color-mix(in srgb, var(--accent) 72%, black 28%));
--border-term-wrap: var(--border);
--border-term-tile-active: transparent;
--shadow-term-wrap: inset 0 1px 0 color-mix(in srgb, var(--ink) 5%, transparent);
--shadow-term-tile-active: inset 0 1px 0 color-mix(in srgb, white 14%, transparent);
--text-term-name: var(--muted);
--text-term-name-active: var(--text-on-accent);
--text-term-sub: var(--muted);
--text-term-sub-active: var(--text-on-accent-strong);
--text-term-discount: color-mix(in srgb, var(--ink) 84%, var(--muted));
--text-term-discount-active: #ffffff;
--surface-best-value: var(--surface-positive-badge-strong);
--border-best-value: var(--border-positive-badge-strong);
--text-best-value: var(--green);
--surface-best-value-active: var(--surface-on-accent-badge);
--border-best-value-active: var(--border-on-accent-badge);
--text-best-value-active: var(--text-on-accent);
--surface-sidebar: var(--card);
--border-sidebar: var(--border);
--surface-sidebar-body: transparent;
--surface-sidebar-header: #5c8097;
--surface-sidebar-utility: var(--card);
--surface-sidebar-utility-border: var(--border);
--surface-export: var(--card);
--border-export-top: transparent;
--surface-compare: rgba(255, 255, 255, 0.06);
--border-compare: var(--border);
--surface-modal: var(--card);
--surface-mobile-sheet: var(--card);
--border-mobile-sheet: var(--border-soft);
--surface-mobile-close-row: transparent;
--surface-mobile-actions: var(--card);
--border-mobile-row: var(--border-soft);
--surface-mobile-sidebar: var(--surface-sidebar);
--surface-mobile-backdrop: rgba(0,0,0,0.65);
--surface-accent-soft: rgba(45, 122, 168, 0.07);
--surface-summary-badge: rgba(45,122,168,0.12);
--border-summary-badge: rgba(45,122,168,0.3);
--surface-chevron: rgba(255,255,255,0.05);
--surface-chevron-active: rgba(255,255,255,0.08);
--surface-chevron-mobile: var(--surface-chevron-active);
--surface-ghost: rgba(255,255,255,0.08);
--surface-ghost-hover: rgba(255,255,255,0.15);
--surface-step: var(--card);
--surface-step-hover: var(--border);
--surface-step-active: var(--accent);
--surface-step-border: var(--border);
--text-step: var(--muted);
--surface-success: #162e22;
--surface-success-border: #245840;
--surface-danger: #2a1319;
--surface-danger-border: #5e2830;
--text-danger: #e87882;
--surface-warning: #2a1e06;
--surface-warning-panel: var(--surface-warning);
--surface-warning-border: #5a3a10;
--surface-compare-success: rgba(39, 174, 96, 0.16);
--surface-compare-warning: rgba(210, 120, 30, 0.16);
--surface-selected: #1d2d3a;
--text-selected-accent: #ccecff;
--surface-positive-soft: rgba(33,112,69,0.08);
--surface-positive-strong: rgba(33,112,69,0.13);
--border-positive-soft: rgba(33,112,69,0.22);
--border-positive-strong: rgba(33,112,69,0.3);
--surface-positive-pill: var(--surface-positive-soft);
--surface-positive-badge: var(--surface-positive-strong);
--border-positive-badge: var(--border-positive-strong);
--surface-positive-badge-strong: var(--surface-positive-strong);
--border-positive-badge-strong: var(--border-positive-strong);
--surface-positive-panel: var(--surface-positive-soft);
--border-positive-panel: var(--border-positive-soft);
--surface-addon-hover: var(--surface-accent-soft);
--border-addon-hover: color-mix(in srgb, var(--accent) 24%, var(--border));
--text-sidebar-kicker: rgba(255,255,255,0.75);
--text-sidebar-heading: #fff;
--text-sidebar-placeholder: rgba(255,255,255,0.65);
--text-money: #f2ede4;
--text-money-hero: #f5f0e8;
--text-vs-heading: #f2ede4;
--text-vs-accent: #5aaedc;
--text-vs-muted: #b5ab9e;
--text-incentive: var(--green);
--text-on-accent: #fff;
--text-on-accent-soft: rgba(255,255,255,0.85);
--text-on-accent-subtle: rgba(255,255,255,0.7);
--text-on-accent-strong: var(--text-on-accent-soft);
--surface-on-accent-badge: rgba(255,255,255,0.18);
--border-on-accent-badge: rgba(255,255,255,0.35);
--text-pill-savings-active: #86efac;
--surface-backdrop: rgba(0, 0, 0, 0.62);
--shadow-modal: 0 16px 50px rgba(0,0,0,0.35);
--shadow-switch-knob: 0 1px 3px rgba(0,0,0,0.3);
--shadow-floating: 0 4px 20px rgba(0,0,0,0.45);
--group-strip: color-mix(in srgb, var(--accent) 18%, var(--paper));
--shadow-card: 0 2px 8px rgba(0,0,0,0.15), 0 1px 3px rgba(0,0,0,0.1);
--shadow-card-hover: 0 4px 16px rgba(0,0,0,0.2), 0 2px 6px rgba(0,0,0,0.12);
--shadow-card-open: 0 6px 20px rgba(0,0,0,0.22), 0 2px 8px rgba(0,0,0,0.14);
--section-hover-border: rgba(45,122,168,0.35);
--section-hover-shadow: -3px 0 0 0 rgba(45,122,168,0.4);
--section-open-border: rgba(45,122,168,0.5);
--section-open-shadow: -3px 0 0 0 rgba(45,122,168,0.7);
--surface-switch-knob: #fff;
--surface-switch-off: #4a4540;
--surface-switch-on: var(--green);
--surface-mobile-close-btn: var(--border);
--surface-mobile-close-btn-active: var(--muted);
--btn-primary-fg: #fff;
--btn-primary-hover: #3a8fc4;
--surface-pill-icon: rgba(255,255,255,0.2);
--surface-overlay-btn: rgba(255,255,255,0.06);
--surface-overlay-btn-hover: rgba(255,255,255,0.12);
--border-overlay-btn: rgba(255,255,255,0.18);
--border-overlay-btn-hover: rgba(255,255,255,0.28);
--focus-ring-overlay: rgba(255,255,255,0.5);
--surface-sidebar-focus-backdrop: rgba(5, 11, 19, 0.58);
--shadow-sidebar: 0 18px 42px rgba(0,0,0,0.12);
--shadow-sidebar-focus: 0 28px 64px rgba(0,0,0,0.28);
--shadow-export-hover: 0 2px 8px rgba(0,0,0,0.25);
--border-nudge-nav: rgba(255,255,255,0.06);
--print-paper: #fff;
--print-ink: #1a1a1a;
--print-accent: #2d7aa8;
--print-muted: #555;
--print-border: #ccc;
--print-border-strong: #ddd;
--print-section-num: #bbb;
--print-sidebar-line: #444;
--print-save-green: #e8f5e9;
--print-save-amber: #fff3e0;
--print-save-amber-panel: #fff8e1;
--print-feature: #f9f9f9;
--print-addon-selected: #e8f4fb;
--print-callout-green: #f0faf4;
--print-callout-red: #fff0f0;
--print-callout-green-border: #3ab870;
--print-callout-red-border: #5e2830;
--print-footer-note: #888;
--sidebar-zone-services: rgba(255, 255, 255, 0.06);
--sidebar-zone-invoice: rgba(255, 255, 255, 0.08);
--sidebar-zone-value: rgba(58, 184, 112, 0.05);
--sidebar-zone-summary: rgba(255, 255, 255, 0.03);
--sidebar-zone-tax: transparent;
--sidebar-rule: color-mix(in srgb, var(--border) 75%, transparent);
--sidebar-rule-style: dashed;
--sidebar-row-stripe: rgba(255, 255, 255, 0.018);
--sidebar-group-title-color: var(--muted);
--sidebar-stack-gap: 14px;
--sidebar-top-gap: calc(var(--sidebar-stack-gap) + 14px);
--top-bar-sticky-offset: 62px;
--sidebar-sticky-top: calc(var(--top-bar-sticky-offset) + var(--sidebar-top-gap));
}
/* ── TABULAR NUMBERS ─────────────────────────────────────────
All monetary values use tabular (fixed-width) figures so
columns of numbers align perfectly.
──────────────────────────────────────────────────────────── */
.val,
.sidebar-line .val,
.price-badge,
.sidebar-hero,
[data-money] {
font-variant-numeric: tabular-nums;
}