Skip to content

Plan viewer: fix edge/label misestimate mismatch, zero-grant text, Light-theme orange contrast - #4632

Merged
erikdarlingdata merged 8 commits into
devfrom
feature/4627-plan-viewer-rendering
Sep 28, 2026
Merged

erikdarlingdata merged 8 commits into
devfrom
feature/4627-plan-viewer-rendering

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Fixes #4627
Fixes #4628
Fixes #4629
Fixes #4635

Why

Four defects in the shared plan-viewer code (PerformanceMonitor.PlanAnalysis, PerformanceMonitor.Ui) and, for #4635, the same fixed-colour pattern in each app's own status bar:

What changes

#4627 — PerformanceMonitor.PlanAnalysis/PlanRowAccuracy.cs (new) is the one shared helper that
turns actual-vs-estimated rows into a per-execution ratio; both the node label
(PlanViewerControl.Rendering.cs) and PlanEdgeColour.ForChild (now taking actualExecutions)
call it, so they cannot disagree again. Both the plan canvas and the minimap callers were updated.
PlanEdgeColour's and GetLinkColorBrush's doc comments no longer claim to match
erikdarlingdata/PerformanceStudio's GetLinkColorBrush "exactly" — PS has the same un-normalized
bug (erikdarlingdata/PerformanceStudio#594), so PerformanceMonitor is now ahead of PerformanceStudio
on this edge-colour calculation
, on purpose, until PS's own issue closes it.

#4628 — PerformanceMonitor.PlanAnalysis/PlanDisplayText.cs, the memory-grant row: when
GrantedMemoryKB == 0 the row now reads "No memory grant" (plus a spill tag if one applies), with
no percentage, and the colour key no longer runs a zero through the utilization thresholds a real
grant uses (defaults to null/neutral, escalating to WarningBrush only if there was a spill
despite no grant). A real grant is untouched: same "X granted, Y used (Z%)" text, same colour rules.
PerformanceStudio has the same bug: erikdarlingdata/PerformanceStudio#595.

#4629 — the "warning" tier (root-node "N warnings" badge, missing-index impact %, per-thread
skew text, cost 25-49%) now reuses the existing theme-token WarningBrush, already proven as
plan-viewer text elsewhere in this same control (the Parameters card annotations). The "critical"
tier (cost >= 50%, elapsed/CPU >= 1s, a row estimate off by 10x+) gets one new theme token,
CriticalTextBrush (renamed from this PR's earlier PlanCriticalOrangeBrush/
PlanCriticalOrangeColor — see below), added to LightTheme.xaml, DarkTheme.xaml and
CoolBreezeTheme.xaml in Lite and the Darling Viewer only (Light/CoolBreeze #A83A0D, Dark
#FF7043; both clear 4.5:1 against every page/card/node background their own theme declares). The
static, always-#FFB347 OrangeBrush field in PlanViewerControl.xaml.cs is gone.

Renamed and rescoped:
ThemeColorOverrideTests pins every Lite/Darling Viewer theme file at exactly eighteen
user-overridable <Color> keys; the original PlanCriticalOrangeColor was a nineteenth and broke
that pin on all six files. Fixed by following the existing WarningTextBrush precedent — a
literal-hex SolidColorBrush with no backing <Color> key, so it never enters the override
palette — and renaming it CriticalTextBrush to match. The deprecated Dashboard is out of
scope
: it is not touched by this PR at all (git diff --stat origin/dev...HEAD -- deprecated/ is
empty), so its three theme files do not carry CriticalTextBrush, and PlanViewerControl's
fallback for a theme without that key is Brushes.OrangeRed — the Dashboard's original, pre-#4629
look — not the Dark theme's #FF7043 (about 2.7:1 on white, worse than OrangeRed's 3.44:1). That
fallback choice is a one-line comment on the property in PlanViewerControl.xaml.cs.

#4635 — Lite/MainWindow.xaml.cs (the "Collectors: N erroring" and "Capture down: ..." status
text) and Darling/PerformanceMonitor.Darling.Viewer/MainWindow.ServerManagement.cs (the same
"Collectors: N erroring" text) now resolve CriticalTextBrush the same way PlanViewerControl
does: (TryFindResource("CriticalTextBrush") as Brush) ?? Brushes.OrangeRed. Both status bars sit
directly on BackgroundLightColor (Lite's status Border and the Darling Viewer's window both
declare Background="{DynamicResource BackgroundLightBrush}" with nothing between it and the
text) — the same background the plan-viewer node card already uses, so the existing #4629 hex
values clear it with no per-theme change needed. The deprecated Dashboard has the identical pattern
in MemoryContent.PlanCache.cs and ResourceMetricsContent.TempdbStats.cs but is not touched,
for the same out-of-scope reason as above.

Left unconverted (non-text, not covered by WCAG's 4.5:1 text floor, which is scoped to text):

  • PlanViewerControl.Rendering.cs:86 and PlanViewerControl.Minimap.cs:185 — Brushes.OrangeRed as
    the border of an "expensive node" highlight (WCAG's non-text/graphical floor is 3:1).
  • PlanViewerControl.Rendering.cs:147 — Brushes.Orange as the fill of the small per-node
    warning-triangle icon (a different, decorative badge from the root-node "N warnings" text the
    issue named).
  • Lite/MainWindow.xaml.cs:1121 and :1233 — the per-tab alert badge's Background, whose text
    (white, set separately on the same badge) is what actually needs to clear a contrast floor, not
    the fill it sits on.

Known pre-existing gap, not touched here: Cool Breeze's own WarningColor (unchanged by this
PR) measures 4.41:1 against the properties-panel background (BackgroundDarkColor) — a hair under
4.5:1. The issue named only Light and Dark; re-tuning Cool Breeze's WarningColor would ripple into
every other place that token is used app-wide, out of this PR's scope. Filed as #4651.

Test plan

  • New Darling/Darling.Tests/Viewer4627Tests.cs, pinned against
    Darling/Darling.Tests/Fixtures/OriginPlans/udf_plan.sqlplan: nodes 7, 8, 10, 12 no longer
    get FluoRed (now Neutral), node 9 is LightOrange, and the exact PlanRowAccuracy ratio is
    pinned for each. A companion fact reproduces the old (pre-fix) total-over-per-execution math
    and shows it would have put all five at FluoRed. Existing Viewer4579Tests.cs updated for
    ForChild's new actualExecutions parameter (inserted as 1, a no-op, so every existing
    pinned ratio is unchanged).
  • New tests in Darling/Darling.Tests/Viewer4570Tests.cs: a real grant keeps
    "1.0 MB granted, 512 KB used (50%)"; a zero grant reads "No memory grant" with no % and a
    null colour key.
  • Darling/Darling.Tests/Viewer4629Tests.cs, rewritten this round: reads each theme XAML
    file's real declared colours/brushes and measures with the shared
    PerformanceMonitor.Ui.WcagContrast helper. WarningColor (via ThemeXamlRewriter. DeclaredColors) and CriticalTextBrush (via a new LiteralBrushHex regex helper, since it
    has no <Color> key) both clear 4.5:1 against the node background (BackgroundLightColor),
    the properties-panel background (BackgroundDarkColor), and — new for Collector health status text: fixed Brushes.OrangeRed fails WCAG contrast on Light theme #4635 — the status bar
    background (BackgroundLightColor again, asserted as its own named constant so a future
    change to either resource is caught independently), on Light and Dark, across Lite and the
    Darling Viewer only. Golden pin on CriticalTextBrush's hex per theme (values unchanged).
    Existence check across all six theme files including Cool Breeze.
  • dotnet build Darling/Darling.Tests/Darling.Tests.csproj -c Debug — Build succeeded, 0 warnings.
  • dotnet build Lite.Tests/Lite.Tests.csproj -c Debug — Build succeeded, 0 warnings (also
    builds Lite/PerformanceMonitorLite.csproj as a dependency).
  • dotnet build deprecated/Dashboard/Dashboard.csproj -c Debug — Build succeeded, 0 warnings.
    Confirms the shared PerformanceMonitor.Ui change (the CriticalTextBrush rename and the
    Brushes.OrangeRed fallback) still compiles for the Dashboard's own consumption, without
    editing any Dashboard source.
  • Full Darling.Tests.exe run: 16541 total, 0 errors, 1 failed, 1025 skipped, 1 not run. The
    one failure, AvailabilityGroupsTabRefreshTests.Render_UnchangedRows_StaysUnderTheHundredMillisecondBudget,
    is a known unrelated flake (a render-timing budget test) and is not connected to anything this PR touches.
    The "not run" test and the 1025 skips were
    identical across both the first (pre-fix) and final full runs, so neither moved with this PR.
  • Full Lite.Tests.exe run: 5521 total, 0 errors, 0 failed.
  • Proof round (this push), full Darling.Tests.exe re-run: 16541 total, 0 errors, 0 failed, 1025
    skipped, 1 not run.
    The known-unrelated flake named above did not fire this run — it stays on
    the known-flake list regardless, since flaky means intermittent, and fixing it is out of this
    PR's scope.
  • Proof round (this push), full Lite.Tests.exe re-run: 5524 total, 0 errors, 0 failed (+3 over
    the count above: the new live pin file below).
  • New live pin Lite.Tests/PlanViewer4632FallbackTests.cs (3 [Fact]s, the first test in
    either suite to construct a live PlanViewerControl): constructs the control inside the
    deprecated Dashboard's real Light theme scope (parsed with XamlReader.Parse; no
    CriticalTextBrush key), asserts nothing throws and the resolved brush is OrangeRed (#FF4500);
    repeats inside Lite's real Light theme scope (has the key) and asserts the theme hex #A83A0D;
    and pins that no .xaml under PerformanceMonitor.Ui binds CriticalTextBrush or WarningBrush
    with StaticResource. Not attempted: loading a real plan and reading a rendered node's cost-text
    brush — LoadPlan is async and awaits Task.Run, and the OnStaThread harness (like its three
    precedents in this repo) joins a thread that never pumps a Dispatcher message loop, so that
    continuation would never return to it; the resolved-brush assertions already pin the exact color
    that render path would hand a critical-tier node.
  • RED, then GREEN, on that new pin. Temporarily changed the fallback line
    (PlanViewerControl.xaml.cs:110) to (SolidColorBrush)FindResource("CriticalTextBrush") (a
    StaticResource-equivalent lookup that throws on a miss).
    Lite.Tests.exe -class Lite.Tests.PlanViewer4632FallbackTests went RED:
    Total: 3, Failed: 1, with the Dashboard-scope case throwing exactly the exception the fallback guards against —
    System.Windows.ResourceReferenceKeyNotFoundException: 'CriticalTextBrush' resource not found. at PlanViewerControl.xaml.cs:line 110. Reverted the edit (git diff on the file
    confirmed empty), rebuilt, reran GREEN: Total: 3, Failed: 0.
  • Reworded the six theme files' CriticalTextBrush comment and Viewer4629Tests.cs's matching
    prose off the retired PlanCriticalOrangeColor/PlanCriticalOrangeBrush pair name (a pair that
    existed only inside this PR, never on dev) to #4629/#4635 and the brush's now-two consumers
    (plan viewer, status bar). Confirmed zero remaining repo-wide hits (outside deprecated/) for
    PlanCriticalOrangeColor, PlanCriticalOrangeBrush, or was PlanCriticalOrange.
    Lite.Tests.exe -class Lite.Tests.ThemeColorOverrideTests -class Lite.Tests.ThemeStatusContrastTests
    — 130/130. Darling.Tests.exe -class Darling.Tests.Viewer4629Tests — 20/20.
  • Two failures that this PR's own first push caused, surfaced by the first full run (not the eighteen-colour palette
    pin, which is covered in its own section below) and fixed in this same PR,
    since both were one or two lines in files this PR already touches:
    - RepoFileAdoptionTests.ExactlyOneFile_DeclaresTheSharedRepoFileReader — the existing
    Viewer4629Tests.cs declared its own private ReadRepoFile/RepoRoot pair instead
    of calling the shared RepoFile.ReadRepoFile thirty-four other classes already use.
    Migrated onto RepoFile.ReadRepoFile; the private pair is gone.
    - PlanViewerWarningColorAndFixTests.PlanViewerControl_HasNoInlineSeverityColorLiterals —
    two #4629 comments in PlanViewerControl.Properties.cs and
    PlanViewerControl.Rendering.cs quoted the old fixed OrangeBrush's hex (#FFB347) for
    context; the source-literal census cannot tell that apart from a real inline color.
    Reworded to "hex FFB347" (no #), same meaning, outside the pin's pattern.
  • git diff --stat origin/dev...HEAD -- deprecated/ prints nothing — confirmed no Dashboard
    source is touched by this PR.
  • No live-PostgreSQL tests were run (no PostgreSQL rig; those tests skip without one).

Root cause of the ThemeColorOverrideTests failures (now fixed)

ThemeColorOverrideTests.EveryThemeFile_DeclaresExactlyTheExposedAndWithheldColors and
TheColorDeclarationRegex_MatchesEveryDeclarationInEveryTheme_ExactlyOnce both count <Color x:Key="..."> declarations per theme file and assert exactly 18 (the twelve user-overridable keys
plus six deliberately-withheld ones). The first push's PlanCriticalOrangeColor was a nineteenth
<Color> declaration in all six Lite/Darling-Viewer theme files, so both tests failed on all six.
Fixed by making the critical-tier brush a literal-hex SolidColorBrush (renamed CriticalTextBrush)
with no backing <Color> key at all — the same shape WarningTextBrush already used for exactly
this reason — so the palette count returns to 18. Verified green:
Lite.Tests.exe -class Lite.Tests.ThemeColorOverrideTests -class Lite.Tests.ThemeStatusContrastTests
(130/130) and
Darling.Tests.exe -class Darling.Tests.Viewer4629Tests -class Darling.Tests.ViewerThemeColorOverridesTests
(24/24), plus both full suites above.

Dashboard (deprecated): unchanged, and why it can't crash

  • The mechanism, at PerformanceMonitor.Ui/PlanViewerControl.xaml.cs:108-110: CriticalOrangeBrush
    resolves in code — (TryFindResource("CriticalTextBrush") as SolidColorBrush) ?? Brushes.OrangeRed.
    TryFindResource returns null on a miss instead of throwing, so the ?? always has a brush to fall
    back to. The same shape guards WarningBrush at :93-94. Neither is a XAML StaticResource binding,
    which is the form that throws (ResourceReferenceKeyNotFoundException) when the key is missing —
    that binding form is what would take the Dashboard's plan viewer down, and neither brush uses it.
  • Grep proof that nothing in PerformanceMonitor.Ui's XAML uses StaticResource for either key:
    grep -rn "StaticResource CriticalTextBrush\|StaticResource WarningBrush" PerformanceMonitor.Ui/ —
    zero hits, checked across all nine .xaml files in that project. Every reference to either brush in
    that project's XAML is DynamicResource instead (also grep-confirmed), which resolves lazily and
    never throws on a miss.
  • The pin: Lite.Tests/PlanViewer4632FallbackTests.cs.
    • RED: Lite.Tests.exe -class Lite.Tests.PlanViewer4632FallbackTests -> Total: 3, Failed: 1 —
      DashboardScope_MissingCriticalTextBrush_ConstructsCleanly_AndFallsBackToOrangeRed threw
      System.Windows.ResourceReferenceKeyNotFoundException: 'CriticalTextBrush' resource not found.
      (from a temporary (SolidColorBrush)FindResource("CriticalTextBrush") edit to the fallback line,
      reverted immediately after).
    • GREEN: same command -> Total: 3, Failed: 0.
  • The deprecated/Dashboard build, no edits: dotnet build deprecated/Dashboard/Dashboard.csproj -c Debug -> Build succeeded, 0 Warning(s), 0 Error(s).
  • The empty diff: git diff --stat origin/dev...HEAD -- deprecated/ prints nothing.

CHANGELOG

SECTION: Fixed
ENTRY: - Nested Loops inner-side plan edges no longer show a misestimate colour the node's own label disagrees with ([#4632]) - The plan-edge colour and the node's "X of Y" label now come from the same per-execution ratio, so an operator that ran thousands of times no longer gets a worst-misestimate red edge while its label shows the estimate was close.
REF: [#4632]: #4632
ENTRY: - The Runtime Summary no longer says a query used "100%" of a memory grant it never got ([#4632]) - When a query's memory grant was zero, the plan viewer now says "No memory grant" instead of a fabricated "0 KB granted, 0 KB used (100%)".
REF: [#4632]: #4632
ENTRY: - Plan viewer orange text now reads clearly in the Light theme ([#4632]) - In Lite and the Darling Viewer, the warning badge, missing-index impact percentage, per-thread skew text, and the node cost/elapsed/CPU/row-estimate text used a fixed orange that was too pale to read on a white background; they now use theme-aware colours that stay readable in both Light and Dark.
REF: [#4632]: #4632
ENTRY: - Collector status text in the status bar now reads clearly in the Light theme ([#4632]) - When collectors were erroring or capture was down, the status bar text used a fixed orange that was too pale to read on a white background; it now uses the same theme-aware colour the plan viewer uses, readable in both Light and Dark.
REF: [#4632]: #4632

…el (#4627)

PlanEdgeColour.ForChild compared the CHILD's un-normalized total ActualRows
(summed across every execution) against its per-execution EstimateRows, while
the node label already divided ActualRows by ActualExecutions first. On the
inner side of a Nested Loops join that ran thousands of times, the edge got
the worst-misestimate colour (FluoRed) even when the label showed the
estimate was close.

Both now go through one shared helper, PlanRowAccuracy, so they can't
disagree again. ForChild takes actualExecutions and normalizes through it;
the plan canvas and minimap callers, and the node-label calculation, all call
the same helper. Pinned against udf_plan.sqlplan: nodes 7, 8, 10 and 12 no
longer get FluoRed, and the ratio PlanRowAccuracy returns for each is pinned
too.
…4628)

GrantedMemory="0" (a query that never asked for or never got a memory
grant) made the percentage math fall back to a fake 100%, so the Runtime
Summary card read "0 KB granted, 0 KB used (100%)". It now says "No memory
grant" with no percentage, and the color key no longer runs the zero
through the same utilization thresholds a real grant uses. A real grant
keeps today's "X granted, Y used (Z%)" text and its existing color rules.
OrangeBrush (#FFB347), Brushes.Orange (#FFA500) and Brushes.OrangeRed (#FF4500)
were fixed WPF brushes that never changed with the theme. On Light they measured
1.78:1, 1.97:1 and 3.44:1 against the node/panel backgrounds they paint text on,
all under WCAG AA's 4.5:1 floor; OrangeRed was 4.46:1 on Dark too, just under it.

The "warning" tier (the root node's "N warnings" badge, the missing-index impact
%, the per-thread skew text, cost 25-49%) now reuses the existing theme-token
WarningBrush, already proven as plan-viewer text elsewhere in this control. The
"critical" tier (cost >= 50%, elapsed/CPU >= 1s, a row estimate off by 10x+) gets
one new theme token, PlanCriticalOrangeBrush, added to Light, Dark and Cool Breeze
in Lite, the Dashboard and the Darling Viewer (all three host apps this shared
control renders in) so a theme switch can never hit a missing FindResource key.
Both keep the orange/warning meaning, tuned per theme: a darker orange on Light,
a lighter one on Dark.

Left unconverted (non-text, not covered by WCAG's 4.5:1 text floor): the
"expensive node" border (Rendering.cs/Minimap.cs, Brushes.OrangeRed) and the
per-node warning-triangle icon fill (Rendering.cs, Brushes.Orange).

Filed #4635 for the same fixed-OrangeRed pattern in each app's own collector
health status text (MainWindow.xaml.cs / MainWindow.ServerManagement.cs) — a
different subsystem, outside this shared plan-viewer code.
…to Lite and the Darling Viewer (#4632)

ThemeColorOverrideTests pins every Lite/Darling Viewer theme file at exactly 18 user-overridable
<Color> keys. #4629's PlanCriticalOrangeColor was a 19th, so EveryThemeFile_DeclaresExactlyThe-
ExposedAndWithheldColors and TheColorDeclarationRegex_MatchesEveryDeclarationInEveryTheme_Exactly-
Once failed on all six files.

Follows the existing WarningTextBrush precedent: a literal-hex SolidColorBrush with no backing
<Color> key, so it never enters the override palette. Renamed PlanCriticalOrangeBrush to
CriticalTextBrush to match. Only Lite and the Darling Viewer carry it - the deprecated Dashboard's
three theme files are reverted to dev, since the Dashboard is out of scope. PlanViewerControl's
fallback for a theme with no CriticalTextBrush (the Dashboard) is Brushes.OrangeRed, the
Dashboard's pre-#4629 look, not the Dark theme's #FF7043 (worse contrast than OrangeRed on white).

Viewer4629Tests: the three tests that read PlanCriticalOrangeColor via DeclaredColors now read the
literal CriticalTextBrush hex via a regex helper; file lists drop the three Dashboard entries and
AllNineFiles is renamed AllSixFiles.
…TextBrush (#4635)

Lite's and the Darling Viewer's status bar set CollectorHealthText.Foreground to the fixed
Brushes.OrangeRed (#FF4500) for "N erroring" and "Capture down" - 3.44:1 on Light's status bar
background (BackgroundLightColor), under WCAG AA's 4.5:1 text floor, the same defect #4629 fixed
in the plan viewer. Both now resolve CriticalTextBrush the same way PlanViewerControl does, falling
back to OrangeRed if the theme doesn't declare it.

Left alone as non-text uses, with the reason:
- Lite/MainWindow.xaml.cs ~1119 and ~1231: the tab alert badge's Background, whose text is white,
  set separately - not a text foreground.
- PlanViewerControl.Minimap.cs ~185 and PlanViewerControl.Rendering.cs ~86: BorderBrush, held to
  WCAG's 3:1 non-text floor, not 4.5:1.
- The deprecated Dashboard's two OrangeRed text spots (MemoryContent.PlanCache.cs,
  ResourceMetricsContent.TempdbStats.cs): out of scope, Dashboard is deprecated.

Viewer4629Tests.CriticalTextBrush_ReadsAsTextOnNodePanelAndStatusBarBackgrounds now also asserts
CriticalTextBrush clears 4.5:1 on BackgroundLightColor, the status bar's background in both apps.
No hex value needed to change: the existing #4629 pins already clear it.
RepoFileAdoptionTests.ExactlyOneFile_DeclaresTheSharedRepoFileReader: Viewer4629Tests had its own
private ReadRepoFile/RepoRoot pair instead of the shared RepoFile.ReadRepoFile thirty-four other
classes already use. Migrated onto RepoFile.ReadRepoFile and dropped the private copy.

PlanViewerControl_HasNoInlineSeverityColorLiterals: two #4629 comments in PlanViewerControl.
Properties.cs and PlanViewerControl.Rendering.cs quoted the old fixed OrangeBrush's hex (#FFB347)
for context, which the source-literal census cannot tell apart from a real inline color. Reworded
to "hex FFB347" (no #), same meaning, outside the pin's pattern.

Both predate this PR's own commits but surfaced only once the full suite ran; fixed in place rather
than deferred since both are one- or two-line, in files this PR already touches.
…ng CriticalTextBrush key (#4629, #4635)

Adds the first live PlanViewerControl pin (Lite.Tests/PlanViewer4632FallbackTests.cs): constructs the
control inside the Dashboard's real Light theme scope (which lacks CriticalTextBrush) and asserts nothing
throws and the resolved brush is the OrangeRed fallback, then repeats inside Lite's Light theme scope
(which has the key) and asserts the theme hex. Also pins that no .xaml under PerformanceMonitor.Ui binds
CriticalTextBrush or WarningBrush with StaticResource, which is the pattern that would throw.

Rewords the six theme files' CriticalTextBrush comment and Viewer4629Tests.cs's matching prose: both
named a PlanCriticalOrangeColor/PlanCriticalOrangeBrush pair that existed only inside this PR and was
never on dev, and the comment predates #4635 giving the brush a second consumer (the status bar).
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 28, 2026 20:56
@erikdarlingdata
erikdarlingdata merged commit 5e0e737 into dev Sep 28, 2026
19 of 20 checks passed
@erikdarlingdata
erikdarlingdata deleted the feature/4627-plan-viewer-rendering branch September 28, 2026 20:56
erikdarlingdata added a commit that referenced this pull request Sep 28, 2026
…or (#4651) (#4658)

WarningColor #9E4A0B measured 4.41:1 against the plan viewer properties
panel's BackgroundDarkColor, under WCAG AA's 4.5:1 text floor, once #4632
put warning-tier text there. Darkened to #9C490B, same hue, the smallest
step that clears 4.5:1 on every background Cool Breeze draws WarningBrush
text on. Applied identically to Lite and the Darling Viewer.

Viewer4629Tests now holds Cool Breeze to the same strict floor as Light
and Dark (previously exempted), and checks the card and status-bar
backgrounds alongside the panel and plan nodes for both WarningBrush and
CriticalTextBrush.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant