mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-07 19:58:24 +00:00
99ecdc2113
Landing, About, Now, Resume (with a generated PDF), Work and case studies, Inquiries and the sent page, Library and the Shelf, Workshop and craft pages, Tabletop, Blog with topics and posts, RSS, the Store, product lines, the order form and the 404, all rendered from the content service's notes. Schema: experience previousRoles, skills stack core items, page stats, make tags and deck favorite. Icon names from notes map to brand icons in one place, and HTML comments are dropped when Markdown renders. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
230 lines
6.1 KiB
Plaintext
230 lines
6.1 KiB
Plaintext
---
|
|
/**
|
|
* The confirmation after an inquiry. The inquiries API sets the short-lived
|
|
* `gk-inquiry` cookie (URL-encoded JSON: type, name, email, rows) before it
|
|
* redirects here; the page shows it once and clears it. Without the cookie
|
|
* the page still reads correctly, showing `?type=` when given.
|
|
*/
|
|
import Button from "@gk/ui/components/Button.astro";
|
|
import PageShell from "@gk/ui/components/PageShell.astro";
|
|
import Seal from "@gk/ui/components/Seal.astro";
|
|
import Star from "@gk/ui/components/Star.astro";
|
|
import TickRing from "@gk/ui/components/TickRing.astro";
|
|
import TickScale from "@gk/ui/components/TickScale.astro";
|
|
import { inquiryTypes, parseInquiryType, parseSentSummary } from "../../lib/work.ts";
|
|
|
|
const sent = parseSentSummary(Astro.cookies.get("gk-inquiry")?.value);
|
|
if (sent) Astro.cookies.delete("gk-inquiry", { path: "/" });
|
|
Astro.response.headers.set("Cache-Control", "private, no-store");
|
|
|
|
const type = sent?.type ?? parseInquiryType(Astro.url.searchParams.get("type"));
|
|
const typeLabel = inquiryTypes.find((t) => t.value === type)?.summary;
|
|
const rows = [
|
|
...(typeLabel ? [{ label: "Type", value: typeLabel }] : []),
|
|
...(sent?.rows ?? []),
|
|
...(sent?.email ? [{ label: "Reply to", value: sent.email }] : []),
|
|
];
|
|
const firstName = sent?.name?.split(/\s+/)[0];
|
|
const steps = [
|
|
{ title: "I read it", text: "Usually within a day or two." },
|
|
{ title: "I reply", text: "With questions, a quote, or a time to talk." },
|
|
{ title: "We settle the details", text: "Nothing starts until you say yes." },
|
|
];
|
|
---
|
|
<PageShell title="Inquiry sent" family="inquiries" current="inquiries" description="Your inquiry is on its way.">
|
|
<meta slot="head" name="robots" content="noindex" />
|
|
<div class="split">
|
|
<div class="intro">
|
|
<Seal name="transmutation" size={132} class="seal" />
|
|
<span class="eyebrow">Inquiry sent</span>
|
|
<h1>Your note is on its way</h1>
|
|
<p class="lede">Thanks{firstName ? `, ${firstName}` : ""}. I read every inquiry myself and reply within [PLACEHOLDER] days.</p>
|
|
<ol class="steps" aria-label="What happens next">
|
|
{
|
|
steps.map((st, i) => (
|
|
<li>
|
|
<TickRing size={36}>{i + 1}</TickRing>
|
|
<span class="step-text">
|
|
<span class="step-title">{st.title}</span>
|
|
<span class="step-detail">{st.text}</span>
|
|
</span>
|
|
</li>
|
|
))
|
|
}
|
|
</ol>
|
|
</div>
|
|
|
|
<div class="side">
|
|
{
|
|
rows.length > 0 && (
|
|
<section class="sent" aria-labelledby="sent-heading">
|
|
<h2 id="sent-heading" class="kicker">
|
|
<Star size={11} />
|
|
What you sent
|
|
</h2>
|
|
<TickScale width={150} height={10} count={30} class="ticks" />
|
|
<dl>
|
|
{rows.map((r) => (
|
|
<div class="row">
|
|
<dt>{r.label}</dt>
|
|
<dd>{r.value}</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
</section>
|
|
)
|
|
}
|
|
<nav class="wait" aria-labelledby="wait-heading">
|
|
<h2 id="wait-heading" class="wait-kicker">While you wait</h2>
|
|
<div class="wait-links">
|
|
<Button href="/blog" variant="secondary">Blog</Button>
|
|
<Button href="/workshop" variant="secondary">Workshop</Button>
|
|
<Button href="/" variant="text">Back home</Button>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</PageShell>
|
|
|
|
<style>
|
|
.split {
|
|
padding: 32px 0 24px;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 48px;
|
|
align-items: flex-start;
|
|
}
|
|
.intro {
|
|
flex: 1 1 420px;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
.intro :global(.seal) {
|
|
filter: drop-shadow(0 0 18px rgba(201, 162, 74, 0.35));
|
|
}
|
|
.eyebrow {
|
|
font-size: 11px;
|
|
letter-spacing: 0.3em;
|
|
font-weight: 600;
|
|
color: var(--gk-gold-bright);
|
|
text-transform: uppercase;
|
|
}
|
|
h1 {
|
|
margin: 0;
|
|
font-size: clamp(32px, 6vw, 46px);
|
|
letter-spacing: 0.06em;
|
|
line-height: 1.1;
|
|
}
|
|
.lede {
|
|
margin: 0;
|
|
padding-left: 14px;
|
|
border-left: 2px solid var(--gk-gold);
|
|
font-size: 17px;
|
|
line-height: 1.6;
|
|
color: var(--gk-soft);
|
|
max-width: 46ch;
|
|
}
|
|
.steps {
|
|
margin: 8px 0 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
border-bottom: 1px solid var(--gk-lines);
|
|
}
|
|
.steps li {
|
|
display: flex;
|
|
gap: 14px;
|
|
align-items: flex-start;
|
|
padding: 14px 0;
|
|
border-top: 1px solid var(--gk-lines);
|
|
font-size: 13px;
|
|
}
|
|
.step-text {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 3px;
|
|
}
|
|
.step-title {
|
|
font-weight: 700;
|
|
font-size: 15px;
|
|
}
|
|
.step-detail {
|
|
font-size: 14px;
|
|
color: var(--gk-muted);
|
|
line-height: 1.5;
|
|
}
|
|
.side {
|
|
flex: 1 1 440px;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
.sent {
|
|
position: relative;
|
|
padding: 28px;
|
|
border-radius: var(--gk-radius);
|
|
background: var(--gk-midnight);
|
|
border: 1px solid rgba(201, 162, 74, 0.55);
|
|
}
|
|
.kicker {
|
|
margin: 0 0 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-family: var(--gk-font-body);
|
|
font-size: 11px;
|
|
letter-spacing: 0.3em;
|
|
font-weight: 600;
|
|
color: var(--gk-gold-bright);
|
|
text-transform: uppercase;
|
|
}
|
|
.sent :global(.ticks) {
|
|
margin: -4px 0 2px;
|
|
}
|
|
dl {
|
|
margin: 8px 0 0;
|
|
}
|
|
.row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
padding: 10px 0;
|
|
border-top: 1px solid var(--gk-lines);
|
|
font-size: 14px;
|
|
}
|
|
dt {
|
|
color: var(--gk-muted);
|
|
}
|
|
dd {
|
|
margin: 0;
|
|
font-weight: 600;
|
|
text-align: right;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
.wait {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
padding: 20px;
|
|
border-radius: var(--gk-radius);
|
|
border: 1px solid var(--gk-lines);
|
|
}
|
|
.wait-kicker {
|
|
margin: 0;
|
|
font-family: var(--gk-font-body);
|
|
font-size: 11px;
|
|
letter-spacing: 0.3em;
|
|
font-weight: 600;
|
|
color: var(--gk-muted);
|
|
text-transform: uppercase;
|
|
}
|
|
.wait-links {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: 10px 16px;
|
|
}
|
|
</style>
|