Science — Dataset Explorer
A client-side research dataset portal with a live search bar, faceted filter rail for domain, format, license, size and release year, plus a sortable, switchable grid and list of dataset cards. Each card carries a license badge, file count, size and citation count, and opens a detail drawer exposing the variable schema, a sample data preview, version history and ready-to-copy citation and DOI actions, all over a seeded in-script catalog of fictional records.
MCP
Code
:root {
--bg: #ffffff;
--bg-alt: #f6f8fb;
--ink: #0f1b2d;
--ink-2: #33445c;
--muted: #697892;
--accent: #1a4f8a;
--accent-d: #123a66;
--accent-50: #e9f0f9;
--teal: #0f7d78;
--teal-50: #e4f3f1;
--line: rgba(15, 27, 45, 0.12);
--line-2: rgba(15, 27, 45, 0.2);
--ok: #2f9e6f;
--warn: #c9821f;
--danger: #cf4538;
--r-sm: 6px;
--r-md: 10px;
--r-lg: 16px;
--sans: "Inter", system-ui, sans-serif;
--serif: "Source Serif 4", Georgia, serif;
--mono: "JetBrains Mono", ui-monospace, monospace;
--shadow-sm: 0 1px 2px rgba(15, 27, 45, 0.06), 0 1px 3px rgba(15, 27, 45, 0.05);
--shadow-md: 0 6px 20px rgba(15, 27, 45, 0.1);
--shadow-lg: 0 18px 50px rgba(15, 27, 45, 0.22);
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0;
font-family: var(--sans);
background: var(--bg);
color: var(--ink);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-radius: 3px;
}
.skip-link {
position: absolute;
left: -999px;
top: 8px;
background: var(--accent);
color: #fff;
padding: 8px 14px;
border-radius: var(--r-sm);
z-index: 60;
}
.skip-link:focus { left: 12px; }
/* ---- Top bar ---- */
.topbar {
border-bottom: 1px solid var(--line);
background: var(--bg);
position: sticky;
top: 0;
z-index: 30;
}
.topbar-inner {
max-width: 1240px;
margin: 0 auto;
padding: 12px 24px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand-mark { color: var(--accent); display: inline-flex; }
.brand-text { display: flex; flex-direction: column; line-height: 1.2; }
.brand-text strong { font-size: 15px; letter-spacing: -0.01em; }
.brand-text span { font-size: 11.5px; color: var(--muted); font-family: var(--mono); }
.topnav { display: flex; gap: 4px; }
.topnav a {
font-size: 13.5px;
font-weight: 500;
color: var(--ink-2);
padding: 7px 12px;
border-radius: var(--r-sm);
}
.topnav a:hover { background: var(--bg-alt); text-decoration: none; }
.topnav a[aria-current="page"] { color: var(--accent); background: var(--accent-50); }
/* ---- Hero ---- */
.hero {
background: linear-gradient(180deg, var(--bg-alt), var(--bg));
border-bottom: 1px solid var(--line);
}
.hero-inner {
max-width: 1240px;
margin: 0 auto;
padding: 40px 24px 32px;
}
.hero h1 {
font-family: var(--serif);
font-weight: 700;
font-size: clamp(28px, 4vw, 40px);
margin: 0 0 8px;
letter-spacing: -0.02em;
}
.hero-sub {
font-family: var(--serif);
color: var(--ink-2);
max-width: 60ch;
margin: 0 0 22px;
font-size: 16.5px;
}
.searchrow { max-width: 640px; }
.searchbox {
display: flex;
align-items: center;
gap: 10px;
background: var(--bg);
border: 1px solid var(--line-2);
border-radius: var(--r-md);
padding: 0 12px;
box-shadow: var(--shadow-sm);
transition: border-color 0.15s, box-shadow 0.15s;
}
.searchbox:focus-within {
border-color: var(--accent);
box-shadow: 0 0 0 4px var(--accent-50);
}
.searchbox svg { color: var(--muted); flex: none; }
.searchbox input {
flex: 1;
border: 0;
outline: 0;
background: transparent;
font-family: var(--sans);
font-size: 15px;
color: var(--ink);
padding: 13px 0;
}
.clear-btn {
border: 0;
background: var(--bg-alt);
color: var(--ink-2);
width: 22px; height: 22px;
border-radius: 50%;
cursor: pointer;
font-size: 16px;
line-height: 1;
flex: none;
}
.clear-btn:hover { background: var(--line); }
/* ---- Layout ---- */
.layout {
max-width: 1240px;
margin: 0 auto;
padding: 28px 24px 56px;
display: grid;
grid-template-columns: 252px 1fr;
gap: 32px;
align-items: start;
}
/* ---- Filter rail ---- */
.rail {
position: sticky;
top: 76px;
display: flex;
flex-direction: column;
gap: 4px;
}
.rail-head {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 6px;
}
.rail-head h2 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin: 0; }
.link-btn {
border: 0; background: none; color: var(--accent);
font-family: var(--sans); font-size: 12.5px; font-weight: 500;
cursor: pointer; padding: 0;
}
.link-btn:hover { text-decoration: underline; }
.facet {
border: 0;
border-top: 1px solid var(--line);
margin: 0;
padding: 16px 0 6px;
}
.facet legend {
font-size: 13px;
font-weight: 600;
color: var(--ink);
padding: 0;
display: flex;
align-items: center;
gap: 8px;
width: 100%;
justify-content: space-between;
}
.year-out { font-family: var(--mono); font-size: 11.5px; color: var(--accent); font-weight: 500; }
.facet-list { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; }
.check {
display: flex;
align-items: center;
gap: 9px;
font-size: 13.5px;
color: var(--ink-2);
padding: 4px 6px;
border-radius: var(--r-sm);
cursor: pointer;
}
.check:hover { background: var(--bg-alt); }
.check input { accent-color: var(--accent); width: 15px; height: 15px; flex: none; }
.check span { flex: 1; }
.check .facet-count {
font-family: var(--mono);
font-size: 11px;
color: var(--muted);
background: var(--bg-alt);
padding: 1px 6px;
border-radius: 20px;
}
.range-wrap {
position: relative;
margin: 14px 4px 6px;
}
.range-wrap input[type="range"] {
-webkit-appearance: none;
appearance: none;
width: 100%;
background: transparent;
pointer-events: none;
position: absolute;
height: 16px;
margin: 0;
}
.range-wrap::before {
content: "";
position: absolute;
left: 0; right: 0; top: 6px;
height: 4px;
background: var(--line);
border-radius: 4px;
}
.range-wrap input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
pointer-events: auto;
width: 16px; height: 16px;
border-radius: 50%;
background: var(--bg);
border: 2px solid var(--accent);
cursor: pointer;
box-shadow: var(--shadow-sm);
}
.range-wrap input[type="range"]::-moz-range-thumb {
pointer-events: auto;
width: 16px; height: 16px;
border-radius: 50%;
background: var(--bg);
border: 2px solid var(--accent);
cursor: pointer;
}
/* ---- Content / toolbar ---- */
.toolbar {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 18px;
}
.resultcount { font-size: 14px; font-weight: 600; color: var(--ink); margin: 0; }
.resultcount span.muted { font-weight: 400; color: var(--muted); }
.active-filters { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; }
.chip {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12px;
background: var(--accent-50);
color: var(--accent-d);
border: 1px solid rgba(26, 79, 138, 0.18);
padding: 3px 6px 3px 10px;
border-radius: 20px;
}
.chip button {
border: 0; background: none; color: inherit;
cursor: pointer; font-size: 14px; line-height: 1; padding: 0 2px;
}
.chip button:hover { color: var(--danger); }
.toolbar-right { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.viewtoggle { display: flex; border: 1px solid var(--line-2); border-radius: var(--r-sm); overflow: hidden; }
.vt-btn {
border: 0; background: var(--bg); color: var(--muted);
padding: 6px 9px; cursor: pointer; display: inline-flex;
}
.vt-btn + .vt-btn { border-left: 1px solid var(--line-2); }
.vt-btn svg { fill: currentColor; }
.vt-btn:hover { background: var(--bg-alt); }
.vt-btn.is-active { background: var(--accent-50); color: var(--accent); }
.sortwrap { display: flex; align-items: center; gap: 8px; }
.sort-label { font-size: 12.5px; color: var(--muted); }
#sort {
font-family: var(--sans);
font-size: 13.5px;
color: var(--ink);
border: 1px solid var(--line-2);
border-radius: var(--r-sm);
padding: 7px 28px 7px 10px;
background: var(--bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' stroke='%23697892' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 9px center;
-webkit-appearance: none;
appearance: none;
cursor: pointer;
}
/* ---- Grid / cards ---- */
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
}
.grid.list { grid-template-columns: 1fr; }
.card {
border: 1px solid var(--line);
border-radius: var(--r-lg);
background: var(--bg);
padding: 18px;
display: flex;
flex-direction: column;
gap: 12px;
cursor: pointer;
transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
text-align: left;
position: relative;
}
.card:hover { border-color: var(--line-2); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.card:focus-visible { border-color: var(--accent); }
.card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.card-domain {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--teal);
display: inline-flex;
align-items: center;
gap: 6px;
}
.card-domain::before {
content: "";
width: 7px; height: 7px; border-radius: 50%;
background: var(--teal);
}
.card h3 {
font-family: var(--serif);
font-size: 17px;
font-weight: 600;
margin: 0;
line-height: 1.3;
letter-spacing: -0.01em;
}
.card .author { font-size: 12.5px; color: var(--muted); margin: 0; }
.card .desc {
font-family: var(--serif);
font-size: 14px;
color: var(--ink-2);
margin: 0;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.card-meta {
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
font-family: var(--mono);
font-size: 11.5px;
color: var(--muted);
padding-top: 4px;
border-top: 1px dashed var(--line);
margin-top: auto;
}
.card-meta .m { display: inline-flex; align-items: center; gap: 5px; }
.card-meta .m strong { color: var(--ink-2); font-weight: 500; }
.card-foot { display: flex; align-items: center; gap: 10px; justify-content: space-between; }
.lic {
font-family: var(--mono);
font-size: 11px;
font-weight: 500;
padding: 3px 8px;
border-radius: var(--r-sm);
border: 1px solid;
}
.lic-cc0 { color: #1f7a4d; background: #e7f5ee; border-color: rgba(31,122,77,0.25); }
.lic-ccby { color: var(--accent-d); background: var(--accent-50); border-color: rgba(26,79,138,0.22); }
.lic-mit { color: #6b4ca8; background: #efe9f8; border-color: rgba(107,76,168,0.25); }
.lic-odbl { color: var(--warn); background: #fbf1e0; border-color: rgba(201,130,31,0.28); }
.lic-restricted { color: var(--danger); background: #fbe9e7; border-color: rgba(207,69,56,0.28); }
.btn {
font-family: var(--sans);
font-size: 13px;
font-weight: 600;
border-radius: var(--r-sm);
border: 1px solid var(--accent);
background: var(--accent);
color: #fff;
padding: 8px 14px;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 7px;
transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.btn:hover { background: var(--accent-d); border-color: var(--accent-d); }
.btn svg { fill: currentColor; }
.btn.ghost { background: transparent; color: var(--accent); }
.btn.ghost:hover { background: var(--accent-50); color: var(--accent-d); }
.btn.sm { padding: 6px 11px; font-size: 12.5px; }
/* list view tweaks */
.grid.list .card { flex-direction: row; align-items: center; gap: 18px; flex-wrap: wrap; }
.grid.list .card .card-main { flex: 1 1 340px; display: flex; flex-direction: column; gap: 8px; }
.grid.list .card .desc { -webkit-line-clamp: 2; }
.grid.list .card .card-meta { border: 0; padding-top: 0; margin: 0; }
.grid.list .card .card-foot { flex: none; flex-direction: column; align-items: flex-end; gap: 8px; }
/* empty */
.empty {
text-align: center;
padding: 64px 20px;
color: var(--muted);
}
.empty svg { color: var(--line-2); margin-bottom: 12px; }
.empty p { font-size: 15px; margin: 0 0 16px; }
/* ---- Drawer ---- */
.overlay {
position: fixed; inset: 0;
background: rgba(15, 27, 45, 0.42);
z-index: 40;
backdrop-filter: blur(2px);
animation: fade 0.18s ease;
}
@keyframes fade { from { opacity: 0; } }
.drawer {
position: fixed;
top: 0; right: 0; bottom: 0;
width: min(560px, 94vw);
background: var(--bg);
z-index: 50;
box-shadow: var(--shadow-lg);
overflow-y: auto;
animation: slidein 0.22s cubic-bezier(0.22, 0.61, 0.36, 1);
}
@keyframes slidein { from { transform: translateX(100%); } }
.drawer-head {
position: sticky;
top: 0;
background: var(--bg);
border-bottom: 1px solid var(--line);
padding: 18px 24px 16px;
z-index: 2;
}
.drawer-close {
position: absolute;
top: 16px; right: 18px;
border: 1px solid var(--line);
background: var(--bg);
width: 32px; height: 32px;
border-radius: 50%;
cursor: pointer;
font-size: 18px;
color: var(--ink-2);
line-height: 1;
}
.drawer-close:hover { background: var(--bg-alt); }
.drawer-head .card-domain { margin-bottom: 8px; }
.drawer-head h2 {
font-family: var(--serif);
font-size: 22px;
font-weight: 700;
margin: 0 44px 6px 0;
line-height: 1.25;
letter-spacing: -0.015em;
}
.drawer-head .author { font-size: 13px; color: var(--muted); margin: 0 0 4px; }
.drawer-head .doi { font-family: var(--mono); font-size: 12px; color: var(--accent); }
.drawer-body { padding: 22px 24px 32px; }
.drawer-body section { margin-bottom: 26px; }
.drawer-body h3 {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
margin: 0 0 10px;
}
.drawer-body p.abstract { font-family: var(--serif); font-size: 15px; color: var(--ink-2); margin: 0; }
.statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 10px; }
.stat {
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 11px 13px;
background: var(--bg-alt);
}
.stat .v { font-family: var(--mono); font-size: 17px; font-weight: 500; color: var(--ink); }
.stat .k { font-size: 11px; color: var(--muted); }
.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-md); }
table.vars { border-collapse: collapse; width: 100%; min-width: 420px; font-size: 13px; }
table.vars th, table.vars td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); }
table.vars thead th {
background: var(--bg-alt);
font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted);
}
table.vars tbody tr:last-child td { border-bottom: 0; }
table.vars td.name { font-family: var(--mono); color: var(--accent-d); }
table.vars td.unit { font-family: var(--mono); color: var(--muted); }
table.vars td.type { color: var(--ink-2); }
.preview {
font-family: var(--mono);
font-size: 12px;
background: #0f1b2d;
color: #cfe0f4;
border-radius: var(--r-md);
padding: 14px 16px;
overflow-x: auto;
line-height: 1.7;
margin: 0;
}
.preview .hl { color: #7fc7ff; }
.preview .num { color: #b7e3a8; }
.versions { display: flex; flex-direction: column; gap: 0; }
.ver {
display: flex;
align-items: baseline;
gap: 12px;
padding: 9px 0;
border-bottom: 1px solid var(--line);
font-size: 13.5px;
}
.ver:last-child { border-bottom: 0; }
.ver .tag {
font-family: var(--mono);
font-size: 11.5px;
font-weight: 500;
color: var(--accent-d);
background: var(--accent-50);
padding: 2px 8px;
border-radius: var(--r-sm);
}
.ver .tag.current { color: #fff; background: var(--teal); }
.ver .date { font-family: var(--mono); font-size: 11.5px; color: var(--muted); }
.ver .note { color: var(--ink-2); }
.cite-box {
background: var(--bg-alt);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 13px 14px;
font-family: var(--serif);
font-size: 13.5px;
color: var(--ink-2);
line-height: 1.65;
}
.cite-box .doi { font-family: var(--mono); font-size: 12.5px; color: var(--accent); }
.drawer-actions {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 12px;
}
/* ---- Footer ---- */
.sitefoot {
border-top: 1px solid var(--line);
background: var(--bg-alt);
padding: 24px;
}
.sitefoot p {
max-width: 1240px;
margin: 0 auto;
font-size: 12.5px;
color: var(--muted);
text-align: center;
}
/* ---- Toast ---- */
.toast {
position: fixed;
left: 50%;
bottom: 28px;
transform: translateX(-50%) translateY(16px);
background: var(--ink);
color: #fff;
font-size: 13.5px;
font-weight: 500;
padding: 11px 18px;
border-radius: var(--r-md);
box-shadow: var(--shadow-lg);
opacity: 0;
pointer-events: none;
transition: opacity 0.2s, transform 0.2s;
z-index: 70;
max-width: 90vw;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
/* ---- Responsive ---- */
@media (max-width: 900px) {
.layout { grid-template-columns: 1fr; }
.rail {
position: static;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 0 24px;
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 16px 18px;
margin-bottom: 8px;
}
.rail-head { grid-column: 1 / -1; }
.facet:first-of-type { border-top: 0; }
}
@media (max-width: 640px) {
.topbar-inner { padding: 10px 16px; flex-wrap: wrap; }
.topnav { width: 100%; overflow-x: auto; }
.hero-inner { padding: 28px 16px 24px; }
.layout { padding: 20px 16px 44px; gap: 20px; }
.rail { grid-template-columns: 1fr 1fr; }
.toolbar-right { width: 100%; justify-content: space-between; margin-left: 0; }
.active-filters { width: 100%; flex: 1 0 100%; order: 3; }
.grid { grid-template-columns: 1fr; }
.grid.list .card { flex-direction: column; align-items: flex-start; }
.grid.list .card .card-foot { flex-direction: row; align-items: center; }
.drawer { width: 100vw; }
.drawer-head h2 { font-size: 19px; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}/* Helios Data Commons — Dataset Explorer (vanilla JS, no deps) */
(function () {
"use strict";
/* ---------- Seeded dataset catalog (fictional) ---------- */
var DATASETS = [
{
id: "hdc-0417", title: "Coastal Sea-Surface Temperature Anomalies, North Atlantic 1998–2023",
author: "Okonkwo, A.; Reyes-Vidal, M. — Maris Oceanographic Institute",
domain: "Earth Science", format: "NetCDF", license: "cc-by", year: 2024,
sizeMB: 8420, files: 312, citations: 187, downloads: 24130,
doi: "10.55821/hdc.0417",
abstract: "Gridded daily sea-surface temperature anomalies derived from a blended satellite–buoy product across the North Atlantic shelf, with quality flags and uncertainty estimates at 0.05° resolution.",
vars: [
["sst_anom", "float32", "°C", "SST anomaly vs 1991–2020 climatology"],
["lat", "float64", "deg N", "Cell-centre latitude"],
["lon", "float64", "deg E", "Cell-centre longitude"],
["qc_flag", "uint8", "—", "Quality control flag (0–4)"],
["sst_unc", "float32", "°C", "1σ uncertainty estimate"]
],
preview: 'time,lat,lon,sst_anom,sst_unc,qc_flag\n2023-08-01,44.25,-63.55,+1.82,0.21,0\n2023-08-01,44.30,-63.55,+1.79,0.20,0\n2023-08-01,44.35,-63.55,+1.91,0.23,1',
versions: [
["v3.1", "2024-03-18", "Extended through 2023; revised uncertainty model", true],
["v2.0", "2022-11-04", "Switched to blended OSTIA-style product"],
["v1.0", "2021-06-29", "Initial release 1998–2020"]
]
},
{
id: "hdc-0288", title: "Single-Cell RNA Atlas of Murine Hippocampal Neurogenesis",
author: "Lindqvist, H.; Banerjee, P.; Costa, F. — Helix Center for Genomics",
domain: "Life Science", format: "HDF5", license: "cc0", year: 2025,
sizeMB: 14760, files: 48, citations: 96, downloads: 9870,
doi: "10.55821/hdc.0288",
abstract: "A single-cell transcriptomic atlas of 211,400 cells sampled along the murine dentate gyrus neurogenic trajectory, with annotated cell types and pseudotime ordering.",
vars: [
["cell_id", "string", "—", "Unique cell barcode"],
["gene_id", "string", "—", "Ensembl gene identifier"],
["counts", "int32", "UMI", "Raw molecular count"],
["cell_type", "category", "—", "Annotated cell type label"],
["pseudotime", "float32", "—", "Inferred differentiation pseudotime [0–1]"]
],
preview: 'cell_id cell_type pseudotime n_genes\nAAACCTGAGT-1 Radial glia 0.041 3120\nAAACCTGCAT-2 Neuroblast 0.387 2740\nAAACGGGTCA-3 Immature gran 0.612 2988',
versions: [
["v1.2", "2025-02-09", "Re-annotated rare interneuron clusters", true],
["v1.0", "2024-10-22", "Initial atlas release"]
]
},
{
id: "hdc-0931", title: "Photometric Light Curves of 4,210 Eclipsing Binary Candidates",
author: "Tanaka, R.; Whitfield, J. — Aurora Sky Survey Consortium",
domain: "Astronomy", format: "FITS", license: "cc-by", year: 2023,
sizeMB: 3240, files: 4210, citations: 312, downloads: 41200,
doi: "10.55821/hdc.0931",
abstract: "Calibrated time-series photometry for eclipsing binary star candidates from the Aurora wide-field survey, including period estimates and folded light curves.",
vars: [
["bjd", "float64", "day", "Barycentric Julian Date"],
["flux", "float32", "e-/s", "Calibrated flux"],
["flux_err", "float32", "e-/s", "Flux uncertainty"],
["period", "float32", "day", "Best-fit orbital period"]
],
preview: 'bjd flux flux_err flag\n2459832.41023 0.99812 0.00041 0\n2459832.42105 0.81204 0.00052 0\n2459832.43187 0.78930 0.00049 1',
versions: [
["v2.1", "2023-09-30", "Added 612 new candidates from DR2", true],
["v1.0", "2022-07-15", "Initial DR1 catalog"]
]
},
{
id: "hdc-0602", title: "Urban Air Quality Sensor Network, Greater Marrowfield 2019–2024",
author: "Adeyemi, B.; Novak, L. — Civic Environmental Lab",
domain: "Earth Science", format: "CSV", license: "odbl", year: 2024,
sizeMB: 92, files: 18, citations: 54, downloads: 13540,
doi: "10.55821/hdc.0602",
abstract: "Hourly readings from 64 low-cost particulate and gas sensors deployed across an urban region, co-located with reference-grade monitors for calibration.",
vars: [
["sensor_id", "string", "—", "Sensor unit identifier"],
["pm25", "float32", "µg/m³", "PM2.5 concentration"],
["no2", "float32", "ppb", "Nitrogen dioxide"],
["temp", "float32", "°C", "Ambient temperature"],
["rh", "float32", "%", "Relative humidity"]
],
preview: 'timestamp,sensor_id,pm25,no2,temp,rh\n2024-01-12T08:00,S-014,18.4,22.1,4.2,78\n2024-01-12T09:00,S-014,21.7,25.6,5.0,74\n2024-01-12T10:00,S-014,19.2,23.0,6.8,69',
versions: [
["v4.0", "2024-05-02", "Recalibration against 2024 reference data", true],
["v3.0", "2023-01-10", "Added 22 sensors"],
["v1.0", "2020-02-28", "Pilot deployment data"]
]
},
{
id: "hdc-0775", title: "Benchmark Corpus for Low-Resource Machine Translation (8 Languages)",
author: "Sørensen, K.; Mwangi, D.; Petrova, I. — Lingua Open Lab",
domain: "Computer Science", format: "Parquet", license: "mit", year: 2025,
sizeMB: 1180, files: 96, citations: 73, downloads: 28760,
doi: "10.55821/hdc.0775",
abstract: "Aligned bilingual sentence pairs across eight under-resourced languages with held-out evaluation splits and document-level metadata for reproducible benchmarking.",
vars: [
["src_text", "string", "—", "Source-language sentence"],
["tgt_text", "string", "—", "Target-language sentence"],
["lang_pair", "category", "—", "Language pair code"],
["split", "category", "—", "train / dev / test"]
],
preview: 'lang_pair split src_len tgt_len\nsw-en train 14 16\nam-en dev 9 11\nqu-en test 21 19',
versions: [
["v2.0", "2025-01-20", "Added Quechua–English pair; dedup pass", true],
["v1.0", "2024-09-03", "Seven-language initial release"]
]
},
{
id: "hdc-0150", title: "High-Entropy Alloy Mechanical Properties Database",
author: "Volkov, S.; Hartmann, G. — Institute for Materials Discovery",
domain: "Materials Science", format: "CSV", license: "cc-by", year: 2022,
sizeMB: 36, files: 6, citations: 241, downloads: 18900,
doi: "10.55821/hdc.0150",
abstract: "Curated composition–processing–property records for 3,940 high-entropy alloy samples, including yield strength, hardness and phase information.",
vars: [
["composition", "string", "at.%", "Elemental composition"],
["yield_strength", "float32", "MPa", "0.2% offset yield strength"],
["hardness", "float32", "HV", "Vickers hardness"],
["phase", "category", "—", "Dominant crystal phase"]
],
preview: 'composition yield_MPa hardness_HV phase\nCoCrFeMnNi 410 152 FCC\nAlCoCrFeNi 1080 520 BCC\nHfNbTaTiZr 980 389 BCC',
versions: [
["v1.3", "2022-12-11", "Corrected 14 hardness entries", true],
["v1.0", "2021-08-30", "Initial release"]
]
},
{
id: "hdc-0843", title: "Global Glacier Surface Velocity Mosaics 2016–2024",
author: "Bergström, E.; Quan, Y. — Cryosphere Remote Sensing Group",
domain: "Earth Science", format: "GeoTIFF", license: "cc-by", year: 2024,
sizeMB: 21800, files: 1024, citations: 129, downloads: 7640,
doi: "10.55821/hdc.0843",
abstract: "Annual ice-surface velocity mosaics derived from feature tracking of optical and SAR imagery over 38 major glacier systems, with per-pixel error fields.",
vars: [
["vx", "float32", "m/yr", "Eastward velocity component"],
["vy", "float32", "m/yr", "Northward velocity component"],
["v_mag", "float32", "m/yr", "Velocity magnitude"],
["v_err", "float32", "m/yr", "Velocity uncertainty"]
],
preview: 'glacier year v_mag_m_yr v_err\nKangia 2023 148.2 6.1\nJakob 2023 213.7 9.4\nPetermann 2023 1102.5 31.0',
versions: [
["v2.0", "2024-04-12", "Reprocessed with updated SAR coherence mask", true],
["v1.0", "2023-03-19", "Initial 2016–2022 mosaics"]
]
},
{
id: "hdc-0319", title: "Synthetic Patient Vital-Sign Streams for ICU Model Validation",
author: "Haddad, N.; Pearson, T. — Clinical Informatics Collaborative",
domain: "Life Science", format: "Parquet", license: "restricted", year: 2025,
sizeMB: 640, files: 12, citations: 31, downloads: 4120,
doi: "10.55821/hdc.0319",
abstract: "Fully synthetic, generative-model-derived intensive-care vital-sign time series with embedded deterioration events, for safe algorithm benchmarking. No real patient data.",
vars: [
["patient_id", "string", "—", "Synthetic subject id"],
["hr", "int16", "bpm", "Heart rate"],
["spo2", "int16", "%", "Oxygen saturation"],
["map", "int16", "mmHg", "Mean arterial pressure"],
["event", "category", "—", "Annotated deterioration event"]
],
preview: 'patient_id t_min hr spo2 map event\nSYN-00012 0 88 97 82 none\nSYN-00012 45 119 91 61 sepsis_onset\nSYN-00012 60 132 88 54 sepsis_onset',
versions: [
["v1.1", "2025-03-05", "Rebalanced event prevalence", true],
["v1.0", "2025-01-14", "Initial synthetic cohort"]
]
},
{
id: "hdc-0507", title: "Proteomic Mass Spectra of Thermophilic Archaea",
author: "Imai, S.; Delacroix, R. — Extremophile Biochemistry Unit",
domain: "Life Science", format: "HDF5", license: "cc-by", year: 2023,
sizeMB: 5120, files: 220, citations: 58, downloads: 6210,
doi: "10.55821/hdc.0507",
abstract: "Tandem mass spectrometry spectra and identified peptides for thermophilic archaeal proteomes cultured across a temperature gradient.",
vars: [
["mz", "float64", "Th", "Mass-to-charge ratio"],
["intensity", "float32", "a.u.", "Peak intensity"],
["peptide", "string", "—", "Identified peptide sequence"],
["temp_c", "float32", "°C", "Culture temperature"]
],
preview: 'scan mz intensity charge peptide\n1042 612.3041 84210 2 GVLDIAR\n1043 745.8920 39112 2 FTPEQISK\n1044 501.2718 120033 1 AAGER',
versions: [
["v1.0", "2023-05-26", "Initial release", true]
]
},
{
id: "hdc-0688", title: "Reanalysis Wind Fields for Offshore Energy Siting",
author: "Karlsen, M.; Owusu, F. — Renewable Resource Atlas",
domain: "Earth Science", format: "NetCDF", license: "cc0", year: 2026,
sizeMB: 47200, files: 540, citations: 12, downloads: 2980,
doi: "10.55821/hdc.0688",
abstract: "Hourly 10 m and 100 m wind fields at 3 km resolution over continental shelf regions, derived from a downscaled atmospheric reanalysis for wind-resource assessment.",
vars: [
["ws100", "float32", "m/s", "100 m wind speed"],
["wd100", "float32", "deg", "100 m wind direction"],
["ws10", "float32", "m/s", "10 m wind speed"],
["air_density", "float32", "kg/m³", "Surface air density"]
],
preview: 'time ws100 wd100 air_density\n2025-12-01T00:00 11.4 248 1.241\n2025-12-01T01:00 12.1 251 1.239\n2025-12-01T02:00 10.8 244 1.242',
versions: [
["v1.0", "2026-01-30", "Initial 2010–2025 reanalysis", true]
]
},
{
id: "hdc-0224", title: "Crowd-Sourced Seismic Waveforms from Citizen Sensors",
author: "Russo, A.; Yamamoto, K. — Open Seismology Network",
domain: "Earth Science", format: "CSV", license: "odbl", year: 2021,
sizeMB: 12, files: 4, citations: 89, downloads: 15600,
doi: "10.55821/hdc.0224",
abstract: "Low-cost accelerometer waveforms from a volunteer sensor network, event-windowed around 1,820 regional earthquakes with manual quality review.",
vars: [
["accel_z", "float32", "m/s²", "Vertical ground acceleration"],
["station", "string", "—", "Volunteer station id"],
["event_mag", "float32", "Mw", "Event magnitude"],
["dist_km", "float32", "km", "Epicentral distance"]
],
preview: 'station event_mag dist_km pga_m_s2\nCS-201 4.6 38.2 0.071\nCS-204 4.6 51.9 0.044\nCS-209 3.2 12.0 0.118',
versions: [
["v2.0", "2021-11-08", "Reprocessed event windows", true],
["v1.0", "2020-04-01", "Initial volunteer dataset"]
]
},
{
id: "hdc-0960", title: "Labelled Sketch Corpus for Geometric Shape Recognition",
author: "Fontaine, J.; Iqbal, R. — Visual Cognition Lab",
domain: "Computer Science", format: "Parquet", license: "mit", year: 2022,
sizeMB: 740, files: 30, citations: 64, downloads: 33400,
doi: "10.55821/hdc.0960",
abstract: "1.2 million hand-drawn geometric sketches with stroke vectors and shape labels, collected through a gamified web tool for benchmarking sketch recognition.",
vars: [
["sketch_id", "string", "—", "Unique sketch id"],
["strokes", "array", "—", "List of stroke point arrays"],
["label", "category", "—", "Ground-truth shape label"],
["n_points", "int32", "—", "Total stroke points"]
],
preview: 'sketch_id label n_points n_strokes\nSK-008812 triangle 46 3\nSK-008813 circle 61 1\nSK-008814 hexagon 88 6',
versions: [
["v1.1", "2022-06-18", "Removed near-duplicate sketches", true],
["v1.0", "2022-02-02", "Initial corpus"]
]
}
];
/* ---------- DOM refs ---------- */
var $ = function (s, r) { return (r || document).querySelector(s); };
var $$ = function (s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); };
var grid = $("#grid");
var emptyEl = $("#empty");
var searchEl = $("#search");
var clearSearchBtn = $("#clearSearch");
var sortEl = $("#sort");
var resultCountEl = $("#resultCount");
var activeFiltersEl = $("#activeFilters");
var yearMin = $("#yearMin");
var yearMax = $("#yearMax");
var yearOut = $("#yearOut");
var overlay = $("#overlay");
var drawer = $("#drawer");
var toastEl = $("#toast");
/* ---------- License display ---------- */
var LICENSES = {
"cc0": { label: "CC0", cls: "lic-cc0", full: "Creative Commons Zero (Public Domain)" },
"cc-by": { label: "CC BY 4.0", cls: "lic-ccby", full: "Creative Commons Attribution 4.0" },
"mit": { label: "MIT", cls: "lic-mit", full: "MIT License" },
"odbl": { label: "ODbL", cls: "lic-odbl", full: "Open Database License" },
"restricted": { label: "Restricted", cls: "lic-restricted", full: "Restricted — registration required" }
};
/* ---------- State ---------- */
var state = {
q: "",
domain: new Set(),
format: new Set(),
license: new Set(),
size: "any",
yMin: 2015, yMax: 2026,
sort: "relevance",
view: "grid"
};
/* ---------- Helpers ---------- */
function toast(msg) {
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toast._t);
toast._t = setTimeout(function () { toastEl.classList.remove("show"); }, 2400);
}
function fmtSize(mb) {
if (mb >= 1024) return (mb / 1024).toFixed(mb >= 10240 ? 0 : 1) + " GB";
return mb + " MB";
}
function fmtNum(n) { return n.toLocaleString("en-US"); }
function sizeBucket(mb) {
if (mb < 100) return "s";
if (mb <= 5120) return "m";
return "l";
}
function escapeHTML(s) {
return String(s).replace(/[&<>"]/g, function (c) {
return { "&": "&", "<": "<", ">": ">", '"': """ }[c];
});
}
function citation(d) {
var names = d.author.split("—")[0].trim();
return names + " (" + d.year + "). " + d.title + " [Data set]. Helios Data Commons. https://doi.org/" + d.doi;
}
/* ---------- Build facet checkboxes ---------- */
function uniqueValues(key) {
var counts = {};
DATASETS.forEach(function (d) { counts[d[key]] = (counts[d[key]] || 0) + 1; });
return Object.keys(counts).sort().map(function (v) { return { value: v, count: counts[v] }; });
}
function buildFacet(facetKey, items, labelFn) {
var container = $('.facet-list[data-facet="' + facetKey + '"]');
container.innerHTML = items.map(function (it) {
var lab = labelFn ? labelFn(it.value) : it.value;
return '<label class="check">' +
'<input type="checkbox" value="' + escapeHTML(it.value) + '" data-facet="' + facetKey + '" />' +
'<span>' + escapeHTML(lab) + '</span>' +
'<span class="facet-count">' + it.count + '</span>' +
'</label>';
}).join("");
}
buildFacet("domain", uniqueValues("domain"));
buildFacet("format", uniqueValues("format"));
buildFacet("license", uniqueValues("license"), function (v) { return LICENSES[v].label; });
/* ---------- Filtering ---------- */
function matchSearch(d, q) {
if (!q) return true;
var hay = (d.title + " " + d.author + " " + d.domain + " " + d.abstract + " " + d.doi).toLowerCase();
return q.toLowerCase().split(/\s+/).every(function (t) { return hay.indexOf(t) !== -1; });
}
function filtered() {
return DATASETS.filter(function (d) {
if (!matchSearch(d, state.q)) return false;
if (state.domain.size && !state.domain.has(d.domain)) return false;
if (state.format.size && !state.format.has(d.format)) return false;
if (state.license.size && !state.license.has(d.license)) return false;
if (state.size !== "any" && sizeBucket(d.sizeMB) !== state.size) return false;
if (d.year < state.yMin || d.year > state.yMax) return false;
return true;
});
}
function sortList(list) {
var s = state.sort;
var arr = list.slice();
arr.sort(function (a, b) {
switch (s) {
case "newest": return b.year - a.year || b.citations - a.citations;
case "oldest": return a.year - b.year;
case "citations": return b.citations - a.citations;
case "size-desc": return b.sizeMB - a.sizeMB;
case "size-asc": return a.sizeMB - b.sizeMB;
case "title": return a.title.localeCompare(b.title);
default: // relevance: cited + downloads weighting, search-aware
return (b.citations * 2 + b.downloads / 100) - (a.citations * 2 + a.downloads / 100);
}
});
return arr;
}
/* ---------- Render cards ---------- */
function cardHTML(d) {
var lic = LICENSES[d.license];
return '<article class="card" tabindex="0" role="button" data-id="' + d.id + '" aria-label="' + escapeHTML(d.title) + '">' +
'<div class="card-main">' +
'<div class="card-top"><span class="card-domain">' + escapeHTML(d.domain) + '</span></div>' +
'<h3>' + escapeHTML(d.title) + '</h3>' +
'<p class="author">' + escapeHTML(d.author) + '</p>' +
'<p class="desc">' + escapeHTML(d.abstract) + '</p>' +
'<div class="card-meta">' +
'<span class="m"><strong>' + d.format + '</strong></span>' +
'<span class="m">' + fmtSize(d.sizeMB) + '</span>' +
'<span class="m">' + fmtNum(d.files) + ' files</span>' +
'<span class="m">' + fmtNum(d.citations) + ' citations</span>' +
'</div>' +
'</div>' +
'<div class="card-foot">' +
'<span class="lic ' + lic.cls + '" title="' + lic.full + '">' + lic.label + '</span>' +
'<button class="btn sm" type="button" data-dl="' + d.id + '">' +
'<svg viewBox="0 0 16 16" width="14" height="14"><path d="M8 1v8m0 0L5 6m3 3l3-3M2 13h12" stroke="currentColor" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
'Download</button>' +
'</div>' +
'</article>';
}
function render() {
var list = sortList(filtered());
grid.className = "grid" + (state.view === "list" ? " list" : "");
if (!list.length) {
grid.innerHTML = "";
emptyEl.hidden = false;
} else {
emptyEl.hidden = true;
grid.innerHTML = list.map(cardHTML).join("");
}
var total = DATASETS.length;
resultCountEl.innerHTML = list.length === total
? fmtNum(total) + ' datasets'
: fmtNum(list.length) + ' <span class="muted">of ' + fmtNum(total) + ' datasets</span>';
renderActiveChips();
}
function renderActiveChips() {
var chips = [];
function add(label, onRemove) { chips.push({ label: label, fn: onRemove }); }
state.domain.forEach(function (v) { add(v, function () { state.domain.delete(v); syncFacetCheckbox("domain", v, false); }); });
state.format.forEach(function (v) { add(v, function () { state.format.delete(v); syncFacetCheckbox("format", v, false); }); });
state.license.forEach(function (v) { add(LICENSES[v].label, function () { state.license.delete(v); syncFacetCheckbox("license", v, false); }); });
if (state.size !== "any") {
var sl = { s: "< 100 MB", m: "100 MB–5 GB", l: "> 5 GB" }[state.size];
add(sl, function () { state.size = "any"; ($('input[name="size"][value="any"]') || {}).checked = true; });
}
if (state.yMin !== 2015 || state.yMax !== 2026) {
add(state.yMin + "–" + state.yMax, function () {
state.yMin = 2015; state.yMax = 2026;
yearMin.value = 2015; yearMax.value = 2026; updateYearOut();
});
}
activeFiltersEl.innerHTML = chips.map(function (c, i) {
return '<span class="chip" data-chip="' + i + '">' + escapeHTML(c.label) +
' <button type="button" aria-label="Remove ' + escapeHTML(c.label) + ' filter">×</button></span>';
}).join("");
$$(".chip", activeFiltersEl).forEach(function (el, i) {
el.querySelector("button").addEventListener("click", function () { chips[i].fn(); render(); });
});
}
function syncFacetCheckbox(facet, value, checked) {
var box = $('input[data-facet="' + facet + '"][value="' + cssEsc(value) + '"]');
if (box) box.checked = checked;
}
function cssEsc(v) { return String(v).replace(/"/g, '\\"'); }
/* ---------- Drawer ---------- */
var lastFocused = null;
function openDrawer(id) {
var d = DATASETS.find(function (x) { return x.id === id; });
if (!d) return;
var lic = LICENSES[d.license];
var varsRows = d.vars.map(function (v) {
return '<tr><td class="name">' + escapeHTML(v[0]) + '</td><td class="type">' + escapeHTML(v[1]) +
'</td><td class="unit">' + escapeHTML(v[2]) + '</td><td>' + escapeHTML(v[3]) + '</td></tr>';
}).join("");
var verRows = d.versions.map(function (v) {
return '<div class="ver"><span class="tag' + (v[3] ? " current" : "") + '">' + escapeHTML(v[0]) +
'</span><span class="date">' + escapeHTML(v[1]) + '</span><span class="note">' + escapeHTML(v[2]) + '</span></div>';
}).join("");
var prev = escapeHTML(d.preview).replace(/^([^\n,]+)/gm, '<span class="hl">$1</span>');
drawer.innerHTML =
'<div class="drawer-head">' +
'<button class="drawer-close" type="button" aria-label="Close">×</button>' +
'<span class="card-domain">' + escapeHTML(d.domain) + '</span>' +
'<h2 id="drawerTitle">' + escapeHTML(d.title) + '</h2>' +
'<p class="author">' + escapeHTML(d.author) + '</p>' +
'<p class="doi">https://doi.org/' + escapeHTML(d.doi) + '</p>' +
'</div>' +
'<div class="drawer-body">' +
'<section><h3>Abstract</h3><p class="abstract">' + escapeHTML(d.abstract) + '</p></section>' +
'<section><h3>At a glance</h3><div class="statgrid">' +
stat(fmtSize(d.sizeMB), "Total size") +
stat(fmtNum(d.files), "Files") +
stat(fmtNum(d.citations), "Citations") +
stat(fmtNum(d.downloads), "Downloads") +
stat('<span class="lic ' + lic.cls + '" style="font-size:12px">' + lic.label + '</span>', "License") +
stat(d.format, "Format") +
'</div></section>' +
'<section><h3>Variables (' + d.vars.length + ')</h3>' +
'<div class="table-scroll"><table class="vars"><thead><tr><th>Name</th><th>Type</th><th>Unit</th><th>Description</th></tr></thead>' +
'<tbody>' + varsRows + '</tbody></table></div></section>' +
'<section><h3>Sample preview</h3><pre class="preview">' + prev + '</pre></section>' +
'<section><h3>Versions</h3><div class="versions">' + verRows + '</div></section>' +
'<section><h3>Cite this dataset</h3>' +
'<div class="cite-box" id="citeText">' + escapeHTML(citation(d)) + '</div>' +
'<div class="drawer-actions">' +
'<button class="btn" type="button" data-dl="' + d.id + '">' +
'<svg viewBox="0 0 16 16" width="14" height="14"><path d="M8 1v8m0 0L5 6m3 3l3-3M2 13h12" stroke="currentColor" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
'Download (' + fmtSize(d.sizeMB) + ')</button>' +
'<button class="btn ghost" type="button" id="citeBtn">Copy citation</button>' +
'<button class="btn ghost" type="button" id="doiBtn">Copy DOI</button>' +
'</div></section>' +
'</div>';
lastFocused = document.activeElement;
overlay.hidden = false;
drawer.hidden = false;
drawer.focus();
document.body.style.overflow = "hidden";
drawer.querySelector(".drawer-close").addEventListener("click", closeDrawer);
$("#citeBtn").addEventListener("click", function () { copy(citation(d), "Citation copied to clipboard"); });
$("#doiBtn").addEventListener("click", function () { copy("https://doi.org/" + d.doi, "DOI copied to clipboard"); });
}
function stat(v, k) { return '<div class="stat"><div class="v">' + v + '</div><div class="k">' + k + '</div></div>'; }
function closeDrawer() {
drawer.hidden = true;
overlay.hidden = true;
document.body.style.overflow = "";
drawer.innerHTML = "";
if (lastFocused && lastFocused.focus) lastFocused.focus();
}
function copy(text, msg) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () { toast(msg); }, function () { fallbackCopy(text, msg); });
} else { fallbackCopy(text, msg); }
}
function fallbackCopy(text, msg) {
var ta = document.createElement("textarea");
ta.value = text; ta.style.position = "fixed"; ta.style.opacity = "0";
document.body.appendChild(ta); ta.select();
try { document.execCommand("copy"); toast(msg); } catch (e) { toast("Copy failed"); }
document.body.removeChild(ta);
}
/* ---------- Events ---------- */
// search (debounced)
var debTimer;
searchEl.addEventListener("input", function () {
clearTimeout(debTimer);
clearSearchBtn.hidden = !searchEl.value;
debTimer = setTimeout(function () { state.q = searchEl.value.trim(); render(); }, 140);
});
clearSearchBtn.addEventListener("click", function () {
searchEl.value = ""; state.q = ""; clearSearchBtn.hidden = true; searchEl.focus(); render();
});
// facet checkboxes
$$(".facet-list input[type=checkbox]").forEach(function (box) {
box.addEventListener("change", function () {
var set = state[box.dataset.facet];
if (box.checked) set.add(box.value); else set.delete(box.value);
render();
});
});
// size radios
$$('input[name="size"]').forEach(function (r) {
r.addEventListener("change", function () { if (r.checked) { state.size = r.value; render(); } });
});
// year dual range
function updateYearOut() { yearOut.textContent = state.yMin + " – " + state.yMax; }
function onYear() {
var a = +yearMin.value, b = +yearMax.value;
if (a > b) { var t = a; a = b; b = t; }
state.yMin = a; state.yMax = b;
updateYearOut();
render();
}
yearMin.addEventListener("input", onYear);
yearMax.addEventListener("input", onYear);
// sort
sortEl.addEventListener("change", function () { state.sort = sortEl.value; render(); });
// view toggle
$("#viewGrid").addEventListener("click", function () { setView("grid"); });
$("#viewList").addEventListener("click", function () { setView("list"); });
function setView(v) {
state.view = v;
var g = $("#viewGrid"), l = $("#viewList");
g.classList.toggle("is-active", v === "grid");
l.classList.toggle("is-active", v === "list");
g.setAttribute("aria-pressed", v === "grid");
l.setAttribute("aria-pressed", v === "list");
render();
}
// reset
function resetAll() {
state.q = ""; searchEl.value = ""; clearSearchBtn.hidden = true;
state.domain.clear(); state.format.clear(); state.license.clear();
state.size = "any"; state.yMin = 2015; state.yMax = 2026;
$$(".facet-list input[type=checkbox]").forEach(function (b) { b.checked = false; });
var anyR = $('input[name="size"][value="any"]'); if (anyR) anyR.checked = true;
yearMin.value = 2015; yearMax.value = 2026; updateYearOut();
render();
toast("Filters reset");
}
$("#resetFilters").addEventListener("click", resetAll);
$("#emptyReset").addEventListener("click", resetAll);
// card / download click delegation
grid.addEventListener("click", function (e) {
var dl = e.target.closest("[data-dl]");
if (dl) {
e.stopPropagation();
var d = DATASETS.find(function (x) { return x.id === dl.dataset.dl; });
toast("Preparing download — " + d.title.slice(0, 40) + "… (" + fmtSize(d.sizeMB) + ")");
return;
}
var card = e.target.closest(".card");
if (card) openDrawer(card.dataset.id);
});
grid.addEventListener("keydown", function (e) {
if ((e.key === "Enter" || e.key === " ") && e.target.classList && e.target.classList.contains("card")) {
e.preventDefault(); openDrawer(e.target.dataset.id);
}
});
// drawer download delegation
drawer.addEventListener("click", function (e) {
var dl = e.target.closest("[data-dl]");
if (dl) {
var d = DATASETS.find(function (x) { return x.id === dl.dataset.dl; });
toast("Preparing download — " + d.title.slice(0, 40) + "… (" + fmtSize(d.sizeMB) + ")");
}
});
// overlay + escape
overlay.addEventListener("click", closeDrawer);
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && !drawer.hidden) closeDrawer();
});
/* ---------- Init ---------- */
$("#totalCount").textContent = fmtNum(DATASETS.length);
updateYearOut();
render();
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Helios Data Commons — Dataset Explorer</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Source+Serif+4:opsz,[email protected],400;8..60,600;8..60,700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#results">Skip to results</a>
<header class="topbar" role="banner">
<div class="topbar-inner">
<div class="brand">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 32 32" width="28" height="28">
<circle cx="16" cy="16" r="14" fill="none" stroke="currentColor" stroke-width="2"/>
<circle cx="16" cy="16" r="4" fill="currentColor"/>
<path d="M16 2v6M16 24v6M2 16h6M24 16h6" stroke="currentColor" stroke-width="2"/>
</svg>
</span>
<div class="brand-text">
<strong>Helios Data Commons</strong>
<span>Open Research Datasets · v3.2</span>
</div>
</div>
<nav class="topnav" aria-label="Primary">
<a href="#" aria-current="page">Explore</a>
<a href="#">Submit</a>
<a href="#">Docs</a>
<a href="#">API</a>
</nav>
</div>
</header>
<div class="hero">
<div class="hero-inner">
<h1>Dataset Explorer</h1>
<p class="hero-sub">Browse <strong id="totalCount">0</strong> curated, openly licensed research datasets across the physical and life sciences. All records are illustrative and fictional.</p>
<div class="searchrow">
<div class="searchbox">
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><circle cx="11" cy="11" r="7" fill="none" stroke="currentColor" stroke-width="2"/><path d="M21 21l-4.3-4.3" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
<input id="search" type="search" placeholder="Search title, author, keyword, DOI…" aria-label="Search datasets" autocomplete="off" />
<button id="clearSearch" class="clear-btn" type="button" aria-label="Clear search" hidden>×</button>
</div>
</div>
</div>
</div>
<main class="layout">
<aside class="rail" aria-label="Filters">
<div class="rail-head">
<h2>Filters</h2>
<button id="resetFilters" class="link-btn" type="button">Reset all</button>
</div>
<fieldset class="facet" id="facet-domain">
<legend>Domain</legend>
<div class="facet-list" data-facet="domain"></div>
</fieldset>
<fieldset class="facet" id="facet-format">
<legend>Format</legend>
<div class="facet-list" data-facet="format"></div>
</fieldset>
<fieldset class="facet" id="facet-license">
<legend>License</legend>
<div class="facet-list" data-facet="license"></div>
</fieldset>
<fieldset class="facet" id="facet-size">
<legend>Size</legend>
<div class="facet-list">
<label class="check"><input type="radio" name="size" value="any" checked /><span>Any size</span></label>
<label class="check"><input type="radio" name="size" value="s" /><span>< 100 MB</span></label>
<label class="check"><input type="radio" name="size" value="m" /><span>100 MB – 5 GB</span></label>
<label class="check"><input type="radio" name="size" value="l" /><span>> 5 GB</span></label>
</div>
</fieldset>
<fieldset class="facet" id="facet-year">
<legend>Year published <output id="yearOut" class="year-out">2015 – 2026</output></legend>
<div class="range-wrap">
<input id="yearMin" type="range" min="2015" max="2026" value="2015" aria-label="Minimum year" />
<input id="yearMax" type="range" min="2015" max="2026" value="2026" aria-label="Maximum year" />
</div>
</fieldset>
</aside>
<section class="content" id="results">
<div class="toolbar">
<p class="resultcount" id="resultCount" aria-live="polite">— datasets</p>
<div class="active-filters" id="activeFilters" aria-label="Active filters"></div>
<div class="toolbar-right">
<div class="viewtoggle" role="group" aria-label="View mode">
<button id="viewGrid" class="vt-btn is-active" type="button" aria-pressed="true" title="Grid view">
<svg viewBox="0 0 20 20" width="16" height="16"><rect x="2" y="2" width="7" height="7" rx="1"/><rect x="11" y="2" width="7" height="7" rx="1"/><rect x="2" y="11" width="7" height="7" rx="1"/><rect x="11" y="11" width="7" height="7" rx="1"/></svg>
</button>
<button id="viewList" class="vt-btn" type="button" aria-pressed="false" title="List view">
<svg viewBox="0 0 20 20" width="16" height="16"><rect x="2" y="3" width="16" height="3" rx="1"/><rect x="2" y="9" width="16" height="3" rx="1"/><rect x="2" y="15" width="16" height="3" rx="1"/></svg>
</button>
</div>
<label class="sortwrap">
<span class="sort-label">Sort</span>
<select id="sort" aria-label="Sort datasets">
<option value="relevance">Relevance</option>
<option value="newest">Newest first</option>
<option value="oldest">Oldest first</option>
<option value="citations">Most cited</option>
<option value="size-desc">Largest size</option>
<option value="size-asc">Smallest size</option>
<option value="title">Title A→Z</option>
</select>
</label>
</div>
</div>
<div id="grid" class="grid" aria-live="polite"></div>
<div id="empty" class="empty" hidden>
<svg viewBox="0 0 48 48" width="48" height="48" aria-hidden="true"><circle cx="22" cy="22" r="14" fill="none" stroke="currentColor" stroke-width="3"/><path d="M32 32l10 10" stroke="currentColor" stroke-width="3" stroke-linecap="round"/></svg>
<p>No datasets match these filters.</p>
<button id="emptyReset" class="btn ghost" type="button">Clear filters</button>
</div>
</section>
</main>
<footer class="sitefoot">
<p>Helios Data Commons is an illustrative demo. Authors, institutions, DOIs and datasets are fictional and for UI design purposes only.</p>
</footer>
<!-- Detail drawer -->
<div id="overlay" class="overlay" hidden></div>
<aside id="drawer" class="drawer" role="dialog" aria-modal="true" aria-labelledby="drawerTitle" hidden tabindex="-1"></aside>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Dataset Explorer
A self-contained research data portal modelled on repositories like a federated open-data commons. A sticky search bar matches across titles, authors, abstracts and DOIs, while a faceted filter rail narrows results by domain, file format, license, dataset size band and a dual-handle release-year range. Active facets surface as removable chips, results update live with an accessible count, and a sort dropdown reorders by relevance, citations, recency, size or title. A grid/list view toggle restyles the same card set without re-querying.
Each dataset card shows the domain tag, title, authors and institution, a trimmed abstract, key metrics (format, size, file count, citation count) and a license badge, plus an inline download button. Selecting a card opens a focus-trapped detail drawer presenting the full abstract, an at-a-glance stat panel, a scrollable variables table (name, dtype, unit, description), a monospaced sample preview, a version history with the current release marked, and a formatted citation block.
The drawer’s actions — download archive, copy citation, copy DOI — run entirely client-side with a small toast helper and a clipboard fallback. Everything is driven by a seeded in-script array of records, so the explorer works offline with no backend, build step or external libraries. Numbers, units and citations are rendered in JetBrains Mono, prose in Source Serif 4 and controls in Inter, against the clean white-and-deep-blue institutional palette.
Illustrative UI only — fictional authors, data, and figures; not real scientific results.