Science — Scientific Data Table
A publication-grade scientific results table built in vanilla HTML, CSS, and JavaScript. Column headers carry units, numeric values align on the decimal point with consistent significant figures, and measurements display as mean plus-or-minus standard deviation in monospace. Footnote markers, a highlighted best-result row, zebra striping, and a sticky header keep dense data legible. Click any header to sort ascending or descending, then export the current ordering with a one-click Download CSV button that builds a Blob in the browser.
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;
--shadow-sm: 0 1px 2px rgba(15, 27, 45, 0.06), 0 1px 3px rgba(15, 27, 45, 0.05);
--shadow-md: 0 6px 24px rgba(15, 27, 45, 0.08);
--serif: "Source Serif 4", Georgia, serif;
--sans: "Inter", system-ui, sans-serif;
--mono: "JetBrains Mono", ui-monospace, monospace;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font-family: var(--serif);
line-height: 1.6;
padding: clamp(1rem, 4vw, 3rem);
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.mono {
font-family: var(--mono);
font-feature-settings: "tnum" 1;
}
.page {
max-width: 920px;
margin: 0 auto;
}
/* ---- Masthead ---- */
.masthead {
border-bottom: 2px solid var(--ink);
padding-bottom: 1.4rem;
margin-bottom: 2rem;
}
.eyebrow {
font-family: var(--sans);
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--accent);
margin: 0 0 0.5rem;
}
.masthead h1 {
font-family: var(--serif);
font-weight: 700;
font-size: clamp(1.5rem, 4vw, 2.1rem);
line-height: 1.2;
margin: 0 0 0.7rem;
letter-spacing: -0.01em;
}
.byline {
font-size: 1.02rem;
color: var(--ink-2);
margin: 0 0 0.35rem;
}
.byline sup {
color: var(--accent);
font-weight: 600;
}
.affil {
font-family: var(--sans);
font-size: 0.82rem;
color: var(--muted);
margin: 0;
line-height: 1.5;
}
.affil a {
color: var(--accent);
text-decoration: none;
border-bottom: 1px solid var(--line-2);
}
.affil a:hover {
color: var(--accent-d);
}
/* ---- Card ---- */
.card {
background: var(--bg);
border: 1px solid var(--line);
border-radius: var(--r-lg);
box-shadow: var(--shadow-md);
padding: clamp(1.1rem, 3vw, 2rem);
}
.table-figure {
margin: 0;
}
.tbl-caption {
font-family: var(--serif);
font-size: 0.92rem;
color: var(--ink-2);
line-height: 1.55;
margin-bottom: 1.1rem;
}
.tbl-caption strong {
color: var(--ink);
font-weight: 700;
}
/* ---- Toolbar ---- */
.toolbar {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 0.75rem;
margin-bottom: 0.9rem;
}
.legend {
display: flex;
gap: 0.6rem;
flex-wrap: wrap;
}
.chip {
display: inline-flex;
align-items: center;
gap: 0.4rem;
font-family: var(--sans);
font-size: 0.72rem;
font-weight: 500;
color: var(--ink-2);
background: var(--bg-alt);
border: 1px solid var(--line);
border-radius: 999px;
padding: 0.25rem 0.6rem;
}
.chip .dot {
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--muted);
}
.chip-best .dot {
background: var(--teal);
}
.dot-meas {
background: var(--accent);
}
.btn {
display: inline-flex;
align-items: center;
gap: 0.45rem;
font-family: var(--sans);
font-size: 0.82rem;
font-weight: 600;
color: #fff;
background: var(--accent);
border: 1px solid var(--accent-d);
border-radius: var(--r-sm);
padding: 0.5rem 0.85rem;
cursor: pointer;
transition: background 0.15s ease, transform 0.05s ease, box-shadow 0.15s ease;
box-shadow: var(--shadow-sm);
}
.btn:hover {
background: var(--accent-d);
}
.btn:active {
transform: translateY(1px);
}
.btn:focus-visible {
outline: 3px solid var(--accent-50);
outline-offset: 2px;
}
/* ---- Table ---- */
.table-scroll {
overflow-x: auto;
border: 1px solid var(--line);
border-radius: var(--r-md);
max-height: 520px;
overflow-y: auto;
}
.table-scroll:focus-visible {
outline: 3px solid var(--accent-50);
outline-offset: 2px;
}
.data-table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
font-family: var(--sans);
font-size: 0.86rem;
}
.data-table thead th {
position: sticky;
top: 0;
z-index: 2;
background: var(--ink);
color: #fff;
text-align: right;
vertical-align: bottom;
padding: 0;
white-space: nowrap;
}
.data-table thead th.th-text {
text-align: left;
}
.sort-btn {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 0.1rem;
width: 100%;
background: none;
border: 0;
color: inherit;
font: inherit;
font-weight: 600;
cursor: pointer;
padding: 0.7rem 0.85rem;
text-align: right;
position: relative;
}
.th-text .sort-btn {
align-items: flex-start;
text-align: left;
}
.sort-btn:hover {
background: rgba(255, 255, 255, 0.08);
}
.sort-btn:focus-visible {
outline: 2px solid #fff;
outline-offset: -2px;
}
.unit {
font-family: var(--mono);
font-size: 0.68rem;
font-weight: 400;
color: rgba(255, 255, 255, 0.7);
}
.arrow {
position: absolute;
top: 50%;
right: 0.3rem;
transform: translateY(-50%);
width: 0;
height: 0;
opacity: 0.35;
}
.th-text .arrow {
right: 0.3rem;
}
.arrow::after {
content: "\2195";
font-family: var(--sans);
font-size: 0.75rem;
}
th[aria-sort="ascending"] .arrow::after {
content: "\2191";
}
th[aria-sort="descending"] .arrow::after {
content: "\2193";
}
th[aria-sort="ascending"] .arrow,
th[aria-sort="descending"] .arrow {
opacity: 1;
}
.data-table tbody td {
padding: 0.55rem 0.85rem;
border-top: 1px solid var(--line);
text-align: right;
white-space: nowrap;
}
.data-table tbody td.col-catalyst {
text-align: left;
font-family: var(--serif);
font-size: 0.94rem;
color: var(--ink);
}
.data-table tbody td.num {
font-family: var(--mono);
font-feature-settings: "tnum" 1;
color: var(--ink);
}
.val {
display: inline-block;
}
.unc {
color: var(--muted);
font-size: 0.82em;
}
.fn-mark {
font-family: var(--sans);
font-size: 0.62em;
vertical-align: super;
color: var(--accent);
margin-left: 1px;
cursor: help;
}
.data-table tbody tr:nth-child(even) {
background: var(--bg-alt);
}
.data-table tbody tr:hover {
background: var(--accent-50);
}
.data-table tbody tr.is-best {
background: var(--teal-50);
box-shadow: inset 3px 0 0 var(--teal);
}
.data-table tbody tr.is-best:hover {
background: #d6ece9;
}
.data-table tbody tr.is-best td.col-catalyst {
font-weight: 600;
}
.best-badge {
font-family: var(--sans);
font-size: 0.6rem;
font-weight: 700;
letter-spacing: 0.05em;
text-transform: uppercase;
color: var(--teal);
background: #fff;
border: 1px solid var(--teal);
border-radius: 999px;
padding: 0.05rem 0.4rem;
margin-left: 0.45rem;
vertical-align: middle;
}
/* ---- Footnotes ---- */
.footnotes {
list-style: none;
padding: 0;
margin: 1rem 0 0;
font-family: var(--sans);
font-size: 0.76rem;
color: var(--muted);
line-height: 1.55;
border-top: 1px solid var(--line);
padding-top: 0.9rem;
}
.footnotes li {
margin-bottom: 0.25rem;
}
.fn-mark {
font-weight: 700;
}
.footnotes .fn-mark {
vertical-align: baseline;
font-size: 0.76rem;
margin-right: 0.35rem;
}
.eq {
font-family: var(--mono);
}
/* ---- Equation block ---- */
.eq-block {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-alt);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 1.1rem 3rem;
margin: 1.6rem 0 0.6rem;
}
.eq-body {
font-family: var(--serif);
font-size: 1.15rem;
display: inline-flex;
align-items: center;
gap: 0.3rem;
}
.eq-body i {
font-style: italic;
}
.frac {
display: inline-flex;
flex-direction: column;
text-align: center;
vertical-align: middle;
margin: 0 0.2rem;
}
.frac .num {
border-bottom: 1.5px solid var(--ink);
padding: 0 0.25rem 0.05rem;
}
.frac .den {
padding: 0.05rem 0.25rem 0;
}
.eq-num {
position: absolute;
right: 1rem;
font-family: var(--mono);
font-size: 0.85rem;
color: var(--muted);
}
.note {
font-family: var(--sans);
font-size: 0.8rem;
color: var(--muted);
margin: 0;
text-align: center;
}
.note i {
font-style: italic;
}
/* ---- Toast ---- */
.toast {
position: fixed;
left: 50%;
bottom: 1.5rem;
transform: translate(-50%, 1.5rem);
background: var(--ink);
color: #fff;
font-family: var(--sans);
font-size: 0.85rem;
font-weight: 500;
padding: 0.65rem 1.1rem;
border-radius: var(--r-sm);
box-shadow: var(--shadow-md);
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease, transform 0.25s ease;
z-index: 50;
}
.toast.show {
opacity: 1;
transform: translate(-50%, 0);
}
/* ---- Responsive ---- */
@media (max-width: 640px) {
body {
padding: 1rem 0.85rem;
}
.toolbar {
align-items: stretch;
}
.btn {
justify-content: center;
}
.data-table {
font-size: 0.8rem;
}
.sort-btn {
padding: 0.55rem 0.6rem;
}
.data-table tbody td {
padding: 0.5rem 0.6rem;
}
.eq-block {
padding: 1rem 1.2rem 2rem;
}
.eq-num {
right: 50%;
bottom: 0.5rem;
transform: translateX(50%);
}
}(function () {
"use strict";
/**
* Fictional benchmark dataset. Each numeric field carries a value, an
* uncertainty (1 SD), the number of significant figures to display, and an
* optional footnote marker. Data is illustrative only.
*/
var ROWS = [
{ catalyst: "Au nanoneedles", loading: [0.42, 0.03, 2, "a"], fe: [91.4, 1.2, 1, "b"], jco: [14.8, 0.6, 1], eta: [690, 12, 0], stability: [48, 3, 0] },
{ catalyst: "Ag dendrites", loading: [0.55, 0.04, 2, "a"], fe: [84.2, 2.1, 1, "b"], jco: [11.2, 0.5, 1], eta: [740, 15, 0], stability: [36, 4, 0] },
{ catalyst: "Ni–N–C single atom", loading: [0.30, 0.02, 2, "a"], fe: [96.7, 0.8, 1, "b"], jco: [22.5, 0.9, 1], eta: [610, 9, 0], stability: [120, 6, 0], best: true },
{ catalyst: "Cu oxide-derived", loading: [0.61, 0.05, 2, "a"], fe: [38.9, 3.4, 1, "b"], jco: [6.4, 0.4, 1], eta: [820, 22, 0], stability: [18, 2, 0] },
{ catalyst: "Zn porous foam", loading: [0.48, 0.03, 2, "a"], fe: [72.6, 2.8, 1, "b"], jco: [9.1, 0.5, 1], eta: [780, 18, 0], stability: [29, 3, 0] },
{ catalyst: "Fe–N–C single atom", loading: [0.27, 0.02, 2, "a"], fe: [89.3, 1.5, 1, "b"], jco: [17.9, 0.7, 1], eta: [660, 11, 0], stability: [84, 5, 0] },
{ catalyst: "Pd–Cu alloy", loading: [0.52, 0.04, 2, "a"], fe: [65.1, 2.6, 1, "b"], jco: [13.3, 0.6, 1], eta: [710, 14, 0], stability: [42, 4, 0] },
{ catalyst: "Sn quantum sheet", loading: [0.39, 0.03, 2, "a"], fe: [12.7, 1.9, 1, "b"], jco: [3.2, 0.3, 1], eta: [905, 25, 0], stability: [22, 3, 0] },
{ catalyst: "Co phthalocyanine", loading: [0.21, 0.02, 2, "a"], fe: [93.8, 1.1, 1, "b"], jco: [19.4, 0.8, 1], eta: [640, 10, 0], stability: [66, 5, 0] }
];
var COLUMNS = [
{ key: "catalyst", type: "text", label: "Catalyst", fn: "" },
{ key: "loading", type: "num", label: "Loading", fn: "a" },
{ key: "fe", type: "num", label: "FE_CO", fn: "b" },
{ key: "jco", type: "num", label: "j_CO", fn: "" },
{ key: "eta", type: "num", label: "eta", fn: "c" },
{ key: "stability", type: "num", label: "Stability", fn: "" }
];
var tbody = document.getElementById("tbody");
var headers = Array.prototype.slice.call(document.querySelectorAll("th.th-sort"));
var toastEl = document.getElementById("toast");
var sortState = { key: "fe", dir: "desc" }; // default matches aria-sort on FE column
/* ---- helpers ---- */
function fmt(num, decimals) {
return Number(num).toFixed(decimals);
}
function sortValue(row, key, type) {
if (type === "text") return row[key].toLowerCase();
return row[key][0];
}
function renderCell(field) {
// field = [value, uncertainty, decimals, footnoteMark?]
var value = fmt(field[0], field[2]);
var unc = fmt(field[1], field[2]);
var mark = field[3] ? '<sup class="fn-mark" title="See footnote ' + field[3] + '">' + field[3] + "</sup>" : "";
return (
'<span class="val">' + value +
' <span class="unc">± ' + unc + "</span></span>" + mark
);
}
function render() {
var rows = ROWS.slice();
var key = sortState.key;
var dir = sortState.dir;
var type = key === "catalyst" ? "text" : "num";
rows.sort(function (a, b) {
var av = sortValue(a, key, type);
var bv = sortValue(b, key, type);
if (av < bv) return dir === "asc" ? -1 : 1;
if (av > bv) return dir === "asc" ? 1 : -1;
return 0;
});
tbody.innerHTML = rows
.map(function (r) {
var badge = r.best ? '<span class="best-badge" title="Best result">best</span>' : "";
return (
'<tr class="' + (r.best ? "is-best" : "") + '">' +
'<td class="col-catalyst">' + r.catalyst + badge + "</td>" +
'<td class="num">' + renderCell(r.loading) + "</td>" +
'<td class="num">' + renderCell(r.fe) + "</td>" +
'<td class="num">' + renderCell(r.jco) + "</td>" +
'<td class="num">' + renderCell(r.eta) + "</td>" +
'<td class="num">' + renderCell(r.stability) + "</td>" +
"</tr>"
);
})
.join("");
headers.forEach(function (th) {
var k = th.getAttribute("data-key");
if (k === key) {
th.setAttribute("aria-sort", dir === "asc" ? "ascending" : "descending");
} else {
th.setAttribute("aria-sort", "none");
}
});
}
/* ---- sorting interaction ---- */
headers.forEach(function (th) {
var btn = th.querySelector(".sort-btn");
btn.addEventListener("click", function () {
var key = th.getAttribute("data-key");
if (sortState.key === key) {
sortState.dir = sortState.dir === "asc" ? "desc" : "asc";
} else {
sortState.key = key;
// numbers default to descending (best-first), text to ascending
sortState.dir = th.getAttribute("data-type") === "num" ? "desc" : "asc";
}
render();
var col = COLUMNS.filter(function (c) { return c.key === key; })[0];
toast("Sorted by " + (col ? col.label.replace(/_/g, "") : key) + " (" + sortState.dir + ")");
});
});
/* ---- CSV export ---- */
function buildCSV() {
var head = [
"Catalyst",
"Loading_mg_cm-2",
"Loading_SD",
"FE_CO_%",
"FE_CO_SD",
"jCO_mA_cm-2",
"jCO_SD",
"Overpotential_mV",
"Overpotential_SD",
"Stability_h",
"Stability_SD"
];
var rows = ROWS.slice().sort(function (a, b) {
var key = sortState.key;
var type = key === "catalyst" ? "text" : "num";
var av = sortValue(a, key, type);
var bv = sortValue(b, key, type);
if (av < bv) return sortState.dir === "asc" ? -1 : 1;
if (av > bv) return sortState.dir === "asc" ? 1 : -1;
return 0;
});
function esc(s) {
s = String(s);
return /[",\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
}
var lines = [head.join(",")];
rows.forEach(function (r) {
lines.push(
[
esc(r.catalyst),
fmt(r.loading[0], r.loading[2]), fmt(r.loading[1], r.loading[2]),
fmt(r.fe[0], r.fe[2]), fmt(r.fe[1], r.fe[2]),
fmt(r.jco[0], r.jco[2]), fmt(r.jco[1], r.jco[2]),
fmt(r.eta[0], r.eta[2]), fmt(r.eta[1], r.eta[2]),
fmt(r.stability[0], r.stability[2]), fmt(r.stability[1], r.stability[2])
].join(",")
);
});
return lines.join("\n");
}
var csvBtn = document.getElementById("csv-btn");
csvBtn.addEventListener("click", function () {
var csv = buildCSV();
var blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = "co2rr_benchmark_table1.csv";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(function () { URL.revokeObjectURL(url); }, 1000);
toast("Downloaded Table 1 as CSV (" + ROWS.length + " rows)");
});
/* ---- toast ---- */
var toastTimer = null;
function toast(msg) {
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2400);
}
render();
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Scientific Data Table — Catalytic CO₂ Reduction Survey</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=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Source+Serif+4:ital,wght@0,400;0,600;0,700;1,400&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="page">
<header class="masthead">
<p class="eyebrow">Supplementary Materials · Section 3.2</p>
<h1>Benchmarking electrocatalysts for CO<sub>2</sub> reduction</h1>
<p class="byline">
A. Marchetti<sup>1</sup>, R. Okonkwo<sup>1</sup>, L. Park<sup>2</sup>, and
J. Vasquez<sup>1,†</sup>
</p>
<p class="affil">
<sup>1</sup>Institute for Interfacial Energetics, Verdant University ·
<sup>2</sup>Northbridge National Laboratory<br />
<sup>†</sup>Correspondence: <span class="mono">j.vasquez@verdant.edu</span> ·
DOI: <a class="mono" href="#doi">10.50219/iie.2026.00731</a>
</p>
</header>
<section class="card" aria-labelledby="tbl-cap">
<figure class="table-figure">
<figcaption id="tbl-cap" class="tbl-caption">
<strong>Table 1.</strong> Faradaic efficiency, partial current density, and overpotential
for nine candidate electrocatalysts measured in 0.1 M KHCO<sub>3</sub> at −0.95 V
vs. RHE. Uncertainties are one standard deviation over <span class="mono">n = 5</span>
independent cells. The highest-performing material is highlighted.
</figcaption>
<div class="toolbar" role="toolbar" aria-label="Table controls">
<div class="legend">
<span class="chip chip-best"><span class="dot"></span>Best result</span>
<span class="chip"><span class="dot dot-meas"></span>Mean ± SD</span>
</div>
<button id="csv-btn" class="btn" type="button">
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true">
<path d="M12 3v12m0 0l-4-4m4 4l4-4M5 21h14" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
Download CSV
</button>
</div>
<div class="table-scroll" tabindex="0" aria-label="Scientific results, scrollable">
<table id="results" class="data-table">
<caption class="sr-only">Electrocatalyst benchmark results, sortable by column.</caption>
<thead>
<tr>
<th scope="col" class="th-sort th-text" data-key="catalyst" data-type="text" aria-sort="none">
<button type="button" class="sort-btn">Catalyst<span class="arrow" aria-hidden="true"></span></button>
</th>
<th scope="col" class="th-sort" data-key="loading" data-type="num" aria-sort="none">
<button type="button" class="sort-btn">Loading<span class="unit">(mg cm<sup>−2</sup>)</span><span class="arrow" aria-hidden="true"></span></button>
</th>
<th scope="col" class="th-sort" data-key="fe" data-type="num" aria-sort="descending">
<button type="button" class="sort-btn">FE<sub>CO</sub><span class="unit">(%)</span><span class="arrow" aria-hidden="true"></span></button>
</th>
<th scope="col" class="th-sort" data-key="jco" data-type="num" aria-sort="none">
<button type="button" class="sort-btn"><i>j</i><sub>CO</sub><span class="unit">(mA cm<sup>−2</sup>)</span><span class="arrow" aria-hidden="true"></span></button>
</th>
<th scope="col" class="th-sort" data-key="eta" data-type="num" aria-sort="none">
<button type="button" class="sort-btn">η<span class="unit">(mV)</span><span class="arrow" aria-hidden="true"></span></button>
</th>
<th scope="col" class="th-sort" data-key="stability" data-type="num" aria-sort="none">
<button type="button" class="sort-btn">Stability<span class="unit">(h)</span><span class="arrow" aria-hidden="true"></span></button>
</th>
</tr>
</thead>
<tbody id="tbody"><!-- rows injected by script.js --></tbody>
</table>
</div>
<ol class="footnotes" aria-label="Table footnotes">
<li><span class="fn-mark">a</span> Loading determined by inductively coupled plasma mass spectrometry.</li>
<li><span class="fn-mark">b</span> Faradaic efficiency toward CO; balance is H<sub>2</sub> and trace formate.</li>
<li><span class="fn-mark">c</span> Overpotential <span class="eq">η = <i>E</i><sub>app</sub> − <i>E</i><sup>0</sup></span>, referenced to the equilibrium potential.</li>
<li><span class="fn-mark">∗</span> Best-performing catalyst by combined FE<sub>CO</sub> and partial current density.</li>
</ol>
</figure>
<div class="eq-block" aria-label="Defining equation">
<div class="eq-body">
FE<sub>CO</sub> =
<span class="frac"><span class="num"><i>z</i> <i>F</i> <i>n</i><sub>CO</sub></span><span class="den"> <i>Q</i><sub>total</sub> </span></span>
× 100%
</div>
<div class="eq-num">(1)</div>
</div>
<p class="note">
where <i>z</i> = 2 is the electron number, <i>F</i> the Faraday constant, <i>n</i><sub>CO</sub>
the moles of CO produced, and <i>Q</i><sub>total</sub> the total charge passed.
</p>
</section>
</main>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Scientific Data Table
A reusable results table styled for a journal supplement. It opens with a bold Table 1.
caption describing the experiment, then renders nine fictional electrocatalysts with their
loading, Faradaic efficiency, partial current density, overpotential, and stability. Every
numeric column header carries an SI unit, values are right-aligned and set in JetBrains Mono so
decimal points line up, and each measurement reads as 12.34 ± 0.05 with a muted uncertainty
and superscript footnote markers.
The header is sticky and the body scrolls inside a bordered, focusable region with zebra
striping for row tracking. Clicking a column header sorts the data — numeric columns default to
descending (best-first) and the catalyst name sorts alphabetically — with the active column
showing an arrow and the correct aria-sort state. The highlighted best-result row keeps its
teal accent and badge across every sort. A short toast confirms each action.
A Download CSV button serializes the table in its current sort order into a properly escaped
CSV string, wraps it in a Blob, and triggers a download entirely client-side. Below the table,
a LaTeX-styled display equation and discipline-correct figure footnotes round out the
publication look. All controls are keyboard-operable with visible focus rings and the layout
reflows cleanly down to about 360px.
Illustrative UI only — fictional authors, data, and figures; not real scientific results.