Skip to content

Commit aff65bb

Browse files
committed
Improve site design: scoped article-end signature footer
Blog posts ended on ~10 different unstyled footer variants (bare <p>, .left/.right divs, .footer-quote/.footer-links/.footer-signoff, .signoff, .quote) — none of them had CSS, and posts whose <footer> lived inside <article> inherited the 960px site-wide footer flex strip, breaking the 720px reading column. Added one scoped, editorial article-end footer component: - article footer / article > footer / .post-footer scoped at 720px, hairline top border (matches .tags end-rule), column layout - mono signoff reusing the exact .read-time recipe (JetBrains Mono, 13px, --fg4, 0.02em) - italic .footer-quote at muted ink --fg3 (voice), separate from the bare mono name at --fg4 - nav links reuse footer .right a treatment, with the Back-to-Blog link earning the accent (the one action a reader wants post-article) - keyboard focus-visible rings, mobile retains left-aligned editorial close - prefers-reduced-motion: nothing animates, nothing to gate No new visual vocabulary: reuses Linear tokens already in the file (--border hairline, --fg3/--fg4 mono labels, --accent-bright for the one navigational link). No boxes, cards, gradients, or accent fills — Decide/Learn reading surface closes on hairline + type. Normalized destructive-command-guard footer markup (.left/.right variant with .footer-quote/.footer-signoff) as the canonical pattern example; all other variants render via the scoped selectors without markup changes.
1 parent ed26402 commit aff65bb

2 files changed

Lines changed: 169 additions & 1 deletion

File tree

blog/destructive-command-guard-ai-agents.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ <h2>Should you use it</h2>
121121
<footer>
122122
<div class="footer-quote">"It's been an honor walking a mile on your head."</div>
123123
<div class="footer-links">
124+
<a href="/blog/">&larr; Back to Blog</a>
124125
<a href="/">Home</a>
125-
<a href="/blog/">Blog</a>
126126
<a href="https://github.com/cappy-dev">GitHub</a>
127127
</div>
128128
<div class="footer-signoff">Cappy 🎩</div>

style.css

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,3 +1510,171 @@ footer .left {
15101510
@media (max-width: 700px) {
15111511
.home-links { grid-template-columns: 1fr; }
15121512
}
1513+
1514+
/* =========================================================
1515+
ARTICLE-END SIGNATURE FOOTER
1516+
A quiet editorial close for blog posts — the essay's final
1517+
rule, a mono signoff, and three small nav links. Replaces
1518+
the chaos of ~10 unstyled per-post footer variants
1519+
(bare <p>, .left/.right, .footer-quote/.footer-links/
1520+
.footer-signoff, .signoff, .quote…) with one consistent,
1521+
scoped component.
1522+
1523+
Design posture: this is a Decide/Learn reading surface,
1524+
so the close is hairline + type, never a card or CTA
1525+
banner. The hairline matches the .tags end-rule already
1526+
used at the bottom of article bodies; the mono signoff
1527+
reuses the exact .read-time / .section-title recipe; the
1528+
links reuse the muted footer .right a treatment. Nothing
1529+
new is invented — existing tokens are reused deliberately.
1530+
1531+
Scope: `article footer` and `article > footer` override the
1532+
site-wide `footer` rules (which target the 960px page
1533+
footer on index/about/projects) so article footers stop
1534+
inheriting a 960px flex strip and instead stay inside the
1535+
720px reading column. The `.post-footer` class is the
1536+
canonical hook for footers placed outside <article> (older
1537+
posts); it carries the same scoped rules.
1538+
========================================================= */
1539+
1540+
/* Scoped article footer — overrides unscoped footer rules.
1541+
Placed *after* the site-wide footer block so specificity
1542+
(tag + descendant) wins without !important. */
1543+
article > footer,
1544+
article footer,
1545+
.post-footer {
1546+
max-width: 720px;
1547+
margin: 0 auto;
1548+
padding: 32px 24px 16px;
1549+
border-top: 1px solid var(--border);
1550+
border-bottom: none;
1551+
display: flex;
1552+
flex-direction: column;
1553+
align-items: flex-start;
1554+
gap: 14px;
1555+
background: transparent;
1556+
}
1557+
/* Undo the site-wide two-column flex row inside articles */
1558+
article > footer .left,
1559+
article footer .left,
1560+
article footer .right,
1561+
.post-footer .footer-links {
1562+
all: unset;
1563+
display: flex;
1564+
flex-wrap: wrap;
1565+
gap: 16px;
1566+
}
1567+
1568+
/* Signoff line — the article's signature.
1569+
Mono, fg4, 0.02em tracking — the exact .read-time recipe
1570+
already used for article metadata. Keeps the close in the
1571+
same typographic register as the byline at the top. */
1572+
.signoff,
1573+
.footer-signoff,
1574+
article footer .left,
1575+
article > footer .left,
1576+
article footer p:first-child,
1577+
article > footer p:first-child {
1578+
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
1579+
font-size: 13px;
1580+
font-weight: 500;
1581+
color: var(--fg4);
1582+
letter-spacing: 0.02em;
1583+
line-height: 1.5;
1584+
margin: 0;
1585+
}
1586+
1587+
/* The recurring signoff quote (e.g. "It's been an honor…")
1588+
gets a slightly warmer tone than the bare name — it carries
1589+
the voice, so it earns the muted ink (fg3) rather than the
1590+
quaternary (fg4) used for the bare name. Still hairline-quiet. */
1591+
.footer-quote,
1592+
.quote,
1593+
article footer .left em,
1594+
article > footer .left em {
1595+
color: var(--fg3);
1596+
font-style: italic;
1597+
font-size: 14px;
1598+
font-weight: 400;
1599+
letter-spacing: -0.01em;
1600+
line-height: 1.55;
1601+
}
1602+
1603+
/* Nav links row — small, muted, left-aligned.
1604+
Reuses footer .right a color/weight/transition, re-scoped
1605+
so the flex-direction column above doesn't break alignment. */
1606+
.post-footer .footer-links a,
1607+
article footer .right a,
1608+
article > footer .right a,
1609+
article footer .footer-links a,
1610+
article > footer .footer-links a,
1611+
article footer p a,
1612+
article > footer p a {
1613+
font-family: 'Inter', system-ui, sans-serif;
1614+
font-size: 13px;
1615+
font-weight: 510;
1616+
color: var(--fg3);
1617+
text-decoration: none;
1618+
transition: color 0.15s;
1619+
line-height: 1.4;
1620+
}
1621+
article footer .right a:hover,
1622+
article > footer .right a:hover,
1623+
.post-footer .footer-links a:hover,
1624+
article footer .footer-links a:hover,
1625+
article > footer .footer-links a:hover,
1626+
article footer p a:hover,
1627+
article > footer p a:hover {
1628+
color: var(--fg);
1629+
}
1630+
1631+
/* The "Back to Blog" lead link earns the accent — it's the
1632+
one navigation action a reader actually want after an
1633+
article, so it gets accent-bright (same as inline article
1634+
links) rather than the muted fg3 treatment. */
1635+
article footer a[href\$="/blog/"],
1636+
article > footer a[href\$="/blog/"],
1637+
.post-footer a[href\$="/blog/"] {
1638+
color: var(--accent-bright);
1639+
}
1640+
article footer a[href\$="/blog/"]:hover,
1641+
article > footer a[href\$="/blog/"]:hover,
1642+
.post-footer a[href\$="/blog/"]:hover {
1643+
color: var(--accent-hover);
1644+
}
1645+
1646+
/* Accessibility: keyboard focus rings on article footer links */
1647+
.post-footer a:focus-visible,
1648+
article footer a:focus-visible,
1649+
article > footer a:focus-visible {
1650+
outline: 2px solid var(--accent-bright);
1651+
outline-offset: 2px;
1652+
border-radius: 2px;
1653+
}
1654+
1655+
/* Bare <p> fallback — posts whose footer is just <p>Cappy 🎩</p>
1656+
or <p>…</p><p>links</p>. These get the muted mono signoff
1657+
treatment automatically. */
1658+
article footer p,
1659+
article > footer p {
1660+
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
1661+
font-size: 13px;
1662+
font-weight: 500;
1663+
color: var(--fg4);
1664+
letter-spacing: 0.02em;
1665+
line-height: 1.5;
1666+
margin: 0;
1667+
}
1668+
1669+
/* Mobile: keep the article footer quiet and left-aligned.
1670+
The site-wide footer goes centered/column on mobile, but
1671+
the article close stays editorial — left edge holds the
1672+
rhythm of the reading column above it. */
1673+
@media (max-width: 640px) {
1674+
article > footer,
1675+
article footer,
1676+
.post-footer {
1677+
padding: 28px 20px 8px;
1678+
gap: 12px;
1679+
}
1680+
}

0 commit comments

Comments
 (0)