From 1e4dddbbade2c46c73b48905d2d154df88c0be24 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Fri, 29 May 2026 15:04:15 +0300 Subject: [PATCH] =?UTF-8?q?feat(ui):=20Velocity=20rollout=20=E2=80=94=20pa?= =?UTF-8?q?ge=20polish=20+=20lime-as-text=20contrast=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Roll the re-skin across the remaining surfaces and fix the readability regressions the lime accent introduced (lime works as a fill/border but is unreadable as text on light): - --m-c-rule is now a soft divider, so page panels/tables get tidy outlines instead of a mess of black hairlines; the brutalist weight stays on cards, nav, sections and inputs (which reference ink directly). - New --m-c-warning (amber) for medium severity, keeping the low→medium→high gradient legible; applied to SeverityBadge, AnomalyCard, feed stat. - Interactive/link/highlight text (Home CTA + links, Journal/Backtest/Compare buttons, KPI + evidence values) moved off lime to the readable --m-c-info blue; Home first-run CTA is now a filled-lime brutalist button; odds-up delta → positive green; rate arrow → neutral. - Results winner colours → tokens (positive / info) + Velocity-aligned tints. CSS-only — build clean, all 568 tests green. --- src/Marathon.UI/Components/AnomalyCard.razor | 4 ++-- src/Marathon.UI/Components/AnomalyEvidence.razor | 2 +- src/Marathon.UI/Components/OddsCell.razor | 2 +- src/Marathon.UI/Components/SeverityBadge.razor | 6 +++--- src/Marathon.UI/Pages/Anomalies/AnomalyFeed.razor | 2 +- src/Marathon.UI/Pages/Anomalies/Backtest.razor | 8 ++++---- src/Marathon.UI/Pages/Anomalies/Insights.razor | 2 +- src/Marathon.UI/Pages/Anomalies/PaperTrading.razor | 2 +- src/Marathon.UI/Pages/Anomalies/StrategyCompare.razor | 2 +- src/Marathon.UI/Pages/Home.razor | 8 ++++---- src/Marathon.UI/Pages/MyBets/Journal.razor | 4 ++-- src/Marathon.UI/Pages/Results/ResultsList.razor | 8 ++++---- src/Marathon.UI/Pages/Results/ResultsLoader.razor | 4 ++-- src/Marathon.UI/Pages/Shared/EventListShell.razor | 2 +- src/Marathon.UI/wwwroot/app.css | 8 +++++--- 15 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/Marathon.UI/Components/AnomalyCard.razor b/src/Marathon.UI/Components/AnomalyCard.razor index db21f8b..4de5d4c 100644 --- a/src/Marathon.UI/Components/AnomalyCard.razor +++ b/src/Marathon.UI/Components/AnomalyCard.razor @@ -77,7 +77,7 @@ outline-offset: 2px; } .m-anomaly-card--high { border-left-color: var(--m-c-anomaly); } - .m-anomaly-card--medium { border-left-color: var(--m-c-accent); } + .m-anomaly-card--medium { border-left-color: var(--m-c-warning); } .m-anomaly-card--low { border-left-color: var(--m-c-ink-soft); } .m-anomaly-card__head { @@ -132,7 +132,7 @@ color: var(--m-c-ink-soft); font-size: 0.875rem; } - .m-anomaly-card__rate-arrow { color: var(--m-c-accent); font-size: 0.875rem; } + .m-anomaly-card__rate-arrow { color: var(--m-c-ink-soft); font-size: 0.875rem; } .m-anomaly-card__rate-post { color: var(--m-c-ink); font-weight: 600; diff --git a/src/Marathon.UI/Components/AnomalyEvidence.razor b/src/Marathon.UI/Components/AnomalyEvidence.razor index e72d16c..f8ef0f5 100644 --- a/src/Marathon.UI/Components/AnomalyEvidence.razor +++ b/src/Marathon.UI/Components/AnomalyEvidence.razor @@ -143,7 +143,7 @@ justify-content: center; font-family: var(--m-font-display); font-size: 1.75rem; - color: var(--m-c-accent); + color: var(--m-c-info); } .m-evidence__row { display: grid; diff --git a/src/Marathon.UI/Components/OddsCell.razor b/src/Marathon.UI/Components/OddsCell.razor index 9846531..482b63d 100644 --- a/src/Marathon.UI/Components/OddsCell.razor +++ b/src/Marathon.UI/Components/OddsCell.razor @@ -60,7 +60,7 @@ color: var(--m-c-ink-soft); transition: color 220ms ease; } - .m-odds.is-up .m-odds__delta { color: var(--m-c-accent); } + .m-odds.is-up .m-odds__delta { color: var(--m-c-positive); } .m-odds.is-down .m-odds__delta { color: var(--m-c-anomaly); } .m-odds.is-flat .m-odds__delta { color: var(--m-c-ink-soft); } diff --git a/src/Marathon.UI/Components/SeverityBadge.razor b/src/Marathon.UI/Components/SeverityBadge.razor index 73ab2ac..81557cd 100644 --- a/src/Marathon.UI/Components/SeverityBadge.razor +++ b/src/Marathon.UI/Components/SeverityBadge.razor @@ -2,7 +2,7 @@ SeverityBadge — small uppercase pill encoding an anomaly's severity bucket. The High variant is signal-red (`--m-c-anomaly`) and pulses to draw the eye - on the feed page. Medium uses the editorial amber accent. Low is a muted + on the feed page. Medium uses an amber warning tone. Low is a muted neutral so it does not compete with higher severities. The component is presentational only — callers compute the severity (via @@ -56,8 +56,8 @@ background: color-mix(in srgb, var(--m-c-ink-soft) 8%, transparent); } .m-severity--medium { - color: var(--m-c-accent); - background: color-mix(in srgb, var(--m-c-accent) 12%, transparent); + color: var(--m-c-warning); + background: color-mix(in srgb, var(--m-c-warning) 12%, transparent); } .m-severity--high { color: var(--m-c-anomaly); diff --git a/src/Marathon.UI/Pages/Anomalies/AnomalyFeed.razor b/src/Marathon.UI/Pages/Anomalies/AnomalyFeed.razor index c87195e..f66080f 100644 --- a/src/Marathon.UI/Pages/Anomalies/AnomalyFeed.razor +++ b/src/Marathon.UI/Pages/Anomalies/AnomalyFeed.razor @@ -200,7 +200,7 @@ font-feature-settings: var(--m-num-feature); } .m-anomaly-feed__stat--high dd { color: var(--m-c-anomaly); } - .m-anomaly-feed__stat--medium dd { color: var(--m-c-accent); } + .m-anomaly-feed__stat--medium dd { color: var(--m-c-warning); } .m-anomaly-feed__list { display: grid; diff --git a/src/Marathon.UI/Pages/Anomalies/Backtest.razor b/src/Marathon.UI/Pages/Anomalies/Backtest.razor index e7d624c..3971f85 100644 --- a/src/Marathon.UI/Pages/Anomalies/Backtest.razor +++ b/src/Marathon.UI/Pages/Anomalies/Backtest.razor @@ -452,8 +452,8 @@ .m-backtest__submit { gap: var(--m-space-2); padding: 8px 16px; - border-color: var(--m-c-accent); - color: var(--m-c-accent); + border-color: var(--m-c-info); + color: var(--m-c-info); font-family: var(--m-font-mono); font-size: 0.75rem; text-transform: uppercase; @@ -553,7 +553,7 @@ letter-spacing: 0.14em; padding: 8px 16px; } - .m-backtest__preset-save-btn:not(:disabled):hover { border-color: var(--m-c-accent); color: var(--m-c-accent); } + .m-backtest__preset-save-btn:not(:disabled):hover { border-color: var(--m-c-info); color: var(--m-c-info); } .m-backtest__preset-save-btn:disabled { opacity: 0.6; cursor: progress; } @@media (prefers-reduced-motion: reduce) { .m-backtest__preset, .m-backtest__preset-del, .m-backtest__preset-save-btn { transition: none; } @@ -748,7 +748,7 @@ transition: color 120ms ease, border-color 120ms ease; } .m-backtest__open:hover { - color: var(--m-c-accent); + color: var(--m-c-info); border-bottom-color: var(--m-c-ink); } diff --git a/src/Marathon.UI/Pages/Anomalies/Insights.razor b/src/Marathon.UI/Pages/Anomalies/Insights.razor index ee75b97..8c7a049 100644 --- a/src/Marathon.UI/Pages/Anomalies/Insights.razor +++ b/src/Marathon.UI/Pages/Anomalies/Insights.razor @@ -617,7 +617,7 @@ transition: color 120ms ease, border-color 120ms ease; } .m-insights__open:hover { - color: var(--m-c-accent); + color: var(--m-c-info); border-bottom-color: var(--m-c-ink); } diff --git a/src/Marathon.UI/Pages/Anomalies/PaperTrading.razor b/src/Marathon.UI/Pages/Anomalies/PaperTrading.razor index 70071e6..c0f4fca 100644 --- a/src/Marathon.UI/Pages/Anomalies/PaperTrading.razor +++ b/src/Marathon.UI/Pages/Anomalies/PaperTrading.razor @@ -220,7 +220,7 @@ color: var(--m-c-ink); border-bottom: 1px solid var(--m-c-accent); padding-bottom: 1px; transition: color 120ms ease, border-color 120ms ease; } - .m-paper__open:hover { color: var(--m-c-accent); border-bottom-color: var(--m-c-ink); } + .m-paper__open:hover { color: var(--m-c-info); border-bottom-color: var(--m-c-ink); } .m-list-empty { display: grid; place-content: center; gap: var(--m-space-3); padding: var(--m-space-7); diff --git a/src/Marathon.UI/Pages/Anomalies/StrategyCompare.razor b/src/Marathon.UI/Pages/Anomalies/StrategyCompare.razor index 31216c4..1dfbc3a 100644 --- a/src/Marathon.UI/Pages/Anomalies/StrategyCompare.razor +++ b/src/Marathon.UI/Pages/Anomalies/StrategyCompare.razor @@ -139,7 +139,7 @@ .m-cmp__form-hint { font-size: 0.75rem; color: var(--m-c-ink-soft); } .m-cmp__form-actions { display: flex; align-items: end; } .m-cmp__run { - gap: var(--m-space-2); padding: 8px 16px; border-color: var(--m-c-accent); color: var(--m-c-accent); + gap: var(--m-space-2); padding: 8px 16px; border-color: var(--m-c-info); color: var(--m-c-info); font-family: var(--m-font-mono); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.14em; } .m-cmp__run:not(:disabled):hover { background: var(--m-c-accent); color: var(--m-c-paper); } diff --git a/src/Marathon.UI/Pages/Home.razor b/src/Marathon.UI/Pages/Home.razor index 529ed1a..458c894 100644 --- a/src/Marathon.UI/Pages/Home.razor +++ b/src/Marathon.UI/Pages/Home.razor @@ -43,7 +43,7 @@ { @* First-run: nothing captured yet. Make the next step unmissable. *@
- + @L["Home.Empty.Heading"]

@@ -51,7 +51,7 @@

+ style="display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px; background: var(--m-c-accent); color: var(--m-c-on-accent); border: 2px solid var(--m-c-ink); border-radius: var(--m-radius-md); box-shadow: var(--m-shadow-hard-sm); font-family: var(--m-font-mono); font-weight: 700; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.12em; text-decoration: none;"> @L["Home.Empty.Cta"] →
@@ -62,7 +62,7 @@ @* Capturing, but the detector hasn't flagged anything yet. *@

@L["Home.NoSignals"]

- + @L["Home.ViewAll"] →
@@ -92,7 +92,7 @@
- + @L["Home.ViewAll"] →
diff --git a/src/Marathon.UI/Pages/MyBets/Journal.razor b/src/Marathon.UI/Pages/MyBets/Journal.razor index 45dbd6b..e3df682 100644 --- a/src/Marathon.UI/Pages/MyBets/Journal.razor +++ b/src/Marathon.UI/Pages/MyBets/Journal.razor @@ -579,8 +579,8 @@ gap: var(--m-space-3); } .m-journal__submit { - border-color: var(--m-c-accent); - color: var(--m-c-accent); + border-color: var(--m-c-info); + color: var(--m-c-info); } .m-journal__submit:not(:disabled):hover { background: var(--m-c-accent); diff --git a/src/Marathon.UI/Pages/Results/ResultsList.razor b/src/Marathon.UI/Pages/Results/ResultsList.razor index 7d534ee..fcadc6d 100644 --- a/src/Marathon.UI/Pages/Results/ResultsList.razor +++ b/src/Marathon.UI/Pages/Results/ResultsList.razor @@ -156,11 +156,11 @@ border-radius: var(--m-radius-xs); border: 1px solid var(--m-c-rule); } - .m-result-winner--side1 { background: rgba(34,197,94,0.10); color: #15803d; border-color: rgba(34,197,94,0.30); } - .m-result-winner--side2 { background: rgba(59,130,246,0.10); color: #1d4ed8; border-color: rgba(59,130,246,0.30); } + .m-result-winner--side1 { background: rgba(31,158,61,0.10); color: var(--m-c-positive); border-color: rgba(31,158,61,0.32); } + .m-result-winner--side2 { background: rgba(36,75,255,0.10); color: var(--m-c-info); border-color: rgba(36,75,255,0.32); } .m-result-winner--draw { background: rgba(120,113,108,0.10); color: var(--m-c-ink-soft); } - [data-theme="dark"] .m-result-winner--side1 { color: #4ade80; background: rgba(34,197,94,0.15); } - [data-theme="dark"] .m-result-winner--side2 { color: #93c5fd; background: rgba(59,130,246,0.15); } + [data-theme="dark"] .m-result-winner--side1 { background: rgba(74,222,128,0.16); } + [data-theme="dark"] .m-result-winner--side2 { background: rgba(111,139,255,0.16); } @code { diff --git a/src/Marathon.UI/Pages/Results/ResultsLoader.razor b/src/Marathon.UI/Pages/Results/ResultsLoader.razor index bc30faf..429f2ff 100644 --- a/src/Marathon.UI/Pages/Results/ResultsLoader.razor +++ b/src/Marathon.UI/Pages/Results/ResultsLoader.razor @@ -198,8 +198,8 @@ border-radius: var(--m-radius-xs); border: 1px solid var(--m-c-rule); } - .m-result-winner--side1 { background: rgba(34,197,94,0.10); color: #15803d; border-color: rgba(34,197,94,0.30); } - .m-result-winner--side2 { background: rgba(59,130,246,0.10); color: #1d4ed8; border-color: rgba(59,130,246,0.30); } + .m-result-winner--side1 { background: rgba(31,158,61,0.10); color: var(--m-c-positive); border-color: rgba(31,158,61,0.32); } + .m-result-winner--side2 { background: rgba(36,75,255,0.10); color: var(--m-c-info); border-color: rgba(36,75,255,0.32); } .m-result-winner--draw { background: rgba(120,113,108,0.10); color: var(--m-c-ink-soft); } diff --git a/src/Marathon.UI/Pages/Shared/EventListShell.razor b/src/Marathon.UI/Pages/Shared/EventListShell.razor index 9b1a890..c7590df 100644 --- a/src/Marathon.UI/Pages/Shared/EventListShell.razor +++ b/src/Marathon.UI/Pages/Shared/EventListShell.razor @@ -516,7 +516,7 @@ { if (_filter.SortKey != key) return; builder.OpenElement(0, "span"); - builder.AddAttribute(1, "style", "margin-left: 6px; color: var(--m-c-accent);"); + builder.AddAttribute(1, "style", "margin-left: 6px; color: var(--m-c-info);"); builder.AddContent(2, _filter.SortDescending ? "▼" : "▲"); builder.CloseElement(); }; diff --git a/src/Marathon.UI/wwwroot/app.css b/src/Marathon.UI/wwwroot/app.css index 39d2847..382cb71 100644 --- a/src/Marathon.UI/wwwroot/app.css +++ b/src/Marathon.UI/wwwroot/app.css @@ -49,13 +49,14 @@ --m-c-paper: #fffef8; --m-c-paper-2: #f3f1e9; --m-c-paper-3: #e7e3d6; - --m-c-rule: #0a0a0a; + --m-c-rule: #d8d4c4; /* soft divider — brutalist weight lives on cards/inputs, not page hairlines */ --m-c-accent: #c6f400; /* acid lime */ --m-c-accent-soft: #b3dd00; --m-c-on-accent: #0a0a0a; /* ink on lime — lime is a light hue */ --m-c-anomaly: #ff3b30; --m-c-positive: #1f9e3d; - --m-c-info: #244bff; /* electric blue */ + --m-c-info: #244bff; /* electric blue — interactive / highlight / link text */ + --m-c-warning: #c2680a; /* amber — medium severity + warnings (lime is unreadable as text) */ /* Tabular numerals for everywhere odds/scores appear */ --m-num-feature: "tnum" 1, "lnum" 1; @@ -69,13 +70,14 @@ --m-c-paper: #1e1c15; --m-c-paper-2: #141310; --m-c-paper-3: #2a2820; - --m-c-rule: #f5f3ea; + --m-c-rule: #3a3730; --m-c-accent: #c6f400; --m-c-accent-soft: #aacc00; --m-c-on-accent: #0a0a0a; --m-c-anomaly: #ff5a4f; --m-c-positive: #4ade80; --m-c-info: #6f8bff; + --m-c-warning: #ffb24d; /* Hard shadow goes pure-black on dark; the light border defines the block. */ --m-shadow-hard: 5px 5px 0 #000000; --m-shadow-hard-sm: 3px 3px 0 #000000;