Skip to content

🌫️ feat: Give the Dialog Scrims Theme-Owned Opacity Roles - #16492

Merged
berry-13 merged 2 commits into
canaryfrom
theme-scrim-role
Sep 29, 2026
Merged

berry-13 merged 2 commits into
canaryfrom
theme-scrim-role

Conversation

@berry-13

@berry-13 berry-13 commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Pull Request

Summary

Each dialog family carried its scrim alpha in the utility itself (bg-surface-overlay/80 on OGDialog, /90 on AlertDialog, /65 on Dialog), so a theme could recolor the scrim but never set how much it dims. Click UI's scrim, dialog.color.opaqueBackground, is 0.75 in both modes.

This adds three appearance roles, scrimOpacity, alertScrimOpacity and modalScrimOpacity, exposed as bg-scrim, bg-scrim-alert and bg-scrim-modal in the published tokens.css and defaulting to the 80%, 90% and 65% each family drew, so the default and high-contrast themes are unchanged. ClickHouse takes Click UI's 0.75, cited in the drift guard, which now compares a scrim role with the alpha of Click UI's scrim color.

Decision on whether a scrim may lift the page: no. A new guard holds every bundled palette's scrim to dimming the page, never lightening it, and on a light canvas to separating the dialog by 3:1. That is why ClickHouse dark keeps a black overlay rather than Click UI's #606060, which would leave the dialog at about 2.1:1.

The mobile drawer's scrim, its dark-mode edge and Scrim.spec (berry-13#105, #145, #65) wait on #16248, which owns UnifiedSidebar/**; they are tracked together in berry-13#199.

Stack: link 4 of the theme-roles stack, based on #16491; merge from the bottom up.

Closes berry-13#181

Type of change

  • Feature
  • Tests / tooling / CI

Testing

Tested environments/configuration:

  • Default, high-contrast and ClickHouse themes, light and dark, plus a reference theme with its own overlay color and three distinct opacities.

Automated tests:

  • packages/client: npx jest src/theme (scrim defaults equal the three families' old alphas; every bundled palette's scrim dims without lifting and clears 3:1 on light canvases; opacity validation rejects 1.5 and 75%; the Click UI drift guard).
  • e2e/specs/mock/scenarios/scrim-opacity.spec.ts via reviewctl verify: default light and dark keep each family's rgba; ClickHouse light and dark dim at 0.75; the reference theme dims each family by its own role.
  • e2e/specs/mock/scenarios/dialog-scrim-role.spec.ts (real OGDialog): all four scenarios pass on desktop light and dark. Its mobile runs time out before any scrim assertion, waiting for a conversation menu inside the closed mobile drawer; that is pre-existing in the spec, which πŸ“± feat: Give the Mobile Drawer One Place for Each ControlΒ #16248 also edits.
  • npx tsc --noEmit -p packages/client, npx eslint on the changed files, sort-imports --check.

Screenshots / recordings

ClickHouse theme, the Archived chats dialog over the chat page: the scrim moves from 80% to Click UI's 75%. The default theme renders unchanged, which the scrim-opacity-default-* scenarios measure.

Before (#16491) After
Light Before, light After, light
Dark Before, dark After, dark

Risk / compatibility

DIALOG_SCRIM_CLASS now exports bg-scrim; its one feature consumer (the shared-layout morph backdrop) follows. Package consumers without a theme get the same alphas through tokens.css fallbacks. The new appearance keys are ignored by an older reader.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
πŸ“ Code Review ⚠️ Failed 2026-09-29T14:13:16.011986Z 8909977 New commits
πŸ”’ Security Review βœ… Completed 2026-09-29T08:04:40.858664Z ee57f14 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with πŸ‘€ while any review is running, comments if it has suggestions, and reacts with πŸ‘ once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

Lighthouse CI failed. The last 80 log lines contain the measured budgets and assertion failures.

β”‚ 23      β”‚ 'http://localhost:3080/api/permissions/mcpServer/effective/all'                                                 β”‚ 3019.756000000023  β”‚ 3783.688999999984  β”‚ 200    β”‚
β”‚ 24      β”‚ 'http://localhost:3080/api/prompts/groups?limit=10'                                                             β”‚ 3020.0739999999932 β”‚ 4286.3490000000165 β”‚ 200    β”‚
β”‚ 25      β”‚ 'http://localhost:3080/api/keys?name=openAI'                                                                    β”‚ 3324.116000000009  β”‚ 3922.2969999999914 β”‚ 200    β”‚
β”‚ 26      β”‚ 'http://localhost:3080/api/presets'                                                                             β”‚ 3324.3940000000002 β”‚ 3925.421000000002  β”‚ 200    β”‚
β”‚ 27      β”‚ 'http://localhost:3080/api/tags'                                                                                β”‚ 3325.6240000000107 β”‚ 3941.597000000009  β”‚ 200    β”‚
β”‚ 28      β”‚ 'http://localhost:3080/api/share/link/16390000-0000-4000-8000-000000000001'                                     β”‚ 3325.839000000007  β”‚ 4291.750000000029  β”‚ 200    β”‚
β”‚ 29      β”‚ 'http://localhost:3080/api/messages/16390000-0000-4000-8000-000000000001'                                       β”‚ 3327.4470000000147 β”‚ 4430.140000000014  β”‚ 200    β”‚
β”‚ 30      β”‚ 'http://localhost:3080/api/files/config'                                                                        β”‚ 3327.6510000000126 β”‚ 4180.04800000001   β”‚ 200    β”‚
β”‚ 31      β”‚ 'http://localhost:3080/api/user/settings/favorites/tools'                                                       β”‚ 3327.837999999989  β”‚ 4448.574000000022  β”‚ 200    β”‚
β”‚ 32      β”‚ 'http://localhost:3080/api/endpoints/token-config'                                                              β”‚ 3329.0659999999916 β”‚ 4434.845000000001  β”‚ 200    β”‚
β”‚ 33      β”‚ 'http://localhost:3080/api/user/settings/skills/active'                                                         β”‚ 3329.530000000028  β”‚ 4798.508000000002  β”‚ 200    β”‚
β”‚ 34      β”‚ 'http://localhost:3080/api/agents/tools/web_search/auth'                                                        β”‚ 3329.7090000000317 β”‚ 7318.589000000007  β”‚ 200    β”‚
β”‚ 35      β”‚ 'http://localhost:3080/api/agents/tools/calls?conversationId=16390000-0000-4000-8000-000000000001'              β”‚ 3329.8759999999893 β”‚ 4800.097000000009  β”‚ 200    β”‚
β”‚ 36      β”‚ 'http://localhost:3080/api/agents/chat/status/16390000-0000-4000-8000-000000000001?generationProtocolVersion=2' β”‚ 4555.964000000007  β”‚ 4811.3490000000165 β”‚ 200    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Inspect .lighthouse HTML/JSON and e2e/lighthouse/README.md. Reuse loaded user/config data; overlap independent reads without bypassing authorization.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (index) β”‚ audit                      β”‚ median              β”‚ limit β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 0       β”‚ 'largest-contentful-paint' β”‚ 4581.682            β”‚ 4500  β”‚
β”‚ 1       β”‚ 'cumulative-layout-shift'  β”‚ 0.01790350483757989 β”‚ 0.1   β”‚
β”‚ 2       β”‚ 'total-blocking-time'      β”‚ 337.6500000000001   β”‚ 500   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”˜

  1) [chrome] β€Ί e2e/lighthouse/load.spec.ts:10:5 β€Ί serial database latency stays within web-vitals budgets 

    Error: Median largest-contentful-paint must stay within 4500

    expect(received).toBeLessThanOrEqual(expected)

    Expected: <= 4500
    Received:    4581.682

       at audit.ts:159

      157 |   console.table(measured);
      158 |   for (const { audit, median, limit } of measured) {
    > 159 |     expect(median, `Median ${audit} must stay within ${limit}`).toBeLessThanOrEqual(limit);
          |                                                                 ^
      160 |   }
      161 |   return results;
      162 | }
        at auditPage (/home/runner/work/LibreChat/LibreChat/e2e/lighthouse/audit.ts:159:65)
        at /home/runner/work/LibreChat/LibreChat/e2e/lighthouse/load.spec.ts:33:19

    attachment #1: screenshot (image/png) ──────────────────────────────────────────────────────────
    e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    Error Context: e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/error-context.md

    attachment #3: trace (application/zip) ─────────────────────────────────────────────────────────
    e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/trace.zip
    Usage:

        npx playwright show-trace e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/trace.zip

    ────────────────────────────────────────────────────────────────────────────────────────────────


πŸ€–: global teardown has been started
2026-09-29 08:23:39 οΏ½[32minfoοΏ½[39m: οΏ½[32mMongo Connection optionsοΏ½[39m
2026-09-29 08:23:39 οΏ½[32minfoοΏ½[39m: οΏ½[32m{οΏ½[39m
οΏ½[32m  "bufferCommands": falseοΏ½[39m
οΏ½[32m}οΏ½[39m
πŸ€–:  βœ…  Connected to Database
πŸ€–:  βœ…  Found user in Database
πŸ€–:  βœ…  Deleted 1 convos & 2 messages
πŸ€–:  βœ…  Deleted user from Database
πŸ€–: global teardown has been started
2026-09-29 08:23:40 οΏ½[32minfoοΏ½[39m: οΏ½[32mMongo Connection optionsοΏ½[39m
2026-09-29 08:23:40 οΏ½[32minfoοΏ½[39m: οΏ½[32m{οΏ½[39m
οΏ½[32m  "bufferCommands": falseοΏ½[39m
οΏ½[32m}οΏ½[39m
πŸ€–:  βœ…  Connected to Database
πŸ€–:  ⚠️  User not found in Database
  1 failed
    [chrome] β€Ί e2e/lighthouse/load.spec.ts:10:5 β€Ί serial database latency stays within web-vitals budgets 

Open the full run

@berry-13
berry-13 added this pull request to stack #16502 September 29, 2026 11:36
@berry-13
berry-13 force-pushed the theme-scrim-role branch 2 times, most recently from db78593 to 4ace4b7 Compare September 29, 2026 14:12
Base automatically changed from theme-type-roles to canary September 29, 2026 14:12
The three dialog families carried their scrim alpha in each utility
(bg-surface-overlay/80, /90, /65), so a theme could recolor a scrim but
not set how much it dims. Add scrimOpacity, alertScrimOpacity and
modalScrimOpacity, exposed as bg-scrim, bg-scrim-alert and
bg-scrim-modal in the published tokens, defaulting to the 80%, 90% and
65% each family drew.

ClickHouse takes Click UI's 0.75 from dialog.color.opaqueBackground,
cited in the drift guard. A bundled scrim never lifts the page and, on
a light canvas, separates the dialog by 3:1, which is why ClickHouse
dark keeps a black overlay rather than Click UI's lighter gray.
…ettings Scenarios

Both scenarios pinned the old bg-surface-overlay/80 literal: the morph
counted elements carrying it and Settings compared its scrim with a
probe of it, whose color-mix value serializes differently from the
role's rgb(). They now use bg-scrim, the class DIALOG_SCRIM_CLASS
exports.
@berry-13
berry-13 merged commit 2d7133f into canary Sep 29, 2026
1 check passed
@berry-13
berry-13 deleted the theme-scrim-role branch September 29, 2026 14:13
@github-actions

Copy link
Copy Markdown
Contributor

Lighthouse CI failed. The last 80 log lines contain the measured budgets and assertion failures.

β”‚ 23      β”‚ 'http://localhost:3080/api/permissions/mcpServer/effective/all'                                                 β”‚ 3015.9949999999953 β”‚ 3774.2910000000848 β”‚ 200    β”‚
β”‚ 24      β”‚ 'http://localhost:3080/api/prompts/groups?limit=10'                                                             β”‚ 3016.9740000000456 β”‚ 4281.48199999996   β”‚ 200    β”‚
β”‚ 25      β”‚ 'http://localhost:3080/api/keys?name=openAI'                                                                    β”‚ 3309.5069999999832 β”‚ 3919.6970000000438 β”‚ 200    β”‚
β”‚ 26      β”‚ 'http://localhost:3080/api/presets'                                                                             β”‚ 3310.5840000000317 β”‚ 3922.057999999961  β”‚ 200    β”‚
β”‚ 27      β”‚ 'http://localhost:3080/api/tags'                                                                                β”‚ 3310.7979999999516 β”‚ 3925.2669999999925 β”‚ 200    β”‚
β”‚ 28      β”‚ 'http://localhost:3080/api/share/link/16390000-0000-4000-8000-000000000001'                                     β”‚ 3312.1680000000633 β”‚ 4281.949000000022  β”‚ 200    β”‚
β”‚ 29      β”‚ 'http://localhost:3080/api/messages/16390000-0000-4000-8000-000000000001'                                       β”‚ 3312.3669999999693 β”‚ 4425.793999999994  β”‚ 200    β”‚
β”‚ 30      β”‚ 'http://localhost:3080/api/files/config'                                                                        β”‚ 3313.1759999999776 β”‚ 4177.993000000017  β”‚ 200    β”‚
β”‚ 31      β”‚ 'http://localhost:3080/api/user/settings/favorites/tools'                                                       β”‚ 3313.353999999934  β”‚ 4430.429000000004  β”‚ 200    β”‚
β”‚ 32      β”‚ 'http://localhost:3080/api/endpoints/token-config'                                                              β”‚ 3314.7579999999143 β”‚ 4435.657999999938  β”‚ 200    β”‚
β”‚ 33      β”‚ 'http://localhost:3080/api/user/settings/skills/active'                                                         β”‚ 3314.9590000000317 β”‚ 4788.856000000029  β”‚ 200    β”‚
β”‚ 34      β”‚ 'http://localhost:3080/api/agents/tools/web_search/auth'                                                        β”‚ 3315.158999999985  β”‚ 7304.239999999991  β”‚ 200    β”‚
β”‚ 35      β”‚ 'http://localhost:3080/api/agents/tools/calls?conversationId=16390000-0000-4000-8000-000000000001'              β”‚ 3315.344999999972  β”‚ 4796.297999999952  β”‚ 200    β”‚
β”‚ 36      β”‚ 'http://localhost:3080/api/agents/chat/status/16390000-0000-4000-8000-000000000001?generationProtocolVersion=2' β”‚ 4539.04999999993   β”‚ 4796.570999999996  β”‚ 200    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Inspect .lighthouse HTML/JSON and e2e/lighthouse/README.md. Reuse loaded user/config data; overlap independent reads without bypassing authorization.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (index) β”‚ audit                      β”‚ median               β”‚ limit β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 0       β”‚ 'largest-contentful-paint' β”‚ 4573.586             β”‚ 4500  β”‚
β”‚ 1       β”‚ 'cumulative-layout-shift'  β”‚ 0.017901170121559694 β”‚ 0.1   β”‚
β”‚ 2       β”‚ 'total-blocking-time'      β”‚ 368.62800000000016   β”‚ 500   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”˜

  1) [chrome] β€Ί e2e/lighthouse/load.spec.ts:10:5 β€Ί serial database latency stays within web-vitals budgets 

    Error: Median largest-contentful-paint must stay within 4500

    expect(received).toBeLessThanOrEqual(expected)

    Expected: <= 4500
    Received:    4573.586

       at audit.ts:159

      157 |   console.table(measured);
      158 |   for (const { audit, median, limit } of measured) {
    > 159 |     expect(median, `Median ${audit} must stay within ${limit}`).toBeLessThanOrEqual(limit);
          |                                                                 ^
      160 |   }
      161 |   return results;
      162 | }
        at auditPage (/home/runner/work/LibreChat/LibreChat/e2e/lighthouse/audit.ts:159:65)
        at /home/runner/work/LibreChat/LibreChat/e2e/lighthouse/load.spec.ts:33:19

    attachment #1: screenshot (image/png) ──────────────────────────────────────────────────────────
    e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    Error Context: e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/error-context.md

    attachment #3: trace (application/zip) ─────────────────────────────────────────────────────────
    e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/trace.zip
    Usage:

        npx playwright show-trace e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chrome/trace.zip

    ────────────────────────────────────────────────────────────────────────────────────────────────


πŸ€–: global teardown has been started
2026-09-29 14:17:51 οΏ½[32minfoοΏ½[39m: οΏ½[32mMongo Connection optionsοΏ½[39m
2026-09-29 14:17:51 οΏ½[32minfoοΏ½[39m: οΏ½[32m{οΏ½[39m
οΏ½[32m  "bufferCommands": falseοΏ½[39m
οΏ½[32m}οΏ½[39m
πŸ€–:  βœ…  Connected to Database
πŸ€–:  βœ…  Found user in Database
πŸ€–:  βœ…  Deleted 1 convos & 2 messages
πŸ€–:  βœ…  Deleted user from Database
πŸ€–: global teardown has been started
2026-09-29 14:17:52 οΏ½[32minfoοΏ½[39m: οΏ½[32mMongo Connection optionsοΏ½[39m
2026-09-29 14:17:52 οΏ½[32minfoοΏ½[39m: οΏ½[32m{οΏ½[39m
οΏ½[32m  "bufferCommands": falseοΏ½[39m
οΏ½[32m}οΏ½[39m
πŸ€–:  βœ…  Connected to Database
πŸ€–:  ⚠️  User not found in Database
  1 failed
    [chrome] β€Ί e2e/lighthouse/load.spec.ts:10:5 β€Ί serial database latency stays within web-vitals budgets 

Open the full run

berry-13 added a commit that referenced this pull request Sep 29, 2026
The stylesheet-ownership check added in #16480 required every declared
color token to be a theme key of its own, so the scrim tokens from #16492,
which compose the surface-overlay role with a scrim opacity role, failed it
once both landed on canary. A token is now owned when a variable its value
reads is one a theme can set.
jeannotdamoiseaux pushed a commit to jeannotdamoiseaux/LibreChat that referenced this pull request Oct 1, 2026
…AI#16492)

* feat: Give the Dialog Scrims Theme-Owned Opacity Roles

The three dialog families carried their scrim alpha in each utility
(bg-surface-overlay/80, /90, /65), so a theme could recolor a scrim but
not set how much it dims. Add scrimOpacity, alertScrimOpacity and
modalScrimOpacity, exposed as bg-scrim, bg-scrim-alert and
bg-scrim-modal in the published tokens, defaulting to the 80%, 90% and
65% each family drew.

ClickHouse takes Click UI's 0.75 from dialog.color.opaqueBackground,
cited in the drift guard. A bundled scrim never lifts the page and, on
a light canvas, separates the dialog by 3:1, which is why ClickHouse
dark keeps a black overlay rather than Click UI's lighter gray.

* test: Read the Dialog Scrim Through Its Role Class in the Morph and Settings Scenarios

Both scenarios pinned the old bg-surface-overlay/80 literal: the morph
counted elements carrying it and Settings compared its scrim with a
probe of it, whose color-mix value serializes differently from the
role's rgb(). They now use bg-scrim, the class DIALOG_SCRIM_CLASS
exports.

(cherry picked from commit 2d7133f)

Original-PR: LibreChat-AI#16492
jeannotdamoiseaux pushed a commit to jeannotdamoiseaux/LibreChat that referenced this pull request Oct 1, 2026
The stylesheet-ownership check added in LibreChat-AI#16480 required every declared
color token to be a theme key of its own, so the scrim tokens from LibreChat-AI#16492,
which compose the surface-overlay role with a scrim opacity role, failed it
once both landed on canary. A token is now owned when a variable its value
reads is one a theme can set.

(cherry picked from commit 75bb189)

Original-PR: LibreChat-AI#16512
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