first commit
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
---
|
||||
interface Props {
|
||||
variant?: "default" | "featured" | "compact";
|
||||
}
|
||||
|
||||
const { variant = "default" } = Astro.props;
|
||||
---
|
||||
|
||||
<a
|
||||
class:list={["post-card", `post-card--${variant}`]}
|
||||
th:href="@{${post.status.permalink}}"
|
||||
>
|
||||
<div
|
||||
th:unless="${#strings.isEmpty(post.spec.cover)}"
|
||||
class="post-card__image-wrap"
|
||||
>
|
||||
<img
|
||||
class="post-card__image"
|
||||
th:src="${post.spec.cover}"
|
||||
th:srcset="|${thumbnail.gen(post.spec.cover, 's')} 400w,
|
||||
${thumbnail.gen(post.spec.cover, 'm')} 800w,
|
||||
${thumbnail.gen(post.spec.cover, 'l')} 1200w|"
|
||||
th:alt="${post.spec.title}"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<div class="post-card__overlay"></div>
|
||||
</div>
|
||||
|
||||
<div class="post-card__content">
|
||||
<time
|
||||
class="post-card__date"
|
||||
th:text="${#dates.format(post.spec.publishTime, 'yyyy-MM-dd')}"
|
||||
></time>
|
||||
<h3 class="post-card__title" th:text="${post.spec.title}"></h3>
|
||||
<p
|
||||
th:if="${variant != 'compact'}"
|
||||
class="post-card__excerpt"
|
||||
th:text="${post.status.excerpt}"
|
||||
></p>
|
||||
<div
|
||||
th:if="${variant != 'compact' and !#lists.isEmpty(post.tags)}"
|
||||
class="post-card__tags"
|
||||
>
|
||||
<span
|
||||
th:each="tag : ${post.tags}"
|
||||
class="post-card__tag"
|
||||
th:text="${tag.spec.displayName}"
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
.post-card {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
gap: var(--space-lg);
|
||||
background: var(--bg-raised);
|
||||
border-radius: var(--border-radius-lg);
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
box-shadow: var(--shadow-sm);
|
||||
transition:
|
||||
transform 400ms var(--ease-out-expo),
|
||||
box-shadow 400ms var(--ease-out-expo);
|
||||
}
|
||||
|
||||
.post-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.post-card__image-wrap {
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
border-radius: var(--border-radius-lg);
|
||||
}
|
||||
|
||||
.post-card__image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 400ms var(--ease-out-expo);
|
||||
}
|
||||
|
||||
.post-card:hover .post-card__image {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
.post-card__overlay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.post-card__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-sm);
|
||||
padding: var(--space-lg);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.post-card__date {
|
||||
font-size: var(--text-xs);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: var(--tracking-wider);
|
||||
color: var(--ink-3);
|
||||
line-height: var(--leading-none);
|
||||
}
|
||||
|
||||
.post-card__title {
|
||||
font-family: var(--font-sans);
|
||||
font-weight: 700;
|
||||
font-size: clamp(1.1rem, 2vw, 1.5rem);
|
||||
line-height: var(--leading-tight);
|
||||
color: var(--ink);
|
||||
margin: 0;
|
||||
transition: color 400ms var(--ease-out-expo);
|
||||
}
|
||||
|
||||
.post-card:hover .post-card__title {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.post-card__excerpt {
|
||||
color: var(--ink-2);
|
||||
font-size: var(--text-sm);
|
||||
line-height: var(--leading-normal);
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.post-card__tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-xs);
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.post-card__tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.2em 0.6em;
|
||||
border-radius: var(--border-radius-sm);
|
||||
background: var(--bg-raised);
|
||||
border: 1px solid var(--rule);
|
||||
font-size: var(--text-xs);
|
||||
color: var(--ink-2);
|
||||
line-height: var(--leading-none);
|
||||
}
|
||||
|
||||
.post-card--default {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.post-card--default .post-card__image-wrap {
|
||||
width: 40%;
|
||||
aspect-ratio: 4 / 3;
|
||||
}
|
||||
|
||||
.post-card--featured {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.post-card--featured .post-card__image-wrap {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.post-card--featured .post-card__overlay {
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 50%;
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
var(--glass-bg),
|
||||
transparent
|
||||
);
|
||||
backdrop-filter: blur(4px);
|
||||
-webkit-backdrop-filter: blur(4px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.post-card--featured .post-card__content {
|
||||
padding: var(--space-xl);
|
||||
gap: var(--space-md);
|
||||
}
|
||||
|
||||
.post-card--featured .post-card__title {
|
||||
font-size: clamp(1.5rem, 3vw, 2rem);
|
||||
}
|
||||
|
||||
.post-card--featured .post-card__excerpt {
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
|
||||
.post-card--compact {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
gap: var(--space-md);
|
||||
}
|
||||
|
||||
.post-card--compact:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.post-card--compact .post-card__image-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
flex-shrink: 0;
|
||||
border-radius: var(--border-radius-md);
|
||||
}
|
||||
|
||||
.post-card--compact .post-card__image-wrap img {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.post-card--compact .post-card__content {
|
||||
padding: var(--space-sm) 0;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.post-card--compact .post-card__title {
|
||||
font-size: var(--text-md);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.post-card--default {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.post-card--default .post-card__image-wrap {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user