diff --git a/gigs/thomaslawson.com/work-fia-edits/zzz-tl-fia-polish.php b/gigs/thomaslawson.com/work-fia-edits/zzz-tl-fia-polish.php index 1329dad29..4044a3a76 100644 --- a/gigs/thomaslawson.com/work-fia-edits/zzz-tl-fia-polish.php +++ b/gigs/thomaslawson.com/work-fia-edits/zzz-tl-fia-polish.php @@ -2,7 +2,17 @@ /** * Plugin Name: TL — Fía polish pass * Description: CSS+JS polish on top of the existing TL theme + Elementor build, per Fía's notes (2026-05-19 + her two replies later that night). Header chrome (no underline / no rule_ hrs / no Home), cream-everywhere, home laid out as a 5-up desktop strip (vertical stack on mobile) in Fía's section order with subtitles, divider widgets dropped on the homepage, Notes image-width capped, In-the-Studio + About years reversed newest-first (with !important on the flex parent so the reorder actually applies), Beyond-the-Studio collapsed to one column with centered subsection labels, 1980-82 caption normalisation, and a JS-injected horizontal cover preview strip per shelf on /bookshelf/. - * Version: 1.5.1 + * Version: 1.5.2 + * + * v1.5.2 — Fía's 2026-06-08 catch: + * - Mobile header was rendering Tom's wordmark twice — the `.custom-logo` + * sat above a redundant `Thomas + * Lawson` because Astra's own mobile media query + * (`@media (max-width:921px) { .site-title { display: block } }`) flipped + * the title back on while the logo image stayed visible. Hide the + * `.ast-site-title-wrap` (title + description) sitewide so only the + * image wordmark renders. Desktop was unaffected — the title was + * display:none there already. * * v1.5.1 — Fía's 2026-05-29 corrections: * - Bookshelf: shelf strips re-centred with the first/last-cover @@ -269,6 +279,22 @@ li.menu-item-home { padding-left: 2.5rem !important; } +/* Mobile branding rendered the logotype TWICE — Tom's wordmark image + (`.custom-logo`) sat directly above a redundant `` + reading "Thomas Lawson" in plain text. Astra's desktop CSS hides the + site-title (display:none), but its own media query at ≤921px flips it back + to display:block, producing the doubled header Fía flagged on mobile. + Hide the title-wrap (site-title + site-description) at every breakpoint — + the wordmark image is the brand mark and the description is already + hidden everywhere (Fía, 2026-06-08). */ +.ast-site-title-wrap, +.ast-mobile-header-wrap .ast-site-title-wrap, +.ast-mobile-header-wrap .site-title, +.ast-mobile-header-wrap .site-header .site-title, +.ast-mobile-header-wrap .site-description { + display: none !important; +} + /* About / Contact sit at the logo's vertical centre — the header grid row is centred so the menu drops in line with the middle of the wordmark (Fía, 2026-05-22). */ -- 2.51.2 From c302d4f54629c80f0972b3b430fbbe9d4a993398 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Mon, 8 Jun 2026 09:54:02 -0700 Subject: [PATCH 2/4] home: label subscriber count "readers" instead of "reading" Co-Authored-By: Claude Opus 4.8 (1M context) --- system/netlify/functions/sotce-net.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/netlify/functions/sotce-net.mjs b/system/netlify/functions/sotce-net.mjs index 14f6416d7..58ca79c38 100644 --- a/system/netlify/functions/sotce-net.mjs +++ b/system/netlify/functions/sotce-net.mjs @@ -4485,9 +4485,9 @@ export const handler = async (event, context) => { if (SUBSCRIBER_COUNT > 0) { let text; if (SUBSCRIBER_COUNT === 1) { - text = "1 reading"; + text = "1 reader"; } else { - text = SUBSCRIBER_COUNT + " reading"; + text = SUBSCRIBER_COUNT + " readers"; } const subscriberCount = cel("div"); subscriberCount.id = "subscriber-count"; -- 2.51.2 From d4279bd62bc1a331107250db33026eb9ad2d7b50 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Mon, 8 Jun 2026 10:15:39 -0700 Subject: [PATCH 3/4] menuband: fix stuck notes when releasing a key with Ctrl/Option held MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit playKeyEvent's `if hasModifier { return false }` bailed on BOTH key-down and key-up. On key-up with Ctrl (or Option) still held it returned before the note-release path, stranding the sounding note/chord — Cmd was unaffected only because Cmd isn't in `hasModifier`. Gate the passthrough on `isDown` so key-ups always reach release, matching the method's own "release is checked on EVERY key-up, not gated by Ctrl" contract. Co-Authored-By: Claude Opus 4.8 (1M context) --- slab/menuband/Sources/MenuBand/MenuBandController.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/slab/menuband/Sources/MenuBand/MenuBandController.swift b/slab/menuband/Sources/MenuBand/MenuBandController.swift index fa876de8f..686cca115 100644 --- a/slab/menuband/Sources/MenuBand/MenuBandController.swift +++ b/slab/menuband/Sources/MenuBand/MenuBandController.swift @@ -2471,8 +2471,13 @@ final class MenuBandController { // through to the system. } - // Modifier combos pass through so cmd-c, cmd-tab etc. work as usual. - if hasModifier { return false } + // Modifier combos pass through so cmd-c, cmd-tab etc. work as usual — + // but ONLY gate this on key-DOWN. A key-up must ALWAYS reach the + // release path below, even while Ctrl/Option is still held; otherwise + // letting go of a note with Ctrl down strands the sounding note/chord + // (the bug: Cmd released fine because Cmd isn't in `hasModifier`, but + // Ctrl bailed here and never sent the note-off). + if hasModifier && isDown { return false } // Spacebar (keyCode 49) = reverse-replay (notepat-native parity). // Plain space rewinds the most-recent audio; we intercept it BEFORE -- 2.51.2 From 71b294009e29dcba6ad55afa3d12aa51ce2eacb7 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Mon, 8 Jun 2026 11:13:51 -0700 Subject: [PATCH 4/4] slab: tiled terminals auto-resize font to a readable floor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tiling only set pixel bounds before — the computed grid font size was stored but never applied, so dense walls clipped at the default 12pt. - tileNow now sets each Terminal window's font to the grid-derived size, then drives View ▸ Default Font Size per window (System Events) so a live window actually adopts it — a per-window zoom otherwise silently overrides the profile font and is invisible to AppleScript. Bounds are re-pinned last so the reflow can't fight the cell geometry. - applyTerminalDecor pins the slab profile font to lastTiledFontSize so a re-theme on the blink tick doesn't bounce back to 12pt. - setTextFar/Near/Tiny update the snapshot synchronously so the first click tiles at the chosen size (refresh() is an async gather). - Readable floors: Far 10 / Near 9 / Tiny 8 — auto-fit shrinks toward them but never past legibility. - Auto-retile-after-close skips the focus-stealing zoom reset. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Sources/SlabMenubar/AppDelegate.swift | 90 +++++++++++++++---- 1 file changed, 74 insertions(+), 16 deletions(-) diff --git a/slab/menubar-swift/Sources/SlabMenubar/AppDelegate.swift b/slab/menubar-swift/Sources/SlabMenubar/AppDelegate.swift index 73cd4495e..f7c9a8a0c 100644 --- a/slab/menubar-swift/Sources/SlabMenubar/AppDelegate.swift +++ b/slab/menubar-swift/Sources/SlabMenubar/AppDelegate.swift @@ -500,7 +500,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { DispatchQueue.main.async { guard let self = self else { return } if self.state.autoTile { - self.tileNow() + // Re-pin geometry only — skip the focus-stealing zoom + // reset on this frequent automatic path. + self.tileNowImpl(resetZoom: false) } self.refresh() } @@ -749,6 +751,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { try? FileManager.default.createDirectory(atPath: dir, withIntermediateDirectories: true) FileManager.default.createFile(atPath: path, contents: nil) try? FileManager.default.removeItem(atPath: Paths.tinyTextFlag) + // Update the live snapshot synchronously: `refresh()` re-derives + // textSize off a *background* gather that posts back later, so the + // immediate `tileNow()` would otherwise tile at the previous size. + state.textSize = .near refresh() tileNow() } @@ -757,8 +763,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { let path = Paths.tinyTextFlag let dir = (path as NSString).deletingLastPathComponent try? FileManager.default.createDirectory(atPath: dir, withIntermediateDirectories: true) - FileManager.default.createFile(atPath: path, contents: nil) try? FileManager.default.removeItem(atPath: Paths.nearTextFlag) + state.textSize = .tiny refresh() tileNow() } @@ -766,6 +772,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { @objc func setTextFar() { try? FileManager.default.removeItem(atPath: Paths.nearTextFlag) try? FileManager.default.removeItem(atPath: Paths.tinyTextFlag) + state.textSize = .far refresh() tileNow() } @@ -1218,8 +1225,16 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { tm.append(" try") tm.append(" set font name of slabSS to font name of default settings") tm.append(" end try") + // Keep the family from the user's default, but pin the size to the + // last tiled font so a re-theme on the blink tick doesn't bounce + // the window back to the un-tiled 12pt. Falls back to the default + // size before the first tile of the session. tm.append(" try") - tm.append(" set font size of slabSS to font size of default settings") + if let tiled = lastTiledFontSize { + tm.append(" set font size of slabSS to \(tiled)") + } else { + tm.append(" set font size of slabSS to font size of default settings") + } tm.append(" end try") // Close windows without the "terminate running processes?" modal: // `clean commands` is Terminal's allowlist of processes ignored when @@ -1612,21 +1627,23 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { // Font is sized for the tightest cell: full-width / widest row, and // equal row height. A char cell is ~fontSize*0.6 wide, *1.2 tall in - // Menlo/SF Mono; target ~24 rows × ~80 cols of monospace. + // Menlo/SF Mono; target ~26 rows × ~84 cols of monospace. let innerW = max(1, geom.width / maxCols - 2 * tileGutter) let innerH = max(1, geom.height / rows - 2 * tileGutter) - let fontByH = Double(innerH) / (24.0 * 1.2) - let fontByW = Double(innerW) / (80.0 * 0.6) + let fontByH = Double(innerH) / (26.0 * 1.2) + let fontByW = Double(innerW) / (84.0 * 0.6) let raw = min(fontByH, fontByW) // Far = legible from a typical sitting distance (the auto-fit - // baseline). Near ≈ 60% — denser when sitting close. Tiny ≈ 40% - // — for cramming many panes at the edge of legibility. + // baseline). Near ≈ 75% — denser when sitting close. Tiny ≈ 60% + // — tightest pack. The floors are the load-bearing rule: a tiled + // wall must ALWAYS stay readable, so even the densest pack never + // drops below ~10pt (Monaspace Argon's comfortable lower bound). let scale: Double let floor: Int switch size { - case .far: scale = 1.0; floor = 8 - case .near: scale = 0.6; floor = 6 - case .tiny: scale = 0.4; floor = 4 + case .far: scale = 1.0; floor = 10 + case .near: scale = 0.85; floor = 9 + case .tiny: scale = 0.7; floor = 8 } let fontSize = max(floor, Int((raw * scale).rounded())) @@ -1647,7 +1664,17 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { /// Terminal gets bounds only — AppleScript can't set per-session decor /// or wallpaper on Terminal.app, so those windows tile but stay /// un-themed (the iTerm2-only port intentionally dropped Terminal decor). - @objc func tileNow() { + /// Menu / hotkey entry point: an explicit tile, which DOES reset each + /// Terminal window's font zoom so the grid-derived size actually lands. + @objc func tileNow() { tileNowImpl(resetZoom: true) } + + /// `resetZoom`: when true, drive View ▸ Default Font Size on every + /// Terminal window so a live window adopts the new profile font (a + /// per-window zoom otherwise silently overrides it — see + /// slab-terminal-font-zoom). It steals focus for ~0.35 s/window, so the + /// frequent auto-retile-after-close path passes false (fresh/unchanged + /// windows already render their profile font). + func tileNowImpl(resetZoom: Bool) { guard let geom = Self.screenGeom() else { return } let textSize = state.textSize DispatchQueue.global(qos: .userInitiated).async { @@ -1681,14 +1708,45 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { lines.append("end tell") } if nTerm > 0 { + // Terminal.app auto-fit, three ordered passes in ONE osascript + // so the sequence is deterministic. Windows are addressed by + // id (captured up front) because pass 2 reorders the list. + // 1. set each window's profile font to the grid-derived size + // 2. View ▸ Default Font Size on each window (System Events) — + // the ONLY reliable way to make a LIVE window adopt a new + // font. A per-window zoom (View ▸ Bigger/Smaller) silently + // overrides the profile font and is invisible to + // AppleScript, so pass 1 alone is a no-op on already-open + // windows (see slab-terminal-font-zoom). Skipped when + // resetZoom is false (frequent auto-retile path). + // 3. re-pin pixel bounds LAST so the reflow can't fight the + // cell geometry. + // Minimized windows are excluded (matches windowCount): they + // neither consume a cell nor get moved. + lines.append("tell application \"Terminal\"") + lines.append(" set _slabIds to id of (every window whose miniaturized is false)") + lines.append(" repeat with _wid in _slabIds") + lines.append(" try") + lines.append(" set font size of current settings of (first window whose id is (contents of _wid)) to \(layout.fontSize)") + lines.append(" end try") + lines.append(" end repeat") + lines.append("end tell") + if resetZoom { + lines.append("tell application \"Terminal\" to activate") + lines.append("repeat with _wid in _slabIds") + lines.append(" try") + lines.append(" tell application \"Terminal\" to set index of (first window whose id is (contents of _wid)) to 1") + lines.append(" delay 0.25") + lines.append(" tell application \"System Events\" to tell process \"Terminal\" to click menu item \"Default Font Size\" of menu 1 of menu bar item \"View\" of menu bar 1") + lines.append(" delay 0.1") + lines.append(" end try") + lines.append("end repeat") + } lines.append("tell application \"Terminal\"") - // Tile only non-minimized windows (matches windowCount): a - // minimized window must neither consume a cell nor be moved. - lines.append(" set _slabVis to (every window whose miniaturized is false)") for j in 0..