Live band with 24 h availability strip, gauges for hit rate, response time, cache fill and client errors, traffic chart 24 h / 7 days from the health log counter deltas drawn with the core Chart.js of EXT:dashboard, warm progress ring with live polling, purge activity timeline, client error cards, link to the site settings. ssr-cockpit.js replaces ssr-warm-progress.js, whose deletion went into a9923e1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
230 lines
17 KiB
CSS
230 lines
17 KiB
CSS
/* VITEC SSR cockpit (module web_vitecssr).
|
|
Deliberately dark, in VITEC colours, independent of the backend theme
|
|
(decision Harry, 2026-11-11). The TYPO3 frame stays core: doc header,
|
|
flash messages, confirmation modals. Everything here is scoped to
|
|
.vitec-cockpit or to this module's body.
|
|
Layout: live band + availability / four gauges / traffic 8 + actions 4 /
|
|
purge activity 7 + client errors 5; below 1200 px the wide pairs stack. */
|
|
|
|
[data-module-name="web_vitecssr"] .module-body {
|
|
--module-bg: #080c26;
|
|
background-color: #080c26;
|
|
}
|
|
[data-module-name="web_vitecssr"] .module-body-container {
|
|
max-width: 1680px;
|
|
}
|
|
|
|
.vitec-cockpit {
|
|
--vc-ink: #080c26; /* page: VITEC navy pushed to night */
|
|
--vc-panel: #0f1640; /* card */
|
|
--vc-panel-2: #151e52; /* raised inside a card */
|
|
--vc-line: rgba(140, 156, 255, .14);
|
|
--vc-line-strong: rgba(140, 156, 255, .28);
|
|
--vc-navy: #26358c; /* VITEC blue */
|
|
--vc-navy-hi: #4a5fd6; /* VITEC blue lifted for the dark ground */
|
|
--vc-orange: #f47937; /* VITEC orange: actions and highlights */
|
|
--vc-text: #e9ecfb;
|
|
--vc-muted: #8e97c6;
|
|
--vc-faint: #6a73a6;
|
|
--vc-ok: #35d39a;
|
|
--vc-warn: #ffc65c;
|
|
--vc-bad: #ff5f73;
|
|
--vc-sky: #6fc3ff;
|
|
--vc-mono: var(--typo3-font-family-monospace, ui-monospace, SFMono-Regular, Consolas, monospace);
|
|
--vc-r: 14px;
|
|
color-scheme: dark;
|
|
color: var(--vc-text);
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
.vitec-cockpit *,
|
|
.vitec-cockpit *::before,
|
|
.vitec-cockpit *::after { box-sizing: border-box; }
|
|
.vitec-cockpit code { font-family: var(--vc-mono); font-size: 12px; color: #cdd4ff; background: none; padding: 0; }
|
|
.vitec-cockpit h2, .vitec-cockpit h3 { color: inherit; }
|
|
.vc-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
|
|
|
.vc-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 20px; }
|
|
.vc-card { background: var(--vc-panel); border: 1px solid var(--vc-line); border-radius: var(--vc-r); padding: 20px; min-width: 0; }
|
|
.vc-s12 { grid-column: span 12; } .vc-s8 { grid-column: span 8; } .vc-s4 { grid-column: span 4; }
|
|
.vc-s7 { grid-column: span 7; } .vc-s5 { grid-column: span 5; } .vc-s3 { grid-column: span 3; }
|
|
@media (max-width: 1199.98px) {
|
|
.vc-s8, .vc-s4, .vc-s7, .vc-s5 { grid-column: span 12; }
|
|
.vc-s3 { grid-column: span 6; }
|
|
}
|
|
@media (max-width: 619.98px) { .vc-s3 { grid-column: span 12; } .vc-grid { gap: 14px; } .vc-card { padding: 16px; } }
|
|
|
|
.vc-card-h { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
|
|
.vc-card-t { font-size: 13px; font-weight: 700; line-height: 1.2; letter-spacing: .08em; text-transform: uppercase; color: var(--vc-muted) !important; margin: 0; display: flex; align-items: center; gap: 8px; }
|
|
.vc-card-t svg { color: var(--vc-navy-hi); }
|
|
.vc-dim { color: var(--vc-muted); font-size: 12px; }
|
|
.vc-ok-text { color: var(--vc-ok); } .vc-bad-text { color: var(--vc-bad); } .vc-warn-text { color: var(--vc-warn); }
|
|
.vc-link { color: var(--vc-sky); text-decoration: none; font-size: 12px; font-weight: 500; }
|
|
.vc-link:hover, .vc-link:focus { color: var(--vc-sky); text-decoration: underline; }
|
|
|
|
/* Pills */
|
|
.vc-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; line-height: 1; letter-spacing: .04em; padding: 5px 9px; border-radius: 99px; white-space: nowrap; background: rgba(140, 156, 255, .12); color: #c4cbf0; }
|
|
.vc-pill.is-ok { background: rgba(53, 211, 154, .14); color: var(--vc-ok); }
|
|
.vc-pill.is-warn { background: rgba(255, 198, 92, .15); color: var(--vc-warn); }
|
|
.vc-pill.is-bad { background: rgba(255, 95, 115, .15); color: var(--vc-bad); }
|
|
.vc-pill.is-sky, .vc-pill.is-info { background: rgba(111, 195, 255, .14); color: var(--vc-sky); }
|
|
.vc-pill.is-navy { background: rgba(74, 95, 214, .24); color: #b8c3ff; }
|
|
.vc-pill.is-orange { background: rgba(244, 121, 55, .16); color: var(--vc-orange); }
|
|
.vc-pill.is-muted { background: rgba(140, 156, 255, .1); color: var(--vc-muted); }
|
|
|
|
/* Live band */
|
|
.vc-hero { padding: 24px 24px 20px; background:
|
|
radial-gradient(120% 140% at 0% 0%, rgba(74, 95, 214, .35), transparent 55%),
|
|
radial-gradient(80% 120% at 100% 0%, rgba(244, 121, 55, .12), transparent 50%),
|
|
var(--vc-panel); }
|
|
.vc-hero-top { display: flex; flex-wrap: wrap; align-items: center; gap: 18px 28px; }
|
|
.vc-live { display: flex; align-items: center; gap: 14px; min-width: 0; }
|
|
.vc-pulse { position: relative; width: 14px; height: 14px; border-radius: 50%; background: var(--vc-ok); flex: none; }
|
|
.vc-pulse::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; border: 2px solid currentColor; color: var(--vc-ok); opacity: 0; animation: vc-ping 2.4s ease-out infinite; }
|
|
.vc-pulse.is-down { background: var(--vc-bad); }
|
|
.vc-pulse.is-down::after { color: var(--vc-bad); }
|
|
@keyframes vc-ping { 0% { transform: scale(.5); opacity: .8; } 100% { transform: scale(1.6); opacity: 0; } }
|
|
.vc-live-title { font-size: 30px; font-weight: 800; line-height: 1.1; letter-spacing: -.01em; margin: 0; }
|
|
.vc-live-sub { margin: 2px 0 0; color: var(--vc-muted); font-size: 13px; }
|
|
.vc-facts { display: flex; flex-wrap: wrap; gap: 10px 28px; margin: 0 0 0 auto; }
|
|
.vc-fact dt { font-size: 11px; font-weight: 400; letter-spacing: .08em; text-transform: uppercase; color: var(--vc-faint); }
|
|
.vc-fact dd { margin: 2px 0 0; font-weight: 600; display: flex; align-items: center; gap: 8px; white-space: nowrap; }
|
|
@media (max-width: 899.98px) { .vc-facts { margin-left: 0; } }
|
|
|
|
.vc-uptime { margin-top: 22px; }
|
|
.vc-uptime-h { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 12px; color: var(--vc-muted); margin-bottom: 8px; }
|
|
.vc-uptime-h b { color: var(--vc-text); font-weight: 600; }
|
|
.vc-bars { display: grid; grid-template-columns: repeat(96, minmax(0, 1fr)); gap: 2px; height: 30px; align-items: end; }
|
|
.vc-bars i { display: block; height: 100%; border-radius: 2px; background: var(--vc-ok); opacity: .85; transition: opacity .15s, transform .15s; }
|
|
.vc-bars i.is-slow { background: var(--vc-warn); }
|
|
.vc-bars i.is-down { background: var(--vc-bad); }
|
|
.vc-bars i.is-none { background: rgba(140, 156, 255, .14); height: 40%; }
|
|
.vc-bars i:hover { opacity: 1; transform: scaleY(1.12); }
|
|
@media (max-width: 619.98px) { .vc-bars { gap: 1px; } }
|
|
.vc-uptime-f { display: flex; justify-content: space-between; font: 11px var(--vc-mono); color: var(--vc-faint); margin-top: 6px; }
|
|
|
|
/* Gauges */
|
|
.vc-tile { display: flex; gap: 14px; align-items: center; }
|
|
.vc-tile .vc-ring { width: 78px; height: 78px; }
|
|
.vc-tile-body { min-width: 0; flex: 1; }
|
|
.vc-label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--vc-muted); font-weight: 600; }
|
|
.vc-big { font-size: 32px; font-weight: 800; line-height: 1.05; margin: 6px 0 4px; font-variant-numeric: tabular-nums; letter-spacing: -.02em; white-space: nowrap; }
|
|
.vc-big small { font-size: 15px; font-weight: 600; color: var(--vc-muted); margin-left: 4px; letter-spacing: 0; }
|
|
.vc-sub { font-size: 12px; color: var(--vc-muted); }
|
|
.vc-sub b { color: var(--vc-text); }
|
|
.vc-sub .is-up { color: var(--vc-ok); } .vc-sub .is-down { color: var(--vc-bad); }
|
|
.vc-ring { flex: none; }
|
|
.vc-ring circle { fill: none; stroke-width: 9; }
|
|
.vc-ring .vc-track { stroke: rgba(140, 156, 255, .12); }
|
|
.vc-ring .vc-val { stroke-linecap: round; transform: rotate(-90deg); transform-origin: 50% 50%; stroke-dasharray: 251.33; stroke-dashoffset: 251.33; transition: stroke-dashoffset 1s cubic-bezier(.2, .8, .2, 1); }
|
|
.vc-ring .vc-val.is-fast { transition-duration: .4s; }
|
|
.vc-val.is-ok { stroke: var(--vc-ok); } .vc-val.is-sky { stroke: var(--vc-sky); } .vc-val.is-orange { stroke: var(--vc-orange); }
|
|
.vc-spark { display: block; width: 100%; height: 46px; margin-top: 6px; }
|
|
.vc-mini { display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); gap: 2px; align-items: end; height: 40px; margin-top: 8px; }
|
|
.vc-mini i { display: block; background: var(--vc-navy-hi); border-radius: 2px 2px 0 0; min-height: 2px; }
|
|
.vc-mini i.is-hot { background: var(--vc-bad); }
|
|
|
|
/* Segmented control */
|
|
.vc-seg { display: inline-flex; background: var(--vc-panel-2); border: 1px solid var(--vc-line); border-radius: 99px; padding: 3px; }
|
|
.vc-seg button, .vc-seg a { border: 0; background: transparent; color: var(--vc-muted); font-size: 12px; font-weight: 600; padding: 5px 12px; border-radius: 99px; cursor: pointer; text-decoration: none; line-height: 1.4; }
|
|
.vc-seg button:hover, .vc-seg a:hover { color: var(--vc-text); text-decoration: none; }
|
|
.vc-seg [aria-pressed="true"] { background: var(--vc-navy); color: #fff; }
|
|
.vitec-cockpit :is(button, a, textarea, summary):focus-visible { outline: 2px solid var(--vc-orange); outline-offset: 2px; }
|
|
|
|
.vc-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12px; color: var(--vc-muted); }
|
|
.vc-legend span { display: inline-flex; align-items: center; gap: 6px; }
|
|
.vc-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
|
|
.vc-legend i.is-navy { background: var(--vc-navy-hi); } .vc-legend i.is-sky { background: var(--vc-sky); }
|
|
.vc-legend i.is-warn { background: var(--vc-warn); } .vc-legend i.is-orange { background: var(--vc-orange); }
|
|
.vc-legend i.is-bad { background: var(--vc-bad); } .vc-legend i.is-ok { background: var(--vc-ok); }
|
|
.vc-legend i.is-round { border-radius: 50%; }
|
|
.vc-legend i.is-tri { border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
|
|
.vc-legend-tl { margin: -6px 0 10px; }
|
|
.vc-chart-card { display: flex; flex-direction: column; }
|
|
.vc-chart { position: relative; flex: 1 1 auto; min-height: 320px; margin-top: 12px; overflow: hidden; }
|
|
.vc-chart canvas { max-width: 100%; }
|
|
@media (max-width: 619.98px) { .vc-chart { min-height: 260px; } }
|
|
.vc-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 16px 0 0; padding-top: 16px; border-top: 1px solid var(--vc-line); }
|
|
.vc-stats dt { font-size: 11px; font-weight: 400; color: var(--vc-faint); text-transform: uppercase; letter-spacing: .07em; }
|
|
.vc-stats dd { margin: 2px 0 0; font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
|
|
@media (max-width: 619.98px) { .vc-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
|
.vc-empty { color: var(--vc-muted); font-size: 13px; margin: 12px 0 0; }
|
|
|
|
/* Actions */
|
|
.vc-actions { display: flex; flex-direction: column; gap: 14px; }
|
|
.vc-act { background: var(--vc-panel-2); border: 1px solid var(--vc-line); border-radius: 12px; padding: 16px; margin: 0; }
|
|
.vc-act-h { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
.vc-act-t { font-size: 15px; font-weight: 700; margin: 0; }
|
|
.vc-help { margin: 8px 0 0; color: var(--vc-muted); font-size: 12.5px; }
|
|
.vc-warm { display: flex; gap: 16px; align-items: center; margin-top: 12px; }
|
|
.vc-warm-ring { position: relative; flex: none; width: 92px; height: 92px; }
|
|
.vc-warm-pct { position: absolute; inset: 0; display: grid; place-items: center; font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }
|
|
.vc-warm-meta { font-size: 12.5px; color: var(--vc-muted); min-width: 0; }
|
|
.vc-warm-meta b { color: var(--vc-text); font-variant-numeric: tabular-nums; }
|
|
.vc-btn-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
|
|
.vc-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; border-radius: 9px; border: 1px solid transparent; font-size: 13px; font-weight: 700; line-height: 1.2; padding: 9px 14px; cursor: pointer; transition: transform .1s, filter .15s, background-color .15s, border-color .15s; }
|
|
.vc-btn:active { transform: scale(.98); }
|
|
.vc-btn.is-primary { background: var(--vc-orange); color: #1b0b02; }
|
|
.vc-btn.is-primary:hover { filter: brightness(1.08); }
|
|
.vc-btn.is-primary[disabled] { background: rgba(244, 121, 55, .3); color: rgba(255, 255, 255, .65); cursor: progress; filter: none; }
|
|
.vc-btn.is-ghost { background: transparent; color: var(--vc-text); border-color: var(--vc-line-strong); }
|
|
.vc-btn.is-ghost:hover { border-color: var(--vc-navy-hi); background: rgba(74, 95, 214, .14); }
|
|
.vc-btn.is-danger { background: transparent; color: var(--vc-bad); border-color: rgba(255, 95, 115, .45); }
|
|
.vc-btn.is-danger:hover { background: rgba(255, 95, 115, .15); }
|
|
.vc-lbl { display: block; font-size: 12px; color: var(--vc-muted); margin: 12px 0 6px; font-weight: 600; }
|
|
.vc-input { width: 100%; resize: vertical; min-height: 84px; background: var(--vc-ink); color: var(--vc-text); border: 1px solid var(--vc-line-strong); border-radius: 9px; padding: 10px 12px; font: 12.5px/1.6 var(--vc-mono); }
|
|
.vc-input::placeholder { color: var(--vc-faint); }
|
|
.vc-input:focus { border-color: var(--vc-navy-hi); outline: none; }
|
|
|
|
/* Purge activity timeline */
|
|
.vc-timeline { list-style: none; margin: 0; padding: 0; position: relative; }
|
|
.vc-timeline::before { content: ""; position: absolute; left: 62px; top: 6px; bottom: 6px; width: 1px; background: var(--vc-line-strong); }
|
|
.vc-ev { display: grid; grid-template-columns: 52px 22px minmax(0, 1fr) auto; gap: 0 10px; align-items: start; padding: 10px 0; }
|
|
.vc-ev + .vc-ev { border-top: 1px dashed rgba(140, 156, 255, .08); }
|
|
.vc-ev time { font: 500 12px var(--vc-mono); color: var(--vc-muted); text-align: right; padding-top: 2px; }
|
|
.vc-dot { width: 11px; height: 11px; border-radius: 50%; margin: 5px auto 0; box-shadow: 0 0 0 4px var(--vc-panel); position: relative; z-index: 1; background: var(--vc-sky); }
|
|
.vc-dot.is-ok { background: var(--vc-ok); } .vc-dot.is-orange { background: var(--vc-orange); }
|
|
.vc-dot.is-navy { background: var(--vc-navy-hi); } .vc-dot.is-warn { background: var(--vc-warn); }
|
|
.vc-ev-main { min-width: 0; }
|
|
.vc-ev-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
|
|
.vc-paths { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }
|
|
.vc-path { font: 12px var(--vc-mono); background: rgba(140, 156, 255, .08); color: #cdd4ff; border-radius: 6px; padding: 2px 7px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
.vc-more { font-size: 12px; }
|
|
.vc-more summary { color: var(--vc-sky); cursor: pointer; list-style: none; padding: 2px 4px; }
|
|
.vc-more summary::-webkit-details-marker { display: none; }
|
|
.vc-more[open] { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 6px; }
|
|
.vc-more[open] summary { flex-basis: 100%; }
|
|
.vc-ev-r { text-align: right; font: 500 12px var(--vc-mono); color: var(--vc-muted); white-space: nowrap; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
|
|
.vc-day { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--vc-faint); padding: 14px 0 4px 74px; }
|
|
.vc-day:first-child { padding-top: 0; }
|
|
@media (max-width: 619.98px) {
|
|
.vc-timeline::before { left: 46px; }
|
|
.vc-ev { grid-template-columns: 38px 18px minmax(0, 1fr); }
|
|
.vc-ev-r { grid-column: 3; flex-direction: row; align-items: center; margin-top: 6px; }
|
|
.vc-day { padding-left: 58px; }
|
|
}
|
|
|
|
/* Client errors */
|
|
.vc-err-sum { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 0 0 16px; }
|
|
.vc-err-sum div { background: var(--vc-panel-2); border-radius: 10px; padding: 10px 12px; min-width: 0; }
|
|
.vc-err-sum dt { font-size: 11px; font-weight: 400; color: var(--vc-faint); text-transform: uppercase; letter-spacing: .07em; }
|
|
.vc-err-sum dd { margin: 2px 0 0; font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
|
|
.vc-errs { display: flex; flex-direction: column; gap: 8px; }
|
|
.vc-err { background: var(--vc-panel-2); border: 1px solid var(--vc-line); border-radius: 10px; }
|
|
.vc-err[open] { border-color: var(--vc-line-strong); }
|
|
.vc-err summary { list-style: none; cursor: pointer; padding: 12px 14px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: center; }
|
|
.vc-err summary::-webkit-details-marker { display: none; }
|
|
.vc-err-msg { min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
.vc-err-msg small { display: block; color: var(--vc-muted); font: 11.5px var(--vc-mono); overflow: hidden; text-overflow: ellipsis; }
|
|
.vc-err-t { font: 12px var(--vc-mono); color: var(--vc-muted); white-space: nowrap; }
|
|
.vc-err-body { padding: 0 14px 14px; font-size: 12.5px; }
|
|
.vc-kv { display: grid; grid-template-columns: 76px minmax(0, 1fr); gap: 6px 12px; margin: 0; }
|
|
.vc-kv dt { color: var(--vc-faint); font-weight: 400; }
|
|
.vc-kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
|
|
.vc-stack { margin: 10px 0 0; background: var(--vc-ink); border: 0; border-radius: 8px; padding: 10px 12px; font: 11.5px/1.55 var(--vc-mono); color: #b9c1ef; overflow: auto; max-height: 320px; white-space: pre; }
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.vitec-cockpit *, .vitec-cockpit *::after { animation: none !important; transition: none !important; }
|
|
}
|