/onthisday: figure-vs-photo hero, plain stacked year, clay title, more space

- Hero now adapts: photos stay full-bleed (cover); seals/logos/diagrams (PNG/SVG
  or near-square / extreme aspect) show WHOLE on a light matte (contain) instead
  of cropping to nonsense — e.g. today's SCOTUS seal.
- Year: dropped the mint chip/bubble. Now plain stacked type — "In history" over
  a larger "2013" — in the homepage card's brown family (kills the green/mint
  clash; makes the page echo the card).
- Eyebrow recolored to the homepage "On this day" card accent (#b06a45 clay).
- Added breathing room between the title and the content.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-26 19:16:14 -04:00
parent e2e59bfdc4
commit d969810c10
+36 -15
View File
@@ -16,6 +16,22 @@
}
let readLabel = $derived(f?.source_url?.includes('wikipedia') ? 'Read more on Wikipedia' : 'Read more');
// Figure-vs-photo: OTD images are uncontrolled (Wikimedia photos, but also seals,
// logos, maps, diagrams). Photos look best full-bleed (cover); figures must be shown
// WHOLE (contain on a clean matte) or they get cropped to nonsense. PNG/SVG sources
// are almost always figures/logos with transparency; refine with aspect ratio on load.
let heroAspect = $state(null);
let heroFit = $derived.by(() => {
const url = f?.image_url || '';
if (/\.(png|svg)(\?|#|$)/i.test(url)) return 'contain';
if (heroAspect == null) return 'cover';
return (heroAspect < 0.9 || heroAspect > 2.0) ? 'contain' : 'cover';
});
function onHeroLoad(e) {
const img = e.currentTarget;
if (img.naturalWidth && img.naturalHeight) heroAspect = img.naturalWidth / img.naturalHeight;
}
onMount(async () => {
try {
f = await getJSON('/api/onthisday/today');
@@ -43,17 +59,17 @@
</div>
<div class="dateline">
<span class="year-chip">
<span class="yc-label">In history</span>
<span class="yc-year">{f.year}</span>
</span>
<div class="year-block">
<span class="yb-label">In history</span>
<span class="yb-year">{f.year}</span>
</div>
<span class="dl-rule"></span>
<span class="dl-label">{dateline(f.date)}</span>
</div>
<div class="hero">
<div class="hero" class:figure={heroFit === 'contain'}>
{#if f.image_url}
<img class="hero-img" src={f.image_url} alt="" loading="lazy" />
<img class="hero-img" src={f.image_url} alt="" loading="lazy" onload={onHeroLoad} />
{/if}
</div>
@@ -101,24 +117,29 @@
padding: clamp(26px, 5vw, 34px) clamp(20px, 5vw, 34px) clamp(34px, 6vw, 44px); overflow: hidden;
}
/* eyebrow matches the homepage "On this day" card accent (clay/brorange) so the card → page read as one */
.eyebrow { display: flex; align-items: center; gap: 14px; }
.eye-rule { width: 34px; height: 3px; background: #3a7d5b; border-radius: 2px; flex: none; }
.eye-label { font-family: 'Hanken Grotesk', sans-serif; font-size: clamp(17px, 2.4vw, 22px); font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase; color: #2c5d44; }
.eye-rule { width: 34px; height: 3px; background: #b06a45; border-radius: 2px; flex: none; }
.eye-label { font-family: 'Hanken Grotesk', sans-serif; font-size: clamp(17px, 2.4vw, 22px); font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase; color: #b06a45; }
.dateline { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 14px; margin: clamp(20px, 3vw, 26px) 0 14px; }
.dl-rule { flex: 1 1 30px; min-width: 24px; height: 1.5px; background: rgba(70, 120, 90, 0.26); }
.dl-label { font-family: 'Hanken Grotesk', sans-serif; font-weight: 700; font-size: clamp(14px, 1.7vw, 17px); letter-spacing: 0.1em; text-transform: uppercase; color: #2c5d44; }
/* extra breathing room between the title and the content below */
.dateline { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 10px 16px; margin: clamp(32px, 5vw, 48px) 0 16px; }
.dl-rule { flex: 1 1 30px; min-width: 24px; height: 1.5px; margin-bottom: 7px; background: rgba(70, 120, 90, 0.26); }
.dl-label { font-family: 'Hanken Grotesk', sans-serif; font-weight: 700; font-size: clamp(14px, 1.7vw, 17px); letter-spacing: 0.1em; text-transform: uppercase; color: #2c5d44; margin-bottom: 5px; }
/* year lives here now (off the image), so it's always legible regardless of the day's photo */
.year-chip { display: inline-flex; align-items: center; gap: 9px; flex: none; background: #e7efe4; border: 1px solid rgba(58, 125, 91, 0.30); border-radius: 999px; padding: 5px 8px 5px 14px; }
.yc-label { font-family: 'Hanken Grotesk', sans-serif; font-size: 11px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: #3a7d5b; }
.yc-year { font-family: 'Playfair Display', Georgia, serif; font-weight: 700; font-size: 20px; line-height: 1; color: #2c5d44; }
/* year lives here (off the image) — plain stacked type, no bubble; echoes the homepage card's brown */
.year-block { display: flex; flex-direction: column; flex: none; line-height: 1; }
.yb-label { font-family: 'Hanken Grotesk', sans-serif; font-size: 12px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: #b06a45; }
.yb-year { font-family: 'Playfair Display', Georgia, serif; font-weight: 700; font-size: clamp(32px, 5.5vw, 44px); line-height: 0.92; color: #7a4a30; margin-top: 4px; }
.hero {
position: relative; border-radius: 12px; overflow: hidden; background: #21392e;
height: clamp(220px, 38vw, 330px);
}
.hero-img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* figures (seals/logos/diagrams) shown whole on a clean light matte, never cropped */
.hero.figure { background: #f4f6f1; border: 1px solid rgba(70, 120, 90, 0.16); }
.hero.figure .hero-img { object-fit: contain; padding: clamp(18px, 3vw, 30px); box-sizing: border-box; }
.headline {
font-family: 'Playfair Display', Georgia, serif; font-style: italic; font-weight: 600;