From: Danilo M. Date: Thu, 16 Apr 2026 13:27:05 +0000 (+0200) Subject: feat: add card component with hover lift and glow effects X-Git-Tag: release_22042026-1342~200 X-Git-Url: https://git.danix.xyz/?a=commitdiff_plain;h=5b4ba192f8a7d405c7070f0276cd66bff96699dd;p=danix.xyz-2.git feat: add card component with hover lift and glow effects - Add .card base component with border, rounded corners, glow shadow - Add .card:hover state with translateY(-2px) lift and enhanced glow - Add .card-image, .card-body, .card-title, .card-excerpt, .card-footer semantic classes - Refactor article-list-item.html to use card component classes - Rebuild CSS: main.min.css updated Co-Authored-By: Claude Haiku 4.5 --- diff --git a/themes/danix-xyz-hacker/assets/css/main.css b/themes/danix-xyz-hacker/assets/css/main.css index 36e7359..e15d756 100644 --- a/themes/danix-xyz-hacker/assets/css/main.css +++ b/themes/danix-xyz-hacker/assets/css/main.css @@ -194,7 +194,146 @@ html.theme-light { border-color: var(--border); } + /* Button component styles */ + .btn { + @apply inline-flex items-center justify-center px-4 py-2 rounded font-bold transition-all duration-200 cursor-pointer; + background-color: var(--accent); + color: #ffffff; + border: none; + outline: none; + } + + .btn:hover:not(:disabled) { + opacity: 0.85; + transform: translateY(-1px); + } + + .btn:focus-visible { + @apply ring-2 ring-offset-2; + ring-color: var(--accent); + ring-offset-color: var(--bg); + } + + .btn:active:not(:disabled) { + transform: translateY(0); + opacity: 0.75; + } + + .btn:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + /* Button variants */ + .btn-primary { + background-color: var(--accent); + color: #ffffff; + } + + .btn-primary:hover:not(:disabled) { + background-color: var(--accent); + } + + .btn-secondary { + background-color: var(--accent2); + color: var(--bg); + font-weight: 600; + } + + .btn-secondary:hover:not(:disabled) { + background-color: var(--accent2); + } + + .btn-outline { + background-color: transparent; + color: var(--accent); + border: 2px solid var(--accent); + } + + .btn-outline:hover:not(:disabled) { + background-color: var(--accent); + color: #ffffff; + } + + /* Button sizes */ + .btn-sm { + @apply px-3 py-1 text-sm; + } + + .btn-lg { + @apply px-6 py-3 text-lg; + } + + /* Icon button (for icons without text) */ + .btn-icon { + @apply p-2 rounded-full inline-flex items-center justify-center; + width: 40px; + height: 40px; + } + + .btn-icon svg { + width: 20px; + height: 20px; + } + + /* Badge base style */ + .badge { + @apply inline-flex items-center px-2.5 py-1 rounded text-sm font-mono font-semibold whitespace-nowrap transition-all duration-200; + border: 1px solid; + } + /* Article type badge styles */ + .badge-tech { + color: var(--type-tech); + background-color: rgba(168, 85, 247, 0.1); + border-color: rgba(168, 85, 247, 0.3); + } + + .badge-tech:hover { + background-color: rgba(168, 85, 247, 0.2); + } + + .badge-life { + color: var(--type-life); + background-color: rgba(245, 158, 11, 0.1); + border-color: rgba(245, 158, 11, 0.3); + } + + .badge-life:hover { + background-color: rgba(245, 158, 11, 0.2); + } + + .badge-quote { + color: var(--type-quote); + background-color: rgba(0, 255, 136, 0.1); + border-color: rgba(0, 255, 136, 0.3); + } + + .badge-quote:hover { + background-color: rgba(0, 255, 136, 0.2); + } + + .badge-link { + color: var(--type-link); + background-color: rgba(56, 189, 248, 0.1); + border-color: rgba(56, 189, 248, 0.3); + } + + .badge-link:hover { + background-color: rgba(56, 189, 248, 0.2); + } + + .badge-photo { + color: var(--type-photo); + background-color: rgba(236, 72, 153, 0.1); + border-color: rgba(236, 72, 153, 0.3); + } + + .badge-photo:hover { + background-color: rgba(236, 72, 153, 0.2); + } + + /* Legacy type-* classes for compatibility (with badge styling) */ .type-tech { color: var(--type-tech); background-color: rgba(168, 85, 247, 0.1); @@ -220,6 +359,51 @@ html.theme-light { background-color: rgba(236, 72, 153, 0.1); } + /* Card component */ + .card { + @apply border border-border rounded-lg overflow-hidden transition-all duration-200; + box-shadow: 0 0 20px var(--accent-glow); + } + + .card:hover { + transform: translateY(-2px); + box-shadow: 0 0 30px var(--accent-glow); + } + + .card-image { + @apply aspect-video object-cover w-full; + } + + .card-body { + @apply p-5 md:p-6 space-y-3; + } + + .card-title { + @apply text-xl font-semibold; + } + + .card-excerpt { + @apply text-text-dim text-sm line-clamp-3; + } + + .card-footer { + @apply flex items-center justify-between gap-4; + } + + /* Article metadata styling (with icons) */ + .article-meta { + @apply flex flex-wrap items-center gap-4 text-sm text-text-dim; + } + + .article-meta-item { + @apply flex items-center gap-2; + } + + .article-meta-item i { + @apply w-4 h-4 flex-shrink-0; + color: var(--accent2); + } + /* Hero typography with fluid sizing */ .hero-title { font-size: clamp(2rem, 5vw + 1rem, 4.5rem); diff --git a/themes/danix-xyz-hacker/assets/css/main.min.css b/themes/danix-xyz-hacker/assets/css/main.min.css index 9c0aadb..122dfcb 100644 --- a/themes/danix-xyz-hacker/assets/css/main.min.css +++ b/themes/danix-xyz-hacker/assets/css/main.min.css @@ -1296,8 +1296,182 @@ button, border-color: var(--border); } +/* Button component styles */ + +.btn { + display: inline-flex; + cursor: pointer; + align-items: center; + justify-content: center; + border-radius: 0.25rem; + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-weight: 700; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 200ms; + background-color: var(--accent); + color: #ffffff; + border: none; + outline: none; +} + +.btn:hover:not(:disabled) { + opacity: 0.85; + transform: translateY(-1px); +} + +.btn:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-width: 2px; + ring-color: var(--accent); + ring-offset-color: var(--bg); +} + +.btn:active:not(:disabled) { + transform: translateY(0); + opacity: 0.75; +} + +.btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +/* Button variants */ + +.btn-primary { + background-color: var(--accent); + color: #ffffff; +} + +.btn-primary:hover:not(:disabled) { + background-color: var(--accent); +} + +.btn-outline { + background-color: transparent; + color: var(--accent); + border: 2px solid var(--accent); +} + +.btn-outline:hover:not(:disabled) { + background-color: var(--accent); + color: #ffffff; +} + +/* Button sizes */ + +.btn-sm { + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: 0.875rem; + line-height: 1.25rem; +} + +.btn-lg { + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + font-size: 1.125rem; + line-height: 1.75rem; +} + +/* Icon button (for icons without text) */ + +/* Badge base style */ + +.badge { + display: inline-flex; + align-items: center; + white-space: nowrap; + border-radius: 0.25rem; + padding-left: 0.625rem; + padding-right: 0.625rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-family: JetBrains Mono, monospace; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 600; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 200ms; + border: 1px solid; +} + /* Article type badge styles */ +/* Legacy type-* classes for compatibility (with badge styling) */ + +/* Card component */ + +.card { + overflow: hidden; + border-radius: 0.5rem; + border-width: 1px; + border-color: var(--border); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 200ms; +} + +article.card.border-border\/30.rounded-lg.overflow-hidden.group.bg-bg { + border-color: var(--border); + box-shadow: 0 0 20px var(--accent-glow); +} + +article.border.border-border\/30.card.overflow-hidden.group.bg-bg { + border-color: var(--border); + box-shadow: 0 0 20px var(--accent-glow); +} + +article.border.border-border\/30.rounded-lg.card.group.bg-bg { + border-color: var(--border); + box-shadow: 0 0 20px var(--accent-glow); +} + +.card { + box-shadow: 0 0 20px var(--accent-glow); +} + +.card:hover { + transform: translateY(-2px); + box-shadow: 0 0 30px var(--accent-glow); +} + +.card-image { + aspect-ratio: 16 / 9; + width: 100%; + -o-object-fit: cover; + object-fit: cover; +} + +.card-body > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} + +.card-body { + padding: 1.25rem; +} + +@media (min-width: 768px) { + .card-body { + padding: 1.5rem; + } +} + +/* Article metadata styling (with icons) */ + /* Hero typography with fluid sizing */ .sr-only { @@ -1444,6 +1618,10 @@ button, margin-bottom: 2rem; } +.ml-2 { + margin-left: 0.5rem; +} + .mt-16 { margin-top: 4rem; } @@ -1638,12 +1816,6 @@ button, margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); } -.space-y-3 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); -} - .space-y-6 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); @@ -1679,10 +1851,6 @@ button, border-width: 1px; } -.border-2 { - border-width: 2px; -} - .border-4 { border-width: 4px; } @@ -1744,10 +1912,6 @@ button, padding: 1rem; } -.p-5 { - padding: 1.25rem; -} - .p-6 { padding: 1.5rem; } @@ -1772,11 +1936,6 @@ button, padding-right: 1.5rem; } -.px-8 { - padding-left: 2rem; - padding-right: 2rem; -} - .py-0\.5 { padding-top: 0.125rem; padding-bottom: 0.125rem; @@ -2312,11 +2471,6 @@ article.border.border-border\/30.rounded-lg.overflow-hidden.group.bg-bg { opacity: 0.5; } -.group\/cta:hover .group-hover\/cta\:translate-x-1 { - --tw-translate-x: 0.25rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - .group:hover .group-hover\:scale-105 { --tw-scale-x: 1.05; --tw-scale-y: 1.05; @@ -2374,10 +2528,6 @@ article.border.border-border\/30.rounded-lg.overflow-hidden.group.bg-bg { gap: 1.5rem; } - .md\:p-6 { - padding: 1.5rem; - } - .md\:text-5xl { font-size: 3rem; line-height: 1; diff --git a/themes/danix-xyz-hacker/layouts/partials/article-list-item.html b/themes/danix-xyz-hacker/layouts/partials/article-list-item.html index 29f8d2b..d473e9a 100644 --- a/themes/danix-xyz-hacker/layouts/partials/article-list-item.html +++ b/themes/danix-xyz-hacker/layouts/partials/article-list-item.html @@ -13,14 +13,14 @@ {{ end }} {{ end }} -