From d02d8edfe9384b3fe1f08a9fc3c024e8a29dec92 Mon Sep 17 00:00:00 2001
From: Kristian Wind
Date: Wed, 19 Aug 2026 11:14:13 +0200
Subject: [PATCH] =?UTF-8?q?feat(site):=20klik=20et=20sk=C3=A6rmbillede=20o?=
=?UTF-8?q?g=20se=20det=20i=20l=C3=A6sbar=20st=C3=B8rrelse?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Et skærmbillede af en brugerflade siger ingenting ved 281 pixels, og det er der,
de fleste af dem sidder i gitteret. Et klik åbner nu det samme billede omkring
tre en halv gang større.
frem for et selvbygget lag: Escape lukker, fokus bliver inde i den,
resten af siden bliver inert — tre ting browseren gør gratis og som et selvbygget
overlay skal have kode for hver af. Billedet får rolle og tabindex, så det også
kan åbnes fra tastaturet; en kontrol, kun en mus kan nå, er ikke en kontrol alle
har.
To ting rettet undervejs, som først kunne ses ved at kigge: billedet fik lov at
blive højere end skærmen, så billedtekst og lukkeknap røg op over kanten — og
lukkeknappen er den synlige vej ud. Og dialogen fyldte hele bredden i stedet for
at slutte om billedet, så skærmbilledet stod op ad venstre kant med knappen ude i
det modsatte hjørne. Nu er den fit-content og centreret, og alt er inden for
vinduet ned til en telefonbredde.
Co-Authored-By: Claude Opus 5
---
site/index.html | 136 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 136 insertions(+)
diff --git a/site/index.html b/site/index.html
index 74ee4c0..f8abe34 100644
--- a/site/index.html
+++ b/site/index.html
@@ -344,6 +344,89 @@
text-align: center;
}
+ /* --- zoom -------------------------------------------------------------
+
+ A screenshot of an interface is unreadable at 280px in a three-column
+ grid, which is where most of them sit. Clicking one opens it at the
+ size it was taken.
+
+ rather than a hand-built overlay: Escape closes it, focus is
+ trapped, the rest of the page is inert, and the browser does all three
+ without a line of script. */
+ .shot img {
+ cursor: zoom-in;
+ }
+
+ /* Sized so the whole thing fits: a screenshot is 1.55 times wider than it
+ is tall, so on a laptop the height is what runs out first. Left to grow,
+ it pushed the caption and the close button off the top of the screen —
+ and the button is the visible way out. */
+ dialog.zoom {
+ max-width: 96vw;
+ max-height: 100vh;
+ /* Wraps the image rather than the viewport. With a plain `auto` the box
+ stayed full width, so the screenshot sat against the left edge and
+ the close button ended up in the far corner, nowhere near it. */
+ width: fit-content;
+ margin: auto;
+ padding: 2.5rem 0 0;
+ border: 0;
+ background: transparent;
+ overflow: visible;
+ }
+
+ dialog.zoom::backdrop {
+ background: rgb(0 0 0 / 0.82);
+ }
+
+ dialog.zoom img {
+ max-width: 96vw;
+ max-height: 78vh;
+ width: auto;
+ height: auto;
+ display: block;
+ border-radius: var(--radius-lg);
+ cursor: zoom-out;
+ }
+
+ dialog.zoom figcaption {
+ margin-top: 0.75rem;
+ font-size: 0.8125rem;
+ color: #a8b0ac;
+ text-align: center;
+ }
+
+ /* The whole backdrop closes, so the button is a visible affordance rather
+ than the only way out. */
+ dialog.zoom .close {
+ position: absolute;
+ top: 0;
+ right: 0;
+ background: none;
+ border: 0;
+ color: #a8b0ac;
+ font-size: 1.5rem;
+ line-height: 1;
+ cursor: pointer;
+ padding: 0.25rem 0.5rem;
+ }
+
+ dialog.zoom .close:hover {
+ color: #fff;
+ }
+
+ @media (prefers-reduced-motion: no-preference) {
+ dialog.zoom[open] {
+ animation: zoom-in 0.15s ease-out;
+ }
+ @keyframes zoom-in {
+ from {
+ opacity: 0;
+ transform: scale(0.98);
+ }
+ }
+ }
+
.shots {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
@@ -636,5 +719,58 @@
+
+
+
+ ×
+
+
+
+
+