diff --git a/static/index.html b/static/index.html
index c97cc5b..be33870 100644
--- a/static/index.html
+++ b/static/index.html
@@ -148,7 +148,11 @@
.template-group-header .icon {
font-size: 1.1em;
line-height: 1;
+ display: inline-flex;
+ align-items: center;
+ color: #495057;
}
+ .template-group-header .icon svg { width: 18px; height: 18px; }
.template-group-header .name {
font-size: 0.78em;
@@ -316,7 +320,14 @@
font-size: 1em;
line-height: 1;
opacity: 0.9;
+ display: inline-flex;
+ align-items: center;
+ color: #495057;
}
+ .template-checkbox .tpl-icon svg { width: 16px; height: 16px; }
+ .template-checkbox.checked .tpl-icon { color: #0056b3; opacity: 1; }
+ .chip svg { width: 14px; height: 14px; }
+ .dev-toggle svg { width: 16px; height: 16px; vertical-align: -3px; }
.template-checkbox .tpl-name {
flex: 1;
@@ -894,56 +905,108 @@
About SDRF Validator
// same group โ they get rendered indented beneath the parent. Exclusive groups
// allow only one selection; non-exclusive allow free combination.
// `dev: true` groups are hidden behind the "Show dev templates" toggle.
+ // Inline SVG icon set (Lucide-style, monochrome, 24x24 viewBox).
+ // Kept inline so the page stays self-contained with no network fetch.
+ const SVG_ICONS = {
+ 'file-text': ' ',
+ 'file-minus': ' ',
+ 'clipboard': ' ',
+ 'clipboard-list':' ',
+ 'flask': ' ',
+ 'flask-round': ' ',
+ 'beaker': ' ',
+ 'link': ' ',
+ 'activity': ' ',
+ 'git-merge': ' ',
+ 'circle-dot': ' ',
+ 'shield-check': ' ',
+ 'droplet': ' ',
+ 'droplets': ' ',
+ 'dna': ' ',
+ 'user': ' ',
+ 'fish': ' ',
+ 'bug': ' ',
+ 'leaf': ' ',
+ 'petri': ' ',
+ 'stethoscope': ' ',
+ 'target': ' ',
+ 'microbe': ' ',
+ 'gut': ' ',
+ 'sprout': ' ',
+ 'test-tube': ' ',
+ };
+
+ function iconSVG(name) {
+ const body = SVG_ICONS[name];
+ if (!body) return ' ';
+ return '' + body + ' ';
+ }
+
const TEMPLATE_CATEGORIES = [
- { name: 'General', icon: '๐', exclusive: false, members: [
+ { name: 'General', icon: 'clipboard', exclusive: false, members: [
{ name: 'default' }, { name: 'minimum' },
]},
- { name: 'Technology', icon: '๐ฌ', exclusive: true, members: [
+ { name: 'Technology', icon: 'flask', exclusive: true, members: [
{ name: 'ms-proteomics' }, { name: 'affinity-proteomics' },
]},
- { name: 'Experiment type', icon: '๐งช', exclusive: false, members: [
+ { name: 'Experiment type', icon: 'beaker', exclusive: false, members: [
{ name: 'dia-acquisition' }, { name: 'crosslinking' },
{ name: 'single-cell' }, { name: 'immunopeptidomics' },
]},
- { name: 'Affinity assay', icon: '๐ฏ', exclusive: true, members: [
+ { name: 'Affinity assay', icon: 'link', exclusive: true, members: [
{ name: 'olink' }, { name: 'somascan' },
]},
- { name: 'Organism', icon: '๐งฌ', exclusive: true, members: [
+ { name: 'Organism', icon: 'dna', exclusive: true, members: [
{ name: 'human' }, { name: 'vertebrates' },
{ name: 'invertebrates' }, { name: 'plants' },
]},
- { name: 'Sample', icon: '๐งซ', exclusive: false, members: [
+ { name: 'Sample', icon: 'test-tube', exclusive: false, members: [
{ name: 'sample-metadata' }, { name: 'cell-lines' },
]},
- { name: 'Clinical', icon: '๐ฉบ', exclusive: true, members: [
+ { name: 'Clinical', icon: 'stethoscope', exclusive: true, members: [
{ name: 'clinical-metadata' },
{ name: 'oncology-metadata', parent: 'clinical-metadata' },
]},
- { name: 'Metaproteomics', icon: '๐ฆ ', exclusive: true, members: [
+ { name: 'Metaproteomics', icon: 'microbe', exclusive: true, members: [
{ name: 'metaproteomics' },
{ name: 'human-gut', parent: 'metaproteomics' },
{ name: 'soil', parent: 'metaproteomics' },
{ name: 'water', parent: 'metaproteomics' },
]},
- { name: 'Metabolomics (dev)', icon: 'โ๏ธ', exclusive: true, dev: true, members: [
+ { name: 'Metabolomics (dev)', icon: 'flask-round', exclusive: true, dev: true, members: [
{ name: 'ms-metabolomics' },
{ name: 'lc-ms-metabolomics', parent: 'ms-metabolomics' },
{ name: 'gc-ms-metabolomics', parent: 'ms-metabolomics' },
]},
];
- // Per-template glyph for the card. Falls back to a neutral dot if absent.
+ // Per-template icon names. Resolved through SVG_ICONS via iconSVG().
const TEMPLATE_ICONS = {
- 'default': '๐', 'minimum': 'โ',
- 'ms-proteomics': '๐ฌ', 'affinity-proteomics': '๐ฏ',
- 'ms-metabolomics': 'โ๏ธ', 'lc-ms-metabolomics': 'โ๏ธ', 'gc-ms-metabolomics': 'โ๏ธ',
- 'dia-acquisition': '๐', 'crosslinking': '๐',
- 'single-cell': '๐', 'immunopeptidomics': '๐ก๏ธ',
- 'olink': '๐ง', 'somascan': '๐งฌ',
- 'human': '๐ค', 'vertebrates': '๐ญ', 'invertebrates': '๐ฆ', 'plants': '๐ฑ',
- 'sample-metadata': '๐ท๏ธ', 'cell-lines': '๐งซ',
- 'clinical-metadata': '๐ฉบ', 'oncology-metadata': '๐๏ธ',
- 'metaproteomics': '๐ฆ ', 'human-gut': '๐ซ', 'soil': '๐', 'water': '๐ง',
+ 'default': 'file-text',
+ 'minimum': 'file-minus',
+ 'ms-proteomics': 'flask',
+ 'affinity-proteomics':'link',
+ 'ms-metabolomics': 'flask-round',
+ 'lc-ms-metabolomics': 'flask-round',
+ 'gc-ms-metabolomics': 'flask-round',
+ 'dia-acquisition': 'activity',
+ 'crosslinking': 'git-merge',
+ 'single-cell': 'circle-dot',
+ 'immunopeptidomics': 'shield-check',
+ 'olink': 'droplet',
+ 'somascan': 'dna',
+ 'human': 'user',
+ 'vertebrates': 'fish',
+ 'invertebrates': 'bug',
+ 'plants': 'leaf',
+ 'sample-metadata': 'clipboard-list',
+ 'cell-lines': 'petri',
+ 'clinical-metadata': 'stethoscope',
+ 'oncology-metadata': 'target',
+ 'metaproteomics': 'microbe',
+ 'human-gut': 'gut',
+ 'soil': 'sprout',
+ 'water': 'droplets',
};
const skipOntology = document.getElementById('skip-ontology');
const useCacheOnly = document.getElementById('use-ols-cache-only');
@@ -1034,7 +1097,7 @@ About SDRF Validator
const header = document.createElement('div');
header.className = 'template-group-header';
header.innerHTML = `
- ${escapeHtml(g.icon || 'โข')}
+ ${iconSVG(g.icon)}
${escapeHtml(g.name)}
${g.exclusive ? 'single choice ' : ''}
`;
@@ -1061,7 +1124,7 @@ About SDRF Validator
const icon = document.createElement('span');
icon.className = 'tpl-icon';
- icon.textContent = TEMPLATE_ICONS[m.name] || 'โข';
+ icon.innerHTML = iconSVG(TEMPLATE_ICONS[m.name]);
const label = document.createElement('span');
label.className = 'tpl-name';
@@ -1085,7 +1148,7 @@ About SDRF Validator
btn.id = 'dev-toggle';
btn.type = 'button';
btn.className = 'dev-toggle';
- btn.innerHTML = 'โ๏ธ Show dev templates (metabolomics) โพ ';
+ btn.innerHTML = '' + iconSVG('flask-round') + ' Show dev templates (metabolomics) โพ ';
btn.addEventListener('click', toggleDev);
templatePicker.parentNode.insertBefore(btn, templatePicker.nextSibling);
}
@@ -1097,9 +1160,9 @@ About SDRF Validator
document.querySelectorAll('.template-group.dev-group').forEach((g) => {
g.classList.toggle('shown', expanded);
});
- btn.querySelector('.lbl').textContent = expanded
- ? 'โ๏ธ Hide dev templates (metabolomics)'
- : 'โ๏ธ Show dev templates (metabolomics)';
+ btn.querySelector('.lbl').innerHTML = iconSVG('flask-round') + (expanded
+ ? ' Hide dev templates (metabolomics)'
+ : ' Show dev templates (metabolomics)');
if (!expanded) {
// Uncheck dev members on hide so they don't get sent silently
document.querySelectorAll('.template-group.dev-group input[type="checkbox"]:checked').forEach((cb) => {
@@ -1152,7 +1215,7 @@ About SDRF Validator
const chip = document.createElement('span');
chip.className = 'chip';
const icon = document.createElement('span');
- icon.textContent = TEMPLATE_ICONS[name] || 'โข';
+ icon.innerHTML = iconSVG(TEMPLATE_ICONS[name]);
const txt = document.createElement('span');
txt.textContent = humanizeName(name);
chip.appendChild(icon);