/* ---- blog tab ---- */ /* Vertical stack of post cards. Cards are linear reading content, so unlike the project grid there is no column packing -- one column, newest first. */ .blog-list { display: flex; flex-direction: column; gap: 16px; margin-top: 24px; } /* Card hover/entrance states are driven by inline styles in BlogPostCard, mirroring ProjectCard; this is the base layer those styles sit on top of. */ .blog-post-card { min-width: 0; } /* Empty state for an unknown or not-yet-written category, mirroring the ModList pattern ("Nothing published here yet.") -- a query param should degrade gracefully, not 404. */ .blog-list-empty { font-family: var(--mono); font-size: var(--text-xs); color: var(--muted); margin: 24px 0 0; } /* Suspense fallback while useSearchParams resolves during static rendering: keeps the column's rhythm so the list paints in without a layout jump. */ .blog-list-fallback { padding: 48px 0; min-width: 0; } /* "showing 1–3 of 5" -- muted mono count line above the filters. */ .blog-count { font-family: var(--mono); font-size: var(--text-xs); color: var(--muted); margin: 0 0 12px; } /* Category chip row, styled after the tag chips in BlogPostCard. */ .blog-category-filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 0; } .blog-category-chip { font-family: var(--mono); font-size: 11px; font-weight: 500; color: var(--muted); padding: 3px 10px; background: transparent; border: 1px solid var(--border); border-radius: 4px; letter-spacing: 0.02em; text-decoration: none; white-space: nowrap; transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease; } .blog-category-chip:hover { color: var(--fg); border-color: var(--border-strong); } .blog-category-chip.is-active { color: var(--accent); background: var(--accent-bg); border-color: var(--accent); } /* Prev/Next + numbered pages, below the stack. */ .blog-pagination { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 28px; } /* Page number: small mono chip, accent when it is the current page. */ .blog-page-number { font-family: var(--mono); font-size: 11px; font-weight: 500; color: var(--fg-secondary); padding: 4px 10px; border: 1px solid var(--border); border-radius: 4px; text-decoration: none; transition: color 0.2s ease, border-color 0.2s ease; } .blog-page-number:hover { color: var(--fg); border-color: var(--border-strong); } .blog-page-number.is-active { color: var(--accent); border-color: var(--accent); background: var(--accent-bg); } /* Prev/Next: the site's existing button class carries the size, shape and hover-scale; this pins its content and keeps the disabled span aligned. */ .blog-page-link { display: flex; align-items: center; justify-content: center; text-decoration: none; font-size: 12px; } /* Disabled Prev/Next: non-link span styled identically, dimmed. */ .blog-pagination span.blog-page-link { color: var(--faint); border-color: var(--border-subtle); background: transparent; scale: 1; cursor: default; user-select: none; pointer-events: none; } /* Blog post page: the category chip above the content reuses the filter chip's look (is-active state) and links to /blog?category=. */ .blog-post-category-chip { margin-bottom: 12px; } /* Narrow layout: the same controls, just tighter. */ @media (max-width: 768px) { .blog-post-card { padding: 20px; } .blog-pagination { margin-top: 20px; } .blog-category-chip, .blog-page-number { padding: 4px 8px; } } @media (prefers-reduced-motion: reduce) { .blog-post-card { transition: none; } .blog-category-chip, .blog-page-number, .blog-page-link { transition: none; } .blog-pagination span.blog-page-link { scale: none; } }