207 lines
7.9 KiB
CSS
207 lines
7.9 KiB
CSS
/* ScadaBridge Central UI – global styles. Loaded from Host App.razor as
|
||
`_content/ZB.MOM.WW.ScadaBridge.CentralUI/css/site.css`.
|
||
The shared ZB.MOM.WW.Theme kit (linked via <ThemeHead/>) owns the tokens and
|
||
the side-rail shell; this sheet carries only app-specific rules the kit does
|
||
not provide. */
|
||
|
||
/* ── App-level tokens (light defaults) ─────────────────────────────────────
|
||
--sb-backdrop: semi-transparent overlay used by DialogHost and ad-hoc
|
||
modal backdrops throughout the app.
|
||
--accent: ScadaBridge's product accent. Declared HERE rather than as
|
||
ThemeShell's Accent="…" parameter: that parameter emits an inline
|
||
style="--accent: …" on the shell root, which is a descendant of <html> and
|
||
therefore beat the [data-bs-theme="dark"] override below for the whole app
|
||
— the dark accent was dead. As a :root declaration it loses to the dark
|
||
block (equal specificity, later in this file) and wins over theme.css
|
||
(equal specificity, earlier sheet), so both schemes resolve correctly.
|
||
The value matches theme.css's own light default, so light mode is
|
||
unchanged. */
|
||
:root {
|
||
--sb-backdrop: rgba(0, 0, 0, 0.4);
|
||
--accent: #2f5fd0;
|
||
}
|
||
|
||
/* Button sizing lives in ZB.MOM.WW.Theme's layout.css as of 0.4.0 (the local
|
||
copy that used to sit here was upstreamed verbatim), so there is deliberately
|
||
no `.btn` rule in this sheet. Do not reintroduce one — and if you ever need
|
||
to, override the CSS *variables* only, never the box properties, because
|
||
.btn-group's seam and border-radius machinery is built on them. */
|
||
|
||
/* Bootstrap ships .form-label and .col-form-label-sm but no .form-label-sm,
|
||
so the small-label intent next to a form-select-sm/form-control-sm was a
|
||
silent no-op wherever it was used. Give it the rule it always implied. */
|
||
.form-label-sm {
|
||
font-size: .8rem;
|
||
margin-bottom: .2rem;
|
||
}
|
||
|
||
/* ── Table cell containment ─────────────────────────────────────────────────
|
||
Text this app does not control — remote exception messages, X.509 DNs, OPC UA
|
||
node ids, serialized payloads, bundle-supplied names — must never be allowed
|
||
to set a table's width. A single long value otherwise pushes the actions
|
||
column off-screen exactly when an operator most needs it. Apply .cell-clip
|
||
(optionally with a width modifier) to the cell or an inner block, and ALWAYS
|
||
pair it with a title="…" so the full value stays reachable; where a fuller
|
||
view exists, keep it in the row's detail drawer/dialog too.
|
||
Modelled on the existing .parked-error-clamp pattern in ParkedMessages. */
|
||
.cell-clip {
|
||
display: block;
|
||
max-width: 22rem;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.cell-clip-sm { max-width: 11rem; }
|
||
.cell-clip-lg { max-width: 34rem; }
|
||
|
||
/* Two-line clamp for message-shaped text that deserves more than one line. */
|
||
.cell-clamp-2 {
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
max-width: 34rem;
|
||
}
|
||
|
||
/* For <pre>/<code> detail blocks: wrap instead of forcing horizontal scroll. */
|
||
.detail-pre {
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* Reusable backdrop class — applied by DialogHost and standalone modal
|
||
backdrop divs so the overlay colour follows the active theme. */
|
||
.sb-modal-backdrop {
|
||
background: var(--sb-backdrop);
|
||
}
|
||
|
||
#reconnect-modal {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 9999;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
}
|
||
|
||
#reconnect-modal .modal-content {
|
||
max-width: 400px;
|
||
padding: 2rem;
|
||
text-align: center;
|
||
background: var(--card, #fff);
|
||
border-radius: 0.5rem;
|
||
}
|
||
|
||
/* Script editor modal — the tabbed Trigger/Code/Parameters/Return content is
|
||
substantial, so the dialog fills most of the viewport. Pairs with
|
||
.modal-dialog-scrollable so the body scrolls within the fixed height. */
|
||
.modal-dialog.script-editor-modal {
|
||
max-width: 96vw;
|
||
width: 96vw;
|
||
height: calc(100vh - 2rem);
|
||
}
|
||
|
||
.modal-dialog.script-editor-modal .modal-content {
|
||
height: 100%;
|
||
}
|
||
|
||
/* ── Dark-mode token overrides ───────────────────────────────────────────────
|
||
Activated when <html data-bs-theme="dark"> is set (T34b toggle task).
|
||
Loads after theme.css / layout.css so [data-bs-theme] specificity (0,1,0)
|
||
beats the theme's :root (0,0,1) at equal cascade layer. */
|
||
[data-bs-theme="dark"] {
|
||
/* Surfaces & ink */
|
||
--paper: #1b1d21;
|
||
--card: #25282d;
|
||
--ink: #e6e8ec;
|
||
--ink-soft: #9aa0aa;
|
||
--ink-faint: #a8b0bc;
|
||
--rule: #33373e;
|
||
--rule-strong: #3a3f46;
|
||
|
||
/* Accent — lightened for contrast on dark */
|
||
--accent: #7aa0ef;
|
||
--accent-deep: #9dbaf6;
|
||
--accent-tint: #1e2640;
|
||
--accent-border: #566d9c;
|
||
--accent-focus: #a7c1ff;
|
||
--on-accent: #111827;
|
||
|
||
/* Status — signal colors are retained; text uses the readable inks below. */
|
||
--ok: #40b856;
|
||
--warn: #f0a030;
|
||
--bad: #f05050;
|
||
--idle: #7a8290;
|
||
--ok-ink: #8ada96;
|
||
--bad-ink: #ff9d9d;
|
||
--idle-ink: #c3cad5;
|
||
|
||
/* Status — tinted backgrounds (dark surface tints) */
|
||
--ok-bg: #1a2e1e;
|
||
--warn-bg: #2e2210;
|
||
--bad-bg: #2e1616;
|
||
--idle-bg: #25282d;
|
||
|
||
/* Status — borders on dark tints */
|
||
--ok-border: #2a5030;
|
||
--warn-border: #4a3510;
|
||
--bad-border: #4a2020;
|
||
--ok-border-soft: #264a2c;
|
||
--warn-border-soft: #44300e;
|
||
--bad-border-soft: #44201e;
|
||
|
||
/* Warning ink — brightened amber for dark contrast */
|
||
--warn-ink: #efbd63;
|
||
--warn-ink-deep: #efbd63;
|
||
|
||
/* Semantic information stays blue, independent of product accent. */
|
||
--info-ink: #b4c6ff;
|
||
--info-bg: #1a2240;
|
||
--info-border: #2a3660;
|
||
|
||
/* Neutral surface washes */
|
||
--zebra-bg: #202328;
|
||
--hover-bg: #2a2e38;
|
||
--active-bg: var(--accent-tint);
|
||
|
||
/* Bootstrap bridge tokens */
|
||
--bs-body-bg: var(--paper);
|
||
--bs-body-color: var(--ink);
|
||
--bs-border-color: var(--rule);
|
||
--bs-emphasis-color: var(--ink);
|
||
|
||
/* Backdrop — slightly darker overlay in dark mode */
|
||
--sb-backdrop: rgba(0, 0, 0, 0.6);
|
||
}
|
||
|
||
/* Supported-dark Bootstrap adapter: secondary actions use host surface inks. */
|
||
[data-bs-theme="dark"] .btn-outline-secondary {
|
||
--bs-btn-color: var(--ink-soft);
|
||
--bs-btn-border-color: var(--ink-soft);
|
||
--bs-btn-hover-color: var(--card);
|
||
--bs-btn-hover-bg: var(--ink-soft);
|
||
--bs-btn-hover-border-color: var(--ink-soft);
|
||
--bs-btn-active-color: var(--card);
|
||
--bs-btn-active-bg: var(--ink-soft);
|
||
--bs-btn-active-border-color: var(--ink-soft);
|
||
--bs-btn-disabled-color: var(--ink-soft);
|
||
--bs-btn-disabled-bg: transparent;
|
||
--bs-btn-disabled-border-color: var(--ink-soft);
|
||
}
|
||
|
||
/* ── Rail pending-updates indicator ──────────────────────────────────────
|
||
Sits in .rail-foot just above .rail-user. One line when quiet, two when
|
||
something is pending; tokens only so dark mode follows for free. */
|
||
.rail-updates { display: flex; flex-direction: column; gap: 0.15rem; padding: 0 0.6rem 0.5rem; font-size: 0.8rem; line-height: 1.3; }
|
||
.rail-updates-muted { color: var(--ink-faint); }
|
||
.rail-updates-head { display: flex; align-items: center; gap: 0.35rem; font-weight: 600; color: var(--ink-soft); }
|
||
.rail-updates-head .badge { font-size: 0.7rem; }
|
||
.rail-updates-detail { color: var(--ink-faint); }
|
||
.rail-updates a { color: inherit; text-decoration: underline dotted; }
|
||
.rail-updates a:hover { color: var(--accent); }
|