From: Danilo M. Date: Tue, 21 Apr 2026 09:30:05 +0000 (+0200) Subject: feat: add timeline CSS component classes X-Git-Tag: release_22042026-1342~49 X-Git-Url: https://git.danix.xyz/?a=commitdiff_plain;h=e69ee817fd09aa4edd5ecaaec799fa4eabb1d710;p=danix.xyz-2.git feat: add timeline CSS component classes --- diff --git a/themes/danix-xyz-hacker/assets/css/main.css b/themes/danix-xyz-hacker/assets/css/main.css index 338a504..f71f4ec 100644 --- a/themes/danix-xyz-hacker/assets/css/main.css +++ b/themes/danix-xyz-hacker/assets/css/main.css @@ -505,6 +505,202 @@ html.theme-light picture img[src="/images/default_thumbnail_dark.png"] { @apply flex items-center justify-between gap-4; } + /* ===================== + Timeline Layout + ===================== */ + + .timeline { + @apply relative mx-auto max-w-5xl px-4 py-12; + } + + /* Vertical spine — center on desktop, left on mobile */ + .timeline::before { + content: ''; + @apply absolute top-0 bottom-0; + left: 20px; + width: 2px; + background: linear-gradient(to bottom, var(--accent), var(--accent2, var(--accent))); + opacity: 0.7; + } + + @screen md { + .timeline::before { + left: 50%; + transform: translateX(-50%); + } + } + + /* Each timeline row */ + .timeline-item { + @apply relative mb-10; + /* Mobile: offset right of left spine */ + margin-left: 44px; + } + + @screen md { + .timeline-item { + margin-left: 0; + @apply flex items-start; + /* Each item takes full width; card is positioned via padding inside */ + } + } + + /* ---- Connector line ---- */ + .timeline-connector { + @apply absolute; + top: 20px; + height: 2px; + /* Mobile: from spine (left:22px) to card left edge (left:44px) */ + left: -22px; + width: 22px; + } + + @screen md { + /* Desktop: driven by .timeline-item--left / --right modifier */ + .timeline-item--left .timeline-connector { + right: calc(50% - 28px + 1px); + left: auto; + width: 28px; + } + .timeline-item--right .timeline-connector { + left: calc(50% + 28px - 28px); + width: 28px; + } + } + + /* ---- Node on spine ---- */ + .timeline-node { + @apply absolute rounded-full z-10; + top: 14px; + /* Mobile: on left spine at left:20px, node is 10px → left:15px */ + left: -27px; + width: 10px; + height: 10px; + border: 2px solid var(--bg); + } + + @screen md { + .timeline-node { + width: 12px; + height: 12px; + top: 14px; + left: calc(50% - 6px); + /* Override mobile left positioning */ + transform: none; + } + /* Reset mobile left for desktop — node always on center spine */ + .timeline-item--left .timeline-node, + .timeline-item--right .timeline-node { + left: calc(50% - 6px); + } + } + + /* ---- Card wrapper ---- */ + .timeline-card { + @apply flex border rounded-lg overflow-hidden bg-surface; + transition: box-shadow 0.2s, transform 0.2s; + } + + .timeline-card:hover { + transform: translateY(-2px); + } + + /* Mobile: full width */ + .timeline-card { + width: 100%; + } + + @screen md { + /* Desktop: card occupies ~45% width, positioned by padding on .timeline-item */ + .timeline-item--left { + padding-right: calc(50% + 28px); + } + .timeline-item--right { + padding-left: calc(50% + 28px); + } + } + + /* ---- Thumbnail panel ---- */ + .timeline-thumb { + @apply flex-shrink-0 overflow-hidden; + /* Mobile: full width banner on top — handled by flex-direction:column on mobile card */ + width: 100%; + height: 90px; + } + + @screen md { + .timeline-thumb { + width: 38%; + height: auto; + aspect-ratio: 2 / 3; + } + } + + .timeline-thumb img { + @apply w-full h-full object-cover; + transition: transform 0.2s; + } + + .timeline-card:hover .timeline-thumb img { + transform: scale(1.03); + } + + /* ---- Text panel ---- */ + .timeline-body { + @apply flex flex-col gap-2 p-4 flex-1; + } + + /* Mobile card stacks thumbnail above body */ + .timeline-card { + flex-direction: column; + } + + @screen md { + .timeline-card { + flex-direction: row; + } + /* Left card: thumb first (outer=left), body second */ + .timeline-item--left .timeline-card { + flex-direction: row; + } + /* Right card: body first (inner=left), thumb last (outer=right) */ + .timeline-item--right .timeline-card { + flex-direction: row-reverse; + } + } + + /* ---- Meta row (TYPE · date) ---- */ + .timeline-meta { + @apply flex items-center gap-2 text-xs font-mono tracking-widest uppercase; + } + + .timeline-meta-sep { + @apply text-border; + } + + .timeline-date { + @apply text-text-dim normal-case tracking-normal; + } + + /* ---- Title ---- */ + .timeline-title { + @apply font-semibold text-base leading-snug; + } + + .timeline-title a { + @apply hover:text-accent transition-colors; + } + + /* ---- Excerpt ---- */ + .timeline-excerpt { + @apply text-text-dim text-sm line-clamp-3 leading-relaxed; + } + + /* ---- Pinned badge ---- */ + .timeline-pinned { + @apply inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-semibold; + } + /* Header navigation styling */ .header { @apply fixed top-0 left-0 right-0 z-40; diff --git a/themes/danix-xyz-hacker/assets/css/main.min.css b/themes/danix-xyz-hacker/assets/css/main.min.css index d9145d2..5c299ff 100644 --- a/themes/danix-xyz-hacker/assets/css/main.min.css +++ b/themes/danix-xyz-hacker/assets/css/main.min.css @@ -1590,6 +1590,36 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg { } } +/* ===================== + Timeline Layout + ===================== */ + +/* Vertical spine — center on desktop, left on mobile */ + +/* Each timeline row */ + +/* ---- Connector line ---- */ + +/* ---- Node on spine ---- */ + +/* ---- Card wrapper ---- */ + +/* Mobile: full width */ + +/* ---- Thumbnail panel ---- */ + +/* ---- Text panel ---- */ + +/* Mobile card stacks thumbnail above body */ + +/* ---- Meta row (TYPE · date) ---- */ + +/* ---- Title ---- */ + +/* ---- Excerpt ---- */ + +/* ---- Pinned badge ---- */ + /* Header navigation styling */ .header {