Better CSS
This commit is contained in:
parent
31648541a2
commit
7d0f895074
11 changed files with 564 additions and 34 deletions
|
|
@ -41,6 +41,8 @@ const isDecorativeLink = Boolean(href) && decorative;
|
|||
href={href}
|
||||
tabindex={isDecorativeLink ? -1 : undefined}
|
||||
aria-label={isDecorativeLink ? (ariaLabel ?? alt) : undefined}
|
||||
data-uncropped-preview
|
||||
data-preview-label={ariaLabel ?? alt}
|
||||
>
|
||||
<Picture
|
||||
src={src}
|
||||
|
|
@ -49,6 +51,7 @@ const isDecorativeLink = Boolean(href) && decorative;
|
|||
fallbackFormat="jpg"
|
||||
widths={widths}
|
||||
sizes={sizes}
|
||||
quality="high"
|
||||
loading={loading}
|
||||
decoding="async"
|
||||
fetchpriority={fetchpriority}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ const videoHeight = item.type === 'video' ? (item.poster?.height ?? 720) : undef
|
|||
formats={['avif', 'webp']}
|
||||
widths={[480, 720, 960, 1280, 1600, 1920]}
|
||||
sizes="(max-width: 700px) calc(100vw - 2 * clamp(20px, 4vw, 32px)), (max-width: 1100px) min(calc(100vw - 4rem), 56rem), 56rem"
|
||||
quality="high"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ for (const root of document.querySelectorAll('.post-thumbnail--iframe')) {
|
|||
<div
|
||||
class:list={['post-thumbnail', iframeSrc && 'post-thumbnail--iframe']}
|
||||
style={iframeSrc ? `--post-thumbnail-aspect: ${aspectRatio}` : undefined}
|
||||
data-uncropped-preview
|
||||
data-preview-label={post.data.title}
|
||||
>
|
||||
<Picture
|
||||
src={post.data.thumbnail.src}
|
||||
|
|
@ -65,6 +67,7 @@ for (const root of document.querySelectorAll('.post-thumbnail--iframe')) {
|
|||
fallbackFormat="jpg"
|
||||
widths={[640, 960, 1280, 1600, 1920]}
|
||||
sizes="(max-width: 700px) calc(100vw - 3rem), (max-width: 1100px) calc(100vw - 4rem), 56rem"
|
||||
quality="high"
|
||||
loading="eager"
|
||||
fetchpriority="high"
|
||||
decoding="async"
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ const hasCode = !!post.body && /(^|[^`])`[^`\n]+`|```/m.test(post.body);
|
|||
const h2Headings = headings.filter((h) => h.depth === 2);
|
||||
const showToc = h2Headings.length >= 3;
|
||||
|
||||
// Don't repeat the banner image at the end — PostThumbnail already rendered it.
|
||||
const thumbnailSrc = post.data.thumbnail.src.src;
|
||||
const trailingMedia = post.data.media.filter(
|
||||
(item) => item.type === 'video' || item.src.src !== thumbnailSrc,
|
||||
);
|
||||
|
||||
const personId = absoluteUrl('/about/#person');
|
||||
|
||||
const blogPosting = {
|
||||
|
|
@ -152,7 +158,7 @@ const personJsonLd = buildPersonJsonLd();
|
|||
<Content />
|
||||
</div>
|
||||
|
||||
<PostMedia items={post.data.media} />
|
||||
<PostMedia items={trailingMedia} />
|
||||
|
||||
{
|
||||
related.length > 0 && (
|
||||
|
|
|
|||
|
|
@ -156,12 +156,12 @@ export function buildPersonJsonLd(extra?: Record<string, unknown>) {
|
|||
// Responsive image config shared by entry listings. Centralized here so a
|
||||
// change to one breakpoint set is a single edit, not two component changes.
|
||||
export const ARTICLE_THUMBNAIL = {
|
||||
widths: [120, 180, 240, 320, 480],
|
||||
widths: [160, 240, 320, 480, 640],
|
||||
sizes: '(max-width: 700px) clamp(64px, 22vw, 80px), (max-width: 960px) 7rem, 8rem',
|
||||
};
|
||||
|
||||
export const PROJECT_THUMBNAIL = {
|
||||
widths: [240, 320, 480, 640, 800],
|
||||
widths: [320, 480, 640, 800, 960, 1200, 1280],
|
||||
sizes:
|
||||
'(max-width: 700px) calc(100vw - 40px), (max-width: 960px) calc((100vw - 64px - 1rem) / 2), calc((min(100vw - 64px, 72rem) - 2rem) / 3)',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,8 +35,9 @@ const startingPointsAnnotated = startingPoints.map((post) => ({
|
|||
}));
|
||||
|
||||
const startingPointThumbnail = {
|
||||
widths: [120, 180, 240, 320],
|
||||
sizes: '(max-width: 700px) 4rem, (max-width: 960px) 28vw, 10rem',
|
||||
widths: [160, 240, 320, 480, 640, 800],
|
||||
sizes:
|
||||
'(max-width: 700px) 4rem, (max-width: 960px) calc((100vw - 64px - 1.5rem) / 3), calc((min(100vw - 64px, 72rem) - 3rem) / 5)',
|
||||
};
|
||||
|
||||
const personImage = await optimizeOgImage(defaultOg);
|
||||
|
|
|
|||
|
|
@ -24,16 +24,15 @@ const personJsonLd = buildPersonJsonLd();
|
|||
|
||||
<Base jsonLd={personJsonLd}>
|
||||
<section class="home-intro">
|
||||
<p class="eyebrow">A notebook, written after the fact</p>
|
||||
<p class="eyebrow">Engineering notes</p>
|
||||
<h1>
|
||||
<span class="home-intro-name">Andras Schmelczer</span> writes about projects, the tradeoffs
|
||||
behind them, and what hindsight changed.
|
||||
<span class="home-intro-name">Andras Schmelczer</span> — software engineer. Writeups
|
||||
of finished projects, with the tradeoffs left in.
|
||||
</h1>
|
||||
<p>
|
||||
Most of these started because I couldn't yet do the thing. An 8-bit ALU, a mobile
|
||||
GPU, a single static HTML file, a cross-language ABI, three editors I didn't
|
||||
control. The <a href="/about/">About page</a> is where I describe what I keep reaching
|
||||
for; the posts below are the evidence.
|
||||
Most started because I couldn't yet do the thing: an 8-bit ALU, a mobile GPU, a
|
||||
single static HTML file, a cross-language ABI. The <a href="/about/">About page</a>
|
||||
covers the patterns I keep returning to.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
|
|
|||
|
|
@ -660,10 +660,11 @@
|
|||
}
|
||||
|
||||
.entry-thumbnail img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 300ms ease;
|
||||
object-position: center center;
|
||||
}
|
||||
|
||||
a.entry-thumbnail {
|
||||
|
|
@ -675,11 +676,6 @@
|
|||
border-color: var(--color-rule-strong);
|
||||
}
|
||||
|
||||
.article-list > li:hover .entry-thumbnail img,
|
||||
.article-list > li:focus-within .entry-thumbnail img {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.article-list > li:focus-within .entry-thumbnail {
|
||||
border-color: var(--color-rule-strong);
|
||||
}
|
||||
|
|
@ -807,15 +803,6 @@
|
|||
aspect-ratio: 4 / 3;
|
||||
}
|
||||
|
||||
.project-card .project-thumbnail img {
|
||||
transition: transform 300ms ease;
|
||||
}
|
||||
|
||||
.project-card:hover .project-thumbnail img,
|
||||
.project-card:focus-within .project-thumbnail img {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.project-card__summary {
|
||||
grid-area: summary;
|
||||
display: flex;
|
||||
|
|
@ -997,11 +984,6 @@
|
|||
line-height: var(--leading-snug);
|
||||
}
|
||||
|
||||
.starting-points > li:hover .entry-thumbnail img,
|
||||
.starting-points > li:focus-within .entry-thumbnail img {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.starting-points > li:focus-within .entry-thumbnail {
|
||||
border-color: var(--color-rule-strong);
|
||||
}
|
||||
|
|
@ -1048,6 +1030,7 @@
|
|||
|
||||
.post-thumbnail--iframe img {
|
||||
object-fit: cover;
|
||||
object-position: center center;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue