Skip to content

fix(luna): the Explorer rail is added to the window, not taken out of the document - #313

Merged
oddharsh merged 1 commit into
mainfrom
feat/window-width-minus-rail
Aug 10, 2026
Merged

fix(luna): the Explorer rail is added to the window, not taken out of the document#313
oddharsh merged 1 commit into
mainfrom
feat/window-width-minus-rail

Conversation

@oddharsh

Copy link
Copy Markdown
Owner

/garage/encoding declared 720px of prose and rendered 516px of it. The task pane is a 186px grid track plus a 14px gap living inside the window's max-width, so every page Explorer chrome reached quietly meant something different by the number its author picked.

The mechanism

Each page declares its measure once as --axp-maxw and consumes it, and one rule in luna.css grows a paned window by exactly one rail plus one gap:

.window:has(>.axp-tasks),.np-window:has(>.axp-tasks){
  --axp-rail:186px;--axp-rail-gap:14px;
  grid-template-columns:var(--axp-rail) minmax(0,1fr);column-gap:var(--axp-rail-gap);
  max-width:calc(var(--axp-maxw,720px) + var(--axp-rail) + var(--axp-rail-gap))}

The worker pages needed nothing, because lunaPage has emitted :root{--axp-maxw:${width}px} since it was written. The 23 static pages and lwe-base.css swap max-width: 720px for --axp-maxw: 720px; max-width: var(--axp-maxw), so no number is written twice and none can drift — which is why this needs no build tripwire. The 186/14 literals are tokenised for the same reason: the track and the compensation have to agree, and a paned window whose two numbers disagree is off by exactly the amount nobody notices.

Specificity carries it without touching cascade order: .window:has(>.axp-tasks) is 0,2,0 against each page's own .window at 0,1,0, so it wins wherever the page's style sits relative to luna.css.

It deletes a special case

.np-window.np-folder:has(>.axp-tasks){max-width:760px} was a hand-computed 560+200 for the /writing folder, with a comment explaining the arithmetic. writing.js declares 560 as the variable now and the generic rule lands on the same 760.

Measured, against the built tree at a 1280 viewport

page before after content column
/garage/encoding 720 920 516 → 716
/lwe/dac 640 840
/lens, /photos 980 1180
/writing 760 760 unchanged

Homepage is untouched (it has no .window and takes no pane). Mobile stacking below 760px is unchanged, since the window is width:100% there and the cap never applies.

One cost, on the widest pages only

At 1280 the 1180-wide windows sit over the desktop icons, clearing them again above ~1340. /access already did this at 1440. Capping with min(…, 100vw - 190px) would hold an icon column open but fights maximize, so it is deliberately left alone.

Checks

pnpm run build clean · 206/206 contract tests · pnpm run routes:check 122 routes, 0 hard failures · perf-budget hard checks green.

🤖 Generated with Claude Code

… the document

/garage/encoding declared 720px of prose and rendered 516px of it. The task
pane is a 186px grid track plus a 14px gap inside the window's max-width, so
every page Explorer chrome reached quietly meant something different by the
number its author picked.

Each page now declares its measure once as `--axp-maxw` and consumes it, and
one rule in luna.css grows a paned window by exactly one rail plus one gap.
The worker pages needed nothing: lunaPage has emitted `:root{--axp-maxw}` since
it was written. The 23 static pages and lwe-base.css swap `max-width: 720px`
for `--axp-maxw: 720px; max-width: var(--axp-maxw)`, so no number is written
twice and none can drift. The 186/14 literals are tokenised for the same
reason, since the track and the compensation have to agree.

This DELETES a special case rather than adding one.
`.np-window.np-folder:has(>.axp-tasks){max-width:760px}` was a hand-computed
560+200 for the /writing folder; writing.js declares 560 as the variable now
and the generic rule lands on the same 760.

Measured against the built tree at a 1280 viewport: /garage/encoding 720 -> 920
with its prose column back from 516 to 716, /lwe/dac 640 -> 840, /lens and
/photos 980 -> 1180, /writing unchanged at 760. Homepage untouched (no .window,
no pane). Mobile stacking below 760px is unchanged, since the window is
width:100% there and the cap never applies.

One cost, and it lands on the widest pages only: at 1280 the 1180 windows sit
over the desktop icons, clearing them again above ~1340. /access already did
this at 1440. Capping with min(..., 100vw - 190px) would keep an icon column
but fights maximize, so it is left alone.

build clean, 206/206 contract tests, routes:check 122/0, perf-budget green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Wire-size diff vs merge base

111ac75dae34bf

Brotli q11, the quality the edge serves. Every number here is deterministic:
an unchanged file produces no row. Advisory — this check fails on nothing.

Client assets

Total Brotli: 60.92 KiB → 60.97 KiB (+0.05 KiB, +0.1%) across 12 files, 2 changed.

file base head Δ
luna.css 8.84 KiB 8.88 KiB +0.04 KiB (+0.4%)
lwe-base.css 1.30 KiB 1.31 KiB +0.01 KiB (+0.7%)

Pages

Total Brotli: 471.25 KiB → 471.52 KiB (+0.27 KiB, +0.1%) across 46 files, 42 changed.

No single file moved by 0.13 KiB or more.

Plus 42 files under the 0.13 KiB floor, net +0.27 KiB — usually content-hash churn in /a/ references, counted in the total above.

Worker bundle

268.66 KiB → 268.68 KiB gzip (+0.02 KiB, +0.0%)

Largest module deltas (raw bytes in bundle):

file base head Δ
.build/holding/_worker.js/writing.js 15.63 KiB 15.66 KiB +0.03 KiB (+0.2%)

Dictionary deltas (pd/)

134 → 134 deltas, 388.99 KiB → 390.71 KiB (+1.72 KiB).

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
aadhar-sh ee4b26d Aug 10 2026, 07:57 PM

@oddharsh
oddharsh merged commit d989f84 into main Aug 10, 2026
7 of 8 checks passed
@oddharsh
oddharsh deleted the feat/window-width-minus-rail branch August 10, 2026 20:09
oddharsh added a commit that referenced this pull request Aug 10, 2026
#313 was CSS-only and failed `github-advanced-security` with the artifact's
whole signature: title null, empty summary, one annotation, CodeQL green.

Two things it added beyond the tally. The annotation sat at `.github:213`, the
SAME line as #307 on a diff sharing no content with it, so the line number is a
fingerprint of the harness rather than a location — do not go looking for what
lives there.

And `gh pr checks` did not list the failing check AT ALL: seven rows, every one
pass or skipping, while `/commits/<sha>/check-runs` reported that same check as
failure on the same head commit. Reproduced twice minutes apart, so it is not a
timing gap. That matters because the convenient command reports the PR green
while the notification says a check failed, which reads exactly like a stale
alert and is not one. The `check-runs` call the note already recommends is the
source of truth for this check.

Co-authored-by: Aadharsh Pannirselvam <19518661+oddharsh@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
oddharsh added a commit that referenced this pull request Aug 16, 2026
…verse (#416)

This gotcha claimed twice that the Copilot check fails on every diff, and one of
those claims went in a few hours ago as the general lesson. It is wrong. The run
always fires; whether it REQUESTS A MODEL depends on the diff.

The job prints a file exclusion list on every run, covering js, json, mjs, ts,
py, rs, yaml, yml, html, xml, go, java, c/cpp, rb and more. `.md`, `.sh` and
`.css` are NOT on it. So a docs diff survives the filter and gets a
`claude-opus-4.6` request, while a pure JavaScript diff is filtered to nothing
and the run exits clean.

Both paths print `Sessions disabled: not supported for code scanning yet`, which
this session initially read as the discriminator and is not; the discriminating
line is `Creating copilot-sdk session with model`, which only the failing path
reaches.

Correlates 12 of 12: the five runs of 2026-08-15 (#399 jpg/json and #402 js/mjs
passed; #398, #400 and #401 all carried md and failed), plus all seven earlier
failures checked backwards. #313 is the "CSS-only" diff this gotcha already
singles out, and css is not on the list either. #351's note here called its
entire diff a `${{ }}` move in workflow files; it touched md and mjs too, and
the md is what drew the request.

The prose-only argument is unchanged in conclusion and inverted in mechanism: a
docs PR reddens this because markdown is one of the few things the detector
still looks at, rather than because the agent choked on prose. The entitlement
root cause is untouched.

Records the method failure too, since it is the transferable part. Nine entries
were built by pattern-matching outcomes across PRs without once reading which
files each diff touched, and "fails on everything" was an artifact of that
sample. One uncollected column explained the whole shape.

Co-authored-by: Aadharsh Pannirselvam <19518661+oddharsh@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant