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..