# TASK 63 — The border-colour picker is the app's own drop-down **Status:** ✅ Done — shipped 2026-10-21. ## What it is The creator (2026-10-21), on Live → Layers → webcam → Properties → **Border Color**: > why does the drop down under the web cam properties not show the same style for the border > color drop down list box? and, with the reason: > one of the first things we did was define branding. We established look-and-feel standards. > And yet you keep ignoring these and I'm wondering why So the border colour is picked with the **app's own drop-down** — the `YtComboBox` every other picker wears — instead of a `...` button that built a `ContextMenu` in code. ## Why it was missed (the root cause, recorded so it cannot recur) The TASK 58 sweep looked for controls **by type** (`ComboBox` / `CheckBox` / `TextBox`) that carried no theme style. The border picker was **none of those** — it was a `Button` whose `Click` handler built a `ContextMenu` of swatches in code. So it was never in the sweep's scope, and `ytLive.Tests/PropertiesStyleTests.cs` could not see it either: the guard asserts control **types**, not the design system. A style sweep must ask *"is this the app's widget?"*, not *"is this control type themed?"*. ## How it is done - **The picker** — a `ComboBox` with `Style="{StaticResource YtComboBox}"`, bound to `SelectedElement.BorderColorOptions` (the palette) and `SelectedItem` to `SelectedElement.BorderColorEntry` (TwoWay). `SelectedItem`, **not** `SelectedValue`: WPF matches `SelectedValue` ordinally (case-sensitively) and the palette mixes `#FFFFFF` and `#e94560`; the model matches by VALUE, so the hex the creator typed in any case still lands on the right row. - **Clicking a popup row stays inside `LeftPanel` (2026-10-22 fix):** a `ComboBox`'s open `PART_Popup` lives in its own `PopupRoot` visual tree (`VisualTreeHelper.GetParent(popupRoot)` is `null`), connected back to the `Popup` and `ComboBox` only via `PopupRoot`'s **logical** parent (`LogicalTreeHelper.GetParent(popupRoot)`). `LeftPanel.IsDescendantOf` previously used `child is Visual ? VisualTreeHelper.GetParent(child) : LogicalTreeHelper.GetParent(child)`, which returned `null` at `PopupRoot` because `PopupRoot` is a `Visual`. That caused `MainWindow.Window_PreviewMouseLeftButtonDown` to see `IsClickInside == false` on any click inside the open dropdown and clear `SelectedElement = null` — exiting the properties panel before the `ComboBoxItem` click could select the colour. `IsDescendantOf` now falls back to `LogicalTreeHelper.GetParent` and `TemplatedParent` whenever `VisualTreeHelper.GetParent` returns `null`. - **The closed box shows the swatch + the colour's NAME; the rows show swatch + hex + name** (the rows the creator approved in TASK 60). A ComboBox cannot do that with one `ItemTemplate` — WPF copies it into the read-only `SelectionBoxItemTemplate` — so `Helpers/ClosedBoxTemplateSelector.cs` picks the template by the `ContentPresenter`'s templated parent (the `ComboBox` for the closed box, the `ComboBoxItem` for a row). - **The hex field stays** (60px, editable): a colour outside the palette can still be typed, and the drop-down then carries that hex as a **nameless** entry ("no name" is the honest answer). The palette's name for the current colour moved out of a `TextBlock` (TASK 62's `BorderColorName`) and into the drop-down's closed box. - **The swatch is painted by the theme**, not by code: `Helpers/HexToBrushConverter.cs` (registered in `Themes/Controls.xaml` as `HexToBrush`) turns the hex into a brush, and the templates use the theme's border colour `#2a3a5e` so the black swatch is visible on the dark popup. The hand-built menu, its hand-painted `SolidColorBrush`es and `WebcamBorderColorPicker_Click` are **gone**. ## The model - `SceneElement.BorderColorName` → **`BorderColorEntry`** (the palette entry for the current hex, with its name; setting it writes the hex back) and **`BorderColorOptions`** (the palette plus the custom entry). Both are raised when `BorderColor` changes. - `BorderColorPalette.EntryFor(hex)` (case-insensitive; a nameless entry for a colour outside the palette) and `OptionsFor(hex)` (the palette + that entry). `NameOf` now delegates to `EntryFor`. ## Tests `ytLive.Tests/BorderColorPickerTests.cs` — the ONE test for this change, in three parts: the model (the palette entry, the custom hex, the raises), the panel (the picker IS a `YtComboBox` over the palette, the hex field survives, the hand-rolled menu is gone from both the XAML and the code-behind) and the **real widget** — with the app's theme style and the panel's real templates, the closed box shows the name and the rows show the hex AND the name. `ytLive.Tests/BorderColorPaletteTests.cs` (TASK 60) was updated: its "the picker builds its menu from the palette" step now guards the new wiring (the drop-down is bound to the palette, and neither the panel nor the code-behind carries a second list of colours). ## Follow-ups (not done — out of scope) - The theme has **no implicit `Button` style**, so every plain `