fix(frontend): inline-direction spacing is logical, so RTL is a dir attribute - #78
Merged
Merged
Conversation
…ttribute Split out of ADR-033 the same way ADR-032 was, at the owner's instruction: a utility swap needs no product decision, while §4's deferral of localisation does. No locale is approved and none is assumed — this caps a debt that grows with every page, and costs nothing today because the logical utilities are the same length and behave identically in a left-to-right document. **The estimate in the ADR was wrong, in the direction estimates usually are.** "About four" came from reading by eye. Counted with a pattern there were **nine**, and they split into two kinds: Six are content flow and are now logical — `Curriculum`'s nesting indent and accordion label, `TranscriptPanel`'s cue marker, scrollbar gutter and cue text, `Field`'s "(optional)" marker. Two are navigation chrome and stay physical. `SiteNavTree` closes the desktop rail and the mobile drawer with `border-r` while both are anchored to the left edge, the drawer sliding in from `-100%`. Making those logical flips which side the navigation lives on, which border closes it and which way the animation travels — **ADR-029 accepted a left rail**, so that is a layout decision, not a tidy-up. They are **pinned rather than exempted**, which is what made a guard possible at all: the test asserts the physical set is exactly those two, so removing them fails just as adding a new one does. An exemption list silently absorbs the next offender. Provoked both ways. `left-`/`right-` insets are deliberately out of scope — they position against the viewport and physical is correct there, so a rule catching them would fire on code that is right. One false positive found by running the pattern: `border-l` matches `border-line`, which is a colour token in this palette. Hence the `(?![a-z])`, and a test that asserts the token is not flagged. **The RTL flip is not verified, and the reason is the third tooling artefact of this session.** Setting `dir="rtl"` made `direction` compute to `rtl` while the physical mapping did not move — which looked exactly like the swap having achieved nothing. An isolated probe settled it: a bare element with an **inline** `padding-inline-start: 16px` also fails to flip when `dir` is set directly on it, so this browser does not re-resolve logical properties on a direction change and cannot demonstrate the behaviour either way. After a frozen `requestAnimationFrame` and a stylesheet that had not loaded reporting every radius as `0px`, that is three artefacts that each first read as a bug in the code. **Isolate before concluding** — not doing so here would have cost a revert of a correct change. What is verified: the emitted CSS carries real `padding-inline-start`, `border-inline-start-width`, `margin-inline-start` and `text-align: start`; and LTR rendering is unchanged, the curriculum indent still computing to `padding-left: 16px` with a left border exactly as before, checked against a `rounded-full` control. ADR-033 now states which of its three habits is done, which is blocked on backend modelling, and that only §4's deferral still needs the owner. STATUS records that both remaining ADRs were split on the same principle. 425 frontend tests across 37 files, tsc, eslint, verify:css, verify:a11y and verify:static all pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split out of ADR-033 the same way ADR-032 was: a utility swap needs no product decision, while §4's deferral of localisation does.
No locale is approved and none is assumed. This caps a debt that grows with every page, and costs nothing today — the logical utilities are the same length and behave identically in a left-to-right document.
The estimate in the ADR was wrong
"About four" came from reading by eye. Counted with a pattern: nine, in two kinds.
Six are content flow and are now logical —
Curriculum's nesting indent and accordion label,TranscriptPanel's cue marker, scrollbar gutter and cue text,Field's "(optional)" marker.Two are navigation chrome and stay physical.
SiteNavTreecloses the desktop rail and the mobile drawer withborder-rwhile both are anchored to the left edge, the drawer sliding in from-100%. Making those logical flips which side the navigation lives on, which border closes it, and which way the animation travels — ADR-029 accepted a left rail, so that's a layout decision, not a tidy-up.Pinned, not exempted
That distinction is what made a guard possible at all. The test asserts the physical set is exactly those two, so removing them fails just as adding a new one does:
An exemption list silently absorbs the next offender; a pinned set makes either direction a deliberate edit to a test.
left-/right-insets are deliberately out of scope — they position against the viewport and physical is correct there, so a rule catching them would fire on code that is right.One false positive found by running the pattern rather than reasoning about it:
border-lmatchesborder-line, a colour token in this palette. Hence the(?![a-z]), and a test asserting the token isn't flagged.Setting
dir="rtl"madedirectioncompute tortlwhile the physical mapping did not move — which looked exactly like the swap having achieved nothing, and I nearly reported it as such.An isolated probe settled it: a bare element with an inline
padding-inline-start: 16pxalso fails to flip whendiris set directly on it. So this browser does not re-resolve logical properties on a direction change and cannot demonstrate the behaviour either way.That's the third tooling artefact this session — after a frozen
requestAnimationFrameand a stylesheet that hadn't loaded reporting every radius as0px. Each first read as a bug in the code. Isolate before concluding: not doing so here would have cost a revert of a correct change.A person with a real browser and
dir="rtl"closes this.What is verified
The emitted CSS carries real
padding-inline-start,border-inline-start-width,margin-inline-startandtext-align: start. LTR rendering is unchanged — the curriculum indent still computes topadding-left: 16pxwith a left border, exactly aspl-4 border-ldid, checked against arounded-fullcontrol.425 frontend tests across 37 files, tsc, eslint,
verify:css,verify:a11y,verify:staticall pass.ADR status after this
ADR-033 now says which of its three habits is done (§2), which is blocked on backend modelling rather than a decision (§3,
<track>language attributes), and that only §4's deferral still needs you. STATUS records that both remaining ADRs were split on the same principle.🤖 Generated with Claude Code