SummerProject2026/dashboard/index.html
2026-07-15 17:55:53 -06:00

380 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Utah Vehicle Health — an accessible, aggregate view of emissions-inspection outcomes.">
<meta name="referrer" content="no-referrer">
<title>Overview · Utah Vehicle Health</title>
<link rel="stylesheet" href="./styles.css">
<script type="module" src="./js/app.js"></script>
</head>
<body>
<a class="skip-link" href="#main-content">Skip to dashboard content</a>
<div id="preview-banner" class="preview-banner" role="status" hidden>
<span class="preview-banner__icon" aria-hidden="true"></span>
<div>
<strong id="preview-title">Development preview</strong>
<span id="preview-copy">Sample results are not population estimates and must not be used for individual decisions.</span>
</div>
</div>
<header class="site-header">
<div class="site-header__inner">
<a class="brand" href="#overview" aria-label="Utah Vehicle Health overview">
<svg class="brand__mark" viewBox="0 0 56 56" aria-hidden="true">
<path d="M9 43 23 17l7 12 6-9 12 23H9Z" fill="currentColor"></path>
<path d="m18 43 9-16 6 10 4-6 6 12H18Z" fill="var(--sand-100)"></path>
</svg>
<span>
<span class="brand__name">Utah Vehicle Health</span>
<span class="brand__tagline">Next-episode inspection insights</span>
</span>
</a>
<div class="header-status" id="header-status" aria-live="polite">
<span class="status-dot" aria-hidden="true"></span>
<span>Loading approved aggregates…</span>
</div>
</div>
<nav class="primary-nav" aria-label="Dashboard views">
<div class="primary-nav__inner">
<a href="#overview" data-route="overview" aria-current="page">Overview</a>
<a href="#reliability" data-route="reliability">Reliability explorer</a>
<a href="#estimator" data-route="estimator">Next-test estimator</a>
<a href="#methods" data-route="methods">Data &amp; methods</a>
</div>
</nav>
</header>
<main id="main-content" tabindex="-1">
<section class="view" id="view-overview" data-view="overview" aria-labelledby="overview-heading">
<div class="page-shell">
<header class="page-heading page-heading--split">
<div>
<p class="eyebrow">Inspection outcomes over time</p>
<h1 id="overview-heading">A clearer view of the next inspection</h1>
<p class="lede">Explore aggregate first-attempt outcomes for returning vehicles in participating Utah county feeds. Non-pass combines fail, reject, and abort.</p>
</div>
<div class="data-stamp" aria-label="Dataset status">
<span>Data through</span>
<strong id="data-cutoff">Unavailable</strong>
<small id="model-version">Waiting for manifest</small>
</div>
</header>
<div class="unavailable-state" data-unavailable hidden role="status">
<div class="unavailable-state__icon" aria-hidden="true">!</div>
<div>
<h2>Dashboard data is unavailable</h2>
<p data-unavailable-message>The approved aggregate files could not be validated. No estimates are being shown.</p>
</div>
</div>
<section class="kpi-grid" aria-label="Overview statistics" data-requires-data>
<article class="kpi-card">
<span class="kpi-card__label">Published support</span>
<strong id="kpi-eligible"></strong>
<small>Rounded total; suppressed cells omitted</small>
</article>
<article class="kpi-card kpi-card--pass">
<span class="kpi-card__label">Pass rate</span>
<strong id="kpi-pass"></strong>
<small>Recognized first-attempt outcomes</small>
</article>
<article class="kpi-card kpi-card--nonpass">
<span class="kpi-card__label">Non-pass rate</span>
<strong id="kpi-nonpass"></strong>
<small>Fail + reject + abort</small>
</article>
<article class="kpi-card">
<span class="kpi-card__label">Covered counties</span>
<strong id="kpi-counties"></strong>
<small>Not statewide coverage</small>
</article>
</section>
<div class="dashboard-grid dashboard-grid--wide" data-requires-data>
<article class="panel panel--wide">
<header class="panel__header">
<div>
<p class="eyebrow">Quarterly outcomes</p>
<h2>First-attempt non-pass trend</h2>
</div>
<div class="chart-legend" aria-label="Outcome legend">
<span><i class="legend-swatch legend-swatch--fail"></i>Non-pass (fail + reject + abort)</span>
</div>
</header>
<div id="outcome-trend-chart" class="chart chart--large" role="img" aria-label="Quarterly inspection outcome rates"></div>
<p class="chart-note" id="outcome-trend-note">Partial periods and source changes are called out when present.</p>
</article>
<article class="panel">
<header class="panel__header">
<div>
<p class="eyebrow">Feed availability</p>
<h2>County coverage</h2>
</div>
</header>
<div id="utah-coverage-map" class="utah-map" role="img" aria-label="Utah county-feed coverage"></div>
<div id="county-coverage-list" class="county-list" aria-label="County availability list"></div>
<p class="chart-note">Teal counties appear in the approved inspection feeds. Gray counties are unavailable, not zero.</p>
</article>
<article class="panel">
<header class="panel__header">
<div>
<p class="eyebrow">Age pattern</p>
<h2>Non-pass risk by vehicle age</h2>
</div>
</header>
<div id="age-risk-chart" class="chart" role="img" aria-label="Published non-pass risk by vehicle-age band"></div>
<p class="chart-note">The development bundle does not include confidence intervals; published aggregate rates are shown as points.</p>
</article>
</div>
<aside class="callout" data-requires-data>
<span class="callout__icon" aria-hidden="true">i</span>
<p><strong>What this measures:</strong> emissions-inspection outcomes for covered feeds. It is not a diagnosis of mechanical condition, safety, roadworthiness, or legal compliance.</p>
</aside>
</div>
</section>
<section class="view" id="view-reliability" data-view="reliability" aria-labelledby="reliability-heading" hidden>
<div class="page-shell">
<header class="page-heading">
<p class="eyebrow">Supported aggregate cohorts</p>
<h1 id="reliability-heading">Reliability explorer</h1>
<p class="lede">Compare published observed next-episode non-pass rates. Every result is a supported aggregate cohort—not an individual prediction.</p>
</header>
<div class="unavailable-state" data-unavailable hidden role="status">
<div class="unavailable-state__icon" aria-hidden="true">!</div>
<div><h2>Explorer unavailable</h2><p data-unavailable-message>Approved scorecards could not be validated.</p></div>
</div>
<div class="explorer-layout" data-requires-data>
<aside class="filter-panel" aria-labelledby="filter-heading">
<div class="filter-panel__heading">
<h2 id="filter-heading">Refine cohorts</h2>
<button class="text-button" id="reset-filters" type="button">Reset</button>
</div>
<form id="explorer-filters">
<label class="field">
<span>Make or model</span>
<input id="cohort-search" type="search" autocomplete="off" placeholder="Search supported cohorts">
</label>
<label class="field">
<span>County</span>
<select id="filter-county"><option value="">All covered counties</option></select>
</label>
<label class="field">
<span>Vehicle age</span>
<select id="filter-age"><option value="">All age bands</option></select>
</label>
<label class="field">
<span>Fuel</span>
<select id="filter-fuel"><option value="">All supported fuels</option></select>
</label>
<label class="field">
<span>Program</span>
<select id="filter-program"><option value="">All approved programs</option></select>
</label>
<label class="field">
<span>Period</span>
<select id="filter-period"><option value="">All published periods</option></select>
</label>
<fieldset class="segmented-control">
<legend>Risk view</legend>
<label><input type="radio" name="risk-view" value="observed" checked><span>Observed</span></label>
<label><input type="radio" name="risk-view" value="adjusted"><span>Model-adjusted</span></label>
</fieldset>
</form>
</aside>
<div class="explorer-results">
<div class="result-toolbar">
<p id="result-summary" aria-live="polite">Loading supported cohorts…</p>
<label class="field field--inline">
<span>Sort</span>
<select id="result-sort">
<option value="support">Largest support</option>
<option value="risk-desc">Highest non-pass risk</option>
<option value="risk-asc">Lowest non-pass risk</option>
<option value="name">Make and model</option>
</select>
</label>
</div>
<article class="panel">
<header class="panel__header">
<div><p class="eyebrow">Published aggregate comparison</p><h2>Supported cohort scorecard</h2></div>
</header>
<div id="cohort-dot-plot" class="chart chart--scorecard" role="img" aria-label="Ranked published cohort non-pass rates"></div>
</article>
<div id="cohort-cards" class="cohort-cards"></div>
<div class="empty-results" id="empty-results" hidden>
<h2>No supported cohorts match</h2>
<p>Try clearing one or more filters. Suppressed cohorts are never included in the browser bundle.</p>
</div>
</div>
</div>
</div>
</section>
<section class="view" id="view-estimator" data-view="estimator" aria-labelledby="estimator-heading" hidden>
<div class="page-shell page-shell--narrow">
<header class="page-heading">
<p class="eyebrow">Cohort estimate · not an individual diagnosis</p>
<h1 id="estimator-heading">Next-test risk estimator</h1>
<p class="lede">This planned tool will combine approved, coarsened attributes to return a calibrated next-episode non-pass probability.</p>
</header>
<div class="locked-panel" role="status" aria-labelledby="estimator-status-title">
<span class="locked-panel__icon" aria-hidden="true"></span>
<div>
<p class="eyebrow">Intentionally disabled</p>
<h2 id="estimator-status-title">An approved prediction lookup is not available</h2>
<p>The estimator will remain off until a privacy-reviewed, suppressed <code>prediction_lookup</code> is published. The current model diagnostics are not enough to serve individual or row-level estimates.</p>
</div>
</div>
<form class="estimator-form" aria-describedby="estimator-disabled-copy">
<fieldset disabled>
<legend>Coarsened cohort attributes</legend>
<div class="form-grid">
<label class="field"><span>County</span><select><option>Select a covered county</option></select></label>
<label class="field"><span>Supported make and model</span><select><option>Select a cohort</option></select></label>
<label class="field"><span>Vehicle-age band</span><select><option>Select an age band</option></select></label>
<label class="field"><span>Fuel</span><select><option>Select a supported fuel</option></select></label>
<label class="field"><span>Prior episode outcome</span><select><option>Pass / fail / reject / abort</option></select></label>
<label class="field"><span>Time since prior episode</span><select><option>Select a coarsened interval</option></select></label>
<label class="field"><span>Season</span><select><option>Select a season</option></select></label>
<label class="field"><span>Program category</span><select><option>Select an approved program</option></select></label>
</div>
<button class="button" type="button">Estimate cohort risk</button>
</fieldset>
</form>
<p id="estimator-disabled-copy" class="form-note">No VIN, plate, exact address, station, free text, or current-test diagnostic will ever be requested.</p>
<section class="method-preview" aria-labelledby="future-output-heading">
<div>
<p class="eyebrow">Future approved output</p>
<h2 id="future-output-heading">Designed for calibrated context</h2>
</div>
<ul class="check-list">
<li>Calibrated non-pass probability and uncertainty</li>
<li>Relevant aggregate baseline</li>
<li>High-level factor contributions</li>
<li>Support and coverage limitations</li>
</ul>
</section>
</div>
</section>
<section class="view" id="view-methods" data-view="methods" aria-labelledby="methods-heading" hidden>
<div class="page-shell">
<header class="page-heading">
<p class="eyebrow">Transparent by design</p>
<h1 id="methods-heading">Data &amp; methods</h1>
<p class="lede">How episodes, labels, temporal evaluation, coverage limits, and privacy controls shape every published result.</p>
</header>
<div class="unavailable-state" data-unavailable hidden role="status">
<div class="unavailable-state__icon" aria-hidden="true">!</div>
<div><h2>Live diagnostics unavailable</h2><p data-unavailable-message>Static methodology remains below; no performance values are being shown.</p></div>
</div>
<section class="method-grid" aria-label="Core definitions">
<article class="method-card">
<span class="method-card__number">01</span>
<h2>Prediction unit</h2>
<p>The first attempt of the next inspection episode. Attempts no more than 30 days apart form one episode.</p>
</article>
<article class="method-card">
<span class="method-card__number">02</span>
<h2>Binary target</h2>
<p>Pass versus non-pass. Non-pass combines fail, reject, and abort; blanks and unrecognized outcomes are not labels.</p>
</article>
<article class="method-card">
<span class="method-card__number">03</span>
<h2>Point-in-time features</h2>
<p>Every history window ends before the target episode. Current-test results, diagnostics, stations, and later attempts are excluded.</p>
</article>
</section>
<section class="panel" data-requires-data>
<header class="panel__header"><div><p class="eyebrow">Availability by source era</p><h2>Coverage timeline</h2></div></header>
<div id="coverage-heatmap" class="heatmap" role="img" aria-label="Inspection source availability by year"></div>
<p class="chart-note">The <code>slc</code> and <code>slco</code> labels are source eras for Salt Lake County, not separate physical counties.</p>
</section>
<section class="split-section" aria-labelledby="split-heading">
<div class="split-section__copy">
<p class="eyebrow">No random row split</p>
<h2 id="split-heading">Chronological evaluation</h2>
<p>Historical events establish prior context. The 2025 development-sample holdout was evaluated once after model choices were frozen, so it is no longer a pristine final test. A later complete-data run is confirmatory; the partial 2026 feed is monitoring only.</p>
</div>
<ol class="timeline">
<li><span>201015</span><strong>Context</strong><small>History only</small></li>
<li><span>201622</span><strong>Train</strong><small>Fit preprocessing + model</small></li>
<li><span>2023</span><strong>Tune</strong><small>Select regularization</small></li>
<li><span>2024</span><strong>Calibrate</strong><small>Scale probabilities</small></li>
<li class="timeline__holdout"><span>2025</span><strong>One-time holdout</strong><small>Already evaluated</small></li>
<li><span>2026</span><strong>Shadow</strong><small>Partial-period drift</small></li>
</ol>
</section>
<div class="dashboard-grid" data-requires-data>
<article class="panel">
<header class="panel__header"><div><p class="eyebrow" id="diagnostic-scope-label">Model diagnostics</p><h2>Published model diagnostics</h2></div></header>
<div class="diagnostic-kpis">
<div><span>PR-AUC</span><strong id="diagnostic-ap"></strong></div>
<div><span>Brier score</span><strong id="diagnostic-brier"></strong></div>
<div><span>Support</span><strong id="diagnostic-n"></strong></div>
</div>
<div id="calibration-chart" class="chart" role="img" aria-label="Predicted versus observed non-pass risk calibration"></div>
</article>
<article class="panel">
<header class="panel__header"><div><p class="eyebrow">Interpret with care</p><h2>Known limitations</h2></div></header>
<ul class="limitation-list" id="manifest-limitations">
<li>Participating inspection feeds do not cover all 29 counties.</li>
<li>Feed and program changes can resemble real-world trends.</li>
<li>DMV history has a 2021 gap and ends in March 2024.</li>
<li>Reject and abort can reflect process or readiness issues.</li>
<li>Association is not causation or a mechanical diagnosis.</li>
</ul>
</article>
</div>
<section class="privacy-panel">
<div><p class="eyebrow">Publication boundary</p><h2>Only approved aggregates reach this site</h2></div>
<div class="privacy-flow" aria-label="Private-to-public data flow">
<span class="privacy-flow__private">Private source<br><small>Read-only local pipeline</small></span>
<span aria-hidden="true"></span>
<span>Suppression<br><small>Minimum support + complements</small></span>
<span aria-hidden="true"></span>
<span class="privacy-flow__public">Public assets<br><small>Aggregate JSON only</small></span>
</div>
<p>Direct identifiers, private vehicle tokens, plates, ZIPs, stations, raw records, and row-level predictions are outside the public data contract.</p>
</section>
</div>
</section>
</main>
<footer class="site-footer">
<div class="page-shell site-footer__inner">
<div><strong>Utah Vehicle Health</strong><p>Aggregate emissions-inspection research.</p></div>
<p>Not a diagnosis, certification, safety assessment, or guarantee of an inspection outcome.</p>
</div>
</footer>
<div id="route-announcer" class="sr-only" aria-live="polite"></div>
<noscript><div class="noscript">JavaScript is required to validate and display the approved aggregate data files. No estimates are shown without validation.</div></noscript>
</body>
</html>