fix(web): alert banner overflow + sidebar logo clipping

Alert banner (top of every page when critical events exist):
- Refactored from a single anchor with inline spans into a structured
  wrapper + inner row with a real CTA link.
- Inner row uses flex-wrap with max-width: 1280px container so the text
  never overflows the viewport.
- Text takes flex: 1 1 auto with min-width: 0 + overflow-wrap: anywhere
  so long messages wrap cleanly. CTA stays shrink-0 so "Go to Admin Panel"
  is always visible.
- On viewports ≤560px the text wraps to its own row above the CTA.
- CTA links directly to /settings?section=Admin%20Panel (the URL the
  Settings router actually consumes), not just /settings.
- Singular/plural ("issue" vs "issues") fixed for n=1.
- Softer styling: card+destructive color-mix instead of bright red,
  no shadow, normal weight, no uppercase.

Sidebar logo / brand block (was clipped):
- Two competing CSS rules (one made it a 44×44 icon-only grid, the
  other a 56px-tall flex row). The grid one was clipping the brand text.
  Now an explicit flex row with min-height: 60px, gap: 12px.
- Icon: shrink-0 22×22.
- Brand wrapper: min-width: 0, two stacked lines with line-height: 1.2/1.3.
- "ByteLyst" and "Trading OS" never clip vertically; they ellipsis-truncate
  if the sidebar is somehow constrained horizontally.
- Below 1279px (tablet sidebar): logo block recenters at 52px tall to fit
  the icon-only narrow sidebar.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
root 2026-05-10 08:06:37 +00:00
parent 46a357c0f1
commit 1fa2bcde3b
2 changed files with 171 additions and 7 deletions

View File

@ -193,13 +193,23 @@ function App() {
}}> }}>
<div className={`app-runtime${hasCriticalEvents ? ' has-critical-alert' : ''}`}> <div className={`app-runtime${hasCriticalEvents ? ' has-critical-alert' : ''}`}>
{hasCriticalEvents && ( {hasCriticalEvents && (
<a className="critical-alert-banner" href="/settings"> <div className="critical-alert-banner-wrap" role="alert">
<span aria-hidden="true"></span> <div className="critical-alert-banner-inner">
<span> <span aria-hidden="true" className="critical-alert-banner-icon">
System alert: {recentCriticalEvents.length} critical issues detected go to Settings Admin Panel
</span> </span>
<span aria-hidden="true"></span> <span className="critical-alert-banner-text">
</a> System alert: {recentCriticalEvents.length} critical{' '}
{recentCriticalEvents.length === 1 ? 'issue' : 'issues'} detected.
</span>
<a
className="critical-alert-banner-cta"
href="/settings?section=Admin%20Panel"
>
Go to Admin Panel
</a>
</div>
</div>
)} )}
<AppShell /> <AppShell />
</div> </div>

View File

@ -234,3 +234,157 @@
gap: 12px; gap: 12px;
} }
.saved-setups-header > div { flex: 1 1 280px; min-width: 0; } .saved-setups-header > div { flex: 1 1 280px; min-width: 0; }
/* ============================================================================
* 22. Critical alert banner refactored with structured inner content
*
* The original banner was a single anchor with three inline spans, with no
* width container, no wrapping, and a loud high-contrast red. The new
* structure has a wrapper + inner content row that wraps cleanly.
* ============================================================================ */
.critical-alert-banner-wrap {
width: 100%;
max-width: 100%;
background: color-mix(in oklab, var(--card) 96%, var(--destructive));
border-bottom: 1px solid color-mix(in oklab, var(--destructive) 18%, var(--border));
color: var(--foreground);
}
.critical-alert-banner-inner {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 6px 12px;
width: 100%;
max-width: 1280px;
margin: 0 auto;
padding: 9px 18px;
font-size: 13px;
font-weight: 600;
line-height: 1.4;
}
.critical-alert-banner-icon {
flex-shrink: 0;
color: var(--destructive);
font-size: 14px;
}
.critical-alert-banner-text {
flex: 1 1 auto;
min-width: 0;
text-align: center;
overflow-wrap: anywhere;
word-break: break-word;
}
.critical-alert-banner-cta {
flex-shrink: 0;
color: var(--destructive);
font-weight: 700;
text-decoration: underline;
text-underline-offset: 2px;
text-decoration-thickness: 1px;
white-space: nowrap;
}
.critical-alert-banner-cta:hover {
text-decoration-thickness: 2px;
}
@media (max-width: 560px) {
.critical-alert-banner-inner {
padding: 8px 12px;
font-size: 12px;
gap: 4px 10px;
}
.critical-alert-banner-text {
text-align: left;
flex: 1 1 100%;
}
}
/* ============================================================================
* 23. Sidebar brand / logo block fix clipped icon and "ByteLyst / Trading OS"
*
* Two CSS rules competed (a 44x44 grid block at line 349 and a 56px-tall flex
* block at line 1546). The grid one made the brand text invisible; the flex
* one was too short and lacked flex layout. This sets up a proper:
* icon (shrink-0) + text (min-w-0, two lines) inside a min-height container.
* ============================================================================ */
.trading-sidebar-logo {
/* Layout */
display: flex !important;
align-items: center !important;
justify-content: flex-start !important;
gap: 12px !important;
width: auto !important;
min-height: 60px !important;
height: auto !important;
margin: 4px 4px 22px !important;
padding: 10px 14px !important;
/* Visuals */
border: 1px solid color-mix(in oklab, var(--accent) 34%, var(--border)) !important;
border-radius: 14px !important;
background: linear-gradient(135deg, var(--accent), color-mix(in oklab, var(--accent) 62%, var(--bl-success))) !important;
box-shadow: 0 12px 30px color-mix(in oklab, var(--accent) 26%, transparent) !important;
color: var(--primary-foreground);
/* Don't clip the inner text/icon */
overflow: visible !important;
}
/* Lucide chart icon inside the logo block */
.trading-sidebar-logo > svg {
flex-shrink: 0;
color: var(--primary-foreground);
width: 22px;
height: 22px;
}
.trading-sidebar-brand {
display: flex !important;
flex-direction: column !important;
justify-content: center;
gap: 1px !important;
min-width: 0;
flex: 1 1 auto;
line-height: 1.2;
}
.trading-sidebar-brand strong,
.trading-sidebar-brand span {
display: block;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.trading-sidebar-brand strong {
color: var(--primary-foreground) !important;
font-size: 14px !important;
font-weight: 800 !important;
line-height: 1.2 !important;
}
.trading-sidebar-brand span {
color: color-mix(in oklab, var(--primary-foreground) 80%, transparent) !important;
font-size: 11px !important;
font-weight: 600 !important;
line-height: 1.3 !important;
letter-spacing: 0.02em;
}
/* In the collapsed/icon-only sidebar (under 1280px tablet view), hide brand
* text but keep the icon centered. Existing stylesheet already does this for
* .trading-sidebar-brand { display: none } make sure the logo block recenters. */
@media (max-width: 1279px) {
.trading-sidebar-logo {
justify-content: center !important;
padding: 8px !important;
min-height: 52px !important;
}
}
/* In the bottom-nav mobile state (560px), the sidebar becomes a horizontal
* bar the existing CSS hides the logo. Don't add anything that fights it. */