ntv3 / index.html
bernardo-de-almeida's picture
fix: remove functional_tracks
7b1a017
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>NTv3 — Next-Gen Foundation Models for Genomics</title>
<meta name="description" content="NTv3 companion hub: PyTorch notebooks for inference, fine-tuning, interpretation, and sequence generation on NTv3 models hosted on Hugging Face." />
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" />
<style>
:root {
--bg: #0b1020;
--card: rgba(255, 255, 255, 0.06);
--text: rgba(255, 255, 255, 0.92);
--muted: rgba(255, 255, 255, 0.65);
--link: #7dd3fc;
--border: rgba(255, 255, 255, 0.12);
--shadow: 0 10px 30px rgba(0,0,0,0.35);
--radius: 18px;
--mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--sans: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji","Segoe UI Emoji";
}
body {
margin: 0;
font-family: var(--sans);
color: var(--text);
background:
radial-gradient(1200px 800px at 10% 10%, rgba(125, 211, 252, 0.12), transparent 60%),
radial-gradient(1200px 800px at 90% 30%, rgba(167, 139, 250, 0.12), transparent 55%),
var(--bg);
min-height: 100vh;
}
.wrap { max-width: 980px; margin: 0 auto; padding: 44px 18px 56px; }
.hero {
display: grid; gap: 14px;
padding: 26px 24px;
border: 1px solid var(--border);
background: var(--card);
box-shadow: var(--shadow);
border-radius: var(--radius);
}
h1 { font-size: 34px; margin: 0; letter-spacing: -0.02em; }
p { margin: 0; color: var(--muted); line-height: 1.5; }
.grid {
margin-top: 18px;
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 14px;
}
.card {
grid-column: span 6;
padding: 18px 18px;
border: 1px solid var(--border);
background: var(--card);
border-radius: var(--radius);
box-shadow: 0 6px 18px rgba(0,0,0,0.22);
}
.card-stack {
grid-column: span 6;
display: flex;
flex-direction: column;
gap: 14px;
}
.card-stack .card {
grid-column: span 1;
margin: 0;
}
.card h2 { margin: 0 0 10px 0; font-size: 16px; letter-spacing: 0.01em; }
.card ul { margin: 0; padding-left: 18px; color: var(--muted); }
.card li { margin: 8px 0; }
.card table {
width: 100%;
margin-top: 12px;
border-collapse: collapse;
font-size: 13px;
}
.card table th {
text-align: left;
padding: 10px 12px;
border-bottom: 2px solid var(--border);
color: var(--text);
font-weight: 600;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.card table td {
padding: 10px 12px;
border-bottom: 1px solid var(--border);
color: var(--muted);
}
.card table tr:last-child td {
border-bottom: none;
}
.card table tr:hover {
background: rgba(255, 255, 255, 0.02);
}
.card table td .checkmark {
color: #4ade80 !important;
}
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
.pillrow { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.pill {
font-size: 12px;
padding: 6px 10px;
border-radius: 999px;
border: 1px solid var(--border);
background: rgba(255,255,255,0.04);
color: var(--muted);
}
.code {
margin-top: 12px;
padding: 16px 18px;
border-radius: 14px;
border: 1px solid var(--border);
background: rgba(0,0,0,0.3);
font-family: var(--mono);
font-size: 13px;
line-height: 1.6;
overflow-x: auto;
color: rgba(255,255,255,0.9);
white-space: pre;
}
.code code {
font-family: inherit;
font-size: inherit;
color: inherit;
}
/* Prism.js theme overrides to match dark theme */
.code pre[class*="language-"] {
background: transparent;
margin: 0;
padding: 0;
}
.code code[class*="language-"] {
background: transparent;
}
.summary {
margin-top: 18px;
padding: 24px;
border: 1px solid var(--border);
background: var(--card);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.summary h2 {
margin: 0 0 16px 0;
font-size: 18px;
letter-spacing: 0.01em;
}
.summary p {
margin: 0 0 14px 0;
color: var(--muted);
line-height: 1.7;
}
.summary p:last-child {
margin-bottom: 0;
}
.why-ntv3 {
margin-top: 18px;
padding: 24px;
border: 1px solid var(--border);
background: var(--card);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.why-ntv3 h2 {
margin: 0 0 16px 0;
font-size: 18px;
letter-spacing: 0.01em;
}
.why-ntv3 ul {
margin: 0;
padding-left: 0;
list-style: none;
color: var(--muted);
}
.why-ntv3 li {
margin: 12px 0;
padding-left: 0;
line-height: 1.7;
}
.paper-summary {
margin-top: 12px;
padding: 24px;
border: 1px solid var(--border);
background: var(--card);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.paper-summary h2 {
text-align: center;
margin: 0 0 20px 0;
}
.paper-summary img {
width: 100%;
height: auto;
display: block;
border-radius: 12px;
}
.footer { margin-top: 22px; color: var(--muted); font-size: 13px; }
/* Tab navigation styles */
.tabs {
margin-top: 24px;
display: flex;
gap: 8px;
border-bottom: 2px solid var(--border);
overflow-x: auto;
}
.tab-button {
padding: 12px 20px;
background: transparent;
border: none;
border-bottom: 2px solid transparent;
color: var(--muted);
font-family: var(--sans);
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
margin-bottom: -2px;
}
.tab-button:hover {
color: var(--text);
background: rgba(255, 255, 255, 0.03);
}
.tab-button.active {
color: var(--link);
border-bottom-color: var(--link);
}
.tab-content {
display: none;
animation: fadeIn 0.3s ease;
}
.tab-content.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
@media (max-width: 860px) {
.card { grid-column: span 12; }
h1 { font-size: 28px; }
.tab-button {
padding: 10px 16px;
font-size: 13px;
}
}
</style>
</head>
<body>
<div class="wrap">
<div class="hero">
<h1>🧬 NTv3 — Next-Gen Foundation Models for Genomics</h1>
<p>
This Space is the companion hub for <strong>NTv3</strong> models: runnable notebooks for inference, fine-tuning, interpretation, and sequence generation.
</p>
<div class="pillrow">
<span class="pill">🤖 Foundation Models</span>
<span class="pill">🧬 Long-context genomics</span>
<span class="pill">🌍 Multi-species</span>
<span class="pill">⚡ Inference • Fine-tune • Interpret • Generate</span>
<span class="pill">📓 Torch notebooks</span>
</div>
</div>
<!-- Tab Navigation -->
<div class="tabs">
<button class="tab-button active" data-tab="home">🏠 Home</button>
<button class="tab-button" data-tab="demo">🚀 Live Demo</button>
</div>
<!-- Home Tab (Content loaded from tabs/home.html) -->
<div id="home" class="tab-content active">
<!-- Content will be loaded dynamically -->
</div>
<!-- Live Demo Tab (Content loaded from tabs/demo.html) -->
<div id="demo" class="tab-content">
<!-- Content will be loaded dynamically -->
</div>
<!-- <div class="paper-summary">
<h2>📄 A foundational model for joint sequence-function multi-species modeling at scale for long-range genomic prediction</h2>
<img src="assets/paper_summary.png" alt="NTv3 Paper Summary" />
</div> -->
<p class="footer">
© instadeep-ai — NTv3 companion Space.
</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<script>
// Tab content mapping
const tabFiles = {
'home': 'tabs/home.html',
'demo': 'tabs/demo.html',
'functional_tracks': 'tabs/functional_tracks.html',
};
// Cache for loaded tab content
const tabCache = {};
// Function to load tab content
async function loadTabContent(tabId) {
// Return cached content if available
if (tabCache[tabId]) {
return tabCache[tabId];
}
// Load content from file
const filePath = tabFiles[tabId];
if (!filePath) {
console.error(`No file path defined for tab: ${tabId}`);
return '';
}
try {
const response = await fetch(filePath);
if (!response.ok) {
throw new Error(`Failed to load ${filePath}: ${response.statusText}`);
}
const content = await response.text();
tabCache[tabId] = content;
return content;
} catch (error) {
console.error(`Error loading tab content for ${tabId}:`, error);
return `<div class="summary"><p>Error loading content. Please refresh the page.</p></div>`;
}
}
// Function to show a tab
async function showTab(tabId) {
const tabContent = document.getElementById(tabId);
if (!tabContent) {
console.error(`Tab element not found: ${tabId}`);
return;
}
// Load content if not already loaded
if (!tabContent.dataset.loaded) {
tabContent.innerHTML = await loadTabContent(tabId);
tabContent.dataset.loaded = 'true';
// Re-run Prism.js syntax highlighting for code blocks in the loaded content
if (typeof Prism !== 'undefined') {
// Find all code blocks in the loaded content and highlight them
const codeBlocks = tabContent.querySelectorAll('code[class*="language-"]');
codeBlocks.forEach(block => {
Prism.highlightElement(block);
});
}
}
}
// Tab switching functionality
document.addEventListener('DOMContentLoaded', function() {
const tabButtons = document.querySelectorAll('.tab-button');
const tabContents = document.querySelectorAll('.tab-content');
// Load the default active tab (home)
const activeTab = document.querySelector('.tab-content.active');
if (activeTab) {
showTab(activeTab.id);
}
tabButtons.forEach(button => {
button.addEventListener('click', async () => {
const targetTab = button.getAttribute('data-tab');
// Remove active class from all buttons and contents
tabButtons.forEach(btn => btn.classList.remove('active'));
tabContents.forEach(content => content.classList.remove('active'));
// Add active class to clicked button and corresponding content
button.classList.add('active');
const tabElement = document.getElementById(targetTab);
tabElement.classList.add('active');
// Load and show the tab content
await showTab(targetTab);
});
});
});
</script>
</body>
</html>