|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Timeline Template</title> |
|
<style> |
|
body { |
|
font-family: 'Arial', sans-serif; |
|
background-color: #f4f4f9; |
|
color: #333; |
|
margin: 0; |
|
padding: 0; |
|
overflow-x: scroll; |
|
scrollbar-width: thin; |
|
-ms-overflow-style: -ms-autohiding-scrollbar; |
|
} |
|
.timeline { |
|
display: flex; |
|
flex-direction: row; |
|
padding: 20px; |
|
gap: 10px; |
|
overflow-x: auto; |
|
} |
|
.month { |
|
display: flex; |
|
flex-direction: column; |
|
gap: 10px; |
|
width: 300px; |
|
flex: 0 0 300px; |
|
} |
|
.month h3 { |
|
margin: 0; |
|
padding: 10px; |
|
background-color: #6200ea; |
|
color: white; |
|
border-radius: 5px; |
|
text-align: center; |
|
} |
|
.event { |
|
background-color: white; |
|
padding: 10px; |
|
border-radius: 5px; |
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
|
position: relative; |
|
transition: all 0.3s ease; |
|
} |
|
|
|
|
|
.event:has(.tag.open-source) { |
|
background-color: #e8f5e9; |
|
border-left: 4px solid #4caf50; |
|
transform: scale(1.02); |
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); |
|
} |
|
|
|
|
|
.event:has(.tag.api-only) { |
|
background-color: #fafafa; |
|
border-left: 4px solid #f44336; |
|
} |
|
|
|
|
|
.event:has(.tag.open-source):hover { |
|
transform: scale(1.03); |
|
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); |
|
} |
|
.event h4 { |
|
margin: 0; |
|
font-size: 14px; |
|
} |
|
.event p { |
|
margin: 5px 0 0; |
|
font-size: 12px; |
|
color: #666; |
|
} |
|
.tag { |
|
display: inline-block; |
|
padding: 2px 5px; |
|
font-size: 10px; |
|
border-radius: 3px; |
|
margin-top: 5px; |
|
} |
|
.tag.open-source { |
|
background-color: #4caf50; |
|
color: white; |
|
} |
|
.tag.api-only { |
|
background-color: #f44336; |
|
color: white; |
|
} |
|
.event p a { |
|
color: #4caf50; |
|
text-decoration: none; |
|
} |
|
.event p a:hover { |
|
text-decoration: underline; |
|
} |
|
.github-link { |
|
text-align: center; |
|
padding: 8px; |
|
background-color: #24292e; |
|
color: white; |
|
font-size: 14px; |
|
} |
|
.github-link a { |
|
color: white; |
|
text-decoration: none; |
|
} |
|
.github-link a:hover { |
|
text-decoration: underline; |
|
} |
|
|
|
body::-webkit-scrollbar { |
|
height: 8px; |
|
} |
|
|
|
body::-webkit-scrollbar-track { |
|
background: #f1f1f1; |
|
} |
|
|
|
body::-webkit-scrollbar-thumb { |
|
background: #888; |
|
border-radius: 4px; |
|
} |
|
|
|
body::-webkit-scrollbar-thumb:hover { |
|
background: #555; |
|
} |
|
|
|
.tag.text { |
|
background-color: #9c27b0; |
|
color: white; |
|
} |
|
.tag.audio { |
|
background-color: #ff9800; |
|
color: white; |
|
} |
|
.tag.vision { |
|
background-color: #03a9f4; |
|
color: white; |
|
} |
|
.tag.multimodal { |
|
background-color: #795548; |
|
color: white; |
|
} |
|
.tag.announcement { |
|
background-color: #607d8b; |
|
color: white; |
|
} |
|
|
|
.filter-group { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
gap: 15px; |
|
padding: 20px 0; |
|
background-color: white; |
|
border-bottom: 1px solid #eee; |
|
} |
|
|
|
.toggle-container { |
|
display: flex; |
|
gap: 8px; |
|
} |
|
|
|
.dropdown-filters { |
|
display: flex; |
|
gap: 8px; |
|
} |
|
|
|
.toggle-button { |
|
padding: 6px 12px; |
|
border: 1px solid #ddd; |
|
border-radius: 15px; |
|
background-color: white; |
|
font-size: 13px; |
|
cursor: pointer; |
|
transition: all 0.2s ease; |
|
} |
|
|
|
.toggle-button.active { |
|
background-color: #2196f3; |
|
border-color: #2196f3; |
|
color: white; |
|
} |
|
|
|
select { |
|
padding: 6px 12px; |
|
border: 1px solid #ddd; |
|
border-radius: 15px; |
|
font-size: 13px; |
|
background-color: white; |
|
cursor: pointer; |
|
} |
|
|
|
.counter-container { |
|
text-align: center; |
|
padding: 15px; |
|
font-size: 14px; |
|
color: #666; |
|
background-color: #f8f9fa; |
|
} |
|
|
|
.counter-item span { |
|
font-weight: bold; |
|
color: #2196f3; |
|
} |
|
|
|
.counter-divider { |
|
margin: 0 10px; |
|
color: #ddd; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="github-link"> |
|
<a href="#" target="_blank">View on GitHub</a> |
|
</div> |
|
<div class="filter-group"> |
|
<div class="toggle-container"> |
|
<button class="toggle-button active" data-filter="all">All Models</button> |
|
<button class="toggle-button" data-filter="open-source">Open Source</button> |
|
<button class="toggle-button" data-filter="api-only">API Only</button> |
|
</div> |
|
<div class="dropdown-filters"> |
|
<select id="modalityFilter" onchange="filterByModality(this.value)"> |
|
<option value="all">All Modalities</option> |
|
<option value="text">Text</option> |
|
<option value="audio">Audio</option> |
|
<option value="vision">Vision</option> |
|
<option value="multimodal">Multimodal</option> |
|
</select> |
|
<select id="typeFilter" onchange="filterByType(this.value)"> |
|
<option value="all">All Types</option> |
|
<option value="model">Models</option> |
|
<option value="announcement">Announcements</option> |
|
</select> |
|
</div> |
|
</div> |
|
<div class="counter-container"> |
|
<span class="counter-item"> |
|
<span id="open-source-count">0</span> Open Source |
|
</span> |
|
<span class="counter-divider">·</span> |
|
<span class="counter-item"> |
|
<span id="api-only-count">0</span> API Only |
|
</span> |
|
</div> |
|
<div class="timeline"> |
|
<div class="month"> |
|
<h3>January 2025</h3> |
|
<div class="event"> |
|
<h4>GPT-5 Announcement</h4> |
|
<p>OpenAI announces GPT-5 development completion</p> |
|
<span class="tag api-only">API Only</span> |
|
<span class="tag text">Text</span> |
|
<span class="tag announcement">Announcement</span> |
|
</div> |
|
<div class="event"> |
|
<h4>Anthropic Claude 4</h4> |
|
<p>Anthropic releases Claude 4 with enhanced reasoning</p> |
|
<span class="tag api-only">API Only</span> |
|
<span class="tag text">Text</span> |
|
</div> |
|
</div> |
|
<div class="month"> |
|
<h3>February 2025</h3> |
|
<div class="event"> |
|
<h4>Meta's AudioCraft 2.0</h4> |
|
<p>Open source audio generation model</p> |
|
<span class="tag open-source">Open Weights</span> |
|
<span class="tag audio">Audio</span> |
|
</div> |
|
<div class="event"> |
|
<h4>Google Gemini Ultra</h4> |
|
<p>Next generation multimodal model</p> |
|
<span class="tag api-only">API Only</span> |
|
<span class="tag multimodal">Multimodal</span> |
|
</div> |
|
</div> |
|
<div class="month"> |
|
<h3>March 2025</h3> |
|
<div class="event"> |
|
<h4>Stability AI ImageGen V5</h4> |
|
<p>Open source image generation</p> |
|
<span class="tag open-source">Open Weights</span> |
|
<span class="tag vision">Vision</span> |
|
</div> |
|
</div> |
|
</div> |
|
<script> |
|
function updateCounts() { |
|
const openSourceCount = document.querySelectorAll('.tag.open-source').length; |
|
const apiOnlyCount = document.querySelectorAll('.tag.api-only').length; |
|
|
|
document.getElementById('open-source-count').textContent = openSourceCount; |
|
document.getElementById('api-only-count').textContent = apiOnlyCount; |
|
} |
|
|
|
let currentFilters = { |
|
category: 'all', |
|
modality: 'all', |
|
type: 'all' |
|
}; |
|
|
|
function filterByModality(modality) { |
|
currentFilters.modality = modality; |
|
applyFilters(); |
|
} |
|
|
|
function filterByType(type) { |
|
currentFilters.type = type; |
|
applyFilters(); |
|
} |
|
|
|
function filterEvents(category) { |
|
|
|
const buttons = document.querySelectorAll('.toggle-button'); |
|
buttons.forEach(button => { |
|
button.classList.remove('active'); |
|
if (button.getAttribute('data-filter') === category) { |
|
button.classList.add('active'); |
|
} |
|
}); |
|
|
|
currentFilters.category = category; |
|
applyFilters(); |
|
} |
|
|
|
function applyFilters() { |
|
const events = document.querySelectorAll('.event'); |
|
|
|
events.forEach(event => { |
|
const matchesCategory = currentFilters.category === 'all' || |
|
event.querySelector(`.tag.${currentFilters.category}`); |
|
const matchesModality = currentFilters.modality === 'all' || |
|
event.querySelector(`.tag.${currentFilters.modality}`); |
|
const matchesType = currentFilters.type === 'all' || |
|
(currentFilters.type === 'announcement' ? |
|
event.querySelector('.tag.announcement') : |
|
!event.querySelector('.tag.announcement')); |
|
|
|
event.style.display = (matchesCategory && matchesModality && matchesType) ? 'block' : 'none'; |
|
}); |
|
|
|
|
|
const months = document.querySelectorAll('.month'); |
|
months.forEach(month => { |
|
const visibleEvents = Array.from(month.querySelectorAll('.event')).filter(event => |
|
event.style.display !== 'none' |
|
); |
|
month.style.display = visibleEvents.length > 0 ? 'flex' : 'none'; |
|
}); |
|
|
|
updateCounts(); |
|
} |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
const buttons = document.querySelectorAll('.toggle-button'); |
|
buttons.forEach(button => { |
|
button.addEventListener('click', function() { |
|
filterEvents(this.getAttribute('data-filter')); |
|
}); |
|
}); |
|
updateCounts(); |
|
}); |
|
</script> |
|
</body> |
|
</html> |