/*
* FleetPack status page.
*
* The layout follows the driver-facing toolbox pages (toolbox/kms, toolbox/inspection) : Open Sans,
* the blue-to-sky gradient with its two drifting blobs, and one white card holding everything. A
* customer who has filled in a mileage form should recognise this page as the same product.
*
* Colours are the official FleetPack logo palette : blue #114c81, red #d7282f, yellow #f2a625.
* Green is added for the healthy state, which the logo has no equivalent for.
*
* One rule runs through the whole sheet : "no data" and "healthy" must never look alike. Unknown is
* a flat neutral grey with no fill weight, so a visitor scanning the bars cannot mistake a stretch
* the collector missed for a stretch that was fine.
*
* There is deliberately no prefers-color-scheme block. The toolbox pages are light only, and a dark
* variant would have to re-decide every state colour, which is the one place this page cannot
* afford a second opinion.
*/

:root {
  --blue: #114c81;
  --blue-dark: #0d3a61;
  --sky: #92c6e2;
  --red: #d7282f;
  --amber: #f2a625;
  --green: #2e7d32;

  --ink: #000000;
  --ink-body: #374151;
  --ink-soft: #6b7280;
  --ink-value: #111827;
  --line: #e5e7eb;
  --line-strong: #d1d5db;
  --panel: #f9fafb;
  --card: #ffffff;
  --unknown: #c8d0d7;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* background-attachment:fixed is the one deviation from the toolbox rule set. Those pages always fit
   one screen, so their gradient never runs out; this page grows with the incident history, and an
   unfixed gradient tiles and restarts halfway down as a hard blue seam. */
body {
  font-family: 'Open Sans', Arial, sans-serif;
  background: linear-gradient(135deg, #114c81 0%, #92c6e2 100%);
  background-attachment: fixed;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  position: relative;
  overflow-x: hidden;
  color: var(--ink-body);
  font-size: 15px;
  line-height: 1.55;
}

/* The toolbox pages place these absolutely, which lets the lower blob hang 250px past the body. On a
   one-screen form nobody notices; here it added a quarter-screen of empty scroll under the card.
   position:fixed keeps them out of the document flow entirely, so the page is exactly as tall as
   its content. */
body::before {
  content: '';
  position: fixed;
  width: 600px; height: 600px;
  background: radial-gradient(circle, rgba(242, 166, 37, 0.15) 0%, transparent 70%);
  border-radius: 50%;
  top: -300px; right: -300px;
  animation: float 25s ease-in-out infinite;
  pointer-events: none;
  z-index: 0;
}

body::after {
  content: '';
  position: fixed;
  width: 500px; height: 500px;
  background: radial-gradient(circle, rgba(215, 40, 47, 0.12) 0%, transparent 70%);
  border-radius: 50%;
  bottom: -250px; left: -250px;
  animation: float 20s ease-in-out infinite reverse;
  pointer-events: none;
  z-index: 0;
}

@keyframes float {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(40px, 40px) rotate(5deg); }
}

/* margin:auto keeps the card centred while it is short and lets it scroll from the top once the
   incident history makes it taller than the viewport, which flex centring alone would clip */
.container {
  background: var(--card);
  border-radius: 8px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
  max-width: 680px;
  width: 100%;
  margin: auto;
  padding: 48px 40px;
  position: relative;
  z-index: 1;
  animation: slideUp 0.5s ease-out;
}

@keyframes slideUp {
  from { opacity: 0; transform: translateY(30px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  body::before, body::after, .container { animation: none; }
}

/* ---------- header ---------- */

.header-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 36px;
  gap: 20px;
}

.logo-img { height: 35px; width: auto; display: block; }

/* the toolbox pages carry a language switcher in this slot. This page is English only, so the slot
   holds the page name instead and the header keeps the same shape */
.page-tag {
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* ---------- the headline ---------- */

.banner {
  padding: 20px 22px;
  border-radius: 4px;
  border: 1px solid var(--line);
  border-left: 5px solid var(--unknown);
  background: var(--panel);
  margin-bottom: 8px;
}

.banner h1 { color: var(--ink); font-size: 24px; font-weight: 600; margin-bottom: 6px; }
.banner p { color: var(--ink-soft); font-size: 14px; line-height: 1.7; }

.banner-operational { border-left-color: var(--green); }
.banner-degraded { border-left-color: var(--amber); }
.banner-partial { border-left-color: var(--amber); }
.banner-major { border-left-color: var(--red); }
.banner-unreachable { border-left-color: var(--unknown); }
.banner-unknown { border-left-color: var(--unknown); }

/* the stalled state overrides everything : if our own data is old, nothing below it is current,
   so the banner says so rather than letting stale component rows speak for themselves */
.banner-stalled { border-left-color: var(--red); }

/* ---------- section headings ---------- */

h2 {
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin: 32px 0 10px;
}

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
}

.row {
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
}

.row:last-child { border-bottom: 0; }

.row-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.row-name { font-weight: 600; color: var(--ink-value); font-size: 15px; }

.state {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.state-up { color: var(--green); }
.state-down { color: var(--red); }
.state-degraded { color: var(--amber); }
.state-unknown { color: var(--ink-soft); }

/* ---------- the 90 day strip ---------- */

.bars {
  display: flex;
  gap: 2px;
  margin-top: 12px;
  height: 30px;
  align-items: stretch;
}

.bar {
  flex: 1 1 auto;
  min-width: 2px;
  border-radius: 2px;
  background: var(--unknown);
}

.bar-ok { background: var(--green); }
.bar-warn { background: var(--amber); }
.bar-bad { background: var(--red); }

/* a day the collector only partly covered is drawn hatched, so an incomplete measurement never
   passes for a complete one */
.bar-partial {
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,.55) 0 2px, transparent 2px 4px);
}

.scale {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--ink-soft);
  margin-top: 6px;
}

/* ---------- servers ---------- */

.server-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line);
}

.server-row:last-child { border-bottom: 0; }

.pill {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  color: var(--ink-soft);
  background: var(--card);
  white-space: nowrap;
  display: inline-block;
}

.pill-normal { color: var(--green); border-color: var(--green); }
.pill-busy { color: var(--amber); border-color: var(--amber); }
.pill-overloaded { color: var(--red); border-color: var(--red); }

.server-meta { font-size: 12px; color: var(--ink-soft); margin-top: 4px; }

/* ---------- incidents ---------- */

.incident {
  padding: 18px 20px;
  border-bottom: 1px solid var(--line);
}

.incident:last-child { border-bottom: 0; }

.incident h3 { color: var(--ink-value); margin-bottom: 4px; font-size: 16px; font-weight: 600; }

.incident-meta {
  font-size: 12px;
  color: var(--ink-soft);
  margin-bottom: 10px;
}

.tag {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 2px 8px;
  border-radius: 4px;
  margin-right: 8px;
  color: #fff;
  background: var(--ink-soft);
}

.tag-minor { background: var(--amber); }
.tag-major { background: var(--red); }
.tag-critical { background: var(--red); }
.tag-resolved { background: var(--green); }

.incident-body { font-size: 14px; color: var(--ink-body); }
.incident-body p { margin-bottom: 8px; }
.incident-body p:last-child { margin-bottom: 0; }
.incident-body a { color: var(--blue); font-weight: 600; text-decoration: none; }
.incident-body a:hover { text-decoration: underline; }
.incident-body code {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 13px;
}

.empty {
  padding: 18px 20px;
  color: var(--ink-soft);
  font-size: 14px;
}

/* ---------- footer ---------- */

.foot {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font-size: 11px;
  color: var(--ink-soft);
  font-style: italic;
}

.foot p { margin-bottom: 4px; }
.foot p:last-child { margin-bottom: 0; }
.muted { color: var(--ink-soft); }

@media (max-width: 560px) {
  .container { padding: 32px 24px; }
  .banner h1 { font-size: 20px; }
  .bars { height: 24px; }
  .row-head { flex-direction: column; align-items: flex-start; gap: 2px; }
  .header-row { margin-bottom: 28px; }
}
