Add video headers
Some checks failed
Deploy to Pages / build (push) Failing after 2m46s

This commit is contained in:
Andras Schmelczer 2026-06-03 08:15:01 +01:00
parent cf509360e6
commit 0ab9889fc8
7 changed files with 535 additions and 131 deletions

View file

@ -630,8 +630,12 @@
line-height: var(--leading-snug);
}
.article-list .entry-title,
.project-list h3 a {
.project-list h3 {
color: var(--color-fg);
font-weight: var(--weight-semibold);
}
.article-list .entry-title {
display: inline-flex;
align-items: center;
min-height: 28px;
@ -640,8 +644,7 @@
text-decoration: none;
}
.article-list .entry-title:hover,
.project-list h3 a:hover {
.article-list .entry-title:hover {
color: var(--color-link-hover);
}
@ -776,6 +779,7 @@
}
.project-card {
position: relative;
display: grid;
grid-template-columns: 1fr;
grid-template-areas:
@ -809,7 +813,8 @@
grid-area: summary;
display: flex;
flex-direction: column;
gap: var(--space-1);
justify-content: space-between;
gap: var(--space-3);
min-width: 0;
padding: var(--space-3) var(--space-4);
}
@ -824,29 +829,78 @@
line-height: var(--leading-snug);
}
.project-card .project-meta {
color: var(--color-muted);
font-size: var(--fs-sm);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
.project-card__head {
display: flex;
flex-direction: column;
gap: var(--space-1);
min-width: 0;
}
.project-essay-badge {
.project-card__actions {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-2) var(--space-3);
margin-top: var(--space-3);
}
/* Stretched link: the Open control's overlay covers the whole card so any
click opens the project website. The Article link sits above the overlay
via a higher z-index and stays independently clickable. */
.project-card__open::after {
content: '';
position: absolute;
inset: 0;
z-index: 1;
/* Cover the whole card, not the Open button's pill radius. The card's own
overflow:hidden + border-radius clips this to the rounded card shape. */
border-radius: 0;
}
.project-card__open {
margin-left: auto;
display: inline-flex;
align-items: center;
margin-left: var(--space-2);
padding: 0.1em 0.5em;
background: var(--color-callout-bg);
border: 1px solid var(--color-rule);
gap: 0.3em;
min-height: 36px;
padding: 0.25em 0.85em;
border: 1px solid var(--color-rule-strong);
border-radius: var(--radius-pill);
color: var(--color-muted);
font-size: var(--fs-xs);
background: var(--color-bg);
color: var(--color-link);
font-size: var(--fs-caption);
font-weight: var(--weight-semibold);
text-decoration: none;
transition:
background-color 150ms ease,
border-color 150ms ease,
color 150ms ease;
}
.project-card:hover .project-card__open,
.project-card:focus-within .project-card__open {
border-color: var(--color-link);
background: var(--color-callout-bg);
color: var(--color-link-hover);
}
.project-article-link {
position: relative;
z-index: 2;
display: inline-flex;
align-items: center;
gap: 0.3em;
min-height: 36px;
color: var(--color-link);
font-size: var(--fs-caption);
font-weight: var(--weight-medium);
text-transform: uppercase;
letter-spacing: 0.08em;
vertical-align: 0.15em;
text-decoration: none;
}
.project-article-link:hover,
.project-article-link:focus-visible {
color: var(--color-link-hover);
text-decoration: underline;
}
.project-links {
@ -877,16 +931,6 @@
font-size: 0.85em;
}
.project-card .project-links {
gap: 0 var(--space-3);
margin-top: auto;
font-size: var(--fs-caption);
}
.project-card .project-links a {
min-height: 44px;
}
.post > .post-media,
.facts {
max-width: var(--measure);
@ -1117,6 +1161,141 @@
font-size: var(--fs-caption);
}
/* Click-to-play header video: a poster with a play button that swaps in an
inline <video> on click. Shared by the article banner and project cards. */
.video-thumbnail {
position: relative;
display: block;
overflow: hidden;
}
.video-thumbnail picture,
.video-thumbnail img {
display: block;
width: 100%;
height: 100%;
}
.video-thumbnail__video {
/* The global `video { display: block }` reset (author origin) overrides the
UA `[hidden]` rule, so hide the idle video explicitly to keep it from
swallowing the play button's click. */
display: none;
position: absolute;
inset: 0;
z-index: 2;
width: 100%;
height: 100%;
object-fit: contain;
background: #000;
}
.video-thumbnail.is-playing .video-thumbnail__video {
display: block;
}
.video-thumbnail__play {
position: absolute;
inset: 0;
z-index: 2;
width: 100%;
border: 0;
padding: 0;
display: grid;
place-items: center;
background: color-mix(in oklch, #000 22%, transparent);
color: var(--color-fg);
cursor: pointer;
}
.video-thumbnail__play:hover,
.video-thumbnail__play:focus-visible {
background: color-mix(in oklch, #000 30%, transparent);
}
.video-thumbnail__play-icon {
width: clamp(3.25rem, 9vw, 4.75rem);
aspect-ratio: 1;
display: grid;
place-items: center;
border: 1px solid var(--color-rule-strong);
border-radius: var(--radius-pill);
background: color-mix(in oklch, var(--color-bg) 88%, transparent);
box-shadow: 0 0.75rem 2rem color-mix(in oklch, #000 28%, transparent);
transition:
background-color 150ms ease,
transform 150ms ease;
}
.video-thumbnail__play:hover .video-thumbnail__play-icon,
.video-thumbnail__play:focus-visible .video-thumbnail__play-icon {
background: var(--color-bg);
transform: scale(1.04);
}
.video-thumbnail__play svg {
width: 42%;
height: 42%;
transform: translateX(8%);
fill: currentColor;
}
.video-thumbnail.is-playing picture,
.video-thumbnail.is-playing .video-thumbnail__play {
display: none;
}
.video-thumbnail__noscript {
position: absolute;
inset-inline: var(--space-3);
inset-block-end: var(--space-3);
z-index: 3;
margin: 0;
padding: var(--space-2) var(--space-3);
border-radius: var(--radius-md);
background: var(--color-bg);
font-size: var(--fs-caption);
}
/* Banner variant: keep the poster's own aspect ratio inside a rounded frame.
Cover with a matching ratio is not a crop, so the no-crop preview QA passes. */
.video-thumbnail--banner {
aspect-ratio: var(--video-aspect, 16 / 9);
border: 1px solid var(--color-rule);
border-radius: var(--radius-md);
background: var(--color-code-bg);
}
.video-thumbnail--banner img {
object-fit: cover;
}
.video-thumbnail--banner.post-thumbnail img {
border: 0;
border-radius: 0;
}
/* Card variant: only the centered badge is the play button, so a click
anywhere else on the thumbnail falls through to the card's Open link. */
.video-thumbnail--card .video-thumbnail__play {
inset: auto;
top: 50%;
left: 50%;
width: auto;
background: transparent;
transform: translate(-50%, -50%);
}
.video-thumbnail--card .video-thumbnail__play:hover,
.video-thumbnail--card .video-thumbnail__play:focus-visible {
background: transparent;
}
.video-thumbnail--card .video-thumbnail__play-icon {
width: clamp(2.25rem, 14vw, 3rem);
box-shadow: 0 0.5rem 1.25rem color-mix(in oklch, #000 32%, transparent);
}
.prose {
max-inline-size: var(--measure);
line-height: var(--leading-prose);
@ -1459,11 +1638,6 @@
overflow-wrap: anywhere;
}
.project-card h3 a {
min-height: 44px;
min-width: 44px;
}
.post-toc ol {
list-style: none;
padding: 0;
@ -1771,8 +1945,9 @@
padding-block-start: 0;
}
.project-card .project-meta {
-webkit-line-clamp: 3;
.project-list {
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-3);
}
.project-card__summary {