Repository navigation
fix(frontend): card layout and UTC date inputs for ladder purchases - #1387
Merged
Merged
Conversation
…te inputs The planned-purchases block rendered inside the laddering card with no section gap, body-size labels glued to their controls, four unstyled paragraphs stacked without hierarchy, and datetime-local inputs that display in the browser locale (with AM/PM) under a "(UTC)" label. The block now renders as its own settings card with a legend. Each filter is a .form-group with a 12px muted label above the control; the totals are one bold stat line, the run snapshot and the missing-fields caveat are muted footnotes, and Clear filters is a tertiary button. The From/To filters are text inputs that take UTC as YYYY-MM-DD HH:MM (time optional; a bare "to" date covers the whole day), are shown back in the same ISO form, and flag an unparseable value inline instead of guessing. Refs LeanerCloud#753 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Conflicts: - frontend/src/__tests__/ladder-timeline.test.ts: both sides appended a describe block at the end of the file. Kept both: this branch's "planned purchases layout and UTC date filters (issue LeanerCloud#753)" followed by main's "chart teardown on navigation (issue LeanerCloud#667)" (LeanerCloud#1357). ladder-timeline.ts merged cleanly: main's disposeLadderTimeline and the hidden-section guard sit before this branch's card template. The moved #ladder-purchase-timeline container is still inside the Purchasing panel, so the root.closest('.hidden') guard keeps working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): APPROVE Blocking:
|
Collaborator
Author
|
Local verification at
|
IAmJSD
marked this pull request as ready for review
October 24, 2026 20:58
Collaborator
Author
|
Marked ready and merged by IAmJSD's agent, at IAmJSD's request (IAmJSD reviewed the before/after screenshots; cristim is traveling), after the independent review and local verification above, all at |
IAmJSD
added a commit
to IAmJSD/cloud-commitments-platform
that referenced
this pull request
Oct 24, 2026
No conflicts (picks up LeanerCloud#1387, which main gained after the previous merge). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IAmJSD
added a commit
to IAmJSD/cloud-commitments-platform
that referenced
this pull request
Oct 24, 2026
…n added Main's LeanerCloud#1387 added .ladder-timeline-controls label (font-weight 500) and .ladder-timeline-stat (font-weight 600) to charts.css. Swap them for --cudly-fw-medium and --cudly-fw-semibold; computed values are unchanged. Refs LeanerCloud#741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IAmJSD
added a commit
to IAmJSD/cloud-commitments-platform
that referenced
this pull request
Oct 24, 2026
No conflicts: main's LeanerCloud#1387 (ladder timeline) merged cleanly and touches no file this branch changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IAmJSD
added a commit
to IAmJSD/cloud-commitments-platform
that referenced
this pull request
Oct 24, 2026
Conflicts: - frontend/src/history.ts: utils import. Main (LeanerCloud#1376) added NO_VALUE to the utils import; this branch added the historyConfirmBody import. Kept both. - frontend/src/__tests__/ladder-timeline.test.ts: both sides appended a test at the same spot. Kept this branch's refreshLadderTimeline test (LeanerCloud#728) and main's planned-purchases layout and UTC date filter describe block (LeanerCloud#1387, issue LeanerCloud#753) one after the other. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IAmJSD
added a commit
that referenced
this pull request
Oct 24, 2026
…ls (#1378) * chore(frontend): add a typography foundation (line-height, heading scale, control font) The body had no line-height, so text used the browser's ~1.2 default. Form controls did not inherit the page font, so .form-group inputs rendered at 13.33px system text next to 14px buttons. Headings had no base scale: every heading without a contextual rule got the browser's em-based default. - body: line-height var(--cudly-lh-normal) (1.5). - button, input, select, textarea: font: inherit, size pinned to --cudly-fs-sm (the button size) and line-height --cudly-lh-tight, so control heights stay where they were. Element selectors keep the existing `select`/`button`/class rules in charge. - :where(h1..h6): a 5-step scale on the --cudly-fs-* tokens (2xl, xl, lg, md, sm), tight line-height, bold weight. Zero specificity, so the ~20 contextual heading rules still win. Refs #741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(frontend): use the type tokens where a literal size or weight equals one Literal font sizes that are exactly a --cudly-fs-* value (0.75rem, 0.875rem, 1rem, 1.75rem) and every numeric or keyword font weight (bold, 700, 600, 500) now use the matching token, so a later change to the scale reaches them. Pure substitution: every computed value is unchanged. Off-scale sizes (0.8rem, 0.85rem, 0.9rem, ...) are left as they are, since snapping them to the scale is a visible design change. Refs #741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(frontend): give form controls one size and pin the foundation with tests Inside the Create API Key modal the text input got 14.4px from the .modal-content rule while the password and date inputs fell back to the browser's 13.33px, next to 14px buttons. The modal input rule and the bare `select` rule now use --cudly-fs-sm, so every control in a form matches the buttons (a 0.4px change for those two rules). Tests: a jest suite reads the stylesheets for the body line-height, the control font rule, the heading scale and the absence of token-duplicate literals; a Playwright spec checks the computed input/button font and body line-height in Chromium, which jsdom cannot cascade. Refs #741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(frontend): render form help text as a block .form-help is used on <small> elements, which are inline by default. With the new 1.5 body line-height their wrapped lines sat on the 16px parent line box and ended up 24px apart, and their margin-top never applied. As a block they get their own 0.8rem line box and the intended gap below the input. Refs #741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(frontend): tokenize the font size and weight main added after the merge Main added .account-delete-pending-total { font-weight: 600 } (#1373) and .last-updated-stamp { font-size: 0.75rem } (#1314). Both equal a design token exactly, so the typography test that pins 'no literal that duplicates a token' failed after merging main. They now use --cudly-fw-semibold and --cudly-fs-xs; computed values are unchanged. Refs #741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(frontend): use typography tokens in the ladder timeline rules main added Main's #1387 added .ladder-timeline-controls label (font-weight 500) and .ladder-timeline-stat (font-weight 600) to charts.css. Swap them for --cudly-fw-medium and --cudly-fw-semibold; computed values are unchanged. Refs #741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
IAmJSD
added a commit
to IAmJSD/cloud-commitments-platform
that referenced
this pull request
Oct 24, 2026
No textual conflicts. frontend/src/ladder.ts and frontend/src/styles/components.css auto-merged: main's LeanerCloud#1387 moved the #ladder-purchase-timeline container out of the laddering fieldset and LeanerCloud#1378 swapped literal font sizes/weights in components.css for the --cudly-fs-*/--cudly-fw-* tokens; this branch's ladder table/modal split and toast stack variables sit in other hunks and are unchanged. Co-Authored-By: Claude Opus 5.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.
The ladder "Planned purchases" block sat flush under the "Add Account Config" button inside the laddering card, with large body-text labels glued to their controls and four plain paragraphs stacked with no hierarchy. Its From/To filters were
datetime-localpickers that display in the browser locale (e.g. "10/24/2026, 09:15:00 AM") under a "(UTC)" label. This PR renders the block as its own settings card with labelled form groups, a stat line and muted footnotes, and replaces the date pickers with ISO UTC text inputs.Closes #753
What changed
frontend/src/ladder-timeline.ts:fieldset.settings-categorycard with the legend "Planned purchases". The intro text is.settings-help..form-groupwhose<label for>sits above it; Reload timeline is.btn-secondary; Clear filters is.btn-tertiary(link style)..ladder-timeline-stat(bold). The run snapshot, the date hint and the "Service, instance type ... unavailable" caveat are muted.ladder-timeline-notefootnotes, and the caveat moved below the table.YYYY-MM-DD HH:MMand the hint "Enter dates in UTC as YYYY-MM-DD HH:MM (24-hour); the time is optional." Valid input is shown back in ISO form. Invalid input setsaria-invalid, shows arole="alert".field-error, and keeps the last valid filter; Clear filters clears the error.frontend/src/ladder-timeline-filters.ts: newparseLadderUtcInput/formatLadderUtcInput. They acceptYYYY-MM-DDoptionally withHH:MMorHH:MM:SS, aTor space separator, and a trailingZ/UTC, and reject impossible dates by round-tripping the value. A bare "to" date covers through 23:59:59.frontend/src/ladder.ts: moves the#ladder-purchase-timelinediv out of the laddering fieldset (3 lines) so the two cards don't nest. It stays inside#commitment-laddering-settings, so the Purchasing "Laddering" nav link and main's hidden-section guard inladder-timeline.tsstill cover it.frontend/src/styles/charts.css: replaces the old label grid rule with filter-row, 12px muted label, stat and note rules built on the design tokens.ladder-timeline-filters.test.ts,ladder-timeline.test.ts, and newtests-e2e/ladder-timeline-layout.spec.ts.Why this approach
No browser lets a page control the
datetime-localdisplay format (Chromium ignoreslangand the page locale and uses the OS locale), so showing and accepting the ISO string is the only way to make UTC unambiguous. The cost is the native picker; in exchange, typing and pasting are exact and match the "Scheduled (UTC)" column. The card and.form-grouppattern copies the other Admin settings cards, as the issue suggests, instead of adding new components. The caveat moved to a footnote so the totals line sits directly above the chart it describes.Screenshots
Screenshots were taken before this branch was merged with main; before = main at a14dc8f. After is this branch at that time. Both are headless Chromium at 1440x900 against the repo's mocked e2e API (the narrow pair is at 390px wide).
Verification
Run on this branch's head
a06f34c5, merged with main6122fa24:ladder-timeline-filters.test.tscovers the parse/format rules (whole-day edges; rejects02.01.2030,01/02/2030,2030-02-30,24:00and8:30).ladder-timeline.test.tsadds 2 tests: the card and legend render, every control has a labelled.form-group, there is nodatetime-localinput and the default From is ISO; valid To dates filter and normalize while an invalid one is flagged and ignored until Clear filters.e2e-local.sh: 233 passed, 0 failed. Newladder-timeline-layout.spec.tsat 1280px and 390px checks that the card is separate from the laddering card, labels sit above controls at 12px, typed dates filter the summary, an invalid date shows the alert and changes nothing, Clear filters resets, and the card doesn't overflow horizontally.ladder-timeline.test.tsresolved, see the merge commits.Notes for review
.btn-tertiarylink style as the "ghost" button.ladder-timeline-editor.ts) still uses adatetime-localinput for the scheduled date. It is outside this block and could get the same treatment later.Overlaps
Measured with
git merge-tree:ladder.tsin other hunks (table, mode warning, save); merges cleanly..chart-tablerules tostyles/charts.cssright after the ladder rules rewritten here; merges cleanly, but keep both sides if a conflict appears at the end of the file.refreshLadderTimelinetoladder-timeline.ts; source merges cleanly, only the appended tests inladder-timeline.test.tsconflict (keep both).ladder.tsand chore(frontend): no dark mode or theming path, literals bypass color tokens #699 editsstyles/charts.css; both merge cleanly.Note for the UI owner
This changes UI code that @cristim owns. IAmJSD reviewed the before/after screenshots and asked for it to be merged; any design point you disagree with can be a follow-up.
🤖 Generated with Claude Code