Files
com.gregkilmer.www/services/site/src/components/work/FeaturedStudy.astro
T
Claude 813c403fcc Make the background seals a little stronger in light mode
A --gk-ghost token scales the faint edge seals, panel seals and banners:
1 in dark, 1.6 in light, so their lines read on Starlight.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
2026-10-18 20:34:46 +00:00

210 lines
5.0 KiB
Plaintext

---
/**
* The one gilt panel on Work: the featured case study with its role, summary,
* tech, key facts and a link to the full study.
*/
import Button from "@gk/ui/components/Button.astro";
import Chip from "@gk/ui/components/Chip.astro";
import GiltCorners from "@gk/ui/components/GiltCorners.astro";
import Seal from "@gk/ui/components/Seal.astro";
import Star from "@gk/ui/components/Star.astro";
import TickScale from "@gk/ui/components/TickScale.astro";
import type { Note } from "../../lib/content.ts";
import { workGroup, workKicker } from "../../lib/work.ts";
interface Props {
study: Note<"post">;
href: string | null;
core: Set<string>;
}
const { study, href, core } = Astro.props;
const d = study.data;
const facts = d.facts ?? [];
---
<section aria-labelledby="work-featured" class="featured-wrap" data-group={workGroup(study)}>
<article class="panel">
<GiltCorners inset={4} />
<div class="inner">
<Seal name="transmutation" size={340} class="ghost" />
<div class="main">
<span class="kicker"><Star size={14} />Featured · {workKicker(study)}</span>
<div class="heading">
<h2 id="work-featured">{d.title}</h2>
<span class="underline" aria-hidden="true"></span>
</div>
{d.role && <span class="role">{d.role}</span>}
{d.period && <span class="period">{d.period}</span>}
{d.summary && <p class="summary">{d.summary}</p>}
{
d.tech?.length ? (
<div class="chips">
{d.tech.map((t) => (
<Chip core={core.has(t.toLowerCase())}>{t}</Chip>
))}
</div>
) : null
}
{href && <Button href={href} arrow class="cta">Read the case study</Button>}
</div>
{
facts.length > 0 && (
<div class="side">
<dl class="facts">
{facts.map((f) => (
<div class="fact">
<dt>{f.label}</dt>
<dd>
<span class="value">{f.value}</span>
<TickScale width={110} height={10} count={22} class="ticks" />
</dd>
</div>
))}
</dl>
</div>
)
}
</div>
</article>
</section>
<style>
.featured-wrap {
padding: 24px 0 8px;
}
.panel {
position: relative;
overflow: hidden;
background: var(--gk-midnight);
border: 1px solid var(--gk-gold);
border-radius: var(--gk-radius);
padding: 8px;
}
.inner {
position: relative;
border: 1px solid rgba(138, 101, 22, 0.35);
border-radius: 6px;
padding: 36px;
display: flex;
flex-wrap: wrap;
gap: 36px;
}
.inner :global(.ghost) {
position: absolute;
right: -60px;
bottom: -80px;
opacity: calc(0.12 * var(--gk-ghost));
pointer-events: none;
}
.main {
flex: 1 1 420px;
min-width: 0;
display: flex;
flex-direction: column;
gap: 14px;
position: relative;
}
.kicker {
display: flex;
align-items: center;
gap: 10px;
font-size: 11px;
letter-spacing: 0.3em;
font-weight: 600;
color: var(--gk-gold-bright);
text-transform: uppercase;
}
.heading {
display: flex;
flex-direction: column;
gap: 8px;
}
h2 {
margin: 0;
font-size: clamp(30px, 5vw, 40px);
letter-spacing: 0.06em;
line-height: 1.1;
}
.underline {
display: block;
width: 180px;
height: 2px;
border-radius: 2px;
background:
linear-gradient(90deg, var(--gk-gold), rgba(var(--gk-gold-rgb), 0.15) 70%, transparent),
radial-gradient(circle at 18% 50%, var(--gk-teal-bright) 0 2px, transparent 3px);
box-shadow: 0 0 8px rgba(var(--gk-gold-rgb), 0.35);
}
.role {
font-size: 15px;
font-weight: 600;
color: var(--gk-teal-bright);
}
.period {
margin-top: -8px;
font-size: 13px;
color: var(--gk-muted);
}
.summary {
margin: 0;
font-size: 16px;
line-height: 1.65;
color: var(--gk-muted);
padding-left: 14px;
border-left: 2px solid var(--gk-gold);
}
.chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.main :global(.cta) {
align-self: flex-start;
margin-top: 6px;
}
.side {
flex: 1 1 360px;
min-width: 0;
position: relative;
}
.facts {
margin: 0;
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.fact {
flex: 1 1 140px;
display: flex;
flex-direction: column;
padding: 20px;
border: 1px solid var(--gk-lines);
border-radius: var(--gk-radius);
background: var(--gk-sky);
}
.fact dd {
margin: 0;
}
.value {
display: block;
font-family: var(--gk-font-display);
font-weight: 700;
font-size: 36px;
color: var(--gk-gold-bright);
line-height: 1;
}
.fact :global(.ticks) {
margin: 6px 0 2px;
}
.fact dt {
order: 1;
margin-top: 6px;
font-size: 14px;
color: var(--gk-muted);
}
@media (max-width: 640px) {
.inner {
padding: 24px 20px;
}
}
</style>