···
justify-content: space-between;
···
background-color: var(--card-bg);
border: 1px solid var(--border-color);
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-
transition: transform 0.2s ease, box-shadow 0.2s ease;
-
transform: translateY(-2px);
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
-
border-bottom: 1px solid var(--border-color);
-
background-color: rgba(77, 250, 123, 0.05);
···
color: var(--accent-color);
-
justify-content: space-between;
-
color: var(--text-muted);
-
font-family: 'JetBrains Mono', monospace;
-
color: var(--accent-alt);
-
border-bottom: 1px solid var(--border-color);
···
color: var(--text-muted);
-
justify-content: space-between;
background-color: transparent;
-
border: 1px solid var(--accent-color);
color: var(--accent-color);
font-family: 'JetBrains Mono', monospace;
transition: all 0.2s ease;
-
background-color: var(--accent-color);
-
color: var(--bg-color);
-
transition: transform 0.2s ease;
-
.read-more.active::after {
-
transform: rotate(180deg);
···
font-family: 'JetBrains Mono', monospace;
-
font-family: 'JetBrains Mono', monospace;
-
color: var(--text-muted);
-
transition: color 0.2s ease;
-
color: var(--accent-alt);
-
.external-link::after {
@media (max-width: 600px) {
-
.feed-item-header, .feed-item-preview, .feed-item-content, .feed-item-actions {
···
const entryCountElement = document.getElementById('entry-count');
const sourceCountElement = document.getElementById('source-count');
-
// Function to format date
function formatDate(dateString) {
const date = new Date(dateString);
-
return date.toLocaleString('en-US', {
···
} else if (firstNewline !== -1) {
-
// If no period or newline, take first 100 chars
-
endIndex = Math.min(text.length, 100);
return text.substring(0, endIndex + 1).trim();
-
// Function to attach toggle handlers
-
function setupToggleHandlers() {
-
document.querySelectorAll('.read-more').forEach(button => {
-
button.addEventListener('click', function() {
-
const article = this.closest('article');
-
const content = article.querySelector('.feed-item-content');
-
if (content.style.display === 'block') {
-
content.style.display = 'none';
-
this.textContent = 'Read More';
-
this.classList.remove('active');
-
content.style.display = 'block';
-
this.textContent = 'Show Less';
-
this.classList.add('active');
···
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
const title = entry.getElementsByTagName('title')[0]?.textContent || 'No Title';
···
const contentType = contentElement?.getAttribute('type') || 'text';
const published = entry.getElementsByTagName('published')[0]?.textContent ||
entry.getElementsByTagName('updated')[0]?.textContent || '';
const categories = entry.getElementsByTagName('category');
// Extract source from category (we're using category to store source name)
···
// Get the first line for preview
const firstLine = getFirstLine(contentHtml);
-
// Format the entry HTML
-
<article class="feed-item">
-
<div class="feed-item-header">
-
<h2 class="feed-item-title"><a href="${link}" target="_blank">${title}</a></h2>
-
<div class="feed-item-meta">
-
<span class="feed-item-source">${source}</span>
-
<span class="timestamp">${formatDate(published)}</span>
-
<div class="feed-item-preview">${firstLine}</div>
-
<div class="feed-item-actions">
-
<button class="read-more">Read More</button>
-
<a href="${link}" target="_blank" class="external-link">View Original</a>
<div class="feed-item-content">${contentHtml}</div>
···
sourceCountElement.textContent = sources.size;
// Hide loading, show content
loadingContainer.style.display = 'none';
feedItemsContainer.innerHTML = entriesHTML;
-
// Setup toggle handlers
console.error('Error loading feed:', error);