diff --git a/pygittools/tui/app_test.py b/pygittools/tui/app_test.py
index a089e32..141d3ea 100644
--- a/pygittools/tui/app_test.py
+++ b/pygittools/tui/app_test.py
@@ -4,8 +4,10 @@ from pathlib import Path
 from unittest.mock import MagicMock, patch
 
 from pygit2 import Repository, init_repository
+from pyratatui import Rect
 
 from pygittools.tui.app import _apply_result, _persist_commit_draft, run_tui
+from pygittools.tui.keys import key
 from pygittools.tui.pages.home import home_page
 from pygittools.tui.pages.no_repo import NoRepoPage
 from pygittools.tui.types import PageAction, PageContext, PageResult
@@ -90,30 +92,41 @@ def test_apply_result_switch_repo_reenters_page(page_ctx: PageContext, tmp_path:
 	assert stack[-1] is home
 
 
-def _run_tui_once(repo_dir: Path, keys: list[int]) -> int:
-	with patch("pygittools.tui.app.initscr") as initscr:
-		initscr.return_value = MagicMock()
-		with (
-			patch("pygittools.tui.app.getmaxyx", return_value=(24, 80)),
-			patch("pygittools.tui.app.getch", side_effect=keys),
-			patch("pygittools.tui.app.noecho"),
-			patch("pygittools.tui.app.cbreak"),
-			patch("pygittools.tui.app.curs_set"),
-			patch("pygittools.tui.app.keypad"),
-			patch("pygittools.tui.app.clear"),
-			patch("pygittools.tui.app.refresh"),
-			patch("pygittools.tui.app.endwin"),
-			patch("pygittools.tui.app.init_tui_color_theme"),
-			patch("pygittools.tui.app.init_tab_colors"),
-			patch("pygittools.tui.app.draw_status_bar"),
-			patch("pygittools.tui.app.status_bar_attr", return_value=0),
-		):
-			return run_tui(repo_dir)
+class _FakeTerm:
+	def __init__(self, keys: list[object]) -> None:
+		self._keys = list(keys)
+		self.hide_cursor = MagicMock()
+
+	def __enter__(self) -> _FakeTerm:
+		return self
+
+	def __exit__(self, *args: object) -> bool:
+		return False
+
+	def draw(self, draw_fn: object) -> None:
+		frame = MagicMock()
+		frame.area = Rect(0, 0, 80, 24)
+		draw_fn(frame)  # type: ignore[operator]
+
+	def poll_event(self, timeout_ms: int = 0) -> object | None:
+		del timeout_ms
+		if not self._keys:
+			return key("q")
+		return self._keys.pop(0)
+
+
+def _run_tui_once(repo_dir: Path, keys: list[object]) -> int:
+	with (
+		patch("pygittools.tui.app.Terminal", return_value=_FakeTerm(keys)),
+		patch("pygittools.tui.app.init_tui_color_theme"),
+		patch("pygittools.tui.app.init_tab_colors"),
+	):
+		return run_tui(repo_dir)
 
 
 def test_run_tui_quits_on_q(committed_repo: Repository) -> None:
-	assert _run_tui_once(Path(committed_repo.workdir), [ord("q")]) == 0
+	assert _run_tui_once(Path(committed_repo.workdir), [key("q")]) == 0
 
 
 def test_run_tui_no_repo(tmp_path: Path) -> None:
-	assert _run_tui_once(tmp_path, [ord("q")]) == 0
+	assert _run_tui_once(tmp_path, [key("q")]) == 0
diff --git a/pygittools/tui/conftest.py b/pygittools/tui/conftest.py
index 7e0f39a..86b3629 100644
--- a/pygittools/tui/conftest.py
+++ b/pygittools/tui/conftest.py
@@ -7,6 +7,7 @@ from unittest.mock import MagicMock
 
 import pytest
 from pygit2 import Repository, Signature, init_repository
+from pyratatui import Rect
 
 from pygittools.tui.types import PageContext
 
@@ -36,21 +37,11 @@ def committed_repo(repo: Repository) -> Repository:
 	return repo
 
 
-@pytest.fixture(autouse=True)
-def _mock_unicurses_io(monkeypatch: pytest.MonkeyPatch) -> None:
-	"""Avoid requiring a real terminal for draw/status/tab helpers."""
-	mock = MagicMock()
-	for name in (
-		"has_colors",
-		"start_color",
-		"use_default_colors",
-		"init_pair",
-		"can_change_color",
-		"init_color",
-	):
-		monkeypatch.setattr(f"pygittools.tui.git_colors.{name}", mock, raising=False)
-		monkeypatch.setattr(f"pygittools.tui.status_bar.{name}", mock, raising=False)
-		monkeypatch.setattr(f"pygittools.tui.tabs.{name}", mock, raising=False)
-	for name in ("move", "clrtoeol", "mvaddstr"):
-		monkeypatch.setattr(f"pygittools.tui.draw.{name}", mock, raising=False)
-		monkeypatch.setattr(f"pygittools.tui.status_bar.{name}", mock, raising=False)
+@pytest.fixture
+def frame() -> MagicMock:
+	return MagicMock()
+
+
+@pytest.fixture
+def area() -> Rect:
+	return Rect(0, 0, 80, 24)
diff --git a/pygittools/tui/coverage_gaps_test.py b/pygittools/tui/coverage_gaps_test.py
index 8cc56e1..8344c16 100644
--- a/pygittools/tui/coverage_gaps_test.py
+++ b/pygittools/tui/coverage_gaps_test.py
@@ -5,12 +5,14 @@ from unittest.mock import MagicMock, patch
 
 import pytest
 from pygit2 import Repository, init_repository
+from pyratatui import Rect
 
 from pygittools.tui.app import _apply_result, run_tui
 from pygittools.tui.changes_list import ChangesList, SectionId
 from pygittools.tui.commit_draft import commit_editmsg_path, load_commit_draft
 from pygittools.tui.input_context import InputContext, nav_context
 from pygittools.tui.input_context_test import FakeHost
+from pygittools.tui.keys import key
 from pygittools.tui.log_list import CommitLogList
 from pygittools.tui.pages.branches import BranchPickerPage
 from pygittools.tui.pages.help import HelpPage
@@ -20,9 +22,8 @@ from pygittools.tui.pages.projects import ProjectsPage
 from pygittools.tui.projects import ProjectEntry
 from pygittools.tui.pygitweb_layout import _bool_value, _int_value, _layout_from_mapping
 from pygittools.tui.status_bar import _format_line
-from pygittools.tui.tabs import _clip_prefix, tab_row_layout
+from pygittools.tui.tasks_list import TasksBoardList
 from pygittools.tui.types import PageAction, PageContext, PageResult
-from pygittools.tui.ucurses import KEY_BACKSPACE, KEY_ENTER, KEY_RESIZE, KEY_RIGHT, KEY_UP
 from pygittools.tui.worktree import commit_staged, unstage_paths
 
 
@@ -31,28 +32,11 @@ def test_read_draft_skips_blank_lines(tmp_path: Path) -> None:
 	assert load_commit_draft(tmp_path) == ""
 
 
-def test_draw_text_zero_clip_width(monkeypatch: pytest.MonkeyPatch) -> None:
-	from pygittools.tui import draw
-
-	monkeypatch.setattr(draw, "move", MagicMock())
-	monkeypatch.setattr(draw, "mvaddstr", MagicMock())
-	assert draw.draw_text(0, 9, "x", 10) == 9
-
-
 def test_status_bar_tight_left_space() -> None:
 	line = _format_line("left", "hint", 5)
 	assert line == "hint "
 
 
-def test_tab_row_layout_multiple_tabs() -> None:
-	layout = tab_row_layout("p", ("A", "B", "C"))
-	assert len(layout) == 3
-
-
-def test_clip_prefix_fits_without_ellipsis() -> None:
-	assert _clip_prefix("x", 80, ("Status", "Log")) == "x"
-
-
 def test_layout_from_mapping_empty_projects_list() -> None:
 	layout = _layout_from_mapping({"PROJECTROOT": "/tmp", "PROJECTS_LIST": ""})
 	assert layout.projects_list == Path("/tmp")
@@ -68,28 +52,27 @@ def test_changes_list_working_tree_clean_hint() -> None:
 	assert changes.status_hint() == "Working tree clean"
 
 
-def test_changes_list_input_resize_and_unknown_key(committed_repo: Repository) -> None:
+def test_changes_list_input_unknown_key(committed_repo: Repository) -> None:
 	changes = ChangesList()
 	changes.refresh(committed_repo)
-	assert changes.handle_input_key(KEY_RESIZE, committed_repo).layout_changed is False
-	assert changes.handle_input_key(999, committed_repo).layout_changed is False
+	assert changes.handle_input_key(key("Null"), committed_repo).layout_changed is False
 
 
 def test_changes_list_nav_with_no_rows_after_collapse(committed_repo: Repository) -> None:
 	changes = ChangesList()
 	changes.refresh(committed_repo)
 	changes._rows = []
-	assert changes.handle_nav_key(KEY_UP, committed_repo).layout_changed is False
+	assert changes.handle_nav_key(key("Up"), committed_repo).layout_changed is False
 
 
 def test_changes_list_commit_hints_and_backspace(committed_repo: Repository) -> None:
 	changes = ChangesList()
 	changes.set_commit_message("msg")
 	changes.refresh(committed_repo)
-	changes._cursor = 0
+	changes._list_state.select(0)
 	assert "Enter commit" in changes.status_hint()
-	changes.handle_nav_key(KEY_BACKSPACE, committed_repo)
-	changes.handle_nav_key(KEY_BACKSPACE, committed_repo)
+	changes.handle_nav_key(key("Backspace"), committed_repo)
+	changes.handle_nav_key(key("Backspace"), committed_repo)
 
 
 def test_changes_list_staged_header_unstage_all(committed_repo: Repository) -> None:
@@ -101,9 +84,9 @@ def test_changes_list_staged_header_unstage_all(committed_repo: Repository) -> N
 	changes.refresh(committed_repo)
 	for index, row in enumerate(changes._rows):
 		if row.kind == "header" and row.section == SectionId.STAGED:
-			changes._cursor = index
+			changes._list_state.select(index)
 			break
-	changes.handle_nav_key(KEY_ENTER, committed_repo)
+	changes.handle_nav_key(key("Enter"), committed_repo)
 
 
 def test_changes_list_unstage_file_row(committed_repo: Repository) -> None:
@@ -115,8 +98,8 @@ def test_changes_list_unstage_file_row(committed_repo: Repository) -> None:
 	changes.refresh(committed_repo)
 	for index, row in enumerate(changes._rows):
 		if row.kind == "file" and row.section == SectionId.STAGED:
-			changes._cursor = index
-			changes.handle_nav_key(KEY_ENTER, committed_repo)
+			changes._list_state.select(index)
+			changes.handle_nav_key(key("Enter"), committed_repo)
 			break
 
 
@@ -125,8 +108,8 @@ def test_changes_list_header_right_key(committed_repo: Repository) -> None:
 	changes.refresh(committed_repo)
 	for index, row in enumerate(changes._rows):
 		if row.kind == "header":
-			changes._cursor = index
-			changes.handle_nav_key(KEY_RIGHT, committed_repo)
+			changes._list_state.select(index)
+			changes.handle_nav_key(key("Right"), committed_repo)
 			break
 
 
@@ -134,31 +117,41 @@ def test_changes_list_failed_commit_nav(committed_repo: Repository) -> None:
 	changes = ChangesList()
 	changes.set_commit_message("msg")
 	changes.refresh(committed_repo)
-	changes._cursor = 0
-	changes.handle_nav_key(KEY_ENTER, committed_repo)
+	changes._list_state.select(0)
+	changes.handle_nav_key(key("Enter"), committed_repo)
 	assert changes.status_hint()
 
 
 def test_log_list_scroll_and_refresh(committed_repo: Repository) -> None:
 	log = CommitLogList()
 	log.refresh(committed_repo)
-	log.draw(0, 0, 80, highlight=True)
-	log._cursor = 100
-	log.draw(0, 2, 80, highlight=True)
-	log.handle_nav_key(KEY_UP, committed_repo)
+	log.draw(MagicMock(), Rect(0, 0, 80, 0), highlight=True)
+	log._list_state.select(100)
+	log.draw(MagicMock(), Rect(0, 0, 80, 2), highlight=True)
+	log.handle_nav_key(key("Up"), committed_repo)
 
 
 def test_input_context_log_tab_at_top(page_ctx: PageContext) -> None:
-	host = FakeHost(page_context=page_ctx, changes=ChangesList(), log=CommitLogList())
+	host = FakeHost(
+		page_context=page_ctx,
+		changes=ChangesList(),
+		log=CommitLogList(),
+		tasks=TasksBoardList(),
+	)
 	host.active_tab = "log"
-	host.log._cursor = 0
-	nav_context().dispatch_key(host, KEY_UP)
+	host.log._list_state.select(0)
+	nav_context().dispatch_key(host, key("Up"))
 	assert host.header_focus == "branch"
 
 
 def test_input_context_input_without_relinquish(page_ctx: PageContext) -> None:
-	host = FakeHost(page_context=page_ctx, changes=ChangesList(), log=CommitLogList())
-	dispatch = InputContext().dispatch_key(host, ord("x"))
+	host = FakeHost(
+		page_context=page_ctx,
+		changes=ChangesList(),
+		log=CommitLogList(),
+		tasks=TasksBoardList(),
+	)
+	dispatch = InputContext().dispatch_key(host, key("x"))
 	assert dispatch.next_mode is None
 
 
@@ -168,10 +161,10 @@ def test_branch_picker_error_and_short_list(committed_repo: Repository) -> None:
 	page.on_enter(ctx)
 	page._error = "bad"
 	assert "bad" in page.status_text()
-	page.draw(0, 2, 80)
+	page.draw(MagicMock(), Rect(0, 0, 80, 2))
 	page._ctx = None
-	page.draw(0, 10, 80)
-	page.handle_key(KEY_ENTER)
+	page.draw(MagicMock(), Rect(0, 0, 80, 10))
+	page.handle_key(key("Enter"))
 
 
 def test_branch_picker_checkout_error(committed_repo: Repository, monkeypatch: pytest.MonkeyPatch) -> None:
@@ -179,12 +172,13 @@ def test_branch_picker_checkout_error(committed_repo: Repository, monkeypatch: p
 	page = BranchPickerPage()
 	page.on_enter(ctx)
 	page._filtered = ["ghost"]
-	page._cursor = 1
+	page._focus_filter = False
+	page._list_state.select(0)
 	monkeypatch.setattr(
 		"pygittools.tui.pages.branches.checkout_branch",
 		lambda _repo, _branch: (False, "nope"),
 	)
-	page.handle_key(KEY_ENTER)
+	page.handle_key(key("Enter"))
 	assert page.status_text() == "nope"
 
 
@@ -192,33 +186,33 @@ def test_help_page_empty_lines(monkeypatch: pytest.MonkeyPatch) -> None:
 	page = HelpPage()
 	monkeypatch.setattr(page, "_lines", [])
 	assert page.status_text() == "Help"
-	page.draw(0, 0, 80)
+	page.draw(MagicMock(), Rect(0, 0, 80, 0))
 
 
 def test_help_page_scroll_past_end() -> None:
 	page = HelpPage()
-	page._offset = 999
-	page.draw(0, 3, 80)
-	page.handle_key(999)
+	page._state.select(999)
+	page.draw(MagicMock(), Rect(0, 0, 80, 3))
+	page.handle_key(key("Null"))
 
 
 def test_home_page_relinquish_input(committed_repo: Repository, monkeypatch: pytest.MonkeyPatch) -> None:
 	ctx = PageContext(repo=committed_repo, repo_path=Path(committed_repo.path))
 	page = home_page()
 	page.on_enter(ctx)
-	page.handle_key(ord("a"))
+	page.handle_key(key("a"))
 	monkeypatch.setattr(
 		"pygittools.tui.changes_list.commit_staged",
 		lambda _repo, _msg: (True, ""),
 	)
-	page.handle_key(KEY_ENTER)
+	page.handle_key(key("Enter"))
 	assert page.status_text()
 
 
 def test_no_repo_page_truncates_lines(tmp_path: Path) -> None:
 	page = NoRepoPage(tmp_path)
-	page.draw(0, 1, 80)
-	page.handle_key(999)
+	page.draw(MagicMock(), Rect(0, 0, 80, 1))
+	page.handle_key(key("Null"))
 
 
 def test_projects_page_error_and_scroll(tmp_path: Path) -> None:
@@ -229,9 +223,9 @@ def test_projects_page_error_and_scroll(tmp_path: Path) -> None:
 	page._projectroot_label = "root"
 	page._error = "bad"
 	assert page.status_text() == "bad"
-	page.draw(0, 5, 40)
-	page.handle_key(KEY_UP)
-	page.handle_key(ord("q"))
+	page.draw(MagicMock(), Rect(0, 0, 40, 5))
+	page.handle_key(key("Up"))
+	page.handle_key(key("q"))
 
 
 def test_unstage_paths_empty(committed_repo: Repository) -> None:
@@ -256,45 +250,50 @@ def test_apply_result_switch_repo_missing(tmp_path: Path, page_ctx: PageContext)
 	assert ctx is page_ctx
 
 
+class _FakeTerm:
+	def __init__(self, keys: list[object]) -> None:
+		self._keys = list(keys)
+		self.hide_cursor = MagicMock()
+
+	def __enter__(self) -> _FakeTerm:
+		return self
+
+	def __exit__(self, *args: object) -> bool:
+		return False
+
+	def draw(self, draw_fn: object) -> None:
+		frame = MagicMock()
+		frame.area = Rect(0, 0, 80, 24)
+		draw_fn(frame)  # type: ignore[operator]
+
+	def poll_event(self, timeout_ms: int = 0) -> object | None:
+		del timeout_ms
+		if not self._keys:
+			return key("q")
+		return self._keys.pop(0)
+
+
 def test_run_tui_keyboard_interrupt(committed_repo: Repository) -> None:
 	repo_dir = Path(committed_repo.workdir)
-	with patch("pygittools.tui.app.initscr") as initscr:
-		initscr.return_value = MagicMock()
-		with (
-			patch("pygittools.tui.app.getmaxyx", return_value=(24, 80)),
-			patch("pygittools.tui.app.getch", side_effect=KeyboardInterrupt),
-			patch("pygittools.tui.app.noecho"),
-			patch("pygittools.tui.app.cbreak"),
-			patch("pygittools.tui.app.curs_set"),
-			patch("pygittools.tui.app.keypad"),
-			patch("pygittools.tui.app.clear"),
-			patch("pygittools.tui.app.refresh"),
-			patch("pygittools.tui.app.endwin"),
-			patch("pygittools.tui.app.init_tui_color_theme"),
-			patch("pygittools.tui.app.init_tab_colors"),
-			patch("pygittools.tui.app.draw_status_bar"),
-			patch("pygittools.tui.app.status_bar_attr", return_value=0),
-		):
-			assert run_tui(repo_dir) == 0
-
-
-def test_run_tui_resize_key(committed_repo: Repository) -> None:
+
+	class BoomTerm(_FakeTerm):
+		def poll_event(self, timeout_ms: int = 0) -> object | None:
+			del timeout_ms
+			raise KeyboardInterrupt
+
+	with (
+		patch("pygittools.tui.app.Terminal", return_value=BoomTerm([])),
+		patch("pygittools.tui.app.init_tui_color_theme"),
+		patch("pygittools.tui.app.init_tab_colors"),
+	):
+		assert run_tui(repo_dir) == 0
+
+
+def test_run_tui_idle_then_quit(committed_repo: Repository) -> None:
 	repo_dir = Path(committed_repo.workdir)
-	with patch("pygittools.tui.app.initscr") as initscr:
-		initscr.return_value = MagicMock()
-		with (
-			patch("pygittools.tui.app.getmaxyx", return_value=(24, 80)),
-			patch("pygittools.tui.app.getch", side_effect=[KEY_RESIZE, ord("q")]),
-			patch("pygittools.tui.app.noecho"),
-			patch("pygittools.tui.app.cbreak"),
-			patch("pygittools.tui.app.curs_set"),
-			patch("pygittools.tui.app.keypad"),
-			patch("pygittools.tui.app.clear"),
-			patch("pygittools.tui.app.refresh"),
-			patch("pygittools.tui.app.endwin"),
-			patch("pygittools.tui.app.init_tui_color_theme"),
-			patch("pygittools.tui.app.init_tab_colors"),
-			patch("pygittools.tui.app.draw_status_bar"),
-			patch("pygittools.tui.app.status_bar_attr", return_value=0),
-		):
-			assert run_tui(repo_dir) == 0
+	with (
+		patch("pygittools.tui.app.Terminal", return_value=_FakeTerm([None, key("q")])),
+		patch("pygittools.tui.app.init_tui_color_theme"),
+		patch("pygittools.tui.app.init_tab_colors"),
+	):
+		assert run_tui(repo_dir) == 0
diff --git a/pygittools/tui/draw.py b/pygittools/tui/draw.py
deleted file mode 100644
index 5eefe2b..0000000
--- a/pygittools/tui/draw.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""unicurses drawing helpers."""
-
-from __future__ import annotations
-
-from pygittools.tui.ucurses import clrtoeol, move, mvaddstr  # type: ignore[import-untyped]
-
-
-def clear_row(row: int) -> None:
-	"""Clear a screen row before multi-segment redraws."""
-	move(row, 0)
-	clrtoeol()
-
-
-def draw_text(row: int, col: int, text: str, width: int, attr: int = 0) -> int:
-	"""Write ``text`` at ``col`` without clearing the rest of the row."""
-	if col >= width or not text:
-		return col
-	clipped = text[: max(0, width - col - 1)]
-	if not clipped:
-		return col
-	move(row, col)
-	if attr:
-		mvaddstr(row, col, clipped, attr)
-	else:
-		mvaddstr(row, col, clipped)
-	return col + len(clipped)
-
-
-def draw_line(row: int, col: int, text: str, width: int, attr: int = 0) -> None:
-	"""Write ``text`` on one row, clipped to the terminal width."""
-	if col == 0:
-		clear_row(row)
-	draw_text(row, col, text, width, attr)
diff --git a/pygittools/tui/draw_test.py b/pygittools/tui/draw_test.py
deleted file mode 100644
index 75b4f27..0000000
--- a/pygittools/tui/draw_test.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from __future__ import annotations
-
-from unittest.mock import MagicMock
-
-import pytest
-
-from pygittools.tui import draw
-
-
-@pytest.fixture
-def draw_mocks(monkeypatch: pytest.MonkeyPatch) -> dict[str, MagicMock]:
-	mocks = {
-		"move": MagicMock(),
-		"clrtoeol": MagicMock(),
-		"mvaddstr": MagicMock(),
-	}
-	for name, mock in mocks.items():
-		monkeypatch.setattr(draw, name, mock)
-	return mocks
-
-
-def test_clear_row_moves_and_clears(draw_mocks: dict[str, MagicMock]) -> None:
-	draw.clear_row(3)
-	draw_mocks["move"].assert_called_once_with(3, 0)
-	draw_mocks["clrtoeol"].assert_called_once()
-
-
-def test_draw_text_empty_returns_col(draw_mocks: dict[str, MagicMock]) -> None:
-	assert draw.draw_text(0, 5, "", 20) == 5
-	draw_mocks["mvaddstr"].assert_not_called()
-
-
-def test_draw_text_past_width_returns_col(draw_mocks: dict[str, MagicMock]) -> None:
-	assert draw.draw_text(0, 20, "hello", 20) == 20
-
-
-def test_draw_text_without_attr(draw_mocks: dict[str, MagicMock]) -> None:
-	end = draw.draw_text(0, 0, "hi", 10)
-	assert end == 2
-	draw_mocks["mvaddstr"].assert_called_once_with(0, 0, "hi")
-
-
-def test_draw_text_with_attr(draw_mocks: dict[str, MagicMock]) -> None:
-	draw.draw_text(0, 0, "hi", 10, attr=1)
-	draw_mocks["mvaddstr"].assert_called_once_with(0, 0, "hi", 1)
-
-
-def test_draw_text_clips_to_width(draw_mocks: dict[str, MagicMock]) -> None:
-	draw.draw_text(0, 0, "hello world", 6)
-	draw_mocks["mvaddstr"].assert_called_once_with(0, 0, "hello")
-
-
-def test_draw_line_clears_when_col_zero(draw_mocks: dict[str, MagicMock]) -> None:
-	draw.draw_line(2, 0, "line", 20, attr=0)
-	draw_mocks["move"].assert_called()
-	draw_mocks["mvaddstr"].assert_called_once()
diff --git a/pygittools/tui/ucurses.py b/pygittools/tui/ucurses.py
deleted file mode 100644
index 1fb588f..0000000
--- a/pygittools/tui/ucurses.py
+++ /dev/null
@@ -1,26 +0,0 @@
-"""unicurses re-exports with upstream docstring SyntaxWarnings silenced.
-
-uni-curses 3.1.2 uses ``prints\\sends`` in docstrings, which triggers
-SyntaxWarning on Python 3.12+ (invalid ``\\s`` escape).
-"""
-
-from __future__ import annotations
-
-import warnings
-from typing import Any
-
-with warnings.catch_warnings():
-	warnings.filterwarnings(
-		"ignore",
-		category=SyntaxWarning,
-		message=r".*invalid escape sequence.*\\s",
-	)
-	import unicurses as _unicurses  # type: ignore[import-untyped]
-
-
-def __getattr__(name: str) -> Any:
-	return getattr(_unicurses, name)
-
-
-def __dir__() -> list[str]:
-	return dir(_unicurses)
