[A11y] Create a11y page with placeholders. (#9889)

The screen is gated by the FeatureFlags.accessibility flag.

internal link: go/devtool-a11y-userjourney 

### General checklist

### Issues checklist

### Tests checklist

### AI-tooling checklist

    * [ ] I read the [AI contributions guidelines] and agree to follow them.
    * [ ] I reviewed all AI-generated code before opening this PR.
    * [ ] I understand and am able to discuss the code in this PR.
    * [ ] I have verifed the accuracy of any AI-generated text included in the PR description.
    * [ ] I commit to verifying the accuracy of any AI-generated code or text that I upload in response to review comments.

### Feature-change checklist 

    * [ ] I added the `release-notes-not-required` label or left a comment requesting the label be added.
    * [ ] I added an entry to `packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md`.
    * [ ] I included before/after screenshots and/or a GIF demo of the new UI to my PR description.
    * [ ] I ran the DevTools app locally to manually verify my changes.

![build.yaml badge]

If you need help, consider asking for help on [Discord].

[`contributions-welcome`]: https://github.com/flutter/devtools/issues?q=state%3Aopen%20label%3Acontributions-welcome
[`good-first-issue`]: https://github.com/flutter/devtools/issues?q=state%3Aopen%20label%3Agood-first-issue
[build.yaml badge]: https://github.com/flutter/devtools/actions/workflows/build.yaml/badge.svg
diff --git a/packages/devtools_app/lib/devtools_app.dart b/packages/devtools_app/lib/devtools_app.dart
index 5125d71..fb2637e 100644
--- a/packages/devtools_app/lib/devtools_app.dart
+++ b/packages/devtools_app/lib/devtools_app.dart
@@ -10,6 +10,8 @@
 export 'src/framework/release_notes.dart';
 export 'src/framework/scaffold/app_bar.dart';
 export 'src/framework/scaffold/status_line.dart';
+export 'src/screens/accessibility/accessibility_controller.dart';
+export 'src/screens/accessibility/accessibility_screen.dart';
 export 'src/screens/app_size/app_size_controller.dart';
 export 'src/screens/app_size/app_size_screen.dart';
 export 'src/screens/debugger/breakpoint_manager.dart';
diff --git a/packages/devtools_app/lib/src/app.dart b/packages/devtools_app/lib/src/app.dart
index 272f1fc..e51ec18 100644
--- a/packages/devtools_app/lib/src/app.dart
+++ b/packages/devtools_app/lib/src/app.dart
@@ -23,6 +23,8 @@
 import 'framework/observer/disconnect_observer.dart';
 import 'framework/release_notes.dart';
 import 'framework/scaffold/scaffold.dart';
+import 'screens/accessibility/accessibility_controller.dart';
+import 'screens/accessibility/accessibility_screen.dart';
 import 'screens/app_size/app_size_controller.dart';
 import 'screens/app_size/app_size_screen.dart';
 import 'screens/debugger/debugger_controller.dart';
@@ -713,6 +715,11 @@
       LoggingScreen(),
       createController: (_) => LoggingController(),
     ),
+    if (FeatureFlags.accessibility.isEnabled)
+      DevToolsScreen<AccessibilityController>(
+        AccessibilityScreen(),
+        createController: (_) => AccessibilityController(),
+      ),
     DevToolsScreen<DevToolsScreenController>(ProviderScreen()),
     DevToolsScreen<AppSizeController>(
       AppSizeScreen(),
diff --git a/packages/devtools_app/lib/src/screens/accessibility/accessibility_controller.dart b/packages/devtools_app/lib/src/screens/accessibility/accessibility_controller.dart
new file mode 100644
index 0000000..69f6dd1
--- /dev/null
+++ b/packages/devtools_app/lib/src/screens/accessibility/accessibility_controller.dart
@@ -0,0 +1,67 @@
+// Copyright 2026 The Flutter Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
+
+import 'package:devtools_app_shared/utils.dart';
+import 'package:flutter/foundation.dart';
+
+import '../../shared/framework/screen.dart';
+import '../../shared/framework/screen_controllers.dart';
+
+/// Controller for the Accessibility screen.
+class AccessibilityController extends DevToolsScreenController
+    with AutoDisposeControllerMixin {
+  AccessibilityController() {
+    _initListeners();
+  }
+
+  void _initListeners() {
+    addAutoDisposeListener(brightness, _onBrightnessChanged);
+    addAutoDisposeListener(textScale, _onTextScaleChanged);
+    addAutoDisposeListener(boldText, _onBoldTextChanged);
+    addAutoDisposeListener(screenReader, _onScreenReaderChanged);
+    addAutoDisposeListener(highContrast, _onHighContrastChanged);
+  }
+
+  void _onBrightnessChanged() {
+    // TODO(hannah-hyj): Implement VM service extension call for brightness override.
+    // e.g. using 'ext.flutter.brightnessOverride'.
+  }
+
+  void _onTextScaleChanged() {
+    // TODO(hannah-hyj): Implement VM service extension call for text scale override.
+  }
+
+  void _onBoldTextChanged() {
+    // TODO(hannah-hyj): Implement VM service extension call for bold text override.
+  }
+
+  void _onScreenReaderChanged() {
+    // TODO(hannah-hyj): Implement VM service extension call for screen reader / semantics debugger.
+    // e.g. using 'ext.flutter.showSemanticsDebugger'.
+  }
+
+  void _onHighContrastChanged() {
+    // TODO(hannah-hyj): Implement VM service extension call for high contrast override.
+  }
+
+  @override
+  final screenId = ScreenMetaData.accessibility.id;
+
+  // --- Accessibility Overrides State ---
+  final brightness = ValueNotifier<String>('System');
+  final textScale = ValueNotifier<double>(1.0);
+  final boldText = ValueNotifier<bool>(false);
+  final screenReader = ValueNotifier<bool>(false);
+  final highContrast = ValueNotifier<bool>(false);
+
+  @override
+  void dispose() {
+    brightness.dispose();
+    textScale.dispose();
+    boldText.dispose();
+    screenReader.dispose();
+    highContrast.dispose();
+    super.dispose();
+  }
+}
diff --git a/packages/devtools_app/lib/src/screens/accessibility/accessibility_screen.dart b/packages/devtools_app/lib/src/screens/accessibility/accessibility_screen.dart
new file mode 100644
index 0000000..6c3efd2
--- /dev/null
+++ b/packages/devtools_app/lib/src/screens/accessibility/accessibility_screen.dart
@@ -0,0 +1,94 @@
+// Copyright 2026 The Flutter Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
+
+import 'package:devtools_app_shared/ui.dart';
+import 'package:devtools_app_shared/utils.dart';
+import 'package:flutter/material.dart';
+
+import '../../shared/framework/screen.dart';
+import '../../shared/globals.dart';
+import '../../shared/ui/common_widgets.dart';
+import 'accessibility_controller.dart';
+
+/// A screen that displays accessibility information.
+class AccessibilityScreen extends Screen {
+  AccessibilityScreen() : super.fromMetaData(ScreenMetaData.accessibility);
+
+  static final id = ScreenMetaData.accessibility.id;
+
+  @override
+  Widget buildScreenBody(BuildContext context) =>
+      const AccessibilityScreenBody();
+}
+
+class AccessibilityScreenBody extends StatefulWidget {
+  const AccessibilityScreenBody({super.key});
+
+  @override
+  State<AccessibilityScreenBody> createState() =>
+      _AccessibilityScreenBodyState();
+}
+
+class _AccessibilityScreenBodyState extends State<AccessibilityScreenBody>
+    with AutoDisposeMixin {
+  late AccessibilityController controller;
+
+  @override
+  void initState() {
+    super.initState();
+    controller = screenControllers.lookup<AccessibilityController>();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final splitAxis = _splitAxisFor(context);
+    return SplitPane(
+      axis: splitAxis,
+      initialFractions: const [0.6, 0.4],
+      children: const [
+        AccessibilitySemanticsTreePane(),
+        AccessibilityOverridesPane(),
+      ],
+    );
+  }
+
+  Axis _splitAxisFor(BuildContext context) {
+    final screenSize = MediaQuery.of(context).size;
+    return screenSize.width > 1000 ? Axis.horizontal : Axis.vertical;
+  }
+}
+
+/// A pane that displays the semantics tree of the connected app.
+class AccessibilitySemanticsTreePane extends StatelessWidget {
+  const AccessibilitySemanticsTreePane({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const DevToolsAreaPane(
+      header: AreaPaneHeader(title: Text('Semantics Tree')),
+      child: CenteredMessage(
+        message:
+            'Accessibility semantics tree placeholder.\n'
+            '// TODO(hannah-hyj): Implement semantics tree view and details explorer.',
+      ),
+    );
+  }
+}
+
+/// A pane that displays the accessibility overrides controls.
+class AccessibilityOverridesPane extends StatelessWidget {
+  const AccessibilityOverridesPane({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const DevToolsAreaPane(
+      header: AreaPaneHeader(title: Text('Accessibility Overrides')),
+      child: CenteredMessage(
+        message:
+            'Accessibility overrides placeholder.\n'
+            '// TODO(hannah-hyj): Implement setting overrides (brightness, text scale, bold text, screen reader, high contrast).',
+      ),
+    );
+  }
+}
diff --git a/packages/devtools_app/lib/src/shared/feature_flags.dart b/packages/devtools_app/lib/src/shared/feature_flags.dart
index 0788278..937c751 100644
--- a/packages/devtools_app/lib/src/shared/feature_flags.dart
+++ b/packages/devtools_app/lib/src/shared/feature_flags.dart
@@ -69,6 +69,12 @@
     enabled: enableExperiments,
   );
 
+  /// Flag to enable the Accessibility page.
+  static final accessibility = BooleanFeatureFlag(
+    name: 'accessibility',
+    enabled: enableExperiments,
+  );
+
   /// A set of all the boolean feature flags for debugging purposes.
   ///
   /// When adding a new boolean flag, you are responsible for adding it to this
@@ -77,6 +83,7 @@
     memorySaveLoad,
     devToolsExtensions,
     dapDebugging,
+    accessibility,
   };
 
   /// A set of all the Flutter channel feature flags for debugging purposes.
diff --git a/packages/devtools_app/lib/src/shared/framework/screen.dart b/packages/devtools_app/lib/src/shared/framework/screen.dart
index a2544f2..2bfe341 100644
--- a/packages/devtools_app/lib/src/shared/framework/screen.dart
+++ b/packages/devtools_app/lib/src/shared/framework/screen.dart
@@ -94,6 +94,12 @@
     supportsWebServerDevice: true,
     tutorialVideoTimestamp: '?t=558',
   ),
+  accessibility(
+    'accessibility',
+    title: 'Accessibility',
+    icon: Icons.accessibility,
+    requiresFlutter: true,
+  ),
   provider(
     'provider',
     title: 'Provider',
diff --git a/packages/devtools_app/test/screens/accessibility/accessibility_screen_test.dart b/packages/devtools_app/test/screens/accessibility/accessibility_screen_test.dart
new file mode 100644
index 0000000..595cf4a
--- /dev/null
+++ b/packages/devtools_app/test/screens/accessibility/accessibility_screen_test.dart
@@ -0,0 +1,80 @@
+// Copyright 2026 The Flutter Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
+
+@TestOn('vm')
+library;
+
+import 'package:devtools_app/devtools_app.dart';
+import 'package:devtools_app_shared/ui.dart';
+import 'package:devtools_app_shared/utils.dart';
+import 'package:devtools_test/devtools_test.dart';
+import 'package:devtools_test/helpers.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:mockito/mockito.dart';
+
+void main() {
+  late AccessibilityScreen screen;
+  late AccessibilityController controller;
+  const windowSize = Size(1000.0, 1000.0);
+
+  group('Accessibility Screen', () {
+    Future<void> pumpAccessibilityScreen(WidgetTester tester) async {
+      await tester.pumpWidget(
+        wrapWithControllers(
+          const AccessibilityScreenBody(),
+          accessibility: controller,
+        ),
+      );
+    }
+
+    setUp(() {
+      final fakeServiceConnection = FakeServiceConnectionManager();
+      when(
+        fakeServiceConnection.serviceManager.connectedApp!.isFlutterWebAppNow,
+      ).thenReturn(false);
+      when(
+        fakeServiceConnection.serviceManager.connectedApp!.isProfileBuildNow,
+      ).thenReturn(false);
+      when(
+        fakeServiceConnection.errorBadgeManager.errorCountNotifier(
+          'accessibility',
+        ),
+      ).thenReturn(ValueNotifier<int>(0));
+
+      setGlobal(NotificationService, NotificationService());
+      setGlobal(
+        DevToolsEnvironmentParameters,
+        ExternalDevToolsEnvironmentParameters(),
+      );
+      setGlobal(PreferencesController, PreferencesController());
+      setGlobal(ServiceConnectionManager, fakeServiceConnection);
+      setGlobal(IdeTheme, IdeTheme());
+
+      controller = AccessibilityController();
+      screen = AccessibilityScreen();
+    });
+
+    testWidgets('builds its tab', (WidgetTester tester) async {
+      await tester.pumpWidget(wrap(Builder(builder: screen.buildTab)));
+      expect(find.text('Accessibility'), findsOneWidget);
+    });
+
+    testWidgetsWithWindowSize('builds split view with panes', windowSize, (
+      WidgetTester tester,
+    ) async {
+      await pumpAccessibilityScreen(tester);
+      await tester.pumpAndSettle();
+
+      expect(find.byType(AccessibilityScreenBody), findsOneWidget);
+      expect(find.byType(SplitPane), findsAtLeastNWidgets(1));
+
+      // Overrides pane should be visible
+      expect(find.byType(AccessibilityOverridesPane), findsOneWidget);
+
+      // Semantics Tree pane should be visible
+      expect(find.byType(AccessibilitySemanticsTreePane), findsOneWidget);
+    });
+  });
+}
diff --git a/packages/devtools_test/lib/src/helpers/wrappers.dart b/packages/devtools_test/lib/src/helpers/wrappers.dart
index 20f16ad..a782b26 100644
--- a/packages/devtools_test/lib/src/helpers/wrappers.dart
+++ b/packages/devtools_test/lib/src/helpers/wrappers.dart
@@ -96,6 +96,7 @@
   ReleaseNotesController? releaseNotes,
   VMDeveloperToolsController? vmDeveloperTools,
   DTDToolsController? dtdTools,
+  AccessibilityController? accessibility,
   bool includeRouter = true,
   DevToolsQueryParams? queryParams,
 }) {
@@ -173,6 +174,12 @@
       offline: offline,
     );
   }
+  if (accessibility != null) {
+    screenControllers.register<AccessibilityController>(
+      () => accessibility,
+      offline: offline,
+    );
+  }
 
   var child = wrapWithNotifications(widget);
   final providers = [