Pre-Alpha to Alpha Ready

This commit is contained in:
John OReilly
2026-03-16 01:42:17 -04:00
parent 42b7b06dda
commit e6c0baef3b
60 changed files with 12287 additions and 230 deletions

View File

@@ -15,6 +15,7 @@
margin-left: var(--section-offset);
border-radius: var(--radius-card);
border: 1px solid var(--border);
border-left: 3px solid transparent;
background: var(--surface-section);
padding: var(--section-padding-top) var(--section-padding-x) var(--section-padding-bottom);
}
@@ -39,7 +40,7 @@
.fa-icon--green { color: var(--green); }
.fa-icon--amber { color: var(--amber); }
.fa-icon--danger { color: var(--text-danger); }
.fa-icon--white { color: #fff; }
.fa-icon--white { color: var(--text-on-accent); }
.fa-icon--theme { color: currentColor; }
/* ── FA Sharp Solid icons — inline data URIs for file:// compatibility ── */
.fa-icon-file-invoice { --fa-icon-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E%3Cpath fill='currentColor' d='M240 0L0 0 0 512 384 512 384 144 240 0zm85.5 176L208 176 208 58.5 325.5 176zM64 416l0-128 256 0 0 128-256 0zM88 64l72 0 0 48-96 0 0-48 24 0zm0 96l72 0 0 48-96 0 0-48 24 0z'/%3E%3C/svg%3E"); }
@@ -85,6 +86,58 @@
#sec-04 { order: 4; }
#sec-05 { order: 5; }
#sec-06 { order: 6; }
/* ── GROUP LABEL — "Managed IT Services" eyebrow above section I ── */
.group-label {
order: 0;
margin-left: var(--section-offset);
margin-bottom: calc(var(--space-xs) * -1);
font-family: 'DM Mono', monospace;
font-size: 0.6875rem;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--accent);
opacity: 0.7;
}
.group-label-sections {
opacity: 0.6;
letter-spacing: 0.06em;
}
/* ── GROUP DIVIDER — separates Server Managed from Site Management ── */
.group-divider {
order: 3;
border: none;
border-top: 1px solid var(--border);
margin: var(--space-xs) var(--section-offset) var(--space-xs) var(--section-offset);
opacity: 0.5;
}
/* ── GROUP STRIP — bracket alongside sections IIII ── */
#sec-02::after, #sec-03::after, #sec-01::after {
content: '';
position: absolute;
left: calc(var(--section-offset) * -1 + 2px);
top: -12px;
bottom: -12px;
width: 6px;
border-left: 3px solid var(--group-strip);
pointer-events: none;
z-index: 0;
}
/* Top cap — wraps above first section */
#sec-02::after {
top: -12px;
border-top: 3px solid var(--group-strip);
border-top-left-radius: 4px;
}
/* Bottom cap — wraps below last section */
#sec-01::after {
bottom: -12px;
border-bottom: 3px solid var(--group-strip);
border-bottom-left-radius: 4px;
}
.section-header {
display: grid;
grid-template-columns: minmax(0, 1fr) auto auto;
@@ -111,6 +164,11 @@
left: calc(var(--section-offset) * -1);
top: calc(var(--section-padding-top) - 2px);
text-align: right;
transition: color var(--transition-medium, 0.2s) ease, opacity var(--transition-medium, 0.2s) ease;
}
.sec-active .section-num {
color: var(--accent);
opacity: 0.9;
}
.section-title-block {
min-width: 0;
@@ -141,7 +199,7 @@
.section-title {
font-family: 'Poppins', sans-serif;
font-size: clamp(1.375rem, 1.5vw, 1.75rem);
font-weight: 600;
font-weight: 700;
color: var(--ink);
line-height: var(--text-title-line);
word-break: break-word;
@@ -152,7 +210,8 @@
.section-subtitle {
grid-column: 1 / -1;
grid-row: 3;
font-size: var(--text-copy-size);
font-size: 0.9em;
font-weight: 400;
color: var(--muted);
margin-top: var(--space-xs);
line-height: var(--text-copy-line);
@@ -198,7 +257,7 @@
will-change: height, opacity;
}
.section-content { min-width: 0; }
.section-content > * + * { margin-top: var(--space-stack); }
.section-content > * + * { margin-top: var(--space-stack-roomy); }
.section-content > .collapsible-header + .collapsible-body,
.section-content > .collapsible-body + .collapsible-header {
margin-top: 0;
@@ -278,20 +337,22 @@
display: none;
align-items: center;
font-family: 'DM Mono', monospace;
font-size: 13px;
font-weight: 500;
font-size: 0.9375rem;
font-weight: 700;
font-variant-numeric: tabular-nums;
letter-spacing: 0.08em;
color: var(--accent);
background: var(--surface-summary-badge);
border: 2px solid var(--border-summary-badge);
border-radius: var(--radius-control);
padding: var(--control-pad-y-tight) var(--space-md);
border-radius: 8px;
padding: 8px 16px;
white-space: normal;
line-height: var(--text-compact-line);
max-width: min(100%, 26ch);
margin-top: var(--space-md);
text-align: left;
align-self: flex-start;
box-shadow: 0 1px 4px rgba(45, 122, 168, 0.2);
animation: badgeFadeIn 0.25s ease both;
}
.sec-open .sec-summary-badge {
@@ -507,24 +568,36 @@
Separate from section-level collapse. JS toggleCollapsible(id)
toggles .open on .collapsible-body and swaps +/- on toggle icon.
.addon-preview-pill pills shown when collapsed (JS toggleCollapsible).
Arrow on RIGHT side to differentiate from section chevron.
─────────────────────────────────────────────────────────────── */
.collapsible-header {
display: flex;
align-items: center;
gap: var(--space-sm);
cursor: pointer;
padding: var(--space-md) 0;
border-top: 1px solid var(--border);
padding: var(--space-stack) var(--space-md);
border: 1px solid var(--border);
border-radius: 8px;
margin-top: var(--space-sm);
background: var(--surface-feature);
user-select: none;
transition: background var(--transition-fast), border-color var(--transition-fast);
}
.collapsible-header:hover {
background: color-mix(in srgb, var(--accent) 6%, var(--surface-feature));
border-color: color-mix(in srgb, var(--accent) 15%, var(--border));
}
.collapsible-header--mt16 { margin-top: var(--space-stack-roomy); }
.collapsible-header--addon { flex-wrap: wrap; gap: var(--space-xs); margin-top: 0; }
.collapsible-header--addon { flex-wrap: wrap; gap: var(--space-xs); }
.collapsible-toggle {
color: var(--accent);
width: 22px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
order: 1;
margin-left: auto;
transition: transform var(--transition-medium) ease;
}
.collapsible-toggle.open { transform: rotate(180deg); }
@@ -532,17 +605,20 @@
.collapsible-label {
font-family: 'DM Mono', monospace;
font-size: 13px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--muted);
letter-spacing: 0.08em;
color: var(--ink);
order: 0;
}
.addon-preview-wrap {
display: flex; flex-wrap: wrap; gap: 5px;
width: 100%; padding-left: var(--space-3xl); margin-top: 6px;
width: 100%; padding-left: 0; margin-top: 6px;
order: 2;
}
.addon-preview-pill {
font-family: 'DM Mono', monospace;
font-size: 13px;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--muted);
@@ -619,21 +695,22 @@
background: var(--surface-step);
border: 1px solid var(--surface-step-border);
color: var(--text-step);
font-size: 20px;
font-size: 1.125rem;
font-weight: 400;
width: 36px;
min-width: 44px;
min-height: 44px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.12s, color 0.12s;
transition: background 0.12s, color 0.12s, border-color var(--transition-fast, 150ms) ease;
flex-shrink: 0;
user-select: none;
line-height: 1;
}
.step-btn:first-child { border-radius: var(--radius-control) 0 0 var(--radius-control); border-right: none; }
.step-btn:last-child { border-radius: 0 var(--radius-control) var(--radius-control) 0; border-left: none; }
.step-btn:hover { background: var(--surface-step-hover); color: var(--ink); }
.step-btn:hover { background: var(--surface-step-hover); color: var(--ink); border-color: var(--accent); }
.step-btn:active { background: var(--surface-step-active); color: var(--btn-primary-fg); border-color: var(--accent); }
.num-input {
background: var(--surface-input);
@@ -641,8 +718,10 @@
border-radius: 0;
color: var(--ink);
font-family: 'DM Mono', monospace;
font-size: 22px;
width: 72px;
font-size: 1.125rem;
font-weight: 700;
width: 56px;
height: 44px;
text-align: center;
padding: var(--space-sm);
outline: none;
@@ -699,7 +778,7 @@
top: 1px;
width: 5px;
height: 10px;
border: solid #fff;
border: solid var(--text-on-accent);
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
@@ -861,43 +940,50 @@
.m365-app-strip {
border: 1px solid var(--border);
border-radius: 10px;
padding: var(--space-stack-roomy) var(--space-lg) var(--space-stack);
border-radius: var(--radius-card);
padding: var(--space-lg) var(--space-lg) var(--space-stack);
background: var(--surface-feature);
}
.m365-app-list {
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: var(--space-md);
gap: var(--space-stack);
}
.m365-app-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-sm);
gap: 8px;
text-align: center;
padding: var(--space-stack-tight) var(--space-sm);
border-radius: var(--radius-control);
background: color-mix(in srgb, var(--surface-accent-soft) 44%, transparent);
padding: var(--space-stack) var(--space-sm);
border-radius: 10px;
transition: background var(--transition-fast), transform var(--transition-fast);
}
.m365-app-item:hover {
background: color-mix(in srgb, var(--accent) 8%, transparent);
transform: translateY(-1px);
}
.m365-app-icon {
width: 17px;
height: 17px;
width: 28px;
height: 28px;
object-fit: contain;
display: block;
}
.m365-app-name {
font-family: 'DM Mono', monospace;
font-size: 0.75rem;
letter-spacing: 0.05em;
font-size: 0.6875rem;
font-weight: 500;
letter-spacing: 0.06em;
color: var(--ink);
opacity: 0.85;
}
.m365-app-strip-note {
margin-top: var(--space-md);
padding-top: var(--space-sm);
font-family: 'DM Mono', monospace;
font-size: 0.75rem;
letter-spacing: 0.05em;
font-size: 0.6875rem;
letter-spacing: 0.06em;
color: var(--muted);
}
.m365-app-note-byol { display: none; }
@@ -929,7 +1015,7 @@
with _m IDs and synced by update() via syncEl/syncClass.
─────────────────────────────────────────────────────────────── */
.sidebar {
--sidebar-rule-color: color-mix(in srgb, var(--border) 88%, transparent);
--sidebar-rule-color: var(--sidebar-line-rule);
--sidebar-copy-size: 0.84375rem;
--sidebar-copy-line: 1.5;
--sidebar-note-size: 0.78125rem;
@@ -939,12 +1025,12 @@
border: 1px solid var(--border-sidebar);
border-radius: var(--radius-card);
overflow: hidden;
box-shadow: 0 18px 42px rgba(0,0,0,0.12);
box-shadow: var(--shadow-sidebar);
}
.sidebar-focus-backdrop {
position: fixed;
inset: 0;
background: rgba(5, 11, 19, 0.58);
background: var(--surface-sidebar-focus-backdrop);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
opacity: 0;
@@ -977,9 +1063,9 @@
justify-content: center;
height: 34px;
padding: 0 var(--space-stack);
border: 1px solid rgba(255,255,255,0.18);
border: 1px solid var(--border-overlay-btn);
border-radius: 10px;
background: rgba(255,255,255,0.06);
background: var(--surface-overlay-btn);
color: var(--text-sidebar-kicker);
font-family: 'DM Mono', monospace;
font-size: 0.6875rem;
@@ -991,16 +1077,16 @@
margin-left: auto;
}
.sidebar-focus-print-btn:hover {
background: rgba(255,255,255,0.12);
border-color: rgba(255,255,255,0.28);
background: var(--surface-overlay-btn-hover);
border-color: var(--border-overlay-btn-hover);
}
.sidebar-focus-print-btn:active { transform: translateY(1px); }
.sidebar-focus-toggle {
width: 34px;
height: 34px;
border: 1px solid rgba(255,255,255,0.18);
border: 1px solid var(--border-overlay-btn);
border-radius: 10px;
background: rgba(255,255,255,0.06);
background: var(--surface-overlay-btn);
color: var(--text-sidebar-kicker);
display: inline-flex;
align-items: center;
@@ -1010,12 +1096,12 @@
flex: 0 0 auto;
}
.sidebar-focus-toggle:hover {
background: rgba(255,255,255,0.12);
border-color: rgba(255,255,255,0.28);
background: var(--surface-overlay-btn-hover);
border-color: var(--border-overlay-btn-hover);
}
.sidebar-focus-toggle:active { transform: translateY(1px); }
.sidebar-focus-toggle:focus-visible {
outline: 2px solid rgba(255,255,255,0.5);
outline: 2px solid var(--focus-ring-overlay);
outline-offset: 2px;
}
.sidebar-focus-icon-close { display: none; }
@@ -1057,29 +1143,41 @@
border-radius: var(--radius-control);
}
.sidebar-group--monthly {
background: var(--sidebar-zone-services, rgba(255, 255, 255, 0.03));
background: var(--sidebar-zone-services);
border-radius: var(--radius-card);
padding: var(--space-stack-roomy);
}
.sidebar-group--tax {
background: transparent;
background: var(--sidebar-zone-tax);
}
.sidebar-group--invoice {
background: var(--sidebar-zone-invoice, rgba(255, 255, 255, 0.05));
background: var(--sidebar-zone-invoice);
}
.sidebar-group--value {
background: var(--sidebar-zone-value, rgba(255, 255, 255, 0.02));
background: var(--sidebar-zone-value);
}
.sidebar-group--summary {
background: var(--sidebar-zone-summary);
}
.sidebar-group + .sidebar-group {
margin-top: var(--space-stack);
}
/* Subtle hover tint for line scanning readability */
.sidebar-line:hover {
background: var(--surface-accent-soft, rgba(45, 122, 168, 0.07));
border-left-color: var(--accent);
padding-left: calc(var(--space-xs) + 4px);
}
.sidebar-group-title {
display: block;
flex: 0 0 auto;
min-height: 12px;
font-family: 'DM Mono', monospace;
font-size: 0.625rem;
letter-spacing: 0.16em;
font-weight: 500;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
color: var(--sidebar-group-title-color);
margin: 0 0 var(--space-stack-tight);
}
.sidebar-line {
@@ -1090,12 +1188,23 @@
font-size: var(--sidebar-copy-size);
color: var(--muted);
line-height: var(--sidebar-copy-line);
padding: var(--space-stack-tight) 0;
border-bottom: 1px dashed var(--sidebar-rule-color);
padding: var(--space-stack-tight) var(--space-xs);
border-bottom: 1px var(--sidebar-line-rule-style) var(--sidebar-rule-color);
border-left: 2px solid transparent;
border-radius: 2px;
transition: background var(--transition-fast, 150ms) ease,
border-color var(--transition-fast, 150ms) ease,
padding-left var(--transition-fast, 150ms) ease;
}
/* Remove border on last visible line before a group boundary */
.sidebar-group > .sidebar-line:last-child,
#sidebarLines > .sidebar-line:last-of-type {
border-bottom: none;
}
.sidebar-line > span:first-child { flex: 1 1 auto; min-width: 0; }
.sidebar-line .val {
font-family: 'DM Mono', monospace;
font-weight: 600;
color: var(--text-money);
font-size: var(--sidebar-copy-size);
line-height: 1.2;
@@ -1108,18 +1217,19 @@
.sidebar-mrr-label {
font-family: 'DM Mono', monospace;
font-size: 0.625rem;
letter-spacing: 0.16em;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: var(--space-sm);
}
.sidebar-mrr {
font-family: 'Poppins', sans-serif;
font-weight: 700;
font-size: var(--sidebar-mrr-size);
font-weight: 800;
font-size: 3rem;
color: var(--text-money-hero);
line-height: 0.94;
letter-spacing: -0.03em;
letter-spacing: -0.02em;
text-shadow: 0 2px 12px rgba(245, 240, 232, 0.08);
margin-bottom: var(--space-stack-roomy);
}
.sidebar-line-value .val,
@@ -1168,9 +1278,11 @@
color: var(--ink);
letter-spacing: 0.02em;
}
.vs-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; line-height: 1.56; }
.vs-table td { padding: 9px var(--space-xs); vertical-align: middle; }
.vs-table { width: 100%; border-collapse: collapse; font-size: 0.775rem; line-height: 1.56; }
.vs-table td { padding: 7px var(--space-xs); vertical-align: middle; }
.vs-table td:last-child { text-align: right; font-family: 'DM Mono', monospace; white-space: nowrap; }
.vs-table tr:not(.vs-save-row) { opacity: 0.85; }
.vs-table tr.vs-save-row { opacity: 1; }
.vs-table tr:first-child td { padding-top: 2px; padding-bottom: var(--space-stack-roomy); border-bottom: 1px solid var(--border); }
.vs-table tr:nth-child(2) td,
.vs-table tr:nth-child(4) td { padding-top: var(--space-stack-roomy); }
@@ -1186,7 +1298,7 @@
.vs-label {
font-family: 'DM Mono', monospace;
font-size: 0.6875rem;
letter-spacing: 0.16em;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 0;
@@ -1245,7 +1357,7 @@
}
.nudge-nav-btn {
background: var(--surface-ghost);
border: 1px solid rgba(255,255,255,0.06);
border: 1px solid var(--border-nudge-nav);
cursor: pointer;
padding: 0;
width: 34px;
@@ -1346,7 +1458,7 @@
.qs-term-wrap .tier-seg {
padding: clamp(14px, 2.5cqi, 16px) clamp(12px, 2.3cqi, 14px) clamp(14px, 2.4cqi, 15px);
background: var(--surface-term-tile);
transition: background 0.18s, border-color 0.18s, box-shadow 0.18s, transform 0.18s;
transition: background 200ms ease, color 200ms ease, border-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
.qs-term-wrap .tier-seg:hover {
background: var(--surface-term-tile-hover);
@@ -1516,7 +1628,10 @@
transition: left 0.2s, background 0.2s;
box-shadow: var(--shadow-switch-knob);
}
.qs-toggle-row input:checked ~ .qs-switch { background: var(--surface-switch-on); }
.qs-toggle-row input:checked ~ .qs-switch {
background: var(--surface-switch-on);
box-shadow: 0 0 8px rgba(58, 184, 112, 0.3);
}
.qs-toggle-row input:checked ~ .qs-switch::after { left: 17px; }
.qs-fee-waive:has(input:disabled) { opacity: 0.5; cursor: default; }
.qs-fee-input:disabled { opacity: 0.4; cursor: not-allowed; }
@@ -1701,16 +1816,31 @@
.sl-discount-val { color: var(--green) !important; }
.sl-discount-detail { font-size: 0.7rem; opacity: 0.7; }
.sl-hst-val { color: var(--text-money) !important; font-size: var(--sidebar-copy-size); }
.sidebar-line-discount { border-bottom-style: dashed; opacity: 0.8; }
.sidebar-line-discount { border-bottom-style: dashed; border-bottom-color: var(--sidebar-rule-color); opacity: 0.8; }
.sidebar-line.sidebar-line-hst {
margin-top: 0;
padding-top: var(--space-stack-tight);
padding-bottom: var(--space-stack-tight);
border-top: 1px dashed var(--sidebar-rule-color);
border-top: 1px var(--sidebar-line-rule-style) var(--sidebar-rule-color);
border-bottom: none;
}
.sidebar-line.sidebar-line-total {
font-weight: 600;
margin-top: 2px;
margin-top: var(--space-sm);
border-top: 2px solid color-mix(in srgb, var(--accent) 30%, transparent);
border-bottom: none;
padding-top: var(--space-stack-roomy);
}
.sidebar-line.sidebar-line-total .val {
font-size: 1.1em;
font-weight: 700;
color: var(--text-money-hero);
}
.suffix-mo {
font-size: 0.7em;
font-weight: 500;
color: var(--muted);
letter-spacing: 0.02em;
}
.sl-hst-toggle {
justify-content: flex-start;
@@ -1740,7 +1870,7 @@
display: flex;
flex-direction: column;
z-index: 540;
box-shadow: 0 28px 64px rgba(0,0,0,0.28);
box-shadow: var(--shadow-sidebar-focus);
}
body.sidebar-focus-open .side-col .sidebar-focus-client {
display: block;
@@ -1807,21 +1937,34 @@
Subtle left accent glow on hover; stronger treatment when open.
─────────────────────────────────────────────────────────────── */
.section {
transition: border-color 0.2s, box-shadow 0.2s;
box-shadow: var(--shadow-card);
transition: border-color var(--transition-medium, 0.2s) ease, box-shadow var(--transition-medium, 0.2s) ease;
}
.section.sec-active {
border-left: 3px solid color-mix(in srgb, var(--accent) 50%, transparent);
}
.section:hover {
border-color: var(--section-hover-border);
box-shadow: var(--section-hover-shadow);
box-shadow: var(--shadow-card-hover), var(--section-hover-shadow);
}
.section.sec-open {
border-color: var(--section-open-border);
box-shadow: var(--section-open-shadow);
box-shadow: var(--shadow-card-open), var(--section-open-shadow);
}
/* ── ADDON ROW SELECTED — stronger check indicator ──────────────
.selected gets a more prominent border + check indicator via
the checkbox's native accent-color. No pseudo-element needed.
─────────────────────────────────────────────────────────────── */
@keyframes stepper-pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.num-input.pulse {
animation: stepper-pulse 150ms ease-out;
}
@keyframes addonPulse {
0% { transform: scale(1); }
50% { transform: scale(1.015); }
@@ -1882,8 +2025,8 @@
─────────────────────────────────────────────────────────────── */
.export-wrap {
padding: var(--space-stack-roomy) var(--space-xl) var(--space-lg);
background: var(--surface-export);
border-top: 1px solid var(--border-export-top);
background: transparent;
border-top: none;
display: flex;
flex-direction: column;
gap: var(--space-stack-tight);
@@ -1909,7 +2052,7 @@
.btn-export:hover {
background: var(--btn-primary-hover);
filter: brightness(1.15);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
box-shadow: var(--shadow-export-hover);
}
.btn-export:active { transform: scale(0.97); filter: brightness(0.95); }
.btn-export-secondary {
@@ -2025,9 +2168,9 @@
.pitch-footer {
background: var(--surface-success);
border-top: 1px solid var(--surface-success-border);
padding: var(--space-md) var(--space-3xl);
padding: var(--space-sm) var(--space-3xl);
font-family: 'DM Mono', monospace;
font-size: 13px;
font-size: 11px;
color: var(--green);
letter-spacing: 0.05em;
text-align: center;