From 0f79d2c8dd096d916a56ff6d0447fad12ee382b4 Mon Sep 17 00:00:00 2001 From: chaxus Date: Sat, 24 Oct 2026 20:22:20 +0800 Subject: [PATCH 1/3] build(deps): upgrade ranui and ranuts to 0.5.2, ranview to 0.2.2 ranui 0.5.2 (chaxus/ran#444) ships :not(:defined) rules in ranui.css that keep light-DOM content such as r-popover's r-content off the page until the element is defined. public/ran-tokens.css is that sheet, re-synced the way bin/build.sh does, so the language menu no longer spills its seven links before the deferred popover bundle runs. The release-age exclusion follows ranview to 0.2.2, and the dompurify override moves to 3.4.17, the version ranui 0.5.2 depends on (the pin forced 3.4.16, which has a critical and a high advisory). Co-Authored-By: Claude Opus 5.5 --- package.json | 4 +-- packages/chat-ui/package.json | 4 +-- packages/converter/package.json | 4 +-- packages/shared/package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++++----------------- pnpm-workspace.yaml | 4 +-- public/ran-tokens.css | 2 +- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 0f7b635c..c04bd6b3 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "@ranuts/converter": "workspace:*", "@ranuts/shared": "workspace:*", "pdfjs-dist": "5.4.624", - "ranui": "0.5.1", - "ranuts": "0.5.1" + "ranui": "0.5.2", + "ranuts": "0.5.2" } } diff --git a/packages/chat-ui/package.json b/packages/chat-ui/package.json index d53935ee..fee8464e 100644 --- a/packages/chat-ui/package.json +++ b/packages/chat-ui/package.json @@ -23,8 +23,8 @@ }, "dependencies": { "marked": "16.4.2", - "ranui": "0.5.1", - "ranuts": "0.5.1" + "ranui": "0.5.2", + "ranuts": "0.5.2" }, "devDependencies": { "typescript": "^6.0.3" diff --git a/packages/converter/package.json b/packages/converter/package.json index 351f9bc2..4bd94e36 100644 --- a/packages/converter/package.json +++ b/packages/converter/package.json @@ -23,8 +23,8 @@ }, "dependencies": { "@ranuts/shared": "workspace:*", - "ranui": "0.5.1", - "ranuts": "0.5.1" + "ranui": "0.5.2", + "ranuts": "0.5.2" }, "devDependencies": { "typescript": "^6.0.3" diff --git a/packages/shared/package.json b/packages/shared/package.json index aafa3966..c797360c 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -38,7 +38,7 @@ "prepare": "tsc -p tsconfig.json" }, "dependencies": { - "ranuts": "0.5.1" + "ranuts": "0.5.2" }, "devDependencies": { "typescript": "^6.0.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1c856aa..3f42cb3d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - dompurify: 3.4.16 + dompurify: 3.4.17 katex: 0.18.2 source-map-js: 1.2.2 undici: 8.10.2 @@ -37,11 +37,11 @@ importers: specifier: 5.4.624 version: 5.4.624 ranui: - specifier: 0.5.1 - version: 0.5.1 + specifier: 0.5.2 + version: 0.5.2 ranuts: - specifier: 0.5.1 - version: 0.5.1 + specifier: 0.5.2 + version: 0.5.2 devDependencies: '@playwright/test': specifier: ^1.64.0 @@ -108,11 +108,11 @@ importers: specifier: 16.4.2 version: 16.4.2 ranui: - specifier: 0.5.1 - version: 0.5.1 + specifier: 0.5.2 + version: 0.5.2 ranuts: - specifier: 0.5.1 - version: 0.5.1 + specifier: 0.5.2 + version: 0.5.2 devDependencies: typescript: specifier: ^6.0.3 @@ -124,11 +124,11 @@ importers: specifier: workspace:* version: link:../shared ranui: - specifier: 0.5.1 - version: 0.5.1 + specifier: 0.5.2 + version: 0.5.2 ranuts: - specifier: 0.5.1 - version: 0.5.1 + specifier: 0.5.2 + version: 0.5.2 devDependencies: typescript: specifier: ^6.0.3 @@ -137,8 +137,8 @@ importers: packages/shared: dependencies: ranuts: - specifier: 0.5.1 - version: 0.5.1 + specifier: 0.5.2 + version: 0.5.2 devDependencies: typescript: specifier: ^6.0.3 @@ -146,8 +146,8 @@ importers: packages: - '@alixex/ranview@0.2.1': - resolution: {integrity: sha512-cAzNX3+sXayjEg8TBWaWD7u6CoSYtAFJ2T4I7AJFOF9gCLMqnnhXr1nmcfudJERmQ1wJ3T36PtT92nRME3/SOQ==} + '@alixex/ranview@0.2.2': + resolution: {integrity: sha512-PNzlwvi44s2mN7fbUd4BaVxt4X3SGHRkHn6+90XtM0VywBQyd51xWhWurzDPodiXgDWC6xsyc8BQJRUupsi04Q==} engines: {node: '>=24.0.0'} '@anthropic-ai/sdk@0.106.0': @@ -874,8 +874,8 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - dompurify@3.4.16: - resolution: {integrity: sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ==} + dompurify@3.4.17: + resolution: {integrity: sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==} entities@8.1.0: resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==} @@ -1173,12 +1173,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - ranui@0.5.1: - resolution: {integrity: sha512-kvqSdrCbLOjfIuqiGNUv1lBl01VTLRy0UMr65mX1GLy8uSUmN5dy+DUZ3eQEgysfGnbRiO9Speni5PcC38NzuQ==} + ranui@0.5.2: + resolution: {integrity: sha512-NMmDNiggT5In+u+syj27mnsPeG7cN+nUrNo47mHbggxBdV6eDI1YNQLjV5D/ZrK8wHPL8I1jQq5EfXzk+d6JeA==} engines: {node: '>=24.0.0'} - ranuts@0.5.1: - resolution: {integrity: sha512-ohiVcoyRPouymZmzpJ/sawJ6QtZh66Lypx/n8l8Qt7y7QDGP3Y4+JWX7by+Yx7e0sEDgrz/qx6qk9rVbOEZomA==} + ranuts@0.5.2: + resolution: {integrity: sha512-Ab95R9EzviMP5MdhpkxDpOCRptA8MmKMhAJ6BqOhiqTCqE+YaDmqapDQ5POOOlIEsygJgij/UulMdC4ub4fqpw==} engines: {node: '>=24.0.0'} regex-recursion@6.0.2: @@ -1436,9 +1436,9 @@ packages: snapshots: - '@alixex/ranview@0.2.1': + '@alixex/ranview@0.2.2': dependencies: - ranuts: 0.5.1 + ranuts: 0.5.2 '@anthropic-ai/sdk@0.106.0': dependencies: @@ -1945,7 +1945,7 @@ snapshots: dependencies: dequal: 2.0.3 - dompurify@3.4.16: + dompurify@3.4.17: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -2237,17 +2237,17 @@ snapshots: punycode@2.3.1: {} - ranui@0.5.1: + ranui@0.5.2: dependencies: - '@alixex/ranview': 0.2.1 - dompurify: 3.4.16 + '@alixex/ranview': 0.2.2 + dompurify: 3.4.17 marked: 18.0.9 - ranuts: 0.5.1 + ranuts: 0.5.2 remend: 1.3.0 shiki: 4.4.3 temml: 0.13.4 - ranuts@0.5.1: + ranuts@0.5.2: dependencies: jschardet: 3.1.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 80f404ac..b933a5d4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,14 +3,14 @@ packages: minimumReleaseAgeExclude: - ranui - ranuts - - '@alixex/ranview@0.2.1' + - '@alixex/ranview@0.2.2' patchedDependencies: '@mlc-ai/web-llm@0.2.85': patches/@mlc-ai__web-llm@0.2.85.patch '@wllama/wllama@3.6.1': patches/@wllama__wllama@3.6.1.patch # Security fixes for transitive dependencies; remove when upstream ranges # select patched releases (KaTeX currently remains on Mermaid's 0.16 range). overrides: - dompurify: 3.4.16 + dompurify: 3.4.17 katex: 0.18.2 source-map-js: 1.2.2 undici: 8.10.2 diff --git a/public/ran-tokens.css b/public/ran-tokens.css index 941cc89e..79ca5adc 100644 --- a/public/ran-tokens.css +++ b/public/ran-tokens.css @@ -1,2 +1,2 @@ /* VENDORED — DO NOT EDIT. Generated from ranui/dist/ranui.css (the ranui design-token :root layer) by bin/build.sh on every build, so it never drifts from the installed ranui version. Landing pages this so the --ran-* tokens resolve at first paint; static pages under public/ have no bundler and cannot import from node_modules. Source of truth: ranui in https://github.com/chaxus/ran (package: ranui) — change tokens there, not here. */ -:root{--ran-background-100: #ffffff;--ran-background-200: #fafafa;--ran-gray-100: #f2f2f2;--ran-gray-200: #ebebeb;--ran-gray-300: #e6e6e6;--ran-gray-400: #eaeaea;--ran-gray-500: #c9c9c9;--ran-gray-600: #a8a8a8;--ran-gray-700: #8f8f8f;--ran-gray-800: #7d7d7d;--ran-gray-900: #4d4d4d;--ran-gray-1000: #171717;--ran-gray-alpha-100: #0000000d;--ran-gray-alpha-200: #00000015;--ran-gray-alpha-300: #0000001a;--ran-gray-alpha-400: #00000014;--ran-gray-alpha-500: #00000036;--ran-gray-alpha-600: #0000003d;--ran-gray-alpha-700: #00000070;--ran-gray-alpha-800: #00000082;--ran-gray-alpha-900: #000000b3;--ran-gray-alpha-1000: #000000e8;--ran-blue-100: #f0f7ff;--ran-blue-200: #e9f4ff;--ran-blue-300: #dfefff;--ran-blue-400: #cae7ff;--ran-blue-500: #94ccff;--ran-blue-600: #48aeff;--ran-blue-700: #006bff;--ran-blue-800: #0059ec;--ran-blue-900: #005ff2;--ran-blue-1000: #002359;--ran-red-100: #ffeeef;--ran-red-200: #ffe8ea;--ran-red-300: #ffe3e4;--ran-red-400: #ffd7d6;--ran-red-500: #ffb1b3;--ran-red-600: #ff676d;--ran-red-700: #fc0035;--ran-red-800: #ea001d;--ran-red-900: #d8001b;--ran-red-1000: #47000c;--ran-amber-100: #fff6de;--ran-amber-200: #fff4cf;--ran-amber-300: #fff1c1;--ran-amber-400: #ffdc73;--ran-amber-500: #ffc543;--ran-amber-600: #ffa600;--ran-amber-700: #ffae00;--ran-amber-800: #ff9300;--ran-amber-900: #aa4d00;--ran-amber-1000: #561900;--ran-green-100: #ecfdec;--ran-green-200: #e5fce7;--ran-green-300: #d3fad1;--ran-green-400: #b9f5bc;--ran-green-500: #82eb8d;--ran-green-600: #4ce15e;--ran-green-700: #28a948;--ran-green-800: #279141;--ran-green-900: #107d32;--ran-green-1000: #003a00;--ran-color-primary: var(--ran-gray-1000);--ran-color-primary-hover: #383838;--ran-color-primary-active: #4d4d4d;--ran-color-primary-text: var(--ran-background-100);--ran-color-success: var(--ran-green-700);--ran-color-warning: var(--ran-amber-700);--ran-color-danger: var(--ran-red-700);--ran-color-warning-foreground: var(--ran-amber-900);--ran-color-danger-foreground: var(--ran-red-900);--ran-color-bg: var(--ran-background-100);--ran-color-bg-subtle: var(--ran-background-200);--ran-color-bg-elevated: var(--ran-background-100);--ran-color-bg-muted: var(--ran-gray-100);--ran-color-bg-hover: var(--ran-gray-200);--ran-color-bg-active: var(--ran-gray-300);--ran-color-text: var(--ran-gray-1000);--ran-color-text-secondary: var(--ran-gray-900);--ran-color-text-disabled: var(--ran-gray-700);--ran-color-border: var(--ran-gray-400);--ran-color-border-secondary: var(--ran-gray-300);--ran-color-border-hover: var(--ran-gray-500);--ran-color-border-active: var(--ran-gray-600);--ran-color-link: var(--ran-blue-700);--ran-font-family: "Geist", "Geist Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--ran-font-mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--ran-font-size: 14px;--ran-line-height: 1.5715;--ran-text-heading-weight: 600;--ran-text-heading-tracking: -.03em;--ran-text-heading-1: 32px;--ran-text-heading-2: 24px;--ran-text-heading-3: 20px;--ran-text-heading-4: 16px;--ran-text-label-weight: 500;--ran-text-label-1: 14px;--ran-text-label-2: 13px;--ran-text-label-3: 12px;--ran-text-copy-weight: 400;--ran-text-copy-1: 16px;--ran-text-copy-2: 14px;--ran-text-button-size: 14px;--ran-text-button-weight: 500;--ran-text-button-line-height: 1;--ran-text-mono-weight-regular: 400;--ran-text-mono-weight-medium: 500;--ran-radius-sm: 6px;--ran-radius-md: 12px;--ran-radius-lg: 16px;--ran-radius-full: 9999px;--ran-space-1: 4px;--ran-space-2: 8px;--ran-space-3: 12px;--ran-space-4: 16px;--ran-space-6: 24px;--ran-space-8: 32px;--ran-space-10: 40px;--ran-space-16: 64px;--ran-space-24: 96px;--ran-size-1: 16px;--ran-size-2: 18px;--ran-size-3: 20px;--ran-size-4: 24px;--ran-size-5: 28px;--ran-size-6: 30px;--ran-size-7: 32px;--ran-shadow-elevated: 0 1px 2px rgba(0, 0, 0, .04), 0 2px 4px -2px rgba(0, 0, 0, .05);--ran-shadow-menu: 0 2px 4px rgba(0, 0, 0, .05), 0 8px 24px -6px rgba(0, 0, 0, .14);--ran-shadow-modal: 0 4px 12px rgba(0, 0, 0, .08), 0 20px 48px -12px rgba(0, 0, 0, .22);--ran-z-modal: 1000;--ran-z-dropdown: 1100;--ran-z-message: 1200;--ran-focus-ring: 0 0 0 2px var(--ran-background-100), 0 0 0 4px var(--ran-blue-700);--ran-focus-ring-inverse-color: #fff;--ran-media-background: #000;--ran-motion-duration-fast: .15s;--ran-motion-duration-base: .2s;--ran-motion-duration-slow: .35s;--ran-motion-ease-standard: cubic-bezier(.645, .045, .355, 1);--ran-motion-ease-snappy: cubic-bezier(.33, 0, .15, 1);--ran-motion-ease-spring: cubic-bezier(.34, 1.26, .5, 1);--ran-motion-ease-bouncy: cubic-bezier(.34, 1.56, .64, 1);--ran-motion-ease-smooth: cubic-bezier(.4, 0, .2, 1);--ran-skin-border-width: 1px;--ran-skin-border-style: solid;--ran-skin-raised-shadow: var(--ran-shadow-elevated);--ran-skin-font-family: var(--ran-font-family);--ran-skin-border-image-width: 4px}@media(prefers-color-scheme:dark){:root:not([data-ran-theme=light]):not([theme=light]):not(.light){--ran-background-100: #000000;--ran-background-200: #000000;--ran-gray-100: #1a1a1a;--ran-gray-200: #1f1f1f;--ran-gray-300: #292929;--ran-gray-400: #2e2e2e;--ran-gray-500: #454545;--ran-gray-600: #878787;--ran-gray-700: #8f8f8f;--ran-gray-800: #7d7d7d;--ran-gray-900: #a0a0a0;--ran-gray-1000: #ededed;--ran-gray-alpha-100: #ffffff12;--ran-gray-alpha-200: #ffffff17;--ran-gray-alpha-300: #ffffff21;--ran-gray-alpha-400: #ffffff24;--ran-gray-alpha-500: #ffffff3d;--ran-gray-alpha-600: #ffffff82;--ran-gray-alpha-700: #ffffff8a;--ran-gray-alpha-800: #ffffff78;--ran-gray-alpha-900: #ffffff9c;--ran-gray-alpha-1000: #ffffffeb;--ran-blue-100: #06193a;--ran-blue-200: #022248;--ran-blue-300: #002f62;--ran-blue-400: #003674;--ran-blue-500: #00418b;--ran-blue-600: #0090ff;--ran-blue-700: #006efe;--ran-blue-800: #005be7;--ran-blue-900: #47a8ff;--ran-blue-1000: #eaf6ff;--ran-red-100: #330a11;--ran-red-200: #440d13;--ran-red-300: #5d0e17;--ran-red-400: #6f101b;--ran-red-500: #88151f;--ran-red-600: #f32e40;--ran-red-700: #f13242;--ran-red-800: #e2162a;--ran-red-900: #ff565f;--ran-red-1000: #ffe9ed;--ran-amber-100: #2a1700;--ran-amber-200: #361900;--ran-amber-300: #502800;--ran-amber-400: #5b3000;--ran-amber-500: #703e00;--ran-amber-600: #ed9a00;--ran-amber-700: #ffae00;--ran-amber-800: #ff9300;--ran-amber-900: #ff9300;--ran-amber-1000: #fff3d5;--ran-green-100: #002608;--ran-green-200: #00320b;--ran-green-300: #003a0e;--ran-green-400: #004615;--ran-green-500: #006717;--ran-green-600: #00952d;--ran-green-700: #00ac3a;--ran-green-800: #009432;--ran-green-900: #00ca50;--ran-green-1000: #d8ffe4;--ran-color-bg-elevated: var(--ran-gray-100);--ran-color-primary-hover: #cccccc;--ran-color-primary-active: #b3b3b3;--ran-shadow-elevated: 0 1px 2px rgba(0, 0, 0, .16);--ran-shadow-menu: 0 1px 1px rgba(0, 0, 0, .2), 0 4px 8px -4px rgba(0, 0, 0, .4), 0 16px 24px -8px rgba(0, 0, 0, .5);--ran-shadow-modal: 0 1px 1px rgba(0, 0, 0, .2), 0 8px 16px -4px rgba(0, 0, 0, .4), 0 24px 32px -8px rgba(0, 0, 0, .5)}}:root[data-ran-theme=dark],:root[theme=dark],:root.dark{--ran-background-100: #000000;--ran-background-200: #000000;--ran-gray-100: #1a1a1a;--ran-gray-200: #1f1f1f;--ran-gray-300: #292929;--ran-gray-400: #2e2e2e;--ran-gray-500: #454545;--ran-gray-600: #878787;--ran-gray-700: #8f8f8f;--ran-gray-800: #7d7d7d;--ran-gray-900: #a0a0a0;--ran-gray-1000: #ededed;--ran-gray-alpha-100: #ffffff12;--ran-gray-alpha-200: #ffffff17;--ran-gray-alpha-300: #ffffff21;--ran-gray-alpha-400: #ffffff24;--ran-gray-alpha-500: #ffffff3d;--ran-gray-alpha-600: #ffffff82;--ran-gray-alpha-700: #ffffff8a;--ran-gray-alpha-800: #ffffff78;--ran-gray-alpha-900: #ffffff9c;--ran-gray-alpha-1000: #ffffffeb;--ran-blue-100: #06193a;--ran-blue-200: #022248;--ran-blue-300: #002f62;--ran-blue-400: #003674;--ran-blue-500: #00418b;--ran-blue-600: #0090ff;--ran-blue-700: #006efe;--ran-blue-800: #005be7;--ran-blue-900: #47a8ff;--ran-blue-1000: #eaf6ff;--ran-red-100: #330a11;--ran-red-200: #440d13;--ran-red-300: #5d0e17;--ran-red-400: #6f101b;--ran-red-500: #88151f;--ran-red-600: #f32e40;--ran-red-700: #f13242;--ran-red-800: #e2162a;--ran-red-900: #ff565f;--ran-red-1000: #ffe9ed;--ran-amber-100: #2a1700;--ran-amber-200: #361900;--ran-amber-300: #502800;--ran-amber-400: #5b3000;--ran-amber-500: #703e00;--ran-amber-600: #ed9a00;--ran-amber-700: #ffae00;--ran-amber-800: #ff9300;--ran-amber-900: #ff9300;--ran-amber-1000: #fff3d5;--ran-green-100: #002608;--ran-green-200: #00320b;--ran-green-300: #003a0e;--ran-green-400: #004615;--ran-green-500: #006717;--ran-green-600: #00952d;--ran-green-700: #00ac3a;--ran-green-800: #009432;--ran-green-900: #00ca50;--ran-green-1000: #d8ffe4;--ran-color-bg-elevated: var(--ran-gray-100);--ran-color-primary-hover: #cccccc;--ran-color-primary-active: #b3b3b3;--ran-shadow-elevated: 0 1px 2px rgba(0, 0, 0, .16);--ran-shadow-menu: 0 1px 1px rgba(0, 0, 0, .2), 0 4px 8px -4px rgba(0, 0, 0, .4), 0 16px 24px -8px rgba(0, 0, 0, .5);--ran-shadow-modal: 0 1px 1px rgba(0, 0, 0, .2), 0 8px 16px -4px rgba(0, 0, 0, .4), 0 24px 32px -8px rgba(0, 0, 0, .5)} +:root{--ran-background-100: #ffffff;--ran-background-200: #fafafa;--ran-gray-100: #f2f2f2;--ran-gray-200: #ebebeb;--ran-gray-300: #e6e6e6;--ran-gray-400: #eaeaea;--ran-gray-500: #c9c9c9;--ran-gray-600: #a8a8a8;--ran-gray-700: #8f8f8f;--ran-gray-800: #7d7d7d;--ran-gray-900: #4d4d4d;--ran-gray-1000: #171717;--ran-gray-alpha-100: #0000000d;--ran-gray-alpha-200: #00000015;--ran-gray-alpha-300: #0000001a;--ran-gray-alpha-400: #00000014;--ran-gray-alpha-500: #00000036;--ran-gray-alpha-600: #0000003d;--ran-gray-alpha-700: #00000070;--ran-gray-alpha-800: #00000082;--ran-gray-alpha-900: #000000b3;--ran-gray-alpha-1000: #000000e8;--ran-blue-100: #f0f7ff;--ran-blue-200: #e9f4ff;--ran-blue-300: #dfefff;--ran-blue-400: #cae7ff;--ran-blue-500: #94ccff;--ran-blue-600: #48aeff;--ran-blue-700: #006bff;--ran-blue-800: #0059ec;--ran-blue-900: #005ff2;--ran-blue-1000: #002359;--ran-red-100: #ffeeef;--ran-red-200: #ffe8ea;--ran-red-300: #ffe3e4;--ran-red-400: #ffd7d6;--ran-red-500: #ffb1b3;--ran-red-600: #ff676d;--ran-red-700: #fc0035;--ran-red-800: #ea001d;--ran-red-900: #d8001b;--ran-red-1000: #47000c;--ran-amber-100: #fff6de;--ran-amber-200: #fff4cf;--ran-amber-300: #fff1c1;--ran-amber-400: #ffdc73;--ran-amber-500: #ffc543;--ran-amber-600: #ffa600;--ran-amber-700: #ffae00;--ran-amber-800: #ff9300;--ran-amber-900: #aa4d00;--ran-amber-1000: #561900;--ran-green-100: #ecfdec;--ran-green-200: #e5fce7;--ran-green-300: #d3fad1;--ran-green-400: #b9f5bc;--ran-green-500: #82eb8d;--ran-green-600: #4ce15e;--ran-green-700: #28a948;--ran-green-800: #279141;--ran-green-900: #107d32;--ran-green-1000: #003a00;--ran-color-primary: var(--ran-gray-1000);--ran-color-primary-hover: #383838;--ran-color-primary-active: #4d4d4d;--ran-color-primary-text: var(--ran-background-100);--ran-color-success: var(--ran-green-700);--ran-color-warning: var(--ran-amber-700);--ran-color-danger: var(--ran-red-700);--ran-color-warning-foreground: var(--ran-amber-900);--ran-color-danger-foreground: var(--ran-red-900);--ran-color-bg: var(--ran-background-100);--ran-color-bg-subtle: var(--ran-background-200);--ran-color-bg-elevated: var(--ran-background-100);--ran-color-bg-muted: var(--ran-gray-100);--ran-color-bg-hover: var(--ran-gray-200);--ran-color-bg-active: var(--ran-gray-300);--ran-color-text: var(--ran-gray-1000);--ran-color-text-secondary: var(--ran-gray-900);--ran-color-text-disabled: var(--ran-gray-700);--ran-color-border: var(--ran-gray-400);--ran-color-border-secondary: var(--ran-gray-300);--ran-color-border-hover: var(--ran-gray-500);--ran-color-border-active: var(--ran-gray-600);--ran-color-link: var(--ran-blue-700);--ran-font-family: "Geist", "Geist Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--ran-font-mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--ran-font-size: 14px;--ran-line-height: 1.5715;--ran-text-heading-weight: 600;--ran-text-heading-tracking: -.03em;--ran-text-heading-1: 32px;--ran-text-heading-2: 24px;--ran-text-heading-3: 20px;--ran-text-heading-4: 16px;--ran-text-label-weight: 500;--ran-text-label-1: 14px;--ran-text-label-2: 13px;--ran-text-label-3: 12px;--ran-text-copy-weight: 400;--ran-text-copy-1: 16px;--ran-text-copy-2: 14px;--ran-text-button-size: 14px;--ran-text-button-weight: 500;--ran-text-button-line-height: 1;--ran-text-mono-weight-regular: 400;--ran-text-mono-weight-medium: 500;--ran-radius-sm: 6px;--ran-radius-md: 12px;--ran-radius-lg: 16px;--ran-radius-full: 9999px;--ran-space-1: 4px;--ran-space-2: 8px;--ran-space-3: 12px;--ran-space-4: 16px;--ran-space-6: 24px;--ran-space-8: 32px;--ran-space-10: 40px;--ran-space-16: 64px;--ran-space-24: 96px;--ran-size-1: 16px;--ran-size-2: 18px;--ran-size-3: 20px;--ran-size-4: 24px;--ran-size-5: 28px;--ran-size-6: 30px;--ran-size-7: 32px;--ran-shadow-elevated: 0 1px 2px rgba(0, 0, 0, .04), 0 2px 4px -2px rgba(0, 0, 0, .05);--ran-shadow-menu: 0 2px 4px rgba(0, 0, 0, .05), 0 8px 24px -6px rgba(0, 0, 0, .14);--ran-shadow-modal: 0 4px 12px rgba(0, 0, 0, .08), 0 20px 48px -12px rgba(0, 0, 0, .22);--ran-z-modal: 1000;--ran-z-dropdown: 1100;--ran-z-message: 1200;--ran-focus-ring: 0 0 0 2px var(--ran-background-100), 0 0 0 4px var(--ran-blue-700);--ran-focus-ring-inverse-color: #fff;--ran-media-background: #000;--ran-motion-duration-fast: .15s;--ran-motion-duration-base: .2s;--ran-motion-duration-slow: .35s;--ran-motion-ease-standard: cubic-bezier(.645, .045, .355, 1);--ran-motion-ease-snappy: cubic-bezier(.33, 0, .15, 1);--ran-motion-ease-spring: cubic-bezier(.34, 1.26, .5, 1);--ran-motion-ease-bouncy: cubic-bezier(.34, 1.56, .64, 1);--ran-motion-ease-smooth: cubic-bezier(.4, 0, .2, 1);--ran-skin-border-width: 1px;--ran-skin-border-style: solid;--ran-skin-raised-shadow: var(--ran-shadow-elevated);--ran-skin-font-family: var(--ran-font-family);--ran-skin-border-image-width: 4px}@media(prefers-color-scheme:dark){:root:not([data-ran-theme=light]):not([theme=light]):not(.light){--ran-background-100: #000000;--ran-background-200: #000000;--ran-gray-100: #1a1a1a;--ran-gray-200: #1f1f1f;--ran-gray-300: #292929;--ran-gray-400: #2e2e2e;--ran-gray-500: #454545;--ran-gray-600: #878787;--ran-gray-700: #8f8f8f;--ran-gray-800: #7d7d7d;--ran-gray-900: #a0a0a0;--ran-gray-1000: #ededed;--ran-gray-alpha-100: #ffffff12;--ran-gray-alpha-200: #ffffff17;--ran-gray-alpha-300: #ffffff21;--ran-gray-alpha-400: #ffffff24;--ran-gray-alpha-500: #ffffff3d;--ran-gray-alpha-600: #ffffff82;--ran-gray-alpha-700: #ffffff8a;--ran-gray-alpha-800: #ffffff78;--ran-gray-alpha-900: #ffffff9c;--ran-gray-alpha-1000: #ffffffeb;--ran-blue-100: #06193a;--ran-blue-200: #022248;--ran-blue-300: #002f62;--ran-blue-400: #003674;--ran-blue-500: #00418b;--ran-blue-600: #0090ff;--ran-blue-700: #006efe;--ran-blue-800: #005be7;--ran-blue-900: #47a8ff;--ran-blue-1000: #eaf6ff;--ran-red-100: #330a11;--ran-red-200: #440d13;--ran-red-300: #5d0e17;--ran-red-400: #6f101b;--ran-red-500: #88151f;--ran-red-600: #f32e40;--ran-red-700: #f13242;--ran-red-800: #e2162a;--ran-red-900: #ff565f;--ran-red-1000: #ffe9ed;--ran-amber-100: #2a1700;--ran-amber-200: #361900;--ran-amber-300: #502800;--ran-amber-400: #5b3000;--ran-amber-500: #703e00;--ran-amber-600: #ed9a00;--ran-amber-700: #ffae00;--ran-amber-800: #ff9300;--ran-amber-900: #ff9300;--ran-amber-1000: #fff3d5;--ran-green-100: #002608;--ran-green-200: #00320b;--ran-green-300: #003a0e;--ran-green-400: #004615;--ran-green-500: #006717;--ran-green-600: #00952d;--ran-green-700: #00ac3a;--ran-green-800: #009432;--ran-green-900: #00ca50;--ran-green-1000: #d8ffe4;--ran-color-bg-elevated: var(--ran-gray-100);--ran-color-primary-hover: #cccccc;--ran-color-primary-active: #b3b3b3;--ran-shadow-elevated: 0 1px 2px rgba(0, 0, 0, .16);--ran-shadow-menu: 0 1px 1px rgba(0, 0, 0, .2), 0 4px 8px -4px rgba(0, 0, 0, .4), 0 16px 24px -8px rgba(0, 0, 0, .5);--ran-shadow-modal: 0 1px 1px rgba(0, 0, 0, .2), 0 8px 16px -4px rgba(0, 0, 0, .4), 0 24px 32px -8px rgba(0, 0, 0, .5)}}:root[data-ran-theme=dark],:root[theme=dark],:root.dark{--ran-background-100: #000000;--ran-background-200: #000000;--ran-gray-100: #1a1a1a;--ran-gray-200: #1f1f1f;--ran-gray-300: #292929;--ran-gray-400: #2e2e2e;--ran-gray-500: #454545;--ran-gray-600: #878787;--ran-gray-700: #8f8f8f;--ran-gray-800: #7d7d7d;--ran-gray-900: #a0a0a0;--ran-gray-1000: #ededed;--ran-gray-alpha-100: #ffffff12;--ran-gray-alpha-200: #ffffff17;--ran-gray-alpha-300: #ffffff21;--ran-gray-alpha-400: #ffffff24;--ran-gray-alpha-500: #ffffff3d;--ran-gray-alpha-600: #ffffff82;--ran-gray-alpha-700: #ffffff8a;--ran-gray-alpha-800: #ffffff78;--ran-gray-alpha-900: #ffffff9c;--ran-gray-alpha-1000: #ffffffeb;--ran-blue-100: #06193a;--ran-blue-200: #022248;--ran-blue-300: #002f62;--ran-blue-400: #003674;--ran-blue-500: #00418b;--ran-blue-600: #0090ff;--ran-blue-700: #006efe;--ran-blue-800: #005be7;--ran-blue-900: #47a8ff;--ran-blue-1000: #eaf6ff;--ran-red-100: #330a11;--ran-red-200: #440d13;--ran-red-300: #5d0e17;--ran-red-400: #6f101b;--ran-red-500: #88151f;--ran-red-600: #f32e40;--ran-red-700: #f13242;--ran-red-800: #e2162a;--ran-red-900: #ff565f;--ran-red-1000: #ffe9ed;--ran-amber-100: #2a1700;--ran-amber-200: #361900;--ran-amber-300: #502800;--ran-amber-400: #5b3000;--ran-amber-500: #703e00;--ran-amber-600: #ed9a00;--ran-amber-700: #ffae00;--ran-amber-800: #ff9300;--ran-amber-900: #ff9300;--ran-amber-1000: #fff3d5;--ran-green-100: #002608;--ran-green-200: #00320b;--ran-green-300: #003a0e;--ran-green-400: #004615;--ran-green-500: #006717;--ran-green-600: #00952d;--ran-green-700: #00ac3a;--ran-green-800: #009432;--ran-green-900: #00ca50;--ran-green-1000: #d8ffe4;--ran-color-bg-elevated: var(--ran-gray-100);--ran-color-primary-hover: #cccccc;--ran-color-primary-active: #b3b3b3;--ran-shadow-elevated: 0 1px 2px rgba(0, 0, 0, .16);--ran-shadow-menu: 0 1px 1px rgba(0, 0, 0, .2), 0 4px 8px -4px rgba(0, 0, 0, .4), 0 16px 24px -8px rgba(0, 0, 0, .5);--ran-shadow-modal: 0 1px 1px rgba(0, 0, 0, .2), 0 8px 16px -4px rgba(0, 0, 0, .4), 0 24px 32px -8px rgba(0, 0, 0, .5)}r-content:not(:defined),r-popover:not(:defined)>r-content,r-select:not(:defined)>r-option,r-modal:not(:defined),r-route:not(:defined),r-reasoning:not(:defined),r-markdown:not(:defined),r-math:not(:defined),r-mermaid:not(:defined){display:none}r-tabs:not(:defined)>r-tab:not(:first-of-type){display:none}r-scratch:not(:defined){visibility:hidden} From 5d81d806e48b00fa177e279118e9adbe1bd72e23 Mon Sep 17 00:00:00 2001 From: chaxus Date: Sat, 24 Oct 2026 20:22:20 +0800 Subject: [PATCH 2/3] test(e2e): keep the language menu closed before r-popover is defined Co-Authored-By: Claude Opus 5.5 --- test/e2e/lang-menu-before-upgrade.spec.ts | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/e2e/lang-menu-before-upgrade.spec.ts diff --git a/test/e2e/lang-menu-before-upgrade.spec.ts b/test/e2e/lang-menu-before-upgrade.spec.ts new file mode 100644 index 00000000..d3a0a238 --- /dev/null +++ b/test/e2e/lang-menu-before-upgrade.spec.ts @@ -0,0 +1,28 @@ +import { expect, test } from './lib/l0'; + +// The language menu is an whose seven links are written straight +// into the page. Until the element is defined (a deferred IIFE on the static +// pages, the Vite bundle on /history) the browser lays those links out in flow +// unless ranui.css (vendored as /ran-tokens.css) hides them; the header used to +// grow from 38px to ~300px and snap back. Withhold every script that could +// define it and check the menu stays a single trigger. +test.use({ serviceWorkers: 'block' }); + +for (const path of ['/', '/zh-CN/', '/help', '/history']) { + test(`${path}: the language menu does not expand before r-popover is defined`, async ({ page }) => { + await page.route('**/ranui-iife/*.iife.js', (route) => route.abort()); + await page.route('**/assets/*.js', (route) => route.abort()); + await page.goto(path, { waitUntil: 'load' }); + + const menu = page.locator('.lang-menu').first(); + await expect(menu).toBeAttached(); + const state = await menu.evaluate((host) => ({ + defined: Boolean(customElements.get('r-popover')), + height: host.getBoundingClientRect().height, + listHeight: host.querySelector('.lang-list')?.getBoundingClientRect().height ?? 0, + })); + expect(state.defined).toBe(false); + expect(state.listHeight).toBe(0); + expect(state.height).toBeLessThan(48); + }); +} From 840a6bc9a7695e5d8fd8f430500cf50d4d9a3c16 Mon Sep 17 00:00:00 2001 From: chaxus Date: Sat, 24 Oct 2026 20:22:21 +0800 Subject: [PATCH 3/3] docs(deps): record the ranui 0.5.2 upgrade and the language menu flash Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 4 ++ ...6-10-24-ranui-0-5-2-language-menu-flash.md | 65 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 docs/explorations/2026-10-24-ranui-0-5-2-language-menu-flash.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 64475e3a..0d08b067 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ notes. Entries describe what users experience, not internal refactors. ### Fixed +- The language menu no longer flashes open and stretches the page header while + the page is still loading. +- Select lists and the dictation privacy note open above the AI assistant panel + instead of behind it. - Local references attached while saved chat history is loading remain attached when the conversation finishes restoring. - Reloading after a completed save restores the saved document instead of an diff --git a/docs/explorations/2026-10-24-ranui-0-5-2-language-menu-flash.md b/docs/explorations/2026-10-24-ranui-0-5-2-language-menu-flash.md new file mode 100644 index 00000000..a7ceab13 --- /dev/null +++ b/docs/explorations/2026-10-24-ranui-0-5-2-language-menu-flash.md @@ -0,0 +1,65 @@ +# ranui 0.5.2: the language menu no longer flashes open + +## Symptom + +On the first load of `/`, the localized landing pages, the content pages and +`/history`, the language menu briefly showed all seven languages in a column. +The header stretched from 38 px to about 300 px, then snapped back. + +## Cause + +The menu is an `` whose links are written straight into the HTML +(`bin/pages/chrome.mjs`, `index.html`). Until the element is defined, the +browser lays those links out in flow. On the static pages the definition comes +from a deferred IIFE, and on `/history` from the Vite bundle. + +`home.css` had `:not(:defined)` fallbacks for `r-button` and `r-theme-switch`, +but nothing hid `r-content`. Measured on production with the defining scripts +blocked, the menu host was 215–223 × 246–266 px on `/`, `/zh-CN/`, `/help` and +`/history`. + +## Fix: in ranui, not here + +The fix was made in the component library (chaxus/ran#444, released as ranui +0.5.2). `ranui.css` now ships `:not(:defined)` rules for every component whose +light-DOM children must stay hidden until the element upgrades: r-popover's +`r-content`, r-select's options, r-tabs, r-modal, r-reasoning, r-route, +r-markdown, r-math, r-mermaid and r-scratch. + +This site vendors that sheet as `public/ran-tokens.css`. `bin/build.sh` +re-syncs it on every build, and every page links it in `` before first +paint. Upgrading ranui is therefore the whole fix; no site CSS was added. + +ranui also documents `