Created
May 2, 2026 22:01
-
-
Save johnrhampton/2c67ab67af9f4a5ed8a0e6ae45088433 to your computer and use it in GitHub Desktop.
COA Mapping redesign mock (ui-portal#281)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>COA Mapping — Redesign Mock</title> | |
| <style> | |
| :root { | |
| --gray-50: #f7fafc; | |
| --gray-100: #edf2f7; | |
| --gray-200: #e2e8f0; | |
| --gray-300: #cbd5e0; | |
| --gray-400: #a0aec0; | |
| --gray-500: #718096; | |
| --gray-600: #4a5568; | |
| --gray-700: #2d3748; | |
| --gray-900: #171923; | |
| --accent: #1d3354; | |
| --accent-300: #5a7da3; | |
| --accent-50: rgba(29, 51, 84, 0.04); | |
| --warning-50: #fffaf0; | |
| --warning-200: #fbd38d; | |
| --warning-400: #ed8936; | |
| --warning-500: #dd6b20; | |
| --warning-700: #9c4221; | |
| --success-200: #9ae6b4; | |
| --success-500: #38a169; | |
| --success-600: #2f855a; | |
| --success-700: #276749; | |
| } | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| background: #f7fafc; | |
| color: var(--gray-900); | |
| line-height: 1.5; | |
| padding: 32px 16px 120px; | |
| } | |
| .container { max-width: 1200px; margin: 0 auto; } | |
| .stack { display: flex; flex-direction: column; gap: 32px; } | |
| .stack-sm { display: flex; flex-direction: column; gap: 16px; } | |
| .stack-xs { display: flex; flex-direction: column; gap: 8px; } | |
| .row { display: flex; align-items: center; gap: 12px; } | |
| .row-end { display: flex; align-items: center; gap: 12px; justify-content: flex-end; } | |
| .row-between { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; flex-wrap: wrap; } | |
| /* Page header */ | |
| .page-header { | |
| border-left: 3px solid var(--accent); | |
| padding: 4px 0 4px 20px; | |
| display: flex; | |
| justify-content: space-between; | |
| gap: 24px; | |
| flex-wrap: wrap; | |
| } | |
| .eyebrow { | |
| font-size: 12px; | |
| font-weight: 600; | |
| color: var(--gray-500); | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| margin-bottom: 8px; | |
| } | |
| .page-title { | |
| font-size: 32px; | |
| font-weight: 800; | |
| letter-spacing: -0.01em; | |
| margin-bottom: 8px; | |
| } | |
| .page-desc { | |
| color: var(--gray-600); | |
| max-width: 540px; | |
| font-size: 15px; | |
| } | |
| .stats-strip { | |
| display: flex; | |
| gap: 24px; | |
| align-items: center; | |
| border-left: 1px solid var(--gray-200); | |
| padding-left: 24px; | |
| } | |
| .stat { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: flex-end; | |
| min-width: 70px; | |
| } | |
| .stat-divider { | |
| width: 1px; | |
| height: 44px; | |
| background: var(--gray-200); | |
| } | |
| .stat-num { | |
| font-size: 32px; | |
| font-weight: 800; | |
| letter-spacing: -0.02em; | |
| line-height: 1; | |
| margin-top: 2px; | |
| } | |
| .stat-num.attention { color: var(--warning-500); } | |
| .stat-num.info { color: var(--accent); } | |
| .stat-num.neutral { color: var(--gray-900); } | |
| /* Section header */ | |
| .section-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| } | |
| .dot { width: 6px; height: 6px; border-radius: 50%; } | |
| .dot.attention { background: var(--warning-500); } | |
| .dot.success { background: var(--success-500); } | |
| .dot.muted { background: var(--gray-400); } | |
| .section-label { | |
| font-size: 12px; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.1em; | |
| display: flex; align-items: center; gap: 6px; | |
| } | |
| .section-label.attention { color: var(--warning-700); } | |
| .section-label.success { color: var(--success-700); } | |
| .section-label.muted { color: var(--gray-600); } | |
| .section-count { font-size: 12px; color: var(--gray-400); font-weight: 500; } | |
| .divider { flex: 1; height: 1px; background: var(--gray-200); } | |
| /* Card grid (selector page) */ | |
| .card-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); | |
| gap: 16px; | |
| } | |
| .card { | |
| border: 1px solid var(--gray-200); | |
| border-radius: 8px; | |
| background: white; | |
| padding: 20px; | |
| transition: all 0.15s ease; | |
| cursor: pointer; | |
| } | |
| .card:hover { border-color: var(--gray-300); transform: translateY(-1px); box-shadow: 0 1px 4px rgba(0,0,0,.04); } | |
| .card.attention { | |
| background: var(--warning-50); | |
| border-color: var(--warning-200); | |
| } | |
| .card.attention:hover { border-color: var(--warning-400); } | |
| .card.muted { | |
| background: var(--gray-50); | |
| border-style: dashed; | |
| } | |
| .card-eyebrow { | |
| font-size: 11px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.06em; | |
| color: var(--warning-700); | |
| display: flex; align-items: center; gap: 6px; | |
| margin-bottom: 4px; | |
| } | |
| .card-title { | |
| font-size: 18px; | |
| font-weight: 700; | |
| color: var(--gray-900); | |
| margin-bottom: 4px; | |
| } | |
| .card-title.sm { font-size: 14px; font-weight: 700; } | |
| .card-sub { font-size: 14px; color: var(--gray-600); } | |
| .card-sub.success { color: var(--success-600); display: flex; align-items: center; gap: 6px; font-weight: 500; } | |
| .card-sub.muted { color: var(--gray-500); display: flex; align-items: center; gap: 6px; } | |
| .card-arrow { color: var(--gray-300); } | |
| .card.attention .card-arrow { color: var(--warning-400); } | |
| .card:hover .card-arrow { color: var(--gray-500); } | |
| .card.attention:hover .card-arrow { color: var(--warning-700); } | |
| /* Per-campus row layout */ | |
| .row-card { | |
| border: 1px solid var(--gray-200); | |
| border-radius: 8px; | |
| background: white; | |
| overflow: hidden; | |
| } | |
| .mapping-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 16px; | |
| padding: 16px; | |
| border-bottom: 1px solid var(--gray-100); | |
| position: relative; | |
| } | |
| .mapping-row:last-child { border-bottom: none; } | |
| .mapping-row.edited { | |
| background: var(--accent-50); | |
| } | |
| .mapping-row.edited::before { | |
| content: ""; | |
| position: absolute; | |
| left: 0; top: 0; bottom: 0; | |
| width: 3px; | |
| background: var(--accent); | |
| } | |
| .row-info { flex: 1; min-width: 0; } | |
| .row-name { font-weight: 600; font-size: 14px; color: var(--gray-900); } | |
| .row-type { font-size: 12px; color: var(--gray-500); margin-top: 2px; } | |
| .row-select { | |
| min-width: 280px; | |
| } | |
| .row-select select { | |
| width: 100%; | |
| padding: 6px 10px; | |
| border: 1px solid var(--gray-300); | |
| border-radius: 6px; | |
| font-size: 14px; | |
| background: white; | |
| cursor: pointer; | |
| } | |
| .row-select select.edited { | |
| border-color: var(--accent-300); | |
| font-weight: 600; | |
| } | |
| .row-group { | |
| font-size: 11px; | |
| color: var(--gray-500); | |
| margin-top: 4px; | |
| padding-left: 4px; | |
| } | |
| /* Sticky save bar */ | |
| .save-bar { | |
| position: fixed; | |
| bottom: 0; left: 0; right: 0; | |
| background: white; | |
| border-top: 1px solid var(--gray-200); | |
| box-shadow: 0 -4px 12px rgba(0,0,0,.04); | |
| padding: 16px 0; | |
| } | |
| .save-bar-inner { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 0 16px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| gap: 16px; | |
| } | |
| .save-bar-status { | |
| display: flex; align-items: center; gap: 8px; | |
| color: var(--accent); | |
| font-weight: 500; | |
| font-size: 14px; | |
| } | |
| .save-bar-actions { display: flex; gap: 12px; } | |
| .btn { | |
| padding: 8px 16px; | |
| border-radius: 6px; | |
| border: none; | |
| font-size: 14px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| display: inline-flex; align-items: center; gap: 6px; | |
| transition: all 0.15s ease; | |
| } | |
| .btn-ghost { background: transparent; color: var(--gray-600); } | |
| .btn-ghost:hover { background: var(--gray-100); color: var(--gray-900); } | |
| .btn-primary { background: var(--accent); color: white; } | |
| .btn-primary:hover { background: #182944; } | |
| .back-link { | |
| color: var(--gray-500); | |
| font-size: 14px; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| text-decoration: none; | |
| margin-bottom: 16px; | |
| } | |
| .back-link:hover { color: var(--accent); } | |
| .demo-divider { | |
| height: 1px; | |
| background: var(--gray-200); | |
| margin: 64px 0 32px; | |
| } | |
| .demo-label { | |
| font-size: 11px; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.1em; | |
| color: var(--gray-500); | |
| margin-bottom: 24px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <p class="demo-label">Mock 1 — School selector landing page</p> | |
| <div class="stack"> | |
| <header class="page-header"> | |
| <div> | |
| <p class="eyebrow">Staff Tools · Analytics</p> | |
| <h1 class="page-title">Account Mapping</h1> | |
| <p class="page-desc">Map each campus's QuickBooks line items to the firm-wide standard categories so revenue and expense roll up consistently across the franchise.</p> | |
| </div> | |
| <div class="stats-strip"> | |
| <div class="stat"> | |
| <p class="eyebrow">Unmapped</p> | |
| <p class="stat-num attention">14</p> | |
| <p style="font-size:13px;color:var(--gray-500);margin-top:2px">across 4 campuses</p> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="stack-sm"> | |
| <div class="section-header"> | |
| <div class="dot attention"></div> | |
| <span class="section-label attention">⚠ Needs mapping</span> | |
| <span class="section-count">2</span> | |
| <div class="divider"></div> | |
| </div> | |
| <div class="card-grid"> | |
| <div class="card attention"> | |
| <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:12px"> | |
| <div> | |
| <div class="card-eyebrow">⚠ 8 unmapped</div> | |
| <div class="card-title">Riverside Academy</div> | |
| <div class="card-sub">23 total accounts</div> | |
| </div> | |
| <div class="card-arrow">↗</div> | |
| </div> | |
| </div> | |
| <div class="card attention"> | |
| <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:12px"> | |
| <div> | |
| <div class="card-eyebrow">⚠ 6 unmapped</div> | |
| <div class="card-title">Brookside Campus</div> | |
| <div class="card-sub">19 total accounts</div> | |
| </div> | |
| <div class="card-arrow">↗</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="stack-sm"> | |
| <div class="section-header"> | |
| <div class="dot success"></div> | |
| <span class="section-label success">✓ Up to date</span> | |
| <span class="section-count">2</span> | |
| <div class="divider"></div> | |
| </div> | |
| <div class="card-grid"> | |
| <div class="card"> | |
| <div style="display:flex;justify-content:space-between;align-items:center;gap:12px"> | |
| <div> | |
| <div class="card-title sm">Lakeside Annex</div> | |
| <div class="card-sub success">✓ All 21 mapped</div> | |
| </div> | |
| <div class="card-arrow">↗</div> | |
| </div> | |
| </div> | |
| <div class="card"> | |
| <div style="display:flex;justify-content:space-between;align-items:center;gap:12px"> | |
| <div> | |
| <div class="card-title sm">Hillcrest Day School</div> | |
| <div class="card-sub success">✓ All 18 mapped</div> | |
| </div> | |
| <div class="card-arrow">↗</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="stack-sm"> | |
| <div class="section-header"> | |
| <div class="dot muted"></div> | |
| <span class="section-label muted">Not connected yet</span> | |
| <span class="section-count">1</span> | |
| <div class="divider"></div> | |
| </div> | |
| <div class="card-grid"> | |
| <div class="card muted"> | |
| <div style="display:flex;justify-content:space-between;align-items:center;gap:12px"> | |
| <div> | |
| <div class="card-title sm" style="color:var(--gray-700)">Pinewood Prep</div> | |
| <div class="card-sub muted">⌁ Not connected to QuickBooks yet</div> | |
| </div> | |
| <div class="card-arrow">↗</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="demo-divider"></div> | |
| <p class="demo-label">Mock 2 — Per-campus mapping page</p> | |
| <div class="stack"> | |
| <a href="#" class="back-link">← All campuses</a> | |
| <header class="page-header"> | |
| <div> | |
| <p class="eyebrow">Account Mapping · Per Campus</p> | |
| <h1 class="page-title">Map QuickBooks accounts</h1> | |
| <p class="page-desc">Match each QuickBooks line item to the firm-wide standard category it belongs to. Mappings flow into financial KPIs and the standardized P&L report.</p> | |
| </div> | |
| <div class="stats-strip"> | |
| <div class="stat"> | |
| <p class="eyebrow">Unmapped</p> | |
| <p class="stat-num attention">3</p> | |
| </div> | |
| <div class="stat-divider"></div> | |
| <div class="stat"> | |
| <p class="eyebrow">Mapped</p> | |
| <p class="stat-num neutral">7</p> | |
| </div> | |
| <div class="stat-divider"></div> | |
| <div class="stat"> | |
| <p class="eyebrow">Pending</p> | |
| <p class="stat-num info">2</p> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="stack-sm"> | |
| <div class="section-header"> | |
| <div class="dot attention"></div> | |
| <span class="section-label attention">⚠ Needs mapping</span> | |
| <span class="section-count">3</span> | |
| <div class="divider"></div> | |
| </div> | |
| <div class="row-card"> | |
| <div class="mapping-row edited"> | |
| <div class="row-info"> | |
| <div class="row-name">Tuition Income</div> | |
| <div class="row-type">Income · ServiceFeeIncome</div> | |
| </div> | |
| <div class="row-select"> | |
| <select class="edited"><option>Tuition Revenue</option></select> | |
| <div class="row-group">Revenue</div> | |
| </div> | |
| </div> | |
| <div class="mapping-row"> | |
| <div class="row-info"> | |
| <div class="row-name">Late Fees</div> | |
| <div class="row-type">Income</div> | |
| </div> | |
| <div class="row-select"> | |
| <select><option>— Select category —</option></select> | |
| </div> | |
| </div> | |
| <div class="mapping-row"> | |
| <div class="row-info"> | |
| <div class="row-name">Misc Revenue</div> | |
| <div class="row-type">Income · OtherPrimaryIncome</div> | |
| </div> | |
| <div class="row-select"> | |
| <select><option>— Select category —</option></select> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="stack-sm"> | |
| <div class="section-header"> | |
| <div class="dot success"></div> | |
| <span class="section-label success">✓ Mapped</span> | |
| <span class="section-count">7</span> | |
| <div class="divider"></div> | |
| </div> | |
| <div class="row-card"> | |
| <div class="mapping-row edited"> | |
| <div class="row-info"> | |
| <div class="row-name">Classroom Materials</div> | |
| <div class="row-type">Expense · Supplies</div> | |
| </div> | |
| <div class="row-select"> | |
| <select class="edited"><option>Classroom Supplies & Materials</option></select> | |
| <div class="row-group">Cost of Goods Sold</div> | |
| </div> | |
| </div> | |
| <div class="mapping-row"> | |
| <div class="row-info"> | |
| <div class="row-name">Office Rent</div> | |
| <div class="row-type">Expense · Rent or Lease</div> | |
| </div> | |
| <div class="row-select"> | |
| <select><option>Rent/Lease</option></select> | |
| <div class="row-group">Operating Expense</div> | |
| </div> | |
| </div> | |
| <div class="mapping-row"> | |
| <div class="row-info"> | |
| <div class="row-name">Electric & Gas</div> | |
| <div class="row-type">Expense · Utilities</div> | |
| </div> | |
| <div class="row-select"> | |
| <select><option>Utilities</option></select> | |
| <div class="row-group">Operating Expense</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="save-bar"> | |
| <div class="save-bar-inner"> | |
| <div class="save-bar-status"> | |
| <div style="width:6px;height:6px;border-radius:50%;background:var(--accent)"></div> | |
| 2 unsaved changes | |
| </div> | |
| <div class="save-bar-actions"> | |
| <button class="btn btn-ghost">Discard</button> | |
| <button class="btn btn-primary">⎙ Save 2 changes</button> | |
| </div> | |
| </div> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment