Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
bb93fea
fix: stop choppy screen resize when switching modes
cursoragent Jul 24, 2026
54d45f6
test: align therapy-compass wiring with pathname mode-home gate
cursoragent Jul 24, 2026
5b7b034
docs(ledger): record mode-switch lag same-class bug hunt
cursoragent Jul 25, 2026
b948439
fix: close same-class mode-switch layout thrash bugs
cursoragent Jul 25, 2026
a32c1a2
docs(ledger): record mode-switch thrash review fixes
cursoragent Jul 25, 2026
775d15a
fix: satisfy lint for mode-switch scroll and portal cleanup
cursoragent Jul 25, 2026
0ef62ff
docs(ledger): record mode-switch thrash lint closeout
cursoragent Jul 25, 2026
68228c0
merge origin/main into cursor/fix-mode-switch-lag-22f6
BigSimmo Jul 25, 2026
113de41
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 25, 2026
7e80c2b
docs(ledger): record frontend-architecture loading/nav review
cursoragent Jul 25, 2026
9c5237f
merge origin/cursor/fix-mode-switch-lag-22f6 (main sync)
cursoragent Jul 25, 2026
876d7ec
fix: reduce mode/page loading blanking and layout rework
cursoragent Jul 25, 2026
c64a2f0
docs(ledger): record parallel loading behaviour review fixes
cursoragent Jul 25, 2026
905b7a5
refactor: extract sidebar transition hook and private-scope URL helper
cursoragent Jul 25, 2026
7bceebf
test: allow DocumentViewer identity-only remount key
cursoragent Jul 25, 2026
ccbd0aa
merge: integrate origin/main into mode-switch lag branch
cursoragent Jul 26, 2026
39cbdb8
Merge remote-tracking branch 'origin/main' into cursor/fix-mode-switc…
cursoragent Jul 26, 2026
21c8694
test: align chrome contracts with pathname reset and gated padding
cursoragent Jul 26, 2026
cff2d31
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 26, 2026
b1a9578
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 26, 2026
141c940
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 26, 2026
8206296
merge: integrate origin/main; keep portal keep-alive without hydratio…
cursoragent Jul 26, 2026
61013b5
Merge branch 'cursor/fix-mode-switch-lag-22f6' of https://github.com/…
cursoragent Jul 26, 2026
c1632db
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 26, 2026
c9f04e5
fix: clear CI hydration and phone-scroll failures
cursoragent Jul 26, 2026
965b821
style: prettier-format portal ready-gate files
cursoragent Jul 26, 2026
e4b3780
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 26, 2026
9ad4ec2
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 26, 2026
a28d95d
Merge branch 'main' into cursor/fix-mode-switch-lag-22f6
github-actions[bot] Jul 26, 2026
deeaa6c
fix: keep document searches dashboard-owned and animate reserve reveal
BigSimmo Jul 26, 2026
c5f31ed
Merge remote-tracking branch 'origin/cursor/fix-mode-switch-lag-22f6'…
BigSimmo Jul 26, 2026
11cab0a
fix: stop duplicate page-root testids from searchParams Suspense
cursoragent Jul 26, 2026
6635cd2
style: prettier format DocumentViewer reserve-transition import
BigSimmo Jul 26, 2026
af4908b
merge: integrate remote Suspense standalone paths with documents-sear…
BigSimmo Jul 26, 2026
e963e48
docs: record babysit sweep ledger rows for #1241/#1248/#1254/#1257/#1…
BigSimmo Jul 26, 2026
d193f78
refactor: extract DocumentViewer/Dashboard helpers under budgets
cursoragent Jul 26, 2026
08e9a7b
test: align desktop page-slot contract with extracted helper
cursoragent Jul 26, 2026
7250d6d
fix: satisfy hooks lint for searchParams Suspense bridge
cursoragent Jul 26, 2026
a3f50f4
Merge remote-tracking branch 'origin/main' into cursor/fix-mode-switc…
cursoragent Jul 26, 2026
ec552fb
fix: seed standalone submitted search params
cursoragent Jul 26, 2026
28335e5
test: stabilize phone-scroll and presentation page assertions
cursoragent Jul 26, 2026
1dfda6c
fix: narrow submitted search param seeding
cursoragent Jul 26, 2026
83419c9
Merge remote-tracking branch 'origin/cursor/fix-mode-switch-lag-22f6'…
cursoragent Jul 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/branch-review-ledger.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions docs/process-hardening.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ passes `p_worker_id`. Ordered apply steps, R17 manual `CONCURRENTLY` index, and
- `GlobalMockupSearchShell` (aka `GlobalSearchShell`, used by the `forms`/`services`/`favourites`/`medications` layouts) wrapped `GlobalMockupSearchShellClient` in a `<Suspense>` whose **fallback also rendered `props.children` inside `#main-content`** — the same subtree the client body renders. Because `useSearchParams()` forces that boundary to the fallback on the server, the page subtree was emitted twice and both copies could persist, producing duplicate `id="main-content"` and duplicate `data-testid` on every shell page. It surfaced as `ui-smoke.spec.ts:1103` failing with a strict-mode violation (two `data-testid="acamprosate-medication-page"` `<main>` elements on `/medications/acamprosate`).
- Fix: the Suspense fallback renders a **neutral placeholder only** — never `props.children`. Rule: do not render the resolved content inside its own Suspense fallback; the fallback is a loading state, not a second copy of the page.

## useSearchParams Suspense must not wrap route children (2026-07-26)

- Removing `ClientHydrationBoundary` around standalone shell `{children}` restored mode-home RSC paint, but left route segments nested inside the shell’s `useSearchParams()` Suspense. Next streamed the page root into a hidden completion template (`<div hidden id="S:N">`) while the live shell also mounted the same `data-testid` root. Playwright’s strict `getByTestId` counts hidden nodes, so Production UI failed on `/forms`, `/favourites`, and differentials presentations under CI load even though the a11y tree showed one `main`.
- Portal ready-gating fixed React #418 (hydration) but not this duplicate-root class.
- Fix: `isAlwaysStandaloneShellPath` skips the outer searchParams Suspense for namespaced routes; standalone chrome reads params via a mount-gated `ShellSearchParamsBridge` sibling so `{children}` stay outside that boundary. Keep mode-home RSC paint; do not restore full-shell `ClientHydrationBoundary`.

## Clinical registry tables applied live (2026-07-03)

- **Migration `20260703020000_clinical_registry_records.sql` (applied live 2026-07-03 with explicit user approval)** created `public.clinical_registry_records` (owner-scoped structured Services/Forms records — 30 cols, JSONB render payloads, conservative `source_status`/`validation_status` governance columns) and the `public.clinical_registry_record_sources` join table (record ↔ verifying corpus document, FK cascade). Both are service-role-only RLS (enabled + revoked from anon/authenticated + a single `for all to service_role` policy); ownership is enforced in the API layer, matching the documents model. Verified post-apply: both tables present with correct columns, RLS enabled, 0 rows; `get_advisors(security)` returns no lints. `supabase/schema.sql` mirrors the migration and `tests/supabase-schema.test.ts` asserts the shape.
Expand Down
10 changes: 9 additions & 1 deletion docs/search-chrome-behaviour.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ This repo uses one shared search experience across the global shell, dashboard r
8. `GlobalSearchShell` uses an inner `mobile-composer-reserve-pad` so phone padding contributes to scroll height; do not move phone shell clearance back to scrollport padding without a browser proof.
9. Keep collapse-budget policy geometry-aware: an in-flow collapsing header needs enough remaining runway to absorb header + dock clearance, while a fixed overlay that only releases bottom reserve may hide when its post-collapse range retains the top reveal band plus deliberate hide intent _and_ the current offset already fits that post-collapse range (no material near-bottom clamp). Do not use synthetic page padding to make the stricter gate pass.
10. Detect reserve-transition clamps from geometry, not a wider pixel tolerance: if the scroll range shrinks and the previous offset no longer fits inside the new maximum, rebase that frame as layout feedback. Once the range stabilizes, the same upward movement must reveal normally.
11. Standalone mode-home detection (`isStandaloneModeHomePath`) is pathname-only. Do not gate hero vs dock on a React `searchMode` that can update before the router pathname lands — that one-frame mismatch animates reserve padding and reads as a choppy screen resize.
12. Phone `#main-content` / reserve-pad `padding-bottom` transitions apply while `data-reserve-transitioning="true"` (scroll-hide and reveal). Mode and route reserve flips clear that marker immediately and must snap.
13. Shared shell must reset phone scroll offset and scroll-hide state on `pathname` change so mode homes do not inherit a mid-page offset or collapsed header.
14. Hero composer portal: keep the default composer mounted until the portal host is actually attached; do not hide on `slotId` alone (mode-home remounts otherwise flash a null gap).
15. Leaving the dashboard shell for a namespaced mode (`selectSearchMode` / `crossModeSearch`) must navigate without rewriting dashboard chrome first.
16. Do not wrap mode-home `{children}` in `ClientHydrationBoundary` — that blanks RSC HTML until JS mounts. Keep hydration guards on the specific leaf that mismatches. Do not call `useSearchParams()` in an ancestor Suspense that also renders route `{children}`: that nests the page segment inside the shell’s incomplete streaming boundary and can leave a persistent hidden `S:` clone (duplicate page-root `data-testid`s). Gate always-standalone pathnames with `isAlwaysStandaloneShellPath`, and bridge search params beside the shell body via `ShellSearchParamsBridge`.
17. Standalone mode-home `loading.tsx` files must render `ModeHomeRouteLoading` (phone top-aligned). Do not reuse unrelated results/medication skeletons.
18. `ClinicalDashboard` must stay out of the shared shell’s static import graph (dynamic import) so namespaced mode routes do not parse the dashboard module.

## Scroll hide/reveal

Expand All @@ -49,7 +57,7 @@ Rules that keep this working:
- **Do not double-sticky tablet search inside an outer sticky stack.** When `wide: "sticky"` owns the tablet stack, the composer stays `relative` in that stack. A second sticky search with its own `top` overlays page controls (and blocks clicks) once the top bar collapses.
- **Desktop search is page-owned.** `desktop-page-search-composer-slot` is rendered at the top of normal shell/dashboard content and accepts the shared composer only at `min-width: 1024px`. The mode-home hero slot takes precedence. Never give the desktop page composer, its slot, or an ancestor `fixed`/`sticky` positioning.
- **Collapse-everywhere hosts still drop their own sticky search offset while the top bar is hidden.** Dashboard result composers that clear a visible top bar with `top: 4.75rem + safe-area` must switch to `top: 0` when collapse hide is active — otherwise a dead band the height of the mode bar remains above the search field.
- **Rebase the reporter on geometry switches.** Pass `resetKey` when the host changes the scrollport under it (`ClinicalDashboard` passes `searchMode`, which swaps `<main>`'s header reserve); otherwise the carried-over offset spends the first post-switch scroll on a spurious hide or reveal.
- **Rebase the reporter on geometry switches.** Pass `resetKey` when the host changes the scrollport under it (`ClinicalDashboard` passes `searchMode`, which swaps `<main>`'s header reserve); otherwise the carried-over offset spends the first post-switch scroll on a spurious hide or reveal. Shared mode-home shells should also reset on `pathname` so collapsed chrome/scroll offset does not carry across modes.
- **Do not carry composer focus into submitted result views.** Focus pins both chrome edges for keyboard safety. `GlobalSearchShell` must not pass `focus: true` with `run: true`, must gate `queryInputAutoFocus` on `!hasSubmittedModeSearch`, and must blur the dock input when the result canvas scrolls so hide-on-scroll can reclaim the header and the bottom dock (including its white safe-area rail).

Coverage: `tests/header-scroll-hide-contract.test.ts` (wiring), `tests/use-hide-on-scroll.test.ts` (decision logic), `tests/ui-chrome-scroll.spec.ts` (tablet pinned-search behaviour and desktop page-flow search plus top-bar hide/reveal), `tests/ui-phone-scroll.spec.ts` (phone scroll geometry), `tests/ui-therapy-nav-scroll.spec.ts` (Therapy section nav hide/reveal with the top bar).
Expand Down
4 changes: 3 additions & 1 deletion scripts/check-maintainability-budgets.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import { readFileSync } from "node:fs";

const budgets = new Map([
["src/components/ClinicalDashboard.tsx", 4140],
// Raised with the mode-loading pass: leave-dashboard nav guards + scroll reset.
// Net client cost still fell — GlobalSearchShell now dynamic-imports this file.
["src/components/ClinicalDashboard.tsx", 4160],
["src/lib/rag/rag.ts", 5030],
["src/components/DocumentViewer.tsx", 1734],
["supabase/functions/indexing-v3-agent/index.ts", 2191],
Expand Down
25 changes: 2 additions & 23 deletions src/app/(search-app)/differentials/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
import { Skeleton, searchPageShell, searchPageContainer } from "@/components/ui-primitives";
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return (
<div className={searchPageShell} role="status" aria-label="Loading library">
<div className={searchPageContainer}>
<div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<Skeleton className="h-10 w-full max-w-sm" />
<div className="flex gap-2">
<Skeleton className="h-9 w-20 rounded-full" />
<Skeleton className="h-9 w-20 rounded-full" />
<Skeleton className="h-9 w-20 rounded-full" />
</div>
</div>

<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
<Skeleton className="h-40 w-full rounded-xl" animationDelay="50ms" />
<Skeleton className="h-40 w-full rounded-xl" animationDelay="100ms" />
<Skeleton className="h-40 w-full rounded-xl" animationDelay="150ms" />
<Skeleton className="h-40 w-full rounded-xl" animationDelay="200ms" />
</div>
</div>
<span className="sr-only">Loading library</span>
</div>
);
return <ModeHomeRouteLoading />;
}
4 changes: 3 additions & 1 deletion src/app/(search-app)/documents/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export default async function DocumentPage({

return (
<DocumentViewer
key={`${id}:${initialPage}:${query.chunk ?? ""}`}
// Key on document identity only — page/chunk updates are handled inside
// DocumentViewer via URL sync. Remounting on every page flip reloaded the PDF.
key={id}
documentId={id}
initialPage={initialPage}
chunkId={query.chunk}
Expand Down
17 changes: 2 additions & 15 deletions src/app/(search-app)/dsm/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
import { Skeleton, searchPageShell, searchPageContainer } from "@/components/ui-primitives";
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return (
<div className={searchPageShell} role="status" aria-label="Loading DSM criteria">
<div className={searchPageContainer}>
<Skeleton className="mb-6 h-10 w-1/3 max-w-sm" />
<div className="grid gap-4">
<Skeleton className="h-32 w-full rounded-xl" animationDelay="50ms" />
<Skeleton className="h-32 w-full rounded-xl" animationDelay="100ms" />
<Skeleton className="h-32 w-full rounded-xl" animationDelay="150ms" />
<Skeleton className="h-32 w-full rounded-xl" animationDelay="200ms" />
</div>
</div>
<span className="sr-only">Loading DSM criteria</span>
</div>
);
return <ModeHomeRouteLoading />;
}
5 changes: 5 additions & 0 deletions src/app/(search-app)/factsheets/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return <ModeHomeRouteLoading />;
}
24 changes: 2 additions & 22 deletions src/app/(search-app)/favourites/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,5 @@
import { Skeleton } from "@/components/ui-primitives";
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return (
<div className="mx-auto w-full max-w-7xl px-3 py-4 sm:px-5 lg:px-6" role="status" aria-label="Loading medication">
<Skeleton className="mb-2 h-10 w-2/3 max-w-sm" />
<Skeleton className="mb-6 h-6 w-1/3 max-w-xs" />

{/* Tabs */}
<div className="mb-6 flex gap-2">
<Skeleton className="h-10 w-24 rounded-lg" />
<Skeleton className="h-10 w-24 rounded-lg" />
<Skeleton className="h-10 w-24 rounded-lg" />
</div>

{/* Grid */}
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<Skeleton className="h-48 w-full rounded-xl" animationDelay="50ms" />
<Skeleton className="h-48 w-full rounded-xl" animationDelay="100ms" />
<Skeleton className="h-48 w-full rounded-xl" animationDelay="150ms" />
</div>
<span className="sr-only">Loading medication</span>
</div>
);
return <ModeHomeRouteLoading />;
}
20 changes: 2 additions & 18 deletions src/app/(search-app)/forms/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
import { Skeleton, searchPageShell, searchPageContainer } from "@/components/ui-primitives";
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return (
<div className={searchPageShell} role="status" aria-label="Loading services">
<div className={searchPageContainer}>
<div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<Skeleton className="h-10 w-full max-w-sm" />
<Skeleton className="h-10 w-32 rounded-lg" />
</div>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<Skeleton className="h-32 w-full rounded-xl" animationDelay="50ms" />
<Skeleton className="h-32 w-full rounded-xl" animationDelay="100ms" />
<Skeleton className="h-32 w-full rounded-xl" animationDelay="150ms" />
<Skeleton className="h-32 w-full rounded-xl" animationDelay="200ms" />
</div>
</div>
<span className="sr-only">Loading services</span>
</div>
);
return <ModeHomeRouteLoading />;
}
4 changes: 3 additions & 1 deletion src/app/(search-app)/forms/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FormsHomePage } from "@/components/forms/forms-home-page";
import { FormsSearchResultsPage } from "@/components/forms/forms-search-results-page";
import { defaultFormSlug } from "@/lib/forms";

type FormsSearchParams = Promise<{ [key: string]: string | string[] | undefined }>;

Expand All @@ -17,7 +18,8 @@ export default async function FormsPage({ searchParams }: { searchParams: FormsS
const hasSubmittedSearch = readFirstSearchParam(resolvedSearchParams.run) === "1" && query.length > 0;

if (!hasSubmittedSearch) {
return <FormsHomePage />;
// Computed server-side so the client route chunk never bundles the forms catalog.
return <FormsHomePage defaultFormSlug={defaultFormSlug() ?? null} />;
}

return <FormsSearchResultsPage query={query} />;
Expand Down
5 changes: 5 additions & 0 deletions src/app/(search-app)/formulation/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return <ModeHomeRouteLoading />;
}
12 changes: 12 additions & 0 deletions src/app/(search-app)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,17 @@ export default async function Home({ searchParams }: HomeProps) {
redirect(suffix ? `/formulation?${suffix}` : "/formulation");
}

// Services/forms are namespaced mode homes; keep /?mode=* from mounting the
// full ClinicalDashboard + registry path for those surfaces.
if (initialSearchMode === "services" || initialSearchMode === "forms") {
redirect(
appModeHomeHref(initialSearchMode, {
query: firstSearchParam(params.q)?.trim(),
focus: firstSearchParam(params.focus) === "1",
run: firstSearchParam(params.run) === "1",
}),
);
}

return <HomePageClient initialMode={initialSearchMode} />;
}
5 changes: 5 additions & 0 deletions src/app/(search-app)/specifiers/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return <ModeHomeRouteLoading />;
}
5 changes: 5 additions & 0 deletions src/app/(search-app)/therapy-compass/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ModeHomeRouteLoading } from "@/components/mode-home-page-skeleton";

export default function Loading() {
return <ModeHomeRouteLoading />;
}
34 changes: 10 additions & 24 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2664,43 +2664,29 @@ html[data-motion="reduced"] .source-capsule-hit[aria-expanded="true"]:hover .sou
}
}

/* iOS Safari bottom reserve transitions to match the composer's hide/show motion.
Shell routes animate the inner reserve pad; dashboard/answer animates
#main-content padding; DocumentViewer animates its own content pad. */
/* Phone reserve padding animates while the short-lived reserve-transition
marker is active (hide and reveal). Mode/route flips of
--mobile-composer-reserve (hero ↔ dock) must snap — those clear the marker
immediately. DocumentViewer keeps its own Tailwind duration classes. */
@media (max-width: 639px) {
#main-content {
will-change: padding-bottom;
transition: padding-bottom 200ms var(--ease-out-soft);
}
#main-content[data-bottom-composer-hidden="true"] {
#main-content[data-reserve-transitioning="true"] {
will-change: padding-bottom;
transition: padding-bottom 240ms var(--ease-out-soft);
}
#main-content [data-testid="mobile-composer-reserve-pad"] {
will-change: padding-bottom;
transition: padding-bottom 200ms var(--ease-out-soft);
}
#main-content[data-bottom-composer-hidden="true"] [data-testid="mobile-composer-reserve-pad"] {
#main-content[data-reserve-transitioning="true"] [data-testid="mobile-composer-reserve-pad"] {
will-change: padding-bottom;
transition: padding-bottom 240ms var(--ease-out-soft);
}
[data-testid="document-viewer-content"] {
will-change: padding-bottom;
transition: padding-bottom 200ms var(--ease-out-soft);
}
[data-testid="document-viewer-content"][data-scroll-hidden="true"] {
[data-testid="document-viewer-content"][data-reserve-transitioning="true"] {
will-change: padding-bottom;
transition: padding-bottom 240ms var(--ease-out-soft);
}
}

@media (max-width: 639px) and (prefers-reduced-motion: reduce) {
#main-content,
#main-content[data-bottom-composer-hidden="true"],
#main-content [data-testid="mobile-composer-reserve-pad"],
#main-content[data-bottom-composer-hidden="true"] [data-testid="mobile-composer-reserve-pad"],
[data-testid="document-viewer-content"],
[data-testid="document-viewer-content"][data-scroll-hidden="true"] {
#main-content[data-reserve-transitioning="true"],
#main-content[data-reserve-transitioning="true"] [data-testid="mobile-composer-reserve-pad"],
[data-testid="document-viewer-content"][data-reserve-transitioning="true"] {
transition: none;
}
}
Expand Down
Loading
Loading