Integrate whynot-design into Economic Observatory UI

Vendor whynot-design Layer 1 (tokens, CSS) and Layer 2 (<wn-*>
components) via scripts/sync-whynot-design.sh with a pinned ref.
Migrate the observatory shell to canonical web components, keep
observatory-specific layout in styles.css, and add vendor integrity
tests plus correct JS MIME types on the dev server.
This commit is contained in:
2026-06-22 03:09:44 +02:00
parent 9c1c2142fc
commit da3b7d66f0
21 changed files with 2903 additions and 354 deletions

View File

@@ -3,71 +3,95 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Coulomb Economic Observatory</title>
<title>Coulomb · Economic Observatory</title>
<link rel="stylesheet" href="/ui/vendor/whynot-design/colors_and_type.css" />
<link rel="stylesheet" href="/ui/vendor/whynot-design/components.css" />
<link rel="stylesheet" href="/ui/styles.css" />
<script type="importmap">
{
"imports": {
"lit": "https://esm.sh/lit@3.2.1",
"lit/": "https://esm.sh/lit@3.2.1/"
}
}
</script>
<script type="module" src="/ui/vendor/whynot-design/index.js"></script>
</head>
<body>
<div class="app">
<header class="topbar">
<div>
<p class="eyebrow">Adaptive Pricing · Coulomb Social MVP</p>
<h1>Economic Observatory</h1>
</div>
<div class="topbar-actions">
<label>
Period
<select id="period-select"></select>
</label>
<span class="badge" id="liquidity-badge"></span>
</div>
</header>
<wn-top-nav brand="adaptive-pricing" slug="coulomb · observatory">
<div slot="right" class="obs-period" id="period-control">
<wn-eyebrow>Period</wn-eyebrow>
<wn-select id="period-select"></wn-select>
</div>
<wn-tag slot="right" id="liquidity-badge"></wn-tag>
</wn-top-nav>
<section class="hero-grid" id="hero-grid"></section>
<main class="wn-main obs-main">
<wn-page-header
eyebrow="Economic Observatory · MVP"
title="Operator liquidity"
lede="Ledger-backed view of infrastructure spend, member payments, and remaining budget. Customer cost-pass-through billing is not active."
id="page-header"
></wn-page-header>
<section class="panel budget-panel">
<div class="panel-head">
<h2>Liquidity &amp; Budget</h2>
<p id="budget-caption">Operator liquidity pool</p>
<section class="obs-section">
<div class="obs-section__head">
<wn-eyebrow>Snapshot</wn-eyebrow>
<div class="obs-section__rule"></div>
</div>
<div class="budget-bar">
<div class="budget-fill" id="budget-fill"></div>
</div>
<div class="budget-stats" id="budget-stats"></div>
<div class="obs-metric-grid" id="metric-grid"></div>
</section>
<div class="split-grid">
<section class="panel">
<div class="panel-head">
<h2>Monthly Net Liquidity</h2>
<p>Member net payments minus infrastructure</p>
<section class="obs-section">
<div class="obs-section__head">
<wn-eyebrow>Liquidity &amp; budget</wn-eyebrow>
<div class="obs-section__rule"></div>
</div>
<wn-banner variant="info" title="Budget position" id="budget-banner">
<p id="budget-caption"></p>
</wn-banner>
<div class="obs-budget-meter" aria-hidden="true">
<div class="obs-budget-meter__fill" id="budget-fill"></div>
</div>
<div class="obs-field-sheet" id="budget-stats"></div>
</section>
<div class="obs-split">
<section class="obs-section">
<div class="obs-section__head">
<wn-eyebrow>Monthly net liquidity</wn-eyebrow>
<div class="obs-section__rule"></div>
</div>
<div class="chart" id="liquidity-chart"></div>
<p class="lead obs-section-note">Member net payments minus infrastructure, by period.</p>
<div class="obs-liquidity-list" id="liquidity-chart"></div>
</section>
<section class="panel">
<div class="panel-head">
<h2>Infrastructure Stack</h2>
<p>Domains, hosting, and Stripe reference</p>
<section class="obs-section">
<div class="obs-section__head">
<wn-eyebrow>Infrastructure stack</wn-eyebrow>
<div class="obs-section__rule"></div>
</div>
<p class="lead obs-section-note">Domains, hosting, and Stripe reference rates.</p>
<div id="infra-stack"></div>
</section>
</div>
<section class="panel">
<div class="panel-head">
<h2>Monthly Ledger</h2>
<p>Computed from expense and payment record tables</p>
<section class="obs-section">
<div class="obs-section__head">
<wn-eyebrow>Monthly ledger</wn-eyebrow>
<div class="obs-section__rule"></div>
</div>
<div class="table-wrap">
<table>
<p class="lead obs-section-note">Computed from expense and payment record tables.</p>
<div class="obs-table-wrap">
<table class="wn-table--native obs-table">
<thead>
<tr>
<th>Period</th>
<th>Members</th>
<th>Gross</th>
<th>Infrastructure</th>
<th>Processing</th>
<th>Net liquidity</th>
<th class="obs-num">Gross</th>
<th class="obs-num">Infrastructure</th>
<th class="obs-num">Processing</th>
<th class="obs-num">Net liquidity</th>
</tr>
</thead>
<tbody id="history-body"></tbody>
@@ -75,12 +99,13 @@
</div>
</section>
<section class="panel">
<div class="panel-head">
<h2>Pricing Model Registry</h2>
<section class="obs-section">
<div class="obs-section__head">
<wn-eyebrow>Pricing model registry</wn-eyebrow>
<div class="obs-section__rule"></div>
</div>
<div class="table-wrap">
<table>
<div class="obs-table-wrap">
<table class="wn-table--native obs-table">
<thead>
<tr>
<th>ID</th>
@@ -94,14 +119,17 @@
</div>
</section>
<footer class="footer">
<p>
Design reference:
<footer class="obs-footer">
<p class="small">
Design:
<a id="design-link" href="#" target="_blank" rel="noreferrer">Claude design share</a>
· Totals computed programmatically from ledgers · Customer cost-pass-through billing not active
·
<span class="mono" id="design-ref-label">whynot-design</span>
· totals computed programmatically from ledgers
</p>
</footer>
</div>
</main>
<script src="/ui/app.js"></script>
</body>
</html>