both bars are only 3px tall visually, which made them fiddly to hit precisely. added a 5px invisible hit-area above and below via ::before on each — the visual bar stays thin, but clicking near it still registers. the seek/volume math is unaffected since it reads the real elements own rect, not the pseudo-elements.
letter-spacing on the ❚❚ glyph could tighten the character cells but not the visible gap between them on a monospace font — each character keeps its own cell regardless. now two bars drawn via ::before/::after on .is-playing, with exact pixel control over the gap; the ▶ span just hides instead of getting replaced.
the play/pause button had no fixed width, so swapping the single-character play glyph for the two-character pause glyph (with the fonts normal spacing between them) visibly widened the button. now a fixed 2.4ch width with tightened tracking on the pause state.\n\nmute only ever toggled — there was no way to set a level. added a small click/drag bar next to it (same interaction as the scrub bar), synced with the video elements own volume/muted state via the volumechange event so it stays correct regardless of how its changed.
scrub fill/time were driven off timeupdate, which browsers fire irregularly (a handful of times a second) — visible as the bar stepping instead of gliding. now driven by requestAnimationFrame while playing (display refresh rate), with a direct sync on pause/seeked so it still tracks immediately when not running.\n\npreload=none meant zero data was fetched until the play button was pressed, causing a visible stall right at playback start. preload=metadata lets the browser prime the connection and read the moov atom ahead of time without fetching the full video for visitors who never press play.
the peek column only exists for images (a side-by-side thumbnail makes sense there, not for text) — but the mouseenter handler routed ALL rows through the locked/peek branch once something was locked, so on about (all text rows, locked by default on load) hovering dossier.md/openbureau.md/rapport.md while cv.md was locked did nothing at all. rows without data-img now always drive the main preview directly on hover, lock or not.
grid-column:3 + justify-self:end put name and tags in the same cell but grid stacks co-located items instead of placing them side by side, so the tag wrapped to a second line. wrapped both in a flex row (justify-content:space-between) inside that grid cell instead.
new categories taxonomy, multi-value per project. shown inline in each ls row as [tag] after the slug, muted like the other row metadata and inverting with it on hover/select. reuses the existing shared taxonomy template, so /categories/ and /categories/<tag>/ come for free as browsable archives in the same shell style already used for schools/degrees/semesters.\n\nassigned by medium: design for anything with plans/models, film for the two video projects, photo for the trieste study trip, text alongside design for translation (collage + accompanying theoretical text).
clicking the already-locked row navigated (the old second-click-to-open flow), which meant there was no way back to the unlocked hover-browsing state once something got locked. row clicks now toggle lock/unlock uniformly everywhere; the preview image is the one dedicated way to actually open a project, on the index same as project pages.
the peek column only makes sense as an alternative to disturbing an existing lock — with nothing locked, hover had stopped updating anything at all, leaving whatever was last locked stuck on screen while browsing other rows. now: locked -> hover drives the peek column only; unlocked -> hover drives the main preview directly, same as before locking existed.
plans and photos have wildly different natural aspect ratios (a 46x31in A0 detail plan next to a 3:2 photo), so the peek box was jumping size on every hover. now uses the same aspect-ratio:3/2 + object-fit:cover treatment as the portfolio-index preview it already mirrors in position/width — stays a fixed size regardless of what is hovered.
replaces the last commits attempt (hover updating the main preview directly) with what was actually asked for: the main preview now stays on the locked file, untouched by hover; a separate 18rem-wide column to the left of the file list — same width and spot as .proj-info on the right — shows whichever OTHER image is under the mouse while something is locked, and disappears again once the mouse leaves the list or lands back on the locked row itself.\n\npositioned via plain absolute positioning against .filebrowser (not scroll-tracked — it scrolls together with the list naturally), sitting inside the padding .proj-layout already reserves to keep the file list anchored. only enabled above 1300px, with a safety margin over the ~1168px point where that reserved space stops being wide enough; caught and fixed a bug in the same pass where .proj-peek had no display:none fallback below that breakpoint and would otherwise render as a bare block in-flow.
the scroll-triggered mini-preview from the last commit solved the wrong problem — it never showed in practice (images are generally as tall or taller than the short project texts, so the gap it needed never opened), and wasnt what was actually wanted: the existing left-column preview pane should keep responding to hover even once a file is locked, only reverting to the locked file once the mouse leaves the list. lock now only gates the is-selected styling, the ● locked indicator, and the click-to-navigate semantics on the portfolio index — not what the pane displays.
the locked image now gets a small pinned copy (18rem, same width as the text column) that appears once the real preview scrolls out of view and disappears again once the text runs out — fixed-position + scroll-driven rather than CSS sticky, since the filebrowser box is only ever as tall as its own content, not the much taller text next to it.\n\nalso scoped the existing click-outside-unfreezes-the-lock listener to clicks inside .filebrowser only, since with listings now starting locked, a click to read or select a word in the text would otherwise silently kill the sticky preview.\n\nportfolio index: rows there are real links (href + data-img together), so a single click used to jump straight into the project — the only way to preview a different one first was hovering, which does nothing for touch and is now also blocked while something is locked. first click on a different project now just previews it (like hover used to); a second click on the same row, or clicking the preview image itself, opens it.
same end state as clicking the first row by hand — hovering other rows no longer steals the preview until you actually click one. clicking a different row still jumps straight to it and relocks there; clicking the locked row again releases it back to hover-browsing. games are excluded (nothing to browse), matched via the game-embed class rather than page context so it stays correct no matter which page a game was launched from.
the .. row has no image/video/text of its own, so the preview fell through to the blank-everything branch — most noticeable on video projects, where the video would stop and vanish. now non-preview rows just leave whatever was last shown in place.
Generalized the doom launcher into launchGame(name) keyed by archive.org identifier; each cds into a fake .<name> folder and runs <name>.sh, same as doom.
cds into a fake .doom folder (breadcrumb + file listing match every other page); .. is a real link back to wherever you typed doom from, so leaving is just normal pjax navigation.
about now lists cv.md, openbureau.md, rapport.md, dossier.md side by side. the standalone /openbureau/ page, its layout, and its home-menu entry are gone; internal links repointed to /about/. also switch the info-panel text to justified (with hyphenation, per earlier request) instead of ragged-right.
Self-hosted, subset to exactly the glyphs the site uses (fonttools --unicodes), so the pair is smaller (6.4+6.3KB) than the curly-slab files they replace despite covering en+de plus shell/tree symbols.