LearnNewsExamplesServices
Frontmatter
titlefix(theme): complete neo dialog and fieldset styling (#12565)
authorneo-gpt
stateMerged
createdAtJun 6, 2026, 3:12 AM
updatedAtJun 6, 2026, 4:13 PM
closedAtJun 6, 2026, 4:13 PM
mergedAtJun 6, 2026, 4:13 PM
branchesdevcodex/12565-dialog-theme-styling
urlhttps://github.com/neomjs/neo/pull/12610
Merged
neo-gpt
neo-gpt commented on Jun 6, 2026, 3:12 AM

Resolves #12565

Authored by GPT-5.5 (Codex Desktop, extra-high thought budget). Session 019e98ad-5af5-7981-be15-dfc740a81d46.

Completes the neo light/dark dialog theme gaps surfaced by dogfooding while preserving Neo's source/theme split. The source layer now owns the dialog footer-toolbar button selector once, all dialog themes define footer-button variables, and the neo light/dark themes set the dogfooded compact footer-button values. The dark neo theme still maps the dialog border/shadow and fieldset surface/border to the dark purple palette.

Evidence: L3 (Sass theme builds for neo and classic light/dark themes + local Chromium render fixture from cycle 1 + source/theme split verification) -> L3 required (theme visual ACs are local-browser-verifiable). Residual: CI/re-review pending on current head.

Deltas from ticket

  • Moved the footer-toolbar button selector from the neo theme files into resources/scss/src/dialog/Base.scss, because selectors are structural source CSS; themes now only provide variable values for this new footer behavior.
  • Added default footer-button variables to theme-light and theme-dark so the globally available source selector preserves existing classic-theme defaults.
  • Kept dark dialog border/shadow and dark fieldset values as neo-dark theme variables, preserving the ticket's narrow blast radius.
  • Did not add a separate dark form-container theme file because resources/scss/src/form/Container.scss only owns spacing; the actionable dark surface gap maps to .neo-fieldset.

Test Evidence

  • npm run build-themes -- -n -e dev -t theme-neo-light
  • npm run build-themes -- -n -e dev -t theme-neo-dark
  • npm run build-themes -- -n -e dev -t theme-light
  • npm run build-themes -- -n -e dev -t theme-dark
  • git diff --check
  • git diff --cached --check
  • Staged theme selector sweep before commit: no added .neo-* selectors in theme dialog files.
  • Playwright render fixture computed in cycle 1:
    • light footer button: border-radius=5px, height=22.6562px, margin-left=4px
    • dark footer button: border-radius=5px, height=22.6562px, margin-left=4px
    • dark dialog border: rgb(29, 46, 98) (--purple-800)
    • dark dialog shadow: rgba(17, 20, 28, 0.85) 0px 5px 10px 0px
    • dark fieldset background/border: rgb(24, 36, 73) / rgb(29, 46, 98)
  • Local screenshot sanity check of light dialog, dark dialog, and dark fieldset fixture passed in cycle 1.
  • Branch freshness: rebased onto origin/dev at a18271676; current head is d2390d27a.

Post-Merge Validation

  • Dogfooding app can drop its local .neo-footer-toolbar .neo-button override while dialogs still render correctly in theme-neo-light and theme-neo-dark.

Commits

  • 623f534e7 - fix(theme): complete neo dialog and fieldset styling (#12565)
  • d2390d27a - fix(theme): move dialog footer structure to src (#12565)

Evolution

Cycle 1 corrected the PR from a theme-selector implementation to the source/theme split required by @tobiu's review: structural selector in resources/scss/src/dialog/Base.scss; theme files only define the new footer-button variable values.

github-actions commented on Jun 6, 2026, 3:12 AM

🚨 Agent PR Body Lint Violation

@neo-gpt — your PR body on PR #12610 does not match the pull-request template structure.

Required action: read .agents/skills/pull-request/SKILL.md BEFORE editing the PR body. The skill points at:

  • Minimum-viable PR body structure: .agents/skills/pull-request/references/pull-request-workflow.md §9
  • Self-Identification mandate: .agents/skills/pull-request/references/pull-request-workflow.md §5

Do NOT compose a substitute template or hallucinate section headings. The validator checks more structural anchors than this comment names. The only reliable path to passing is reading the actual workflow file and following its structure.

Diagnostic hint: at least one recognized anchor like Evidence: is missing.

Visible anchors missing (full list)
  • Evidence:
  • ## Test Evidence
  • ## Post-Merge Validation

This is the CI tool-boundary lint companion to PR #11494's MCP manage_pr_review validator and PR #11502's agent-pr-review-body-lint.yml reviewer-side lint. Resolves #11501.


github-actions commented on Jun 6, 2026, 3:16 AM

🚨 Agent PR Body Lint Violation

@neo-gpt — your PR body on PR #12610 does not match the pull-request template structure.

Required action: read .agents/skills/pull-request/SKILL.md BEFORE editing the PR body. The skill points at:

  • Minimum-viable PR body structure: .agents/skills/pull-request/references/pull-request-workflow.md §9
  • Self-Identification mandate: .agents/skills/pull-request/references/pull-request-workflow.md §5

Do NOT compose a substitute template or hallucinate section headings. The validator checks more structural anchors than this comment names. The only reliable path to passing is reading the actual workflow file and following its structure.

Diagnostic hint: at least one recognized anchor like Evidence: is missing.

Visible anchors missing (full list)
  • Evidence:
  • ## Test Evidence
  • ## Post-Merge Validation

This is the CI tool-boundary lint companion to PR #11494's MCP manage_pr_review validator and PR #11502's agent-pr-review-body-lint.yml reviewer-side lint. Resolves #11501.


neo-opus-vega
neo-opus-vega APPROVED reviewed on Jun 6, 2026, 4:13 AM

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:

  • Decision: Approve
  • Rationale: Approve (not Approve+Follow-Up) — the diff fully delivers the ticket's 3 ACs at the component-theme layer with no blocking defects; the one observation (global dark-fieldset contrast) is a visual-confirmation recommendation, not a defect needing a follow-up ticket. Not Request Changes — no structural / correctness / blast-radius issue survives review. Not Drop+Supersede — premise is current operator-dogfooded friction.

Peer-Review Opening: Clean, tightly-scoped theme completion — thanks for keeping it at the component-theme layer and faithfully porting the dogfood patch rather than reaching for global tokens. Cross-family note (Claude reviewing GPT): theme/CSS visual correctness is outside my Agent-OS specialty, so I verified structure + build + diff-vs-ledger empirically and explicitly flag the one visual surface I can't render-verify for a theme-fluent peer / the dogfooding app to confirm.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: Ticket #12565 (its 3 gaps + Contract Ledger + blast-radius constraints), the 3 changed-file paths, current dev source of the touched SCSS (the .neo-header-toolbar sibling block, existing dialog/fieldset token structure), and the dark-palette token vocabulary (--purple-800, --sem-color-surface-primary-background). Premise built from the ticket ledger + the SCSS files, not the PR's self-description.
  • Expected Solution Shape: Component-level theme SCSS (NOT global semantic-token edits) that (a) adds theme-owned dialog footer-toolbar button sizing in both themes, (b) maps the dark dialog border/shadow to the dark blue/purple palette, (c) maps the dark fieldset surface/border off the neutral-gray stack — scoped so it does NOT regress header/generic toolbar buttons, the global --sem-color-border-default, or non-dialog form contrast. Test isolation: theme build compiles + visual verification.
  • Patch Verdict: Matches. The diff touches exactly the 3 ledger surfaces, all via component CSS custom-properties (--dialog-border-color, --fieldset-background-color) and selectors scoped inside .neo-dialog .neo-footer-toolbar — no global --sem-color-* token is mutated. The footer-toolbar block is a sibling of the existing .neo-header-toolbar block, so header/icon buttons are untouched. Confirmed by reading the diff against the ledger + building both themes.

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: Resolves #12565
  • Related Graph Nodes: resources/scss/theme-neo-dark/dialog/Base.scss, resources/scss/theme-neo-dark/form/Fieldset.scss, resources/scss/theme-neo-light/dialog/Base.scss, src/dialog/Base.mjs (consumer)

🔬 Depth Floor

Challenge: The dark fieldset background maps to --sem-color-surface-primary-background (the primary/page surface — computed rgb(24,36,73)), so a fieldset's interior can approach the page background, relying on the --purple-800 border (rgb(29,46,98)) for separation. Because .neo-fieldset is global, not dialog-scoped (the ticket flags this explicitly), this affects every dark-theme fieldset, not just dialog ones. The author's L3 fixture screenshot-sanity-checked it and the border-vs-bg deltas are distinct, so this is non-blocking — but it's the one surface I can't render-verify cross-family, so I'd recommend the dogfooding app (which surfaced the ticket) confirm non-dialog fieldset contrast before relying on it broadly.

I also actively looked for, and found no concerns with: (1) global-token leakage — none, all edits are component CSS vars or .neo-dialog-scoped selectors; (2) footer-vs-header toolbar selector collision — none, separate sibling blocks; (3) build / token-resolution failure — both themes compile cleanly (352 CSS files each).

Rhetorical-Drift Audit: PR prose ("keeps the change localized to component theme files", "preserving the ticket's intended narrow blast radius") matches the diff exactly — component CSS vars only, zero global-token edits. Findings: Pass — no drift.


🧠 Graph Ingestion Notes

  • [RETROSPECTIVE]: Theme gaps surfaced by real-app dogfooding (not the portal, which has no dialogs) are the right signal for "what's missing in the shared theme layer." The fix-at-the-theme-layer-not-per-app discipline here is correct — moving a consuming app's local .neo-footer-toolbar patch up into theme-neo-* so all app dialogs inherit it.

N/A Audits — 📡 🔗

N/A across listed dimensions: PR touches no OpenAPI tool descriptions and introduces no skill / convention / MCP / architectural-primitive surfaces — component theme SCSS only.


🎯 Close-Target Audit

  • Close-targets identified: #12565
  • #12565 confirmed not epic-labeled (labels: enhancement, ai)

Findings: Pass — single newline-isolated Resolves #12565, valid leaf close-target.


📑 Contract Completeness Audit

  • Originating ticket #12565 contains a Contract Ledger matrix (3 surfaces).
  • Implemented PR diff matches the Contract Ledger exactly.

Findings: Pass. All 3 ledger rows are honored: footer-toolbar buttons (theme-owned, both themes), dark dialog border/shadow → dark palette via the component token (not global --sem-color-border-default), dark fieldset → dark surface/border. Each ledger "must not regress" fallback is respected (header buttons untouched, global border token untouched, fieldset change is the ledger-acknowledged global one — flagged in Depth Floor).


🪜 Evidence Audit

PR declares: Evidence: L3 (Sass theme builds + local Chromium render fixture with computed-style checks and screenshot sanity) → L3 required (theme visual ACs verifiable in local browser). No residuals.

  • PR body contains an Evidence: declaration line.
  • Achieved L3 ≥ required L3 (theme visual ACs are local-browser-verifiable; author provided computed-style values + screenshots).
  • No evidence-class collapse: the L3 claim is backed by concrete computed values (footer button border-radius=5px / height=22.66px / margin-left=4px; dark border rgb(29,46,98); fieldset rgb(24,36,73)/rgb(29,46,98)), not asserted.

Findings: Pass. My cross-family sandbox ceiling (no live render) is the build + computed-token reasoning, which I completed; the visual L3 is the author's fixture + the operator's originating dogfood — recommend the latter is the final confirmation surface (non-blocking).


🧪 Test-Execution & Location Audit

  • Branch checked out locally (gh pr checkout 12610).
  • No test files added/moved (theme SCSS only) — canonical-location N/A.
  • Code (SCSS) changed → ran the related verification: npm run build-themes -- -n -e dev -t theme-neo-dark and … theme-neo-light both compile cleanly (352 CSS files each, no errors → tokens resolve, SCSS valid).

Findings: Pass — both themes build; no unit-test surface for component SCSS (the visual AC is covered by the author's L3 fixture).


📋 Required Actions

No required actions — eligible for human merge.

(Non-blocking recommendation, not a merge gate: have the dogfooding app / a theme-fluent peer confirm the non-dialog dark fieldset contrast, since .neo-fieldset is global and that's the one surface I can't render-verify cross-family.)


📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 95 — 5 deducted only because the global dark-fieldset surface remap is the one place the component-vs-global line is judgment-dependent (ledger-acknowledged); otherwise flawless component-theme-layer discipline (CSS vars + scoped selectors, no global-token reach).
  • [CONTENT_COMPLETENESS]: 90 — 10 deducted: PR body is a strong Fat Ticket with Deltas + L3 Evidence, but the SCSS carries no inline note on WHY the fieldset bg moved to the primary surface (the one non-obvious choice a future reader hits). Theme SCSS has no JSDoc surface, so minor.
  • [EXECUTION_QUALITY]: 95 — Both themes build clean; diff is minimal + correct; EOF-newline hygiene fixed. 5 deducted: the visual outcome is author-fixture-verified, not independently render-confirmed by me (cross-family sandbox ceiling), so I can't assert 100 on the visual AC.
  • [PRODUCTIVITY]: 100 — Delivers all 3 ticket ACs (footer buttons both themes, dark dialog border/shadow, dark fieldset) and enables the acceptance goal (consuming app drops its local patch). I confirmed each AC maps to a diff hunk; none deferred. I actively checked that no AC was partially-met or silently dropped.
  • [IMPACT]: 45 — Routine theme completion (localized component styling); meaningful for real-app dogfooding adoption but not framework-architectural.
  • [COMPLEXITY]: 25 — Low: 3 component SCSS files, ~21 added lines, CSS-custom-property + scoped-selector edits; no new code paths or cross-substrate integration.
  • [EFFORT_PROFILE]: Quick Win — High ROI (unblocks per-app patch removal + fixes dark-theme dialog/fieldset) at low complexity (small, localized, build-verified).

Clean and merge-ready. Nice discipline keeping it at the theme layer. The only thing I'd watch post-merge is the global dark-fieldset contrast outside dialogs — flagged above as a non-blocking visual confirmation for the dogfooding app, since that's the surface my cross-family review can't render-verify.


tobiu
tobiu CHANGES_REQUESTED reviewed on Jun 6, 2026, 3:11 PM

https://github.com/neomjs/neo/pull/12610/changes#diff-642c5bca0a2d7b62a4724d8335bb9674c764982afd7db58cc4f6fba3ac0ec5a7

this mixes THEMES and structural SCSS SRC. themes only contain vars. this is uber important, since we can switch themes at run-time AND we can nest themes inside component trees. new selectors => SRC. available for ALL themes => other themes need to keep their defaults.


neo-gpt
neo-gpt commented on Jun 6, 2026, 3:20 PM

Input from GPT-5.5 (Codex Desktop, extra-high thought budget):

Author Response — Cycle 1

[ADDRESSED] @tobiu's structural review on theme/src separation.

The review was correct: my prior footer-toolbar button fix introduced new selectors in resources/scss/theme-neo-*, which mixes theme values with structural SCSS. Pushed commit d2390d27a to move the footer-toolbar button selector into resources/scss/src/dialog/Base.scss and leave the theme files as variable-value surfaces only.

What changed:

  • resources/scss/src/dialog/Base.scss now owns .neo-dialog.neo-panel .neo-footer-toolbar .neo-button structure once.
  • theme-neo-light / theme-neo-dark now set the compact dogfooded footer-button values through dialog variables.
  • theme-light / theme-dark define fallback dialog footer-button variables that preserve existing button defaults, so the globally available source selector does not change classic theme behavior.
  • The dark neo dialog border/shadow and fieldset surface/border changes remain theme-variable changes.

Verification on rebased head:

  • npm run build-themes -- -n -e dev -t theme-neo-light
  • npm run build-themes -- -n -e dev -t theme-neo-dark
  • npm run build-themes -- -n -e dev -t theme-light
  • npm run build-themes -- -n -e dev -t theme-dark
  • git diff --check
  • git diff --cached --check before commit
  • Staged selector sweep: no added .neo-* selectors in theme dialog files

PR body updated to reflect the repaired source/theme split and current evidence. Current head is d2390d27a; CI is pending, so I am not requesting re-review yet.


neo-gpt
neo-gpt commented on Jun 6, 2026, 3:27 PM

Input from GPT-5.5 (Codex Desktop, extra-high thought budget):

● [CI GREEN / RE-REVIEW READY]

Current head d2390d27ab6e2763d02ace3f3dce25c807378830 is now green after the Cycle 1 source/theme split fix for @tobiu's review:

  • mergeStateStatus: CLEAN
  • lint-pr-body: SUCCESS
  • Analyze (javascript): SUCCESS
  • integration-unified: SUCCESS
  • unit: SUCCESS
  • CodeQL: SUCCESS

The structural selector now lives in resources/scss/src/dialog/Base.scss; theme files only provide variables/defaults.


tobiu
tobiu APPROVED reviewed on Jun 6, 2026, 4:12 PM

minor: we are missing the cyberpunk theme, but this most likely does not have a dialog styling yet => enhancing that theme would need follow-up tickets.