Repository: Textualize/textual
Pull request: Add `SelectionList`
The `SelectionList` is a child of `OptionList`, combining the look and feel of `CheckBox`, but done as a single widget. It is, in effect, to `CheckBox` what `RadioSet` is to `RadioButton`, but done in a way that is as lightweight as possible. Here it is in action:

https://github.com/Textualize/textual/assets/28237/2bae63a2-5b7a-4688-a384-89a7f3fffb77

This PR should satisfy the requirements of #2518 and #2379.

Problem statement:
Create a RadioSet-like interface for checkbox groups
When using checkboxes in forms, they often appear in groups. I want to be able to say, “given this CheckboxSet, which options are currently active?”

Right now, to find this out, we'd have to do some DOM querying and it doesn't feel very ergonomic to work with.

RadioSet has a nice interface, where I can basically query for the RadioSet widget and ask find out which one is selected without having to worry about how things are structured in the DOM.

I think they work well when standalone, treated as a boolean - but are a little unwieldy when you have groups of them.

Implement MultiSelect
We need a widget to select multiple options from a list.

Similar to HTML Select with multiple, but greater usability.

I think this should be built on OptionList, but have a checkbox by each item. The return value should be a tuple of values.

I don't think we need a overlay (like Select). Since this is designed to show multiple things, it probably should be multiple lines long, scrolling as required.

Hints from issue discussion:
On further discussion, it may not even be a CheckboxSet we need. The problem is: we need a way of selecting multiple items from a list. The solution: 🤷 
An extension to OptionList feels like it would cover that use case.
See also #2518.
I have a widget like that...but it's based on RadioSet rather than OptionList (and uses a bunch of CheckBoxes instead of RadioButtons...)

Do you want me to submit at PR?

The widget looks something like this:
![image](https://github.com/Textualize/textual/assets/4029895/34140641-9fcc-48a8-8fd2-42d8ce8cab71)

That looks very close to what we need! Could you share the code?
@willmcgugan : sure, it's in PR #2524
(In anticipation of the PR coming in tomorrow, and so I don't forget...) See also #2379.

Commit message: Fix a typo

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

Patch to review:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f43453c25e..99a46540b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 ### Added
 
 - `work` decorator accepts `description` parameter to add debug string https://github.com/Textualize/textual/issues/2597
+- Added `SelectionList` widget https://github.com/Textualize/textual/pull/2652
 
 ### Changed
 
diff --git a/docs/examples/widgets/selection_list.css b/docs/examples/widgets/selection_list.css
new file mode 100644
index 0000000000..a05e16281f
--- /dev/null
+++ b/docs/examples/widgets/selection_list.css
@@ -0,0 +1,10 @@
+Screen {
+    align: center middle;
+}
+
+SelectionList {
+    padding: 1;
+    border: solid $accent;
+    width: 80%;
+    height: 80%;
+}
diff --git a/docs/examples/widgets/selection_list_selected.css b/docs/examples/widgets/selection_list_selected.css
new file mode 100644
index 0000000000..92db41c14c
--- /dev/null
+++ b/docs/examples/widgets/selection_list_selected.css
@@ -0,0 +1,19 @@
+Screen {
+    align: center middle;
+}
+
+Horizontal {
+    width: 80%;
+    height: 80%;
+}
+
+SelectionList {
+    padding: 1;
+    border: solid $accent;
+    width: 1fr;
+}
+
+Pretty {
+    width: 1fr;
+    border: solid $accent;
+}
diff --git a/docs/examples/widgets/selection_list_selected.py b/docs/examples/widgets/selection_list_selected.py
new file mode 100644
index 0000000000..954fb36b11
--- /dev/null
+++ b/docs/examples/widgets/selection_list_selected.py
@@ -0,0 +1,40 @@
+from textual import on
+from textual.app import App, ComposeResult
+from textual.containers import Horizontal
+from textual.events import Mount
+from textual.widgets import Footer, Header, Pretty, SelectionList
+from textual.widgets.selection_list import Selection
+
+
+class SelectionListApp(App[None]):
+    CSS_PATH = "selection_list_selected.css"
+
+    def compose(self) -> ComposeResult:
+        yield Header()
+        with Horizontal():
+            yield SelectionList[str](  # (1)!
+                Selection("Falken's Maze", "secret_back_door", True),
+                Selection("Black Jack", "black_jack"),
+                Selection("Gin Rummy", "gin_rummy"),
+                Selection("Hearts", "hearts"),
+                Selection("Bridge", "bridge"),
+                Selection("Checkers", "checkers"),
+                Selection("Chess", "a_nice_game_of_chess", True),
+                Selection("Poker", "poker"),
+                Selection("Fighter Combat", "fighter_combat", True),
+            )
+            yield Pretty([])
+        yield Footer()
+
+    def on_mount(self) -> None:
+        self.query_one(SelectionList).border_title = "Shall we play some games?"
+        self.query_one(Pretty).border_title = "Selected games"
+
+    @on(Mount)
+    @on(SelectionList.SelectedChanged)
+    def update_selected_view(self) -> None:
+        self.query_one(Pretty).update(self.query_one(SelectionList).selected)
+
+
+if __name__ == "__main__":
+    SelectionListApp().run()
diff --git a/docs/examples/widgets/selection_list_selections.py b/docs/examples/widgets/selection_list_selections.py
new file mode 100644
index 0000000000..4a5e582a07
--- /dev/null
+++ b/docs/examples/widgets/selection_list_selections.py
@@ -0,0 +1,29 @@
+from textual.app import App, ComposeResult
+from textual.widgets import Footer, Header, SelectionList
+from textual.widgets.selection_list import Selection
+
+
+class SelectionListApp(App[None]):
+    CSS_PATH = "selection_list.css"
+
+    def compose(self) -> ComposeResult:
+        yield Header()
+        yield SelectionList[int](  # (1)!
+            Selection("Falken's Maze", 0, True),
+            Selection("Black Jack", 1),
+            Selection("Gin Rummy", 2),
+            Selection("Hearts", 3),
+            Selection("Bridge", 4),
+            Selection("Checkers", 5),
+            Selection("Chess", 6, True),
+            Selection("Poker", 7),
+            Selection("Fighter Combat", 8, True),
+        )
+        yield Footer()
+
+    def on_mount(self) -> None:
+        self.query_one(SelectionList).border_title = "Shall we play some games?"
+
+
+if __name__ == "__main__":
+    SelectionListApp().run()
diff --git a/docs/examples/widgets/selection_list_tuples.py b/docs/examples/widgets/selection_list_tuples.py
new file mode 100644
index 0000000000..bff54e69cc
--- /dev/null
+++ b/docs/examples/widgets/selection_list_tuples.py
@@ -0,0 +1,28 @@
+from textual.app import App, ComposeResult
+from textual.widgets import Footer, Header, SelectionList
+
+
+class SelectionListApp(App[None]):
+    CSS_PATH = "selection_list.css"
+
+    def compose(self) -> ComposeResult:
+        yield Header()
+        yield SelectionList[int](  # (1)!
+            ("Falken's Maze", 0, True),
+            ("Black Jack", 1),
+            ("Gin Rummy", 2),
+            ("Hearts", 3),
+            ("Bridge", 4),
+            ("Checkers", 5),
+            ("Chess", 6, True),
+            ("Poker", 7),
+            ("Fighter Combat", 8, True),
+        )
+        yield Footer()
+
+    def on_mount(self) -> None:
+        self.query_one(SelectionList).border_title = "Shall we play some games?"
+
+
+if __name__ == "__main__":
+    SelectionListApp().run()
diff --git a/docs/widget_gallery.md b/docs/widget_gallery.md
index 04e6fada27..15610ad964 100644
--- a/docs/widget_gallery.md
+++ b/docs/widget_gallery.md
@@ -197,6 +197,14 @@ Select from a number of possible options.
 ```{.textual path="docs/examples/widgets/select_widget.py" press="tab,enter,down,down"}
 ```
 
+## SelectionList
+
+Select multiple values from a list of options.
+
+[SelectionList reference](./widgets/selection_list.md){ .md-button .md-button--primary }
+
+```{.textual path="docs/examples/widgets/selection_list_selections.py" press="down,down,down"}
+```
 
 ## Static
 
diff --git a/docs/widgets/selection_list.md b/docs/widgets/selection_list.md
new file mode 100644
index 0000000000..cb22e048f5
--- /dev/null
+++ b/docs/widgets/selection_list.md
@@ -0,0 +1,171 @@
+# SelectionList
+
+!!! tip "Added in version 0.27.0"
+
+A widget for showing a vertical list of selectable options.
+
+- [x] Focusable
+- [ ] Container
+
+## Typing
+
+The `SelectionList` control is a
+[`Generic`](https://docs.python.org/3/library/typing.html#typing.Generic),
+which allows you to set the type of the
+[selection values][textual.widgets.selection_list.Selection.value]. For instance, if
+the data type for your values is an integer, you would type the widget as
+follows:
+
+```python
+selections = [("First", 1), ("Second", 2)]
+my_selection_list: SelectionList[int] =  SelectionList[int](selections)
+```
+
+!!! note
+
+    Typing is entirely optional.
+
+    If you aren't familiar with typing or don't want to worry about it right now, feel free to ignore it.
+
+## Examples
+
+A selection list is designed to be built up of single-line prompts (which
+can be [Rich renderables](/guide/widgets/#rich-renderables)) and an
+associated unique value.
+
+### Selections as tuples
+
+A selection list can be built with tuples, either of two or three values in
+length. Each tuple must contain a prompt and a value, and it can also
+optionally contain a flag for the initial selected state of the option.
+
+=== "Output"
+
+    ```{.textual path="docs/examples/widgets/selection_list_tuples.py"}
+    ```
+
+=== "selection_list_tuples.py"
+
+    ~~~python
+    --8<-- "docs/examples/widgets/selection_list_tuples.py"
+    ~~~
+
+    1. Note that the `SelectionList` is typed as `int`, for the type of the values.
+
+=== "selection_list.css"
+
+    ~~~python
+    --8<-- "docs/examples/widgets/selection_list.css"
+    ~~~
+
+### Selections as Selection objects
+
+Alternatively, selections can be passed in as
+[`Selection`][textual.widgets.selection_list.Selection]s:
+
+=== "Output"
+
+    ```{.textual path="docs/examples/widgets/selection_list_selections.py"}
+    ```
+
+=== "selection_list_selections.py"
+
+    ~~~python
+    --8<-- "docs/examples/widgets/selection_list_selections.py"
+    ~~~
+
+    1. Note that the `SelectionList` is typed as `int`, for the type of the values.
+
+=== "selection_list.css"
+
+    ~~~python
+    --8<-- "docs/examples/widgets/selection_list.css"
+    ~~~
+
+### Handling changes to the selections
+
+Most of the time, when using the `SelectionList`, you will want to know when
+the collection of selected items has changed, this is ideally done using the
+[`SelectedChanged`][textual.widgets.SelectionList.SelectedChanged] message.
+Here is an example of using that message to update a `Pretty` with the
+collection of selected values:
+
+=== "Output"
+
+    ```{.textual path="docs/examples/widgets/selection_list_selected.py"}
+    ```
+
+=== "selection_list_selections.py"
+
+    ~~~python
+    --8<-- "docs/examples/widgets/selection_list_selected.py"
+    ~~~
+
+    1. Note that the `SelectionList` is typed as `str`, for the type of the values.
+
+=== "selection_list.css"
+
+    ~~~python
+    --8<-- "docs/examples/widgets/selection_list_selected.css"
+    ~~~
+
+## Reactive Attributes
+
+| Name          | Type            | Default | Description                                                                  |
+|---------------|-----------------|---------|------------------------------------------------------------------------------|
+| `highlighted` | `int` \| `None` | `None`  | The index of the highlighted selection. `None` means nothing is highlighted. |
+
+## Messages
+
+The following messages will be posted as the user interacts with the list:
+
+- [SelectionList.SelectionHighlighted][textual.widgets.SelectionList.SelectionHighlighted]
+- [SelectionList.SelectionToggled][textual.widgets.SelectionList.SelectionToggled]
+
+The following message will be posted if the content of
+[`selected`][textual.widgets.SelectionList.selected] changes, either by user
+interaction or by API calls:
+
+- [SelectionList.SelectedChanged][textual.widgets.SelectionList.SelectedChanged]
+
+## Bindings
+
+The selection list widget defines the following bindings:
+
+::: textual.widgets.SelectionList.BINDINGS
+    options:
+      show_root_heading: false
+      show_root_toc_entry: false
+
+It inherits from [`OptionList`][textual.widgets.OptionList]
+and so also inherits the following bindings:
+
+::: textual.widgets.OptionList.BINDINGS
+    options:
+      show_root_heading: false
+      show_root_toc_entry: false
+
+## Component Classes
+
+The selection list provides the following component classes:
+
+::: textual.widgets.SelectionList.COMPONENT_CLASSES
+    options:
+      show_root_heading: false
+      show_root_toc_entry: false
+
+It inherits from [`OptionList`][textual.widgets.OptionList] and so also
+makes use of the following component classes:
+
+::: textual.widgets.OptionList.COMPONENT_CLASSES
+    options:
+      show_root_heading: false
+      show_root_toc_entry: false
+
+::: textual.widgets.SelectionList
+    options:
+      heading_level: 2
+
+::: textual.widgets.selection_list
+    options:
+      heading_level: 2
diff --git a/mkdocs-nav.yml b/mkdocs-nav.yml
index f5a9ab4f18..3be2151805 100644
--- a/mkdocs-nav.yml
+++ b/mkdocs-nav.yml
@@ -150,6 +150,7 @@ nav:
       - "widgets/radiobutton.md"
       - "widgets/radioset.md"
       - "widgets/select.md"
+      - "widgets/selection_list.md"
       - "widgets/static.md"
       - "widgets/switch.md"
       - "widgets/tabbed_content.md"
diff --git a/src/textual/widgets/__init__.py b/src/textual/widgets/__init__.py
index 04e00e53ba..3ed23b4c2c 100644
--- a/src/textual/widgets/__init__.py
+++ b/src/textual/widgets/__init__.py
@@ -30,6 +30,7 @@
     from ._radio_button import RadioButton
     from ._radio_set import RadioSet
     from ._select import Select
+    from ._selection_list import SelectionList
     from ._static import Static
     from ._switch import Switch
     from ._tabbed_content import TabbedContent, TabPane
@@ -61,6 +62,7 @@
     "RadioButton",
     "RadioSet",
     "Select",
+    "SelectionList",
     "Static",
     "Switch",
     "Tab",
diff --git a/src/textual/widgets/__init__.pyi b/src/textual/widgets/__init__.pyi
index 27e7f4ed16..86a3985a59 100644
--- a/src/textual/widgets/__init__.pyi
+++ b/src/textual/widgets/__init__.pyi
@@ -20,6 +20,7 @@ from ._progress_bar import ProgressBar as ProgressBar
 from ._radio_button import RadioButton as RadioButton
 from ._radio_set import RadioSet as RadioSet
 from ._select import Select as Select
+from ._selection_list import SelectionList as SelectionList
 from ._static import Static as Static
 from ._switch import Switch as Switch
 from ._tabbed_content import TabbedContent as TabbedContent
diff --git a/src/textual/widgets/_selection_list.py b/src/textual/widgets/_selection_list.py
new file mode 100644
index 0000000000..c0208dfca4
--- /dev/null
+++ b/src/textual/widgets/_selection_list.py
@@ -0,0 +1,655 @@
+"""Provides a selection list widget, allowing one or more items to be selected."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from typing import Callable, ClassVar, Generic, Iterable, TypeVar, cast
+
+from rich.repr import Result
+from rich.segment import Segment
+from rich.style import Style
+from rich.text import Text, TextType
+from typing_extensions import Self
+
+from ..binding import Binding
+from ..messages import Message
+from ..strip import Strip
+from ._option_list import NewOptionListContent, Option, OptionList
+from ._toggle_button import ToggleButton
+
+SelectionType = TypeVar("SelectionType")
+"""The type for the value of a [`Selection`][textual.widgets.selection_list.Selection] in a [`SelectionList`][textual.widgets.SelectionList]"""
+
+MessageSelectionType = TypeVar("MessageSelectionType")
+"""The type for the value of a [`Selection`][textual.widgets.selection_list.Selection] in a [`SelectionList`][textual.widgets.SelectionList] message."""
+
+
+class SelectionError(TypeError):
+    """Type of an error raised if a selection is badly-formed."""
+
+
+class Selection(Generic[SelectionType], Option):
+    """A selection for a [`SelectionList`][textual.widgets.SelectionList]."""
+
+    def __init__(
+        self,
+        prompt: TextType,
+        value: SelectionType,
+        initial_state: bool = False,
+        id: str | None = None,
+        disabled: bool = False,
+    ):
+        """Initialise the selection.
+
+        Args:
+            prompt: The prompt for the selection.
+            value: The value for the selection.
+            initial_state: The initial selected state of the selection.
+            id: The optional ID for the selection.
+            disabled: The initial enabled/disabled state. Enabled by default.
+        """
+        if isinstance(prompt, str):
+            prompt = Text.from_markup(prompt)
+        super().__init__(prompt.split()[0], id, disabled)
+        self._value: SelectionType = value
+        """The value associated with the selection."""
+        self._initial_state: bool = initial_state
+        """The initial selected state for the selection."""
+
+    @property
+    def value(self) -> SelectionType:
+        """The value for this selection."""
+        return self._value
+
+    @property
+    def initial_state(self) -> bool:
+        """The initial selected state for the selection."""
+        return self._initial_state
+
+
+class SelectionList(Generic[SelectionType], OptionList):
+    """A vertical selection list that allows making multiple selections."""
+
+    BINDINGS = [Binding("space", "select")]
+    """
+    | Key(s) | Description |
+    | :- | :- |
+    | space | Toggle the state of the highlighted selection. |
+    """
+
+    COMPONENT_CLASSES: ClassVar[set[str]] = {
+        "selection-list--button",
+        "selection-list--button-selected",
+        "selection-list--button-highlighted",
+        "selection-list--button-selected-highlighted",
+    }
+    """
+    | Class | Description |
+    | :- | :- |
+    | `selection-list--button` | Target the default button style. |
+    | `selection-list--button-selected` | Target a selected button style. |
+    | `selection-list--button-highlighted` | Target a highlighted button style. |
+    | `selection-list--button-selected-highlighted` | Target a highlighted selected button style. |
+    """
+
+    DEFAULT_CSS = """
+    SelectionList > .selection-list--button {
+        text-style: bold;
+        background: $foreground 15%;
+    }
+
+    SelectionList:focus > .selection-list--button {
+        text-style: bold;
+        background: $foreground 25%;
+    }
+
+    SelectionList > .selection-list--button-highlighted {
+        text-style: bold;
+        background: $foreground 15%;
+    }
+
+    SelectionList:focus > .selection-list--button-highlighted {
+        text-style: bold;
+        background: $foreground 25%;
+    }
+
+    SelectionList > .selection-list--button-selected {
+        text-style: bold;
+        background: $foreground 15%;
+    }
+
+    SelectionList:focus > .selection-list--button-selected {
+        text-style: bold;
+        color: $success;
+        background: $foreground 25%;
+    }
+
+    SelectionList > .selection-list--button-selected-highlighted {
+        text-style: bold;
+        color: $success;
+        background: $foreground 15%;
+    }
+
+    SelectionList:focus > .selection-list--button-selected-highlighted {
+        text-style: bold;
+        color: $success;
+        background: $foreground 25%;
+    }
+    """
+
+    class SelectionMessage(Generic[MessageSelectionType], Message):
+        """Base class for all selection messages."""
+
+        def __init__(self, selection_list: SelectionList, index: int) -> None:
+            """Initialise the selection message.
+
+            Args:
+                selection_list: The selection list that owns the selection.
+                index: The index of the selection that the message relates to.
+            """
+            super().__init__()
+            self.selection_list: SelectionList[MessageSelectionType] = selection_list
+            """The option list that sent the message."""
+            self.selection: Selection[
+                MessageSelectionType
+            ] = selection_list.get_option_at_index(index)
+            """The highlighted selection."""
+            self.selection_index: int = index
+            """The index of the selection that the message relates to."""
+
+        @property
+        def control(self) -> OptionList:
+            """The selection list that sent the message.
+
+            This is an alias for
+            [`SelectionMessage.selection_list`][textual.widgets.SelectionList.SelectionMessage.selection_list]
+            and is used by the [`on`][textual.on] decorator.
+            """
+            return self.selection_list
+
+        def __rich_repr__(self) -> Result:
+            yield "selection_list", self.selection_list
+            yield "selection", self.selection
+            yield "selection_index", self.selection_index
+
+    class SelectionHighlighted(SelectionMessage):
+        """Message sent when a selection is highlighted.
+
+        Can be handled using `on_selection_list_selection_highlighted` in a subclass of
+        [`SelectionList`][textual.widgets.SelectionList] or in a parent node in the DOM.
+        """
+
+    class SelectionToggled(SelectionMessage):
+        """Message sent when a selection is toggled.
+
+        Can be handled using `on_selection_list_selection_toggled` in a subclass of
+        [`SelectionList`][textual.widgets.SelectionList] or in a parent node in the DOM.
+
+        Note:
+            This message is only sent if the selection is toggled by user
+            interaction. See
+            [`SelectedChanged`][textual.widgets.SelectionList.SelectedChanged]
+            for a message sent when any change (selected or deselected,
+            either by user interaction or by API calls) is made to the
+            selected values.
+        """
+
+    @dataclass
+    class SelectedChanged(Generic[MessageSelectionType], Message):
+        """Message sent when the collection of selected values changes.
+
+        This message is sent when any change to the collection of selected
+        values takes place; either by user interaction or by API calls.
+        """
+
+        selection_list: SelectionList[MessageSelectionType]
+        """The `SelectionList` that sent the message."""
+
+        @property
+        def control(self) -> SelectionList[MessageSelectionType]:
+            """An alias for `selection_list`."""
+            return self.selection_list
+
+    def __init__(
+        self,
+        *selections: Selection
+        | tuple[TextType, SelectionType]
+        | tuple[TextType, SelectionType, bool],
+        name: str | None = None,
+        id: str | None = None,
+        classes: str | None = None,
+        disabled: bool = False,
+    ):
+        """Initialise the selection list.
+
+        Args:
+            *content: The content for the selection list.
+            name: The name of the selection list.
+            id: The ID of the selection list in the DOM.
+            classes: The CSS classes of the selection list.
+            disabled: Whether the selection list is disabled or not.
+        """
+        self._selected: dict[SelectionType, None] = {}
+        """Tracking of which values are selected."""
+        self._send_messages = False
+        """Keep track of when we're ready to start sending messages."""
+        super().__init__(
+            *[self._make_selection(selection) for selection in selections],
+            name=name,
+            id=id,
+            classes=classes,
+            disabled=disabled,
+        )
+
+    @property
+    def selected(self) -> list[SelectionType]:
+        """The selected values.
+
+        This is a list of all of the
+        [values][textual.widgets.selection_list.Selection.value] associated
+        with selections in the list that are currently in the selected
+        state.
+        """
+        return list(self._selected.keys())
+
+    def _on_mount(self) -> None:
+        """Configure the list once the DOM is ready."""
+        self._send_messages = True
+
+    def _message_changed(self) -> None:
+        """Post a message that the selected collection has changed, where appropriate.
+
+        Note:
+            A message will only be send if `_send_messages` is `True`. This
+            makes this safe to call before the widget is ready for posting
+            messages.
+        """
+        if self._send_messages:
+            self.post_message(self.SelectedChanged(self))
+
+    def _apply_to_all(self, state_change: Callable[[SelectionType], bool]) -> Self:
+        """Apply a selection state change to all selection options in the list.
+
+        Args:
+            state_change: The state change function to apply.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+        """
+
+        # Keep track of if anything changed.
+        changed = False
+
+        # Next we run through everything and apply the change, preventing
+        # the changed message because the caller really isn't going to be
+        # expecting a message storm from this.
+        with self.prevent(self.SelectedChanged):
+            for selection in self._options:
+                changed = state_change(cast(Selection, selection).value) or changed
+
+        # If the above did make a change, *then* send a message.
+        if changed:
+            self._message_changed()
+
+        self.refresh()
+        return self
+
+    def _select(self, value: SelectionType) -> bool:
+        """Mark the given value as selected.
+
+        Args:
+            value: The value to mark as selected.
+
+        Returns:
+            `True` if the value was selected, `False` if not.
+        """
+        if value not in self._selected:
+            self._selected[value] = None
+            self._message_changed()
+            return True
+        return False
+
+    def select(self, selection: Selection[SelectionType] | SelectionType) -> Self:
+        """Mark the given selection as selected.
+
+        Args:
+            selection: The selection to mark as selected.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+        """
+        if self._select(
+            selection.value
+            if isinstance(selection, Selection)
+            else cast(SelectionType, selection)
+        ):
+            self.refresh()
+        return self
+
+    def select_all(self) -> Self:
+        """Select all items.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+        """
+        return self._apply_to_all(self._select)
+
+    def _deselect(self, value: SelectionType) -> bool:
+        """Mark the given selection as not selected.
+
+        Args:
+            value: The value to mark as not selected.
+
+        Returns:
+            `True` if the value was deselected, `False` if not.
+        """
+        try:
+            del self._selected[value]
+        except KeyError:
+            return False
+        self._message_changed()
+        return True
+
+    def deselect(self, selection: Selection[SelectionType] | SelectionType) -> Self:
+        """Mark the given selection as not selected.
+
+        Args:
+            selection: The selection to mark as not selected.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+        """
+        if self._deselect(
+            selection.value
+            if isinstance(selection, Selection)
+            else cast(SelectionType, selection)
+        ):
+            self.refresh()
+        return self
+
+    def deselect_all(self) -> Self:
+        """Deselect all items.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+        """
+        return self._apply_to_all(self._deselect)
+
+    def _toggle(self, value: SelectionType) -> bool:
+        """Toggle the selection state of the given value.
+
+        Args:
+            value: The value to toggle.
+
+        Returns:
+            Always `True`.
+        """
+        if value in self._selected:
+            self._deselect(value)
+        else:
+            self._select(value)
+        return True
+
+    def toggle(self, selection: Selection[SelectionType] | SelectionType) -> Self:
+        """Toggle the selected state of the given selection.
+
+        Args:
+            selection: The selection to toggle.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+        """
+        self._toggle(
+            selection.value
+            if isinstance(selection, Selection)
+            else cast(SelectionType, selection)
+        )
+        self.refresh()
+        return self
+
+    def toggle_all(self) -> Self:
+        """Toggle all items.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+        """
+        return self._apply_to_all(self._toggle)
+
+    def _make_selection(
+        self,
+        selection: Selection
+        | tuple[TextType, SelectionType]
+        | tuple[TextType, SelectionType, bool],
+    ) -> Selection[SelectionType]:
+        """Turn incoming selection data into a `Selection` instance.
+
+        Args:
+            selection: The selection data.
+
+        Returns:
+            An instance of a `Selection`.
+
+        Raises:
+            SelectionError: If the selection was badly-formed.
+        """
+
+        # If we've been given a tuple of some sort, turn that into a proper
+        # Selection.
+        if isinstance(selection, tuple):
+            if len(selection) == 2:
+                selection = cast(
+                    "tuple[TextType, SelectionType, bool]", (*selection, False)
+                )
+            elif len(selection) != 3:
+                raise SelectionError(f"Expected 2 or 3 values, got {len(selection)}")
+            selection = Selection[SelectionType](*selection)
+
+        # At this point we should have a proper selection.
+        assert isinstance(selection, Selection)
+
+        # If the initial state for this is that it's selected, add it to the
+        # selected collection.
+        if selection.initial_state:
+            self._select(selection.value)
+
+        return selection
+
+    def _toggle_highlighted_selection(self) -> None:
+        """Toggle the state of the highlighted selection.
+
+        If nothing is selected in the list this is a non-operation.
+        """
+        if self.highlighted is not None:
+            self.toggle(self.get_option_at_index(self.highlighted))
+
+    def render_line(self, y: int) -> Strip:
+        """Render a line in the display.
+
+        Args:
+            y: The line to render.
+
+        Returns:
+            A [`Strip`][textual.strip.Strip] that is the line to render.
+        """
+
+        # First off, get the underlying prompt from OptionList.
+        prompt = super().render_line(y)
+
+        # If it looks like the prompt itself is actually an empty line...
+        if not prompt:
+            # ...get out with that. We don't need to do any more here.
+            return prompt
+
+        # We know the prompt we're going to display, what we're going to do
+        # is place a CheckBox-a-like button next to it. So to start with
+        # let's pull out the actual Selection we're looking at right now.
+        _, scroll_y = self.scroll_offset
+        selection_index = scroll_y + y
+        selection = self.get_option_at_index(selection_index)
+
+        # Figure out which component style is relevant for a checkbox on
+        # this particular line.
+        component_style = "selection-list--button"
+        if selection.value in self._selected:
+            component_style += "-selected"
+        if self.highlighted == selection_index:
+            component_style += "-highlighted"
+
+        # Get the underlying style used for the prompt.
+        underlying_style = next(iter(prompt)).style
+        assert underlying_style is not None
+
+        # Get the style for the button.
+        button_style = self.get_component_rich_style(component_style)
+
+        # If the button is in the unselected state, we're going to do a bit
+        # of a switcharound to make it look like it's a "cutout".
+        if not selection.value in self._selected:
+            button_style += Style.from_color(
+                self.background_colors[1].rich_color, button_style.bgcolor
+            )
+
+        # Build the style for the side characters. Note that this is
+        # sensitive to the type of character used, so pay attention to
+        # BUTTON_LEFT and BUTTON_RIGHT.
+        side_style = Style.from_color(button_style.bgcolor, underlying_style.bgcolor)
+
+        # At this point we should have everything we need to place a
+        # "button" before the option.
+        return Strip(
+            [
+                Segment(ToggleButton.BUTTON_LEFT, style=side_style),
+                Segment(ToggleButton.BUTTON_INNER, style=button_style),
+                Segment(ToggleButton.BUTTON_RIGHT, style=side_style),
+                Segment(" ", style=underlying_style),
+                *prompt,
+            ]
+        )
+
+    def _on_option_list_option_highlighted(
+        self, event: OptionList.OptionHighlighted
+    ) -> None:
+        """Capture the `OptionList` highlight event and turn it into a [`SelectionList`][textual.widgets.SelectionList] event.
+
+        Args:
+            event: The event to capture and recreate.
+        """
+        event.stop()
+        self.post_message(self.SelectionHighlighted(self, event.option_index))
+
+    def _on_option_list_option_selected(self, event: OptionList.OptionSelected) -> None:
+        """Capture the `OptionList` selected event and turn it into a [`SelectionList`][textual.widgets.SelectionList] event.
+
+        Args:
+            event: The event to capture and recreate.
+        """
+        event.stop()
+        self._toggle_highlighted_selection()
+        self.post_message(self.SelectionToggled(self, event.option_index))
+
+    def get_option_at_index(self, index: int) -> Selection[SelectionType]:
+        """Get the selection option at the given index.
+
+        Args:
+            index: The index of the selection option to get.
+
+        Returns:
+            The selection option at that index.
+
+        Raises:
+            OptionDoesNotExist: If there is no selection option with the index.
+        """
+        return cast("Selection[SelectionType]", super().get_option_at_index(index))
+
+    def get_option(self, option_id: str) -> Selection[SelectionType]:
+        """Get the selection option with the given ID.
+
+        Args:
+            index: The ID of the selection option to get.
+
+        Returns:
+            The selection option with the ID.
+
+        Raises:
+            OptionDoesNotExist: If no selection option has the given ID.
+        """
+        return cast("Selection[SelectionType]", super().get_option(option_id))
+
+    def _remove_option(self, index: int) -> None:
+        """Remove a selection option from the selection option list.
+
+        Args:
+            index: The index of the selection option to remove.
+
+        Raises:
+            IndexError: If there is no selection option of the given index.
+        """
+        self._deselect(self.get_option_at_index(index).value)
+        return super()._remove_option(index)
+
+    def add_options(
+        self,
+        items: Iterable[
+            NewOptionListContent
+            | Selection
+            | tuple[TextType, SelectionType]
+            | tuple[TextType, SelectionType, bool]
+        ],
+    ) -> Self:
+        """Add new selection options to the end of the list.
+
+        Args:
+            items: The new items to add.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+
+        Raises:
+            DuplicateID: If there is an attempt to use a duplicate ID.
+            SelectionError: If one of the selection options is of the wrong form.
+        """
+        # This... is sort of sub-optimal, but a natural consequence of
+        # inheriting from and narrowing down OptionList. Here we don't want
+        # things like a separator, or a base Option, being passed in. So we
+        # extend the types of accepted items to keep mypy and friends happy,
+        # but then we runtime check that we've been given sensible types (in
+        # this case the supported tuple values).
+        cleaned_options: list[Selection] = []
+        for item in items:
+            if isinstance(item, tuple):
+                cleaned_options.append(
+                    self._make_selection(
+                        cast(
+                            "tuple[TextType, SelectionType] | tuple[TextType, SelectionType, bool]",
+                            item,
+                        )
+                    )
+                )
+            elif isinstance(item, Selection):
+                cleaned_options.append(self._make_selection(item))
+            else:
+                raise SelectionError(
+                    "Only Selection or a prompt/value tuple is supported in SelectionList"
+                )
+        return super().add_options(cleaned_options)
+
+    def add_option(
+        self,
+        item: NewOptionListContent
+        | Selection
+        | tuple[TextType, SelectionType]
+        | tuple[TextType, SelectionType, bool] = None,
+    ) -> Self:
+        """Add a new selection option to the end of the list.
+
+        Args:
+            item: The new item to add.
+
+        Returns:
+            The [`SelectionList`][textual.widgets.SelectionList] instance.
+
+        Raises:
+            DuplicateID: If there is an attempt to use a duplicate ID.
+            SelectionError: If the selection option is of the wrong form.
+        """
+        return self.add_options([item])
diff --git a/src/textual/widgets/selection_list.py b/src/textual/widgets/selection_list.py
new file mode 100644
index 0000000000..06209dbabf
--- /dev/null
+++ b/src/textual/widgets/selection_list.py
@@ -0,0 +1,8 @@
+from ._selection_list import (
+    MessageSelectionType,
+    Selection,
+    SelectionError,
+    SelectionType,
+)
+
+__all__ = ["MessageSelectionType", "Selection", "SelectionError", "SelectionType"]
diff --git a/tests/selection_list/test_selection_list_create.py b/tests/selection_list/test_selection_list_create.py
new file mode 100644
index 0000000000..7df871bf60
--- /dev/null
+++ b/tests/selection_list/test_selection_list_create.py
@@ -0,0 +1,100 @@
+"""Core selection list unit tests, aimed at testing basic list creation.
+
+Note that the vast majority of the API *isn't* tested in here as
+`SelectionList` inherits from `OptionList` and so that would be duplicated
+effort. Instead these tests aim to just test the things that have been
+changed or wrapped in some way.
+"""
+
+from __future__ import annotations
+
+import pytest
+from rich.text import Text
+
+from textual.app import App, ComposeResult
+from textual.widgets import SelectionList
+from textual.widgets.option_list import Option
+from textual.widgets.selection_list import Selection, SelectionError
+
+
+class SelectionListApp(App[None]):
+    """Test selection list application."""
+
+    def compose(self) -> ComposeResult:
+        yield SelectionList[int](
+            ("0", 0),
+            ("1", 1, False),
+            ("2", 2, True),
+            Selection("3", 3, id="3"),
+            Selection("4", 4, True, id="4"),
+        )
+
+
+async def test_all_parameters_become_selctions() -> None:
+    """All input parameters to a list should become selections."""
+    async with SelectionListApp().run_test() as pilot:
+        selections = pilot.app.query_one(SelectionList)
+        assert selections.option_count == 5
+        for n in range(5):
+            assert isinstance(selections.get_option_at_index(n), Selection)
+
+
+async def test_get_selection_by_index() -> None:
+    """It should be possible to get a selection by index."""
+    async with SelectionListApp().run_test() as pilot:
+        option_list = pilot.app.query_one(SelectionList)
+        for n in range(5):
+            assert option_list.get_option_at_index(n).prompt == Text(str(n))
+        assert option_list.get_option_at_index(-1).prompt == Text("4")
+
+
+async def test_get_selection_by_id() -> None:
+    """It should be possible to get a selection by ID."""
+    async with SelectionListApp().run_test() as pilot:
+        option_list = pilot.app.query_one(SelectionList)
+        assert option_list.get_option("3").prompt == Text("3")
+        assert option_list.get_option("4").prompt == Text("4")
+
+
+async def test_add_later() -> None:
+    """It should be possible to add more items to a selection list."""
+    async with SelectionListApp().run_test() as pilot:
+        selections = pilot.app.query_one(SelectionList)
+        assert selections.option_count == 5
+        selections.add_option(("5", 5))
+        assert selections.option_count == 6
+        selections.add_option(Selection("6", 6))
+        assert selections.option_count == 7
+        selections.add_options(
+            [Selection("7", 7), Selection("8", 8, True), ("9", 9), ("10", 10, True)]
+        )
+        assert selections.option_count == 11
+        selections.add_options([])
+        assert selections.option_count == 11
+
+
+async def test_add_later_selcted_state() -> None:
+    """When adding selections later the selected collection should get updated."""
+    async with SelectionListApp().run_test() as pilot:
+        selections = pilot.app.query_one(SelectionList)
+        assert selections.selected == [2, 4]
+        selections.add_option(("5", 5, True))
+        assert selections.selected == [2, 4, 5]
+        selections.add_option(Selection("6", 6, True))
+        assert selections.selected == [2, 4, 5, 6]
+
+
+async def test_add_non_selections() -> None:
+    """Adding options that aren't selections should result in errors."""
+    async with SelectionListApp().run_test() as pilot:
+        selections = pilot.app.query_one(SelectionList)
+        with pytest.raises(SelectionError):
+            selections.add_option(None)
+        with pytest.raises(SelectionError):
+            selections.add_option(Option("Nope"))
+        with pytest.raises(SelectionError):
+            selections.add_option("Nope")
+        with pytest.raises(SelectionError):
+            selections.add_option(("Nope",))
+        with pytest.raises(SelectionError):
+            selections.add_option(("Nope", 0, False, 23))
diff --git a/tests/selection_list/test_selection_messages.py b/tests/selection_list/test_selection_messages.py
new file mode 100644
index 0000000000..5dd68a3535
--- /dev/null
+++ b/tests/selection_list/test_selection_messages.py
@@ -0,0 +1,210 @@
+"""Unit tests aimed at testing the selection list messages.
+
+Note that these tests only cover a subset of the public API of this widget.
+The bulk of the API is inherited from OptionList, and as such there are
+comprehensive tests for that. These tests simply cover the parts of the API
+that have been modified by the child class.
+"""
+
+from __future__ import annotations
+
+from textual import on
+from textual.app import App, ComposeResult
+from textual.messages import Message
+from textual.widgets import OptionList, SelectionList
+
+
+class SelectionListApp(App[None]):
+    """Test selection list application."""
+
+    def __init__(self) -> None:
+        super().__init__()
+        self.messages: list[tuple[str, int | None]] = []
+
+    def compose(self) -> ComposeResult:
+        yield SelectionList[int](*[(str(n), n) for n in range(10)])
+
+    @on(OptionList.OptionHighlighted)
+    @on(OptionList.OptionSelected)
+    @on(SelectionList.SelectionHighlighted)
+    @on(SelectionList.SelectionToggled)
+    @on(SelectionList.SelectedChanged)
+    def _record(self, event: Message) -> None:
+        assert event.control == self.query_one(SelectionList)
+        self.messages.append(
+            (
+                event.__class__.__name__,
+                event.selection_index
+                if isinstance(event, SelectionList.SelectionMessage)
+                else None,
+            )
+        )
+
+
+async def test_messages_on_startup() -> None:
+    """There should be a highlighted message when a non-empty selection list first starts up."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        assert pilot.app.messages == [("SelectionHighlighted", 0)]
+
+
+async def test_new_highlight() -> None:
+    """Setting the highlight to a new option should result in a message."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).highlighted = 2
+        await pilot.pause()
+        assert pilot.app.messages[1:] == [("SelectionHighlighted", 2)]
+
+
+async def test_toggle() -> None:
+    """Toggling an option should result in messages."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).toggle(0)
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+        ]
+
+
+async def test_toggle_via_user() -> None:
+    """Toggling via the user should result in the correct messages."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.press("space")
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+            ("SelectionToggled", 0),
+        ]
+
+
+async def test_toggle_all() -> None:
+    """Toggling all options should result in messages."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).toggle_all()
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+        ]
+
+
+async def test_select() -> None:
+    """Selecting all an option should result in a message."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select(1)
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+        ]
+
+
+async def test_select_selected() -> None:
+    """Selecting an option that is already selected should emit no extra message.."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select(0)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select(0)
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+        ]
+
+
+async def test_select_all() -> None:
+    """Selecting all options should result in messages."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select_all()
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+        ]
+
+
+async def test_select_all_selected() -> None:
+    """Selecting all when all are selected should result in no extra messages."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select_all()
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select_all()
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+        ]
+
+
+async def test_deselect() -> None:
+    """Deselecting an option should result in a message."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select(1)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).deselect(1)
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+            ("SelectedChanged", None),
+        ]
+
+
+async def test_deselect_deselected() -> None:
+    """Deselecting a deselected option should result in no extra messages."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).deselect(0)
+        await pilot.pause()
+        assert pilot.app.messages == [("SelectionHighlighted", 0)]
+
+
+async def test_deselect_all() -> None:
+    """Deselecting all options should result in no additional."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).deselect_all()
+        await pilot.pause()
+        assert pilot.app.messages == [("SelectionHighlighted", 0)]
+
+
+async def test_select_then_deselect_all() -> None:
+    """Selecting and then deselecting all options should result in messages."""
+    async with SelectionListApp().run_test() as pilot:
+        assert isinstance(pilot.app, SelectionListApp)
+        await pilot.pause()
+        pilot.app.query_one(SelectionList).select_all()
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+        ]
+        pilot.app.query_one(SelectionList).deselect_all()
+        await pilot.pause()
+        assert pilot.app.messages == [
+            ("SelectionHighlighted", 0),
+            ("SelectedChanged", None),
+            ("SelectedChanged", None),
+        ]
diff --git a/tests/selection_list/test_selection_values.py b/tests/selection_list/test_selection_values.py
new file mode 100644
index 0000000000..0e2779b0ca
--- /dev/null
+++ b/tests/selection_list/test_selection_values.py
@@ -0,0 +1,82 @@
+"""Unit tests dealing with the tracking of selection list values."""
+
+from __future__ import annotations
+
+from textual.app import App, ComposeResult
+from textual.widgets import SelectionList
+
+
+class SelectionListApp(App[None]):
+    def __init__(self, default_state: bool = False) -> None:
+        super().__init__()
+        self._default_state = default_state
+
+    def compose(self) -> ComposeResult:
+        yield SelectionList[int](*[(str(n), n, self._default_state) for n in range(50)])
+
+
+async def test_empty_selected() -> None:
+    """Selected should be empty when nothing is selected."""
+    async with SelectionListApp().run_test() as pilot:
+        assert pilot.app.query_one(SelectionList).selected == []
+
+
+async def test_programatic_select() -> None:
+    """Selected should contain a selected value."""
+    async with SelectionListApp().run_test() as pilot:
+        selection = pilot.app.query_one(SelectionList)
+        selection.select(0)
+        assert pilot.app.query_one(SelectionList).selected == [0]
+
+
+async def test_programatic_select_all() -> None:
+    """Selected should contain all selected values."""
+    async with SelectionListApp().run_test() as pilot:
+        selection = pilot.app.query_one(SelectionList)
+        selection.select_all()
+        assert pilot.app.query_one(SelectionList).selected == list(range(50))
+
+
+async def test_programatic_deselect() -> None:
+    """Selected should not contain a deselected value."""
+    async with SelectionListApp(True).run_test() as pilot:
+        selection = pilot.app.query_one(SelectionList)
+        selection.deselect(0)
+        assert pilot.app.query_one(SelectionList).selected == list(range(50)[1:])
+
+
+async def test_programatic_deselect_all() -> None:
+    """Selected should not contain anything after deselecting all values."""
+    async with SelectionListApp(True).run_test() as pilot:
+        selection = pilot.app.query_one(SelectionList)
+        selection.deselect_all()
+        assert pilot.app.query_one(SelectionList).selected == []
+
+
+async def test_programatic_toggle() -> None:
+    """Selected should reflect a toggle."""
+    async with SelectionListApp().run_test() as pilot:
+        selection = pilot.app.query_one(SelectionList)
+        for n in range(25, 50):
+            selection.select(n)
+        for n in range(50):
+            selection.toggle(n)
+        assert pilot.app.query_one(SelectionList).selected == list(range(50)[:25])
+
+
+async def test_programatic_toggle_all() -> None:
+    """Selected should contain all values after toggling all on."""
+    async with SelectionListApp().run_test() as pilot:
+        selection = pilot.app.query_one(SelectionList)
+        selection.toggle_all()
+        assert pilot.app.query_one(SelectionList).selected == list(range(50))
+
+
+async def test_removal_of_selected_item() -> None:
+    """Removing a selected selection should remove its value from the selected set."""
+    async with SelectionListApp().run_test() as pilot:
+        selection = pilot.app.query_one(SelectionList)
+        selection.toggle(0)
+        assert pilot.app.query_one(SelectionList).selected == [0]
+        selection.remove_option_at_index(0)
+        assert pilot.app.query_one(SelectionList).selected == []
diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
index 7013a574ac..ea041f7723 100644
--- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
+++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
@@ -23523,6 +23523,497 @@
   
   '''
 # ---
+# name: test_selection_list
+  '''
+  <svg class="rich-terminal" viewBox="0 0 994 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
+      <!-- Generated with Rich https://www.textualize.io -->
+      <style>
+  
+      @font-face {
+          font-family: "Fira Code";
+          src: local("FiraCode-Regular"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
+          font-style: normal;
+          font-weight: 400;
+      }
+      @font-face {
+          font-family: "Fira Code";
+          src: local("FiraCode-Bold"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
+          font-style: bold;
+          font-weight: 700;
+      }
+  
+      .terminal-11693157-matrix {
+          font-family: Fira Code, monospace;
+          font-size: 20px;
+          line-height: 24.4px;
+          font-variant-east-asian: full-width;
+      }
+  
+      .terminal-11693157-title {
+          font-size: 18px;
+          font-weight: bold;
+          font-family: arial;
+      }
+  
+      .terminal-11693157-r1 { fill: #c5c8c6 }
+  .terminal-11693157-r2 { fill: #e3e3e3 }
+  .terminal-11693157-r3 { fill: #e1e1e1 }
+  .terminal-11693157-r4 { fill: #0178d4 }
+  .terminal-11693157-r5 { fill: #e1e1e1;font-weight: bold }
+  .terminal-11693157-r6 { fill: #62666a }
+  .terminal-11693157-r7 { fill: #4ebf71;font-weight: bold }
+  .terminal-11693157-r8 { fill: #ddedf9;font-weight: bold }
+  .terminal-11693157-r9 { fill: #98a84b }
+  .terminal-11693157-r10 { fill: #34393f;font-weight: bold }
+  .terminal-11693157-r11 { fill: #e4e5e6 }
+  .terminal-11693157-r12 { fill: #ddedf9 }
+      </style>
+  
+      <defs>
+      <clipPath id="terminal-11693157-clip-terminal">
+        <rect x="0" y="0" width="975.0" height="584.5999999999999" />
+      </clipPath>
+      <clipPath id="terminal-11693157-line-0">
+      <rect x="0" y="1.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-1">
+      <rect x="0" y="25.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-2">
+      <rect x="0" y="50.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-3">
+      <rect x="0" y="74.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-4">
+      <rect x="0" y="99.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-5">
+      <rect x="0" y="123.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-6">
+      <rect x="0" y="147.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-7">
+      <rect x="0" y="172.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-8">
+      <rect x="0" y="196.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-9">
+      <rect x="0" y="221.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-10">
+      <rect x="0" y="245.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-11">
+      <rect x="0" y="269.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-12">
+      <rect x="0" y="294.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-13">
+      <rect x="0" y="318.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-14">
+      <rect x="0" y="343.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-15">
+      <rect x="0" y="367.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-16">
+      <rect x="0" y="391.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-17">
+      <rect x="0" y="416.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-18">
+      <rect x="0" y="440.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-19">
+      <rect x="0" y="465.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-20">
+      <rect x="0" y="489.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-21">
+      <rect x="0" y="513.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-11693157-line-22">
+      <rect x="0" y="538.3" width="976" height="24.65"/>
+              </clipPath>
+      </defs>
+  
+      <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="633.6" rx="8"/><text class="terminal-11693157-title" fill="#c5c8c6" text-anchor="middle" x="496" y="27">SelectionListApp</text>
+              <g transform="translate(26,22)">
+              <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+              <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+              <circle cx="44" cy="0" r="7" fill="#28c840"/>
+              </g>
+          
+      <g transform="translate(9, 41)" clip-path="url(#terminal-11693157-clip-terminal)">
+      <rect fill="#282828" x="0" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="12.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="24.4" y="1.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="85.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="97.6" y="1.5" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="378.2" y="1.5" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="573.4" y="1.5" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="854" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="866.2" y="1.5" width="0" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="866.2" y="1.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="963.8" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="25.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="50.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="74.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="74.7" width="329.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="451.4" y="74.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="512.4" y="74.7" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="707.6" y="74.7" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="74.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="99.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="99.1" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="512.4" y="99.1" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="99.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="123.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="122" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="146.4" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="158.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="170.8" y="123.5" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="329.4" y="123.5" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="123.5" width="48.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="549" y="123.5" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="768.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="780.8" y="123.5" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="123.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="147.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="147.9" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="292.8" y="147.9" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="147.9" width="48.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="549" y="147.9" width="268.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="817.4" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="829.6" y="147.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="147.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="172.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="172.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="280.6" y="172.3" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="172.3" width="48.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="549" y="172.3" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="744.2" y="172.3" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="172.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="196.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="196.7" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="244" y="196.7" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="512.4" y="196.7" width="353.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="196.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="221.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="221.1" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="244" y="221.1" width="219.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="221.1" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="221.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="268.4" y="245.5" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="245.5" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="269.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="269.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="231.8" y="269.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="269.9" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="269.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="294.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="294.3" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="231.8" y="294.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="294.3" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="294.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="318.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="318.7" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="341.6" y="318.7" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="318.7" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="318.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="343.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="343.1" width="341.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="343.1" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="343.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="367.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="367.5" width="341.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="367.5" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="367.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="391.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="391.9" width="341.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="391.9" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="391.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="416.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="416.3" width="341.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="463.6" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="416.3" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="416.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="440.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="440.7" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="440.7" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="440.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="465.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="465.1" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="475.8" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="488" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="500.2" y="465.1" width="366" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="866.2" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="465.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="489.5" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="513.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="538.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="0" y="562.7" width="976" height="24.65" shape-rendering="crispEdges"/>
+      <g class="terminal-11693157-matrix">
+      <text class="terminal-11693157-r2" x="12.2" y="20" textLength="12.2" clip-path="url(#terminal-11693157-line-0)">⭘</text><text class="terminal-11693157-r2" x="378.2" y="20" textLength="195.2" clip-path="url(#terminal-11693157-line-0)">SelectionListApp</text><text class="terminal-11693157-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-11693157-line-0)">
+  </text><text class="terminal-11693157-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-11693157-line-1)">
+  </text><text class="terminal-11693157-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-11693157-line-2)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="93.2" textLength="12.2" clip-path="url(#terminal-11693157-line-3)">┌</text><text class="terminal-11693157-r4" x="109.8" y="93.2" textLength="12.2" clip-path="url(#terminal-11693157-line-3)">─</text><text class="terminal-11693157-r4" x="122" y="93.2" textLength="329.4" clip-path="url(#terminal-11693157-line-3)">&#160;Shall&#160;we&#160;play&#160;some&#160;games?&#160;</text><text class="terminal-11693157-r4" x="451.4" y="93.2" textLength="24.4" clip-path="url(#terminal-11693157-line-3)">──</text><text class="terminal-11693157-r4" x="475.8" y="93.2" textLength="12.2" clip-path="url(#terminal-11693157-line-3)">┐</text><text class="terminal-11693157-r4" x="488" y="93.2" textLength="12.2" clip-path="url(#terminal-11693157-line-3)">┌</text><text class="terminal-11693157-r4" x="500.2" y="93.2" textLength="12.2" clip-path="url(#terminal-11693157-line-3)">─</text><text class="terminal-11693157-r4" x="512.4" y="93.2" textLength="195.2" clip-path="url(#terminal-11693157-line-3)">&#160;Selected&#160;games&#160;</text><text class="terminal-11693157-r4" x="707.6" y="93.2" textLength="158.6" clip-path="url(#terminal-11693157-line-3)">─────────────</text><text class="terminal-11693157-r4" x="866.2" y="93.2" textLength="12.2" clip-path="url(#terminal-11693157-line-3)">┐</text><text class="terminal-11693157-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-11693157-line-3)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="117.6" textLength="12.2" clip-path="url(#terminal-11693157-line-4)">│</text><text class="terminal-11693157-r4" x="475.8" y="117.6" textLength="12.2" clip-path="url(#terminal-11693157-line-4)">│</text><text class="terminal-11693157-r4" x="488" y="117.6" textLength="12.2" clip-path="url(#terminal-11693157-line-4)">│</text><text class="terminal-11693157-r5" x="500.2" y="117.6" textLength="12.2" clip-path="url(#terminal-11693157-line-4)">[</text><text class="terminal-11693157-r4" x="866.2" y="117.6" textLength="12.2" clip-path="url(#terminal-11693157-line-4)">│</text><text class="terminal-11693157-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-11693157-line-4)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">│</text><text class="terminal-11693157-r6" x="122" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">▐</text><text class="terminal-11693157-r7" x="134.2" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">X</text><text class="terminal-11693157-r6" x="146.4" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">▌</text><text class="terminal-11693157-r8" x="170.8" y="142" textLength="158.6" clip-path="url(#terminal-11693157-line-5)">Falken&#x27;s&#160;Maze</text><text class="terminal-11693157-r4" x="475.8" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">│</text><text class="terminal-11693157-r4" x="488" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">│</text><text class="terminal-11693157-r9" x="549" y="142" textLength="219.6" clip-path="url(#terminal-11693157-line-5)">&#x27;secret_back_door&#x27;</text><text class="terminal-11693157-r3" x="768.6" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">,</text><text class="terminal-11693157-r4" x="866.2" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">│</text><text class="terminal-11693157-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-11693157-line-5)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">│</text><text class="terminal-11693157-r6" x="122" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">▐</text><text class="terminal-11693157-r10" x="134.2" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">X</text><text class="terminal-11693157-r6" x="146.4" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">▌</text><text class="terminal-11693157-r11" x="170.8" y="166.4" textLength="122" clip-path="url(#terminal-11693157-line-6)">Black&#160;Jack</text><text class="terminal-11693157-r4" x="475.8" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">│</text><text class="terminal-11693157-r4" x="488" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">│</text><text class="terminal-11693157-r9" x="549" y="166.4" textLength="268.4" clip-path="url(#terminal-11693157-line-6)">&#x27;a_nice_game_of_chess&#x27;</text><text class="terminal-11693157-r3" x="817.4" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">,</text><text class="terminal-11693157-r4" x="866.2" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">│</text><text class="terminal-11693157-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-11693157-line-6)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">│</text><text class="terminal-11693157-r6" x="122" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">▐</text><text class="terminal-11693157-r10" x="134.2" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">X</text><text class="terminal-11693157-r6" x="146.4" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">▌</text><text class="terminal-11693157-r11" x="170.8" y="190.8" textLength="109.8" clip-path="url(#terminal-11693157-line-7)">Gin&#160;Rummy</text><text class="terminal-11693157-r4" x="475.8" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">│</text><text class="terminal-11693157-r4" x="488" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">│</text><text class="terminal-11693157-r9" x="549" y="190.8" textLength="195.2" clip-path="url(#terminal-11693157-line-7)">&#x27;fighter_combat&#x27;</text><text class="terminal-11693157-r4" x="866.2" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">│</text><text class="terminal-11693157-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-11693157-line-7)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">│</text><text class="terminal-11693157-r6" x="122" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">▐</text><text class="terminal-11693157-r10" x="134.2" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">X</text><text class="terminal-11693157-r6" x="146.4" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">▌</text><text class="terminal-11693157-r11" x="170.8" y="215.2" textLength="73.2" clip-path="url(#terminal-11693157-line-8)">Hearts</text><text class="terminal-11693157-r4" x="475.8" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">│</text><text class="terminal-11693157-r4" x="488" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">│</text><text class="terminal-11693157-r5" x="500.2" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">]</text><text class="terminal-11693157-r4" x="866.2" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">│</text><text class="terminal-11693157-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-11693157-line-8)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">│</text><text class="terminal-11693157-r6" x="122" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">▐</text><text class="terminal-11693157-r10" x="134.2" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">X</text><text class="terminal-11693157-r6" x="146.4" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">▌</text><text class="terminal-11693157-r11" x="170.8" y="239.6" textLength="73.2" clip-path="url(#terminal-11693157-line-9)">Bridge</text><text class="terminal-11693157-r4" x="475.8" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">│</text><text class="terminal-11693157-r4" x="488" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">│</text><text class="terminal-11693157-r4" x="866.2" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">│</text><text class="terminal-11693157-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-11693157-line-9)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">│</text><text class="terminal-11693157-r6" x="122" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">▐</text><text class="terminal-11693157-r10" x="134.2" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">X</text><text class="terminal-11693157-r6" x="146.4" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">▌</text><text class="terminal-11693157-r11" x="170.8" y="264" textLength="97.6" clip-path="url(#terminal-11693157-line-10)">Checkers</text><text class="terminal-11693157-r4" x="475.8" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">│</text><text class="terminal-11693157-r4" x="488" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">│</text><text class="terminal-11693157-r4" x="866.2" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">│</text><text class="terminal-11693157-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-11693157-line-10)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">│</text><text class="terminal-11693157-r6" x="122" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">▐</text><text class="terminal-11693157-r7" x="134.2" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">X</text><text class="terminal-11693157-r6" x="146.4" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">▌</text><text class="terminal-11693157-r11" x="170.8" y="288.4" textLength="61" clip-path="url(#terminal-11693157-line-11)">Chess</text><text class="terminal-11693157-r4" x="475.8" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">│</text><text class="terminal-11693157-r4" x="488" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">│</text><text class="terminal-11693157-r4" x="866.2" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">│</text><text class="terminal-11693157-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-11693157-line-11)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">│</text><text class="terminal-11693157-r6" x="122" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">▐</text><text class="terminal-11693157-r10" x="134.2" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">X</text><text class="terminal-11693157-r6" x="146.4" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">▌</text><text class="terminal-11693157-r11" x="170.8" y="312.8" textLength="61" clip-path="url(#terminal-11693157-line-12)">Poker</text><text class="terminal-11693157-r4" x="475.8" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">│</text><text class="terminal-11693157-r4" x="488" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">│</text><text class="terminal-11693157-r4" x="866.2" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">│</text><text class="terminal-11693157-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-11693157-line-12)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">│</text><text class="terminal-11693157-r6" x="122" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">▐</text><text class="terminal-11693157-r7" x="134.2" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">X</text><text class="terminal-11693157-r6" x="146.4" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">▌</text><text class="terminal-11693157-r11" x="170.8" y="337.2" textLength="170.8" clip-path="url(#terminal-11693157-line-13)">Fighter&#160;Combat</text><text class="terminal-11693157-r4" x="475.8" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">│</text><text class="terminal-11693157-r4" x="488" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">│</text><text class="terminal-11693157-r4" x="866.2" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">│</text><text class="terminal-11693157-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-11693157-line-13)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="361.6" textLength="12.2" clip-path="url(#terminal-11693157-line-14)">│</text><text class="terminal-11693157-r4" x="475.8" y="361.6" textLength="12.2" clip-path="url(#terminal-11693157-line-14)">│</text><text class="terminal-11693157-r4" x="488" y="361.6" textLength="12.2" clip-path="url(#terminal-11693157-line-14)">│</text><text class="terminal-11693157-r4" x="866.2" y="361.6" textLength="12.2" clip-path="url(#terminal-11693157-line-14)">│</text><text class="terminal-11693157-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-11693157-line-14)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="386" textLength="12.2" clip-path="url(#terminal-11693157-line-15)">│</text><text class="terminal-11693157-r4" x="475.8" y="386" textLength="12.2" clip-path="url(#terminal-11693157-line-15)">│</text><text class="terminal-11693157-r4" x="488" y="386" textLength="12.2" clip-path="url(#terminal-11693157-line-15)">│</text><text class="terminal-11693157-r4" x="866.2" y="386" textLength="12.2" clip-path="url(#terminal-11693157-line-15)">│</text><text class="terminal-11693157-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-11693157-line-15)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="410.4" textLength="12.2" clip-path="url(#terminal-11693157-line-16)">│</text><text class="terminal-11693157-r4" x="475.8" y="410.4" textLength="12.2" clip-path="url(#terminal-11693157-line-16)">│</text><text class="terminal-11693157-r4" x="488" y="410.4" textLength="12.2" clip-path="url(#terminal-11693157-line-16)">│</text><text class="terminal-11693157-r4" x="866.2" y="410.4" textLength="12.2" clip-path="url(#terminal-11693157-line-16)">│</text><text class="terminal-11693157-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-11693157-line-16)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="434.8" textLength="12.2" clip-path="url(#terminal-11693157-line-17)">│</text><text class="terminal-11693157-r4" x="475.8" y="434.8" textLength="12.2" clip-path="url(#terminal-11693157-line-17)">│</text><text class="terminal-11693157-r4" x="488" y="434.8" textLength="12.2" clip-path="url(#terminal-11693157-line-17)">│</text><text class="terminal-11693157-r4" x="866.2" y="434.8" textLength="12.2" clip-path="url(#terminal-11693157-line-17)">│</text><text class="terminal-11693157-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-11693157-line-17)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="459.2" textLength="12.2" clip-path="url(#terminal-11693157-line-18)">│</text><text class="terminal-11693157-r4" x="475.8" y="459.2" textLength="12.2" clip-path="url(#terminal-11693157-line-18)">│</text><text class="terminal-11693157-r4" x="488" y="459.2" textLength="12.2" clip-path="url(#terminal-11693157-line-18)">│</text><text class="terminal-11693157-r4" x="866.2" y="459.2" textLength="12.2" clip-path="url(#terminal-11693157-line-18)">│</text><text class="terminal-11693157-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-11693157-line-18)">
+  </text><text class="terminal-11693157-r4" x="97.6" y="483.6" textLength="12.2" clip-path="url(#terminal-11693157-line-19)">└</text><text class="terminal-11693157-r4" x="109.8" y="483.6" textLength="366" clip-path="url(#terminal-11693157-line-19)">──────────────────────────────</text><text class="terminal-11693157-r4" x="475.8" y="483.6" textLength="12.2" clip-path="url(#terminal-11693157-line-19)">┘</text><text class="terminal-11693157-r4" x="488" y="483.6" textLength="12.2" clip-path="url(#terminal-11693157-line-19)">└</text><text class="terminal-11693157-r4" x="500.2" y="483.6" textLength="366" clip-path="url(#terminal-11693157-line-19)">──────────────────────────────</text><text class="terminal-11693157-r4" x="866.2" y="483.6" textLength="12.2" clip-path="url(#terminal-11693157-line-19)">┘</text><text class="terminal-11693157-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-11693157-line-19)">
+  </text><text class="terminal-11693157-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-11693157-line-20)">
+  </text><text class="terminal-11693157-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-11693157-line-21)">
+  </text><text class="terminal-11693157-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-11693157-line-22)">
+  </text>
+      </g>
+      </g>
+  </svg>
+  
+  '''
+# ---
+# name: test_selection_list.1
+  '''
+  <svg class="rich-terminal" viewBox="0 0 994 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
+      <!-- Generated with Rich https://www.textualize.io -->
+      <style>
+  
+      @font-face {
+          font-family: "Fira Code";
+          src: local("FiraCode-Regular"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
+          font-style: normal;
+          font-weight: 400;
+      }
+      @font-face {
+          font-family: "Fira Code";
+          src: local("FiraCode-Bold"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
+          font-style: bold;
+          font-weight: 700;
+      }
+  
+      .terminal-3782657965-matrix {
+          font-family: Fira Code, monospace;
+          font-size: 20px;
+          line-height: 24.4px;
+          font-variant-east-asian: full-width;
+      }
+  
+      .terminal-3782657965-title {
+          font-size: 18px;
+          font-weight: bold;
+          font-family: arial;
+      }
+  
+      .terminal-3782657965-r1 { fill: #c5c8c6 }
+  .terminal-3782657965-r2 { fill: #e3e3e3 }
+  .terminal-3782657965-r3 { fill: #e1e1e1 }
+  .terminal-3782657965-r4 { fill: #0178d4 }
+  .terminal-3782657965-r5 { fill: #62666a }
+  .terminal-3782657965-r6 { fill: #4ebf71;font-weight: bold }
+  .terminal-3782657965-r7 { fill: #ddedf9;font-weight: bold }
+  .terminal-3782657965-r8 { fill: #34393f;font-weight: bold }
+  .terminal-3782657965-r9 { fill: #e4e5e6 }
+  .terminal-3782657965-r10 { fill: #ddedf9 }
+      </style>
+  
+      <defs>
+      <clipPath id="terminal-3782657965-clip-terminal">
+        <rect x="0" y="0" width="975.0" height="584.5999999999999" />
+      </clipPath>
+      <clipPath id="terminal-3782657965-line-0">
+      <rect x="0" y="1.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-1">
+      <rect x="0" y="25.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-2">
+      <rect x="0" y="50.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-3">
+      <rect x="0" y="74.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-4">
+      <rect x="0" y="99.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-5">
+      <rect x="0" y="123.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-6">
+      <rect x="0" y="147.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-7">
+      <rect x="0" y="172.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-8">
+      <rect x="0" y="196.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-9">
+      <rect x="0" y="221.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-10">
+      <rect x="0" y="245.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-11">
+      <rect x="0" y="269.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-12">
+      <rect x="0" y="294.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-13">
+      <rect x="0" y="318.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-14">
+      <rect x="0" y="343.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-15">
+      <rect x="0" y="367.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-16">
+      <rect x="0" y="391.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-17">
+      <rect x="0" y="416.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-18">
+      <rect x="0" y="440.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-19">
+      <rect x="0" y="465.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-20">
+      <rect x="0" y="489.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-21">
+      <rect x="0" y="513.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-22">
+      <rect x="0" y="538.3" width="976" height="24.65"/>
+              </clipPath>
+      </defs>
+  
+      <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="633.6" rx="8"/><text class="terminal-3782657965-title" fill="#c5c8c6" text-anchor="middle" x="496" y="27">SelectionListApp</text>
+              <g transform="translate(26,22)">
+              <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+              <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+              <circle cx="44" cy="0" r="7" fill="#28c840"/>
+              </g>
+          
+      <g transform="translate(9, 41)" clip-path="url(#terminal-3782657965-clip-terminal)">
+      <rect fill="#282828" x="0" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="12.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="24.4" y="1.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="85.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="97.6" y="1.5" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="378.2" y="1.5" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="573.4" y="1.5" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="854" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="866.2" y="1.5" width="0" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="866.2" y="1.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="963.8" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="25.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="50.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="74.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="74.7" width="329.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="451.4" y="74.7" width="414.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="74.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="99.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="99.1" width="756.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="99.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="123.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="122" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="146.4" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="158.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="170.8" y="123.5" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="329.4" y="123.5" width="524.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="123.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="147.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="147.9" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="292.8" y="147.9" width="561.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="147.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="172.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="172.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="280.6" y="172.3" width="573.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="172.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="196.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="196.7" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="244" y="196.7" width="610" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="196.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="221.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="221.1" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="244" y="221.1" width="610" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="221.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="268.4" y="245.5" width="585.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="269.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="269.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="231.8" y="269.9" width="622.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="269.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="294.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="294.3" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="231.8" y="294.3" width="622.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="294.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="318.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="318.7" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="341.6" y="318.7" width="512.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="318.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="343.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="343.1" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="343.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="367.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="367.5" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="367.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="391.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="391.9" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="391.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="416.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="416.3" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="416.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="440.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="440.7" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="440.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="465.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="465.1" width="756.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="465.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="489.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="489.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="489.5" width="756.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="489.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="489.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="513.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="538.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="0" y="562.7" width="976" height="24.65" shape-rendering="crispEdges"/>
+      <g class="terminal-3782657965-matrix">
+      <text class="terminal-3782657965-r2" x="12.2" y="20" textLength="12.2" clip-path="url(#terminal-3782657965-line-0)">⭘</text><text class="terminal-3782657965-r2" x="378.2" y="20" textLength="195.2" clip-path="url(#terminal-3782657965-line-0)">SelectionListApp</text><text class="terminal-3782657965-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-3782657965-line-0)">
+  </text><text class="terminal-3782657965-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-1)">
+  </text><text class="terminal-3782657965-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-2)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">┌</text><text class="terminal-3782657965-r4" x="109.8" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">─</text><text class="terminal-3782657965-r4" x="122" y="93.2" textLength="329.4" clip-path="url(#terminal-3782657965-line-3)">&#160;Shall&#160;we&#160;play&#160;some&#160;games?&#160;</text><text class="terminal-3782657965-r4" x="451.4" y="93.2" textLength="414.8" clip-path="url(#terminal-3782657965-line-3)">──────────────────────────────────</text><text class="terminal-3782657965-r4" x="866.2" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">┐</text><text class="terminal-3782657965-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="117.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-4)">│</text><text class="terminal-3782657965-r4" x="866.2" y="117.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-4)">│</text><text class="terminal-3782657965-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-4)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">│</text><text class="terminal-3782657965-r5" x="122" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">▐</text><text class="terminal-3782657965-r6" x="134.2" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">X</text><text class="terminal-3782657965-r5" x="146.4" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">▌</text><text class="terminal-3782657965-r7" x="170.8" y="142" textLength="158.6" clip-path="url(#terminal-3782657965-line-5)">Falken&#x27;s&#160;Maze</text><text class="terminal-3782657965-r4" x="866.2" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">│</text><text class="terminal-3782657965-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">│</text><text class="terminal-3782657965-r5" x="122" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">X</text><text class="terminal-3782657965-r5" x="146.4" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="166.4" textLength="122" clip-path="url(#terminal-3782657965-line-6)">Black&#160;Jack</text><text class="terminal-3782657965-r4" x="866.2" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">│</text><text class="terminal-3782657965-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">│</text><text class="terminal-3782657965-r5" x="122" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">X</text><text class="terminal-3782657965-r5" x="146.4" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="190.8" textLength="109.8" clip-path="url(#terminal-3782657965-line-7)">Gin&#160;Rummy</text><text class="terminal-3782657965-r4" x="866.2" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">│</text><text class="terminal-3782657965-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">│</text><text class="terminal-3782657965-r5" x="122" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">X</text><text class="terminal-3782657965-r5" x="146.4" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="215.2" textLength="73.2" clip-path="url(#terminal-3782657965-line-8)">Hearts</text><text class="terminal-3782657965-r4" x="866.2" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">│</text><text class="terminal-3782657965-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">│</text><text class="terminal-3782657965-r5" x="122" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">X</text><text class="terminal-3782657965-r5" x="146.4" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="239.6" textLength="73.2" clip-path="url(#terminal-3782657965-line-9)">Bridge</text><text class="terminal-3782657965-r4" x="866.2" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">│</text><text class="terminal-3782657965-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">│</text><text class="terminal-3782657965-r5" x="122" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">X</text><text class="terminal-3782657965-r5" x="146.4" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="264" textLength="97.6" clip-path="url(#terminal-3782657965-line-10)">Checkers</text><text class="terminal-3782657965-r4" x="866.2" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">│</text><text class="terminal-3782657965-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">│</text><text class="terminal-3782657965-r5" x="122" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">▐</text><text class="terminal-3782657965-r6" x="134.2" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">X</text><text class="terminal-3782657965-r5" x="146.4" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="288.4" textLength="61" clip-path="url(#terminal-3782657965-line-11)">Chess</text><text class="terminal-3782657965-r4" x="866.2" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">│</text><text class="terminal-3782657965-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">│</text><text class="terminal-3782657965-r5" x="122" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">X</text><text class="terminal-3782657965-r5" x="146.4" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="312.8" textLength="61" clip-path="url(#terminal-3782657965-line-12)">Poker</text><text class="terminal-3782657965-r4" x="866.2" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">│</text><text class="terminal-3782657965-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">│</text><text class="terminal-3782657965-r5" x="122" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">▐</text><text class="terminal-3782657965-r6" x="134.2" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">X</text><text class="terminal-3782657965-r5" x="146.4" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="337.2" textLength="170.8" clip-path="url(#terminal-3782657965-line-13)">Fighter&#160;Combat</text><text class="terminal-3782657965-r4" x="866.2" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">│</text><text class="terminal-3782657965-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="361.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-14)">│</text><text class="terminal-3782657965-r4" x="866.2" y="361.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-14)">│</text><text class="terminal-3782657965-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-14)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="386" textLength="12.2" clip-path="url(#terminal-3782657965-line-15)">│</text><text class="terminal-3782657965-r4" x="866.2" y="386" textLength="12.2" clip-path="url(#terminal-3782657965-line-15)">│</text><text class="terminal-3782657965-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-3782657965-line-15)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="410.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-16)">│</text><text class="terminal-3782657965-r4" x="866.2" y="410.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-16)">│</text><text class="terminal-3782657965-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-16)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="434.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-17)">│</text><text class="terminal-3782657965-r4" x="866.2" y="434.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-17)">│</text><text class="terminal-3782657965-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-17)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="459.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-18)">│</text><text class="terminal-3782657965-r4" x="866.2" y="459.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-18)">│</text><text class="terminal-3782657965-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-18)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="483.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-19)">│</text><text class="terminal-3782657965-r4" x="866.2" y="483.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-19)">│</text><text class="terminal-3782657965-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-19)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="508" textLength="12.2" clip-path="url(#terminal-3782657965-line-20)">└</text><text class="terminal-3782657965-r4" x="109.8" y="508" textLength="756.4" clip-path="url(#terminal-3782657965-line-20)">──────────────────────────────────────────────────────────────</text><text class="terminal-3782657965-r4" x="866.2" y="508" textLength="12.2" clip-path="url(#terminal-3782657965-line-20)">┘</text><text class="terminal-3782657965-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-3782657965-line-20)">
+  </text><text class="terminal-3782657965-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-21)">
+  </text><text class="terminal-3782657965-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-22)">
+  </text>
+      </g>
+      </g>
+  </svg>
+  
+  '''
+# ---
+# name: test_selection_list.2
+  '''
+  <svg class="rich-terminal" viewBox="0 0 994 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
+      <!-- Generated with Rich https://www.textualize.io -->
+      <style>
+  
+      @font-face {
+          font-family: "Fira Code";
+          src: local("FiraCode-Regular"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
+          font-style: normal;
+          font-weight: 400;
+      }
+      @font-face {
+          font-family: "Fira Code";
+          src: local("FiraCode-Bold"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
+                  url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
+          font-style: bold;
+          font-weight: 700;
+      }
+  
+      .terminal-3782657965-matrix {
+          font-family: Fira Code, monospace;
+          font-size: 20px;
+          line-height: 24.4px;
+          font-variant-east-asian: full-width;
+      }
+  
+      .terminal-3782657965-title {
+          font-size: 18px;
+          font-weight: bold;
+          font-family: arial;
+      }
+  
+      .terminal-3782657965-r1 { fill: #c5c8c6 }
+  .terminal-3782657965-r2 { fill: #e3e3e3 }
+  .terminal-3782657965-r3 { fill: #e1e1e1 }
+  .terminal-3782657965-r4 { fill: #0178d4 }
+  .terminal-3782657965-r5 { fill: #62666a }
+  .terminal-3782657965-r6 { fill: #4ebf71;font-weight: bold }
+  .terminal-3782657965-r7 { fill: #ddedf9;font-weight: bold }
+  .terminal-3782657965-r8 { fill: #34393f;font-weight: bold }
+  .terminal-3782657965-r9 { fill: #e4e5e6 }
+  .terminal-3782657965-r10 { fill: #ddedf9 }
+      </style>
+  
+      <defs>
+      <clipPath id="terminal-3782657965-clip-terminal">
+        <rect x="0" y="0" width="975.0" height="584.5999999999999" />
+      </clipPath>
+      <clipPath id="terminal-3782657965-line-0">
+      <rect x="0" y="1.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-1">
+      <rect x="0" y="25.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-2">
+      <rect x="0" y="50.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-3">
+      <rect x="0" y="74.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-4">
+      <rect x="0" y="99.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-5">
+      <rect x="0" y="123.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-6">
+      <rect x="0" y="147.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-7">
+      <rect x="0" y="172.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-8">
+      <rect x="0" y="196.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-9">
+      <rect x="0" y="221.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-10">
+      <rect x="0" y="245.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-11">
+      <rect x="0" y="269.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-12">
+      <rect x="0" y="294.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-13">
+      <rect x="0" y="318.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-14">
+      <rect x="0" y="343.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-15">
+      <rect x="0" y="367.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-16">
+      <rect x="0" y="391.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-17">
+      <rect x="0" y="416.3" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-18">
+      <rect x="0" y="440.7" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-19">
+      <rect x="0" y="465.1" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-20">
+      <rect x="0" y="489.5" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-21">
+      <rect x="0" y="513.9" width="976" height="24.65"/>
+              </clipPath>
+  <clipPath id="terminal-3782657965-line-22">
+      <rect x="0" y="538.3" width="976" height="24.65"/>
+              </clipPath>
+      </defs>
+  
+      <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="633.6" rx="8"/><text class="terminal-3782657965-title" fill="#c5c8c6" text-anchor="middle" x="496" y="27">SelectionListApp</text>
+              <g transform="translate(26,22)">
+              <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+              <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+              <circle cx="44" cy="0" r="7" fill="#28c840"/>
+              </g>
+          
+      <g transform="translate(9, 41)" clip-path="url(#terminal-3782657965-clip-terminal)">
+      <rect fill="#282828" x="0" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="12.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="24.4" y="1.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="85.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="97.6" y="1.5" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="378.2" y="1.5" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="573.4" y="1.5" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="854" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="866.2" y="1.5" width="0" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="866.2" y="1.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#282828" x="963.8" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="25.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="50.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="74.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="74.7" width="329.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="451.4" y="74.7" width="414.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="74.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="74.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="99.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="99.1" width="756.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="99.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="99.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="123.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="122" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="146.4" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="158.6" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="170.8" y="123.5" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="329.4" y="123.5" width="524.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="123.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="123.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="147.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="147.9" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="292.8" y="147.9" width="561.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="147.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="147.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="172.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="172.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="280.6" y="172.3" width="573.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="172.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="172.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="196.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="196.7" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="244" y="196.7" width="610" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="196.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="196.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="221.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="221.1" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="244" y="221.1" width="610" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="221.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="221.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="268.4" y="245.5" width="585.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="245.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="245.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="269.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="269.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="231.8" y="269.9" width="622.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="269.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="269.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="294.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="294.3" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="231.8" y="294.3" width="622.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="294.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="294.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="318.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#62666a" x="134.2" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="146.4" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="158.6" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="170.8" y="318.7" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="341.6" y="318.7" width="512.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="318.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="318.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="343.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="343.1" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="343.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="343.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="367.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="367.5" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="367.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="367.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="391.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="391.9" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="391.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="391.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="416.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="416.3" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="416.3" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="416.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="440.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="122" y="440.7" width="732" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="854" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="440.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="440.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="465.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="465.1" width="756.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="465.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="465.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="489.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="97.6" y="489.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="109.8" y="489.5" width="756.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#34393f" x="866.2" y="489.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="878.4" y="489.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="513.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="538.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="0" y="562.7" width="976" height="24.65" shape-rendering="crispEdges"/>
+      <g class="terminal-3782657965-matrix">
+      <text class="terminal-3782657965-r2" x="12.2" y="20" textLength="12.2" clip-path="url(#terminal-3782657965-line-0)">⭘</text><text class="terminal-3782657965-r2" x="378.2" y="20" textLength="195.2" clip-path="url(#terminal-3782657965-line-0)">SelectionListApp</text><text class="terminal-3782657965-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-3782657965-line-0)">
+  </text><text class="terminal-3782657965-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-1)">
+  </text><text class="terminal-3782657965-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-2)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">┌</text><text class="terminal-3782657965-r4" x="109.8" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">─</text><text class="terminal-3782657965-r4" x="122" y="93.2" textLength="329.4" clip-path="url(#terminal-3782657965-line-3)">&#160;Shall&#160;we&#160;play&#160;some&#160;games?&#160;</text><text class="terminal-3782657965-r4" x="451.4" y="93.2" textLength="414.8" clip-path="url(#terminal-3782657965-line-3)">──────────────────────────────────</text><text class="terminal-3782657965-r4" x="866.2" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">┐</text><text class="terminal-3782657965-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-3)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="117.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-4)">│</text><text class="terminal-3782657965-r4" x="866.2" y="117.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-4)">│</text><text class="terminal-3782657965-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-4)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">│</text><text class="terminal-3782657965-r5" x="122" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">▐</text><text class="terminal-3782657965-r6" x="134.2" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">X</text><text class="terminal-3782657965-r5" x="146.4" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">▌</text><text class="terminal-3782657965-r7" x="170.8" y="142" textLength="158.6" clip-path="url(#terminal-3782657965-line-5)">Falken&#x27;s&#160;Maze</text><text class="terminal-3782657965-r4" x="866.2" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">│</text><text class="terminal-3782657965-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-3782657965-line-5)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">│</text><text class="terminal-3782657965-r5" x="122" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">X</text><text class="terminal-3782657965-r5" x="146.4" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="166.4" textLength="122" clip-path="url(#terminal-3782657965-line-6)">Black&#160;Jack</text><text class="terminal-3782657965-r4" x="866.2" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">│</text><text class="terminal-3782657965-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-6)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">│</text><text class="terminal-3782657965-r5" x="122" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">X</text><text class="terminal-3782657965-r5" x="146.4" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="190.8" textLength="109.8" clip-path="url(#terminal-3782657965-line-7)">Gin&#160;Rummy</text><text class="terminal-3782657965-r4" x="866.2" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">│</text><text class="terminal-3782657965-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-7)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">│</text><text class="terminal-3782657965-r5" x="122" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">X</text><text class="terminal-3782657965-r5" x="146.4" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="215.2" textLength="73.2" clip-path="url(#terminal-3782657965-line-8)">Hearts</text><text class="terminal-3782657965-r4" x="866.2" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">│</text><text class="terminal-3782657965-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-8)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">│</text><text class="terminal-3782657965-r5" x="122" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">X</text><text class="terminal-3782657965-r5" x="146.4" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="239.6" textLength="73.2" clip-path="url(#terminal-3782657965-line-9)">Bridge</text><text class="terminal-3782657965-r4" x="866.2" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">│</text><text class="terminal-3782657965-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-9)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">│</text><text class="terminal-3782657965-r5" x="122" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">X</text><text class="terminal-3782657965-r5" x="146.4" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="264" textLength="97.6" clip-path="url(#terminal-3782657965-line-10)">Checkers</text><text class="terminal-3782657965-r4" x="866.2" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">│</text><text class="terminal-3782657965-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-3782657965-line-10)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">│</text><text class="terminal-3782657965-r5" x="122" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">▐</text><text class="terminal-3782657965-r6" x="134.2" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">X</text><text class="terminal-3782657965-r5" x="146.4" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="288.4" textLength="61" clip-path="url(#terminal-3782657965-line-11)">Chess</text><text class="terminal-3782657965-r4" x="866.2" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">│</text><text class="terminal-3782657965-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-11)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">│</text><text class="terminal-3782657965-r5" x="122" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">▐</text><text class="terminal-3782657965-r8" x="134.2" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">X</text><text class="terminal-3782657965-r5" x="146.4" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="312.8" textLength="61" clip-path="url(#terminal-3782657965-line-12)">Poker</text><text class="terminal-3782657965-r4" x="866.2" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">│</text><text class="terminal-3782657965-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-12)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">│</text><text class="terminal-3782657965-r5" x="122" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">▐</text><text class="terminal-3782657965-r6" x="134.2" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">X</text><text class="terminal-3782657965-r5" x="146.4" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">▌</text><text class="terminal-3782657965-r9" x="170.8" y="337.2" textLength="170.8" clip-path="url(#terminal-3782657965-line-13)">Fighter&#160;Combat</text><text class="terminal-3782657965-r4" x="866.2" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">│</text><text class="terminal-3782657965-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-13)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="361.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-14)">│</text><text class="terminal-3782657965-r4" x="866.2" y="361.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-14)">│</text><text class="terminal-3782657965-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-14)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="386" textLength="12.2" clip-path="url(#terminal-3782657965-line-15)">│</text><text class="terminal-3782657965-r4" x="866.2" y="386" textLength="12.2" clip-path="url(#terminal-3782657965-line-15)">│</text><text class="terminal-3782657965-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-3782657965-line-15)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="410.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-16)">│</text><text class="terminal-3782657965-r4" x="866.2" y="410.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-16)">│</text><text class="terminal-3782657965-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-16)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="434.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-17)">│</text><text class="terminal-3782657965-r4" x="866.2" y="434.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-17)">│</text><text class="terminal-3782657965-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-17)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="459.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-18)">│</text><text class="terminal-3782657965-r4" x="866.2" y="459.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-18)">│</text><text class="terminal-3782657965-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-3782657965-line-18)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="483.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-19)">│</text><text class="terminal-3782657965-r4" x="866.2" y="483.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-19)">│</text><text class="terminal-3782657965-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-3782657965-line-19)">
+  </text><text class="terminal-3782657965-r4" x="97.6" y="508" textLength="12.2" clip-path="url(#terminal-3782657965-line-20)">└</text><text class="terminal-3782657965-r4" x="109.8" y="508" textLength="756.4" clip-path="url(#terminal-3782657965-line-20)">──────────────────────────────────────────────────────────────</text><text class="terminal-3782657965-r4" x="866.2" y="508" textLength="12.2" clip-path="url(#terminal-3782657965-line-20)">┘</text><text class="terminal-3782657965-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-3782657965-line-20)">
+  </text><text class="terminal-3782657965-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-3782657965-line-21)">
+  </text><text class="terminal-3782657965-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-3782657965-line-22)">
+  </text>
+      </g>
+      </g>
+  </svg>
+  
+  '''
+# ---
 # name: test_switches
   '''
   <svg class="rich-terminal" viewBox="0 0 994 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py
index fd22c0ca30..130ff19f3e 100644
--- a/tests/snapshot_tests/test_snapshots.py
+++ b/tests/snapshot_tests/test_snapshots.py
@@ -232,6 +232,14 @@ def test_progress_bar_completed_styled(snap_compare):
 def test_select(snap_compare):
     assert snap_compare(WIDGET_EXAMPLES_DIR / "select_widget.py")
 
+def test_selection_list_selected(snap_compare):
+    assert snap_compare(WIDGET_EXAMPLES_DIR / "selection_list_selected.py")
+
+def test_selection_list_selections(snap_compare):
+    assert snap_compare(WIDGET_EXAMPLES_DIR / "selection_list_selections.py")
+
+def test_selection_list_tuples(snap_compare):
+    assert snap_compare(WIDGET_EXAMPLES_DIR / "selection_list_tuples.py")
 
 def test_select_expanded(snap_compare):
     assert snap_compare(


Code review comments:
diff_hunk: @@ -0,0 +1,171 @@
+# SelectionList
+
+!!! tip "Added in version 0.27.0"
+
+A widget for showing a vertical list of selectable options.
+
+- [x] Focusable
+- [ ] Container
+
+## Typing
+
+The `SelectionList` control is a
+[`Generic`](https://docs.python.org/3/library/typing.html#typing.Generic),
+which allows you to set the type of the
+[selection values][textual.widgets.selection_list.Selection.value]. For instance, if
+the data type for your values is an integer, you would type the widget as
+follows:
+
+```python
+selections = [("First", 1), ("Second", 2)]
+my_selection_list: SelectionList[int] =  SelectionList[int](selections)
path: docs/widgets/selection_list.md
text: @user1:
Let's drop the annotation on the RHS.