1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
---
import CodeBlock from './CodeBlock.astro';
interface AssetRef {
src: string;
}
interface Service {
name: string;
eyebrow: string;
description: string;
subfeatures: string[];
command: string;
commands: string[];
art: AssetRef;
glyph: AssetRef;
accent: string;
}
interface Props {
service: Service;
reverse?: boolean;
}
const { service, reverse = false } = Astro.props;
---
<article class:list={['feature-row', { 'feature-row-reverse': reverse }]} style={`--service-accent: ${service.accent}`}>
<div class="feature-row-copy reveal">
<span class="eyebrow">{service.eyebrow}</span>
<h3>{service.name}</h3>
<p>{service.description}</p>
<ul class="feature-points">
{service.subfeatures.map((feature) => <li>{feature}</li>)}
</ul>
</div>
<div class="feature-row-visual reveal">
<div class="service-art-card">
<div class="art-card-bar">
<span>{service.name} workspace</span>
<span class="art-card-signal" aria-hidden="true"></span>
</div>
<div class="art-stage">
<img class="service-art" src={service.art.src} alt={`${service.name} illustration`} width="480" height="360" loading="lazy" decoding="async" />
<span class="service-glyph" aria-hidden="true">
<img src={service.glyph.src} alt="" width="48" height="48" loading="lazy" decoding="async" />
</span>
</div>
<CodeBlock code={service.command} label={`grr ${service.name.toLowerCase()}`} />
<details class="service-command-details">
<summary>More verified commands</summary>
<ul>
{service.commands.map((command) => <li><code>{command}</code></li>)}
</ul>
</details>
</div>
</div>
</article>