Emdash source with visual editor image upload fix
Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
135
templates/marketing/src/components/blocks/Features.astro
Normal file
135
templates/marketing/src/components/blocks/Features.astro
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
import { Icon } from "astro-iconset/components";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
_key?: string;
|
||||
headline?: string;
|
||||
subheadline?: string;
|
||||
features: Array<{
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
const { _key, headline, subheadline, features } = node;
|
||||
|
||||
const iconMap: Record<string, string> = {
|
||||
zap: "ph:lightning",
|
||||
shield: "ph:shield-check",
|
||||
users: "ph:users-three",
|
||||
chart: "ph:chart-bar",
|
||||
code: "ph:code",
|
||||
globe: "ph:globe",
|
||||
heart: "ph:heart",
|
||||
star: "ph:star",
|
||||
check: "ph:check-circle",
|
||||
lock: "ph:lock",
|
||||
clock: "ph:clock",
|
||||
cloud: "ph:cloud",
|
||||
};
|
||||
---
|
||||
|
||||
<section class="features section" id={_key}>
|
||||
<div class="container">
|
||||
{(headline || subheadline) && (
|
||||
<header class="features-header">
|
||||
{headline && <h2 class="features-headline">{headline}</h2>}
|
||||
{subheadline && <p class="features-subheadline">{subheadline}</p>}
|
||||
</header>
|
||||
)}
|
||||
<div class="features-grid">
|
||||
{features.map((feature) => (
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<Icon name={iconMap[feature.icon] || "ph:sparkle"} aria-hidden="true" />
|
||||
</div>
|
||||
<h3 class="feature-title">{feature.title}</h3>
|
||||
<p class="feature-description">{feature.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.features-header {
|
||||
text-align: center;
|
||||
max-width: var(--max-width);
|
||||
margin: 0 auto var(--spacing-4xl);
|
||||
}
|
||||
|
||||
.features-headline {
|
||||
font-size: var(--font-size-3xl);
|
||||
font-weight: 800;
|
||||
margin-bottom: var(--spacing-md);
|
||||
}
|
||||
|
||||
.features-subheadline {
|
||||
font-size: var(--font-size-lg);
|
||||
color: var(--color-muted);
|
||||
}
|
||||
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: var(--spacing-xl);
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
padding: var(--spacing-xl);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
transition:
|
||||
transform var(--transition-base),
|
||||
box-shadow var(--transition-base),
|
||||
border-color var(--transition-base);
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
border-color: var(--color-primary-light);
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
|
||||
border-radius: var(--radius);
|
||||
margin-bottom: var(--spacing-lg);
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: 700;
|
||||
margin-bottom: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.feature-description {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.features-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.features-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user