380 lines
21 KiB
HTML
380 lines
21 KiB
HTML
<!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 & 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 & 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>2010–15</span><strong>Context</strong><small>History only</small></li>
|
||
<li><span>2016–22</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>
|