mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-07 19:58:24 +00:00
813c403fcc
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
210 lines
5.0 KiB
Plaintext
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>
|