/* ============================================================================
   Latch brand design for the status page.

   AN OVERLAY, NOT A FORK EDIT. Gatus is upstream software we run, not software we maintain, so
   this is additive and scoped to the markup Gatus emits. It is injected LAST in <head> by the
   nginx sidecar, so it wins over Gatus's own stylesheet without !important on every rule.

   THE VALUES ARE THE KIT'S, VERBATIM (`latch design/README.md` § Color), never approximations
   chosen to look close: Latch Blue #2B8BFF, Deep Blue #0A63E0, Signal Blue #4A9BFF, Void #04060C,
   Panel #070C17, Hairline #16223A, Ink #E4ECF9, Muted #8A9BB6.

   TYPOGRAPHY loads from Google Fonts, which is correct HERE and wrong for the analytics dashboard:
   Gatus sets no CSP (verified), Umami sets a strict one. Same kit, different constraint — the
   analytics skin falls back to a system stack rather than weakening somebody else's CSP.

   SELECTORS ARE READ OFF THE LIVE DOM, not guessed. Gatus v5 is Vue + Tailwind and defines no
   themeable custom properties; the first version of this skin set `--color-primary` and friends,
   matched nothing, and left the page in stock navy for hours. Where Gatus gives a semantic hook
   (`.endpoint`, `.endpoint-group`, `.endpoint-group-content`, `.status-over-time`) it is used;
   Tailwind utilities are used only where no semantic hook exists.
   ============================================================================ */

@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@600;700&family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@400;500&display=swap');

:root {
  --void: #04060c;
  --panel: #070c17;
  --panel-alt: #080e1a;
  --hairline: #16223a;
  --hairline-soft: #131f34;
  --ink: #e4ecf9;
  --ink-bright: #ffffff;
  --muted: #8a9bb6;
  --blue: #2b8bff;
  --blue-deep: #0a63e0;
  --blue-signal: #4a9bff;

  /* Data encoding, not brand chrome: the CVD-safe pair the rest of the stack uses
     (charts/viz.css). On a status page colour IS the message, so this matters more here than
     almost anywhere — stock green/red is the one palette a red-green colourblind reader cannot
     resolve, and "is it up" is exactly the question they need answered at a glance. */
  --up: #1f9e89;
  --down: #e4572e;

  --font-display: "Chakra Petch", ui-sans-serif, system-ui, sans-serif;
  --font-body: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

  --dur: 0.42s;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------------------------------------------------------------- ground

   The kit's hero treatment: Void, a soft blue glow off the top, and a very faint grid. The grid is
   4% alpha on purpose — present enough to give the page a surface, quiet enough that it never
   competes with the uptime bars, which are the only thing on this page anyone came to read. */
html,
body,
body.dark\:bg-gray-900 {
  background: var(--void) !important;
  color: var(--ink) !important;
  font-family: var(--font-body) !important;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(1100px 520px at 50% -18%, rgba(43, 139, 255, 0.13), transparent 70%),
    linear-gradient(rgba(22, 34, 58, 0.4) 1px, transparent 1px) 0 0 / 100% 64px,
    linear-gradient(90deg, rgba(22, 34, 58, 0.4) 1px, transparent 1px) 0 0 / 64px 100%;
  mask-image: linear-gradient(180deg, #000 0%, #000 42%, transparent 92%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 42%, transparent 92%);
  opacity: 0.55;
}

/* ---------------------------------------------------------------- the card */
.container {
  position: relative;
  z-index: 1;
  background: var(--panel) !important;
  border: 1px solid var(--hairline) !important;
  border-radius: 14px !important;
  color: var(--ink) !important;
  box-shadow:
    0 1px 0 rgba(43, 139, 255, 0.07) inset,
    0 28px 70px -36px rgba(4, 6, 12, 0.95) !important;
}

/* ---------------------------------------------------------------- masthead

   The lockup carries the title. Gatus's own `header` text is hidden rather than restyled: the
   brand rule is the kit's lockup AS SHIPPED, so "Latch" set in a webfont would be a redraw of the
   logo. (Setting `header: ""` in config.yaml does not help — Gatus substitutes its default
   "Health Status", which is what the page showed.)

   The row is reversed so the lockup sits left, where a masthead belongs, rather than orphaned in
   the corner Gatus reserves for a logo. */
.mb-2 > .flex.flex-wrap:first-child {
  align-items: center !important;
  gap: 12px;
  padding: 6px 0 18px;
  border-bottom: 1px solid var(--hairline-soft);
  margin-bottom: 20px;
}

/* Gatus renders a SECOND flex row under the masthead for its header buttons (`ui.buttons`). It now
   carries the navigation — styled at the end of this file — but the `:empty` guard stays: with no
   buttons configured the row holds open ~60px of nothing between the lockup and the first group,
   which is what it did before the nav existed. Guarding on `:empty` rather than deleting the rule
   means removing every button degrades to a tidy page instead of a gap nobody can explain. */
.mb-2 > .flex.flex-wrap:last-child:empty {
  display: none;
}

.mb-2 > .flex > .w-3\/4 {
  display: none !important;
}

/* The logo slot becomes the masthead row: lockup, then the descriptor beside it. `nowrap` and a
   non-growing anchor matter — Gatus's <a> wrapper is `flex justify-center`, so left to itself it
   filled the row and pushed the descriptor onto a second line, indented under nothing. */
.mb-2 > .flex > .w-1\/4 {
  width: 100% !important;
  justify-content: flex-start !important;
  align-items: center !important;
  flex-wrap: nowrap !important;
  gap: 16px;
}

.mb-2 > .flex > .w-1\/4 > a {
  flex: 0 0 auto;
}

.mb-2 img.object-scale-down {
  width: auto !important;
  max-width: 196px !important;
  height: 50px !important;
  object-fit: contain !important;
  object-position: left center !important;
}

/* A one-line descriptor under the lockup. Descriptive copy, not data — it states what the page is,
   and states its limit honestly rather than implying a guarantee the page cannot make. */
.mb-2 > .flex > .w-1\/4::after {
  content: "Service status · checked from Latch infrastructure";
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--muted);
  align-self: center;
  white-space: nowrap;
  padding-top: 3px;
}

/* ---------------------------------------------------------------- groups */
.endpoint-group {
  position: relative;
  background: linear-gradient(180deg, rgba(43, 139, 255, 0.07), rgba(43, 139, 255, 0)) !important;
  border: 1px solid var(--hairline) !important;
  border-bottom: 0 !important;
  border-radius: 10px 10px 0 0 !important;
  padding: 12px 14px !important;
  font-family: var(--font-display) !important;
  font-weight: 600 !important;
  font-size: 0.95rem !important;
  letter-spacing: 0.03em !important;
  color: var(--ink-bright) !important;
}

/* A short accent bar, the kit's section idiom. */
.endpoint-group::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 2px;
  border-radius: 0 2px 2px 0;
  background: linear-gradient(180deg, var(--blue), var(--blue-deep));
}

.endpoint-group-arrow {
  color: var(--blue) !important;
  opacity: 0.75;
}

.endpoint-group-content {
  border-radius: 0 0 10px 10px;
  overflow: hidden;
}

/* ---------------------------------------------------------------- rows */
.endpoint {
  background: transparent !important;
  border-color: var(--hairline) !important;
  padding: 14px !important;
  transition: background-color 0.18s ease;
}

.endpoint:hover,
.endpoint.dark\:hover\:bg-gray-700:hover {
  background: rgba(43, 139, 255, 0.05) !important;
}

/* Endpoint name: the display face, like every card title in the stack. */
.endpoint a.font-bold {
  color: var(--ink-bright) !important;
  font-family: var(--font-display) !important;
  font-weight: 600 !important;
  letter-spacing: 0.01em;
  text-decoration: none !important;
  transition: color 0.16s ease;
}

.endpoint a.font-bold:hover {
  color: var(--blue-signal) !important;
}

/* The hostname beside it, and the response time / timestamps: all data, so all mono. */
.endpoint .text-gray-500,
.endpoint .font-light,
.endpoint .text-sm {
  color: var(--muted) !important;
  font-family: var(--font-mono) !important;
  font-size: 0.78rem !important;
  letter-spacing: 0.01em;
}

/* ---------------------------------------------------------------- uptime bars

   The one data visual on this page, and the reason anyone loads it.

   Bars rise from the baseline on load with a short stagger, so the eye reads the strip
   left-to-right as a timeline rather than as a block that simply appears. Gatus renders its own
   tooltip with the exact timestamp, status and response time on hover — that is the interactive
   layer, and the hover scale here is what invites it. All motion is off under reduced-motion. */
.status-over-time {
  gap: 3px;
  padding-top: 4px;
}

.status-over-time > * {
  border-radius: 3px !important;
  transform-origin: bottom center;
  transition: transform 0.14s ease, filter 0.14s ease;
  animation: latch-rise var(--dur) var(--ease) both;
}

.status-over-time > *:hover {
  transform: scaleY(1.22);
  filter: brightness(1.18);
  z-index: 2;
}

/* A short stagger across the first twenty marks; the rest share the last delay, which keeps the
   rule list short and is indistinguishable once the strip is this wide. */
.status-over-time > *:nth-child(1) { animation-delay: 0ms; }
.status-over-time > *:nth-child(2) { animation-delay: 14ms; }
.status-over-time > *:nth-child(3) { animation-delay: 28ms; }
.status-over-time > *:nth-child(4) { animation-delay: 42ms; }
.status-over-time > *:nth-child(5) { animation-delay: 56ms; }
.status-over-time > *:nth-child(6) { animation-delay: 70ms; }
.status-over-time > *:nth-child(7) { animation-delay: 84ms; }
.status-over-time > *:nth-child(8) { animation-delay: 98ms; }
.status-over-time > *:nth-child(9) { animation-delay: 112ms; }
.status-over-time > *:nth-child(10) { animation-delay: 126ms; }
.status-over-time > *:nth-child(n + 11) { animation-delay: 140ms; }

@keyframes latch-rise {
  from {
    transform: scaleY(0.2);
    opacity: 0;
  }
  to {
    transform: scaleY(1);
    opacity: 1;
  }
}

/* CVD-safe encoding.
   ⚠ GATUS USES ITS OWN SEMANTIC CLASSES for the uptime marks — `.status-success` / `.bg-success`,
   NOT Tailwind's `bg-green-600`. Targeting only the Tailwind names left the bars stock green while
   the group health circle (which does use a Tailwind class) turned teal, which is a worse result
   than not trying: two different greens on one page, encoding the same thing. Both sets are
   covered below. Read off the live DOM, again. */
.bg-success,
.status-success,
.bg-green-600,
.bg-green-500,
.bg-green-400 {
  background-color: var(--up) !important;
}

.bg-failure,
.bg-danger,
.status-failure,
.bg-red-600,
.bg-red-500,
.bg-red-400 {
  background-color: var(--down) !important;
}

.text-success,
.text-green-600,
.text-green-500 {
  color: var(--up) !important;
}

.text-failure,
.text-danger,
.text-red-600,
.text-red-500 {
  color: var(--down) !important;
}

/* An unfilled slot is "no data yet", not "down" — it must never read as a failure. */
.status-over-time > .border-dashed,
.status-over-time > [class*="dashed"] {
  border-color: var(--hairline) !important;
  background: transparent !important;
}

/* The per-group health pill. */
.endpoint-group .rounded-xl,
.endpoint-group [class*="rounded-full"] {
  font-family: var(--font-mono) !important;
  font-weight: 500 !important;
  font-size: 0.72rem !important;
}

/* ---------------------------------------------------------------- footer controls */
select,
button,
input {
  background: var(--panel-alt) !important;
  color: var(--ink) !important;
  border: 1px solid var(--hairline) !important;
  border-radius: 7px !important;
  font-family: var(--font-mono) !important;
  font-size: 0.78rem !important;
}

select:hover,
button:hover {
  border-color: var(--blue) !important;
  color: var(--ink-bright) !important;
}

/* Keyboard focus is visible and on-brand. */
:focus-visible {
  outline: 2px solid var(--blue-signal) !important;
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- responsive

   The kit's rule: a 16px side gutter and no horizontal page scroll at phone width. Gatus's own
   layout is close; this keeps the masthead from crowding at small sizes. */
@media (max-width: 640px) {
  .container {
    border-radius: 0 !important;
    border-left: 0 !important;
    border-right: 0 !important;
    padding-left: 16px !important;
    padding-right: 16px !important;
  }

  .mb-2 img.object-scale-down {
    max-width: 150px !important;
    height: 40px !important;
  }

  /* The descriptor wraps badly beside a 150px lockup; it is supporting copy, not data. */
  .mb-2 > .flex > .w-1\/4::after {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .status-over-time > * {
    animation: none !important;
    transition: none !important;
  }

  .status-over-time > *:hover {
    transform: none !important;
  }
}

/* ==================================================================== navigation

   Gatus's only nav slot is `ui.buttons` — a flat list rendered as plain-text links in the row
   under the masthead (the same row collapsed above when it is empty). There is no markup hook for
   an icon, so each one is painted here, keyed off the destination in the href.

   MASK, NOT BACKGROUND-IMAGE. An SVG used as `background-image` cannot inherit `currentColor`, so
   a hover or focus colour change would not reach it and the icon would stay one fixed colour while
   its label moved. `mask-image` + `background-color: currentColor` makes the glyph take the link's
   own colour in every state, which is the whole point of having states.

   The glyphs are plain geometry on the kit's 24-unit grid at one stroke weight — never an
   approximation of anybody's mark (CLAUDE.md forbids that, and none of these are brands anyway). */

.mb-2 > .flex.flex-wrap:last-child {
  gap: 4px;
  padding-bottom: 18px;
  flex-wrap: wrap !important;
}

.mb-2 > .flex.flex-wrap:last-child a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 0.86rem;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.16s ease, background-color 0.16s ease, border-color 0.16s ease;
}

.mb-2 > .flex.flex-wrap:last-child a:hover,
.mb-2 > .flex.flex-wrap:last-child a:focus-visible {
  color: var(--ink-bright);
  background: rgba(43, 139, 255, 0.08);
  border-color: var(--hairline);
}

/* The glyph itself. `currentColor` + mask, so it follows the link's colour. */
.mb-2 > .flex.flex-wrap:last-child a::before {
  content: "";
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask: var(--glyph) center / contain no-repeat;
  mask: var(--glyph) center / contain no-repeat;
}

/* Keyed on the destination, because the label is the only other thing available and a label is
   copy — it can be reworded without anyone thinking about this file. An href is the address. */
.mb-2 a[href="https://latches.fun"] {
  --glyph: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M3 10l9-7 9 7v10a1 1 0 0 1-1 1h-5v-6H9v6H4a1 1 0 0 1-1-1z'/></svg>");
}

.mb-2 a[href$="/app"] {
  --glyph: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linejoin='round'><path d='M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4zM14 14h6v6h-6z'/></svg>");
}

.mb-2 a[href^="https://docs."] {
  --glyph: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M6 3h7l5 5v13H6zM13 3v5h5M9 13h6M9 17h6'/></svg>");
}

.mb-2 a[href$="/locks"] {
  --glyph: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M5 11h14v10H5zM9 11V7.5a3 3 0 0 1 6 0V11'/></svg>");
}

/* A parachute, for a drop. */
.mb-2 a[href$="/airdrops"] {
  --glyph: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M3 12a9 9 0 0 1 18 0M3 12l9 9 9-9M9 12l3 9 3-9'/></svg>");
}

/* Connected nodes, for an ecosystem. */
.mb-2 a[href$="/ecosystem"] {
  --glyph: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='5' r='2.4'/><circle cx='5' cy='18' r='2.4'/><circle cx='19' cy='18' r='2.4'/><path d='M10.4 7L6.6 15.8M13.6 7l3.8 8.8M7.4 18h9.2'/></svg>");
}

@media (max-width: 640px) {
  /* The labels wrap badly at six items; the icons carry it, and the accessible name survives
     because the text is clipped rather than removed. */
  .mb-2 > .flex.flex-wrap:last-child a {
    gap: 0;
    padding: 8px;
    font-size: 0;
  }
}

/* ==================================================================== the chart

   Gatus serves its response-time chart as `<img src=".../chart.svg">` — a server-rendered image,
   and therefore a separate document that page CSS cannot enter, that cannot hover, cannot take
   focus and cannot animate. `brand/status-chart.js` replaces it with one drawn from Gatus's own
   /api/v1/endpoints/statuses data; these rules dress that. */

.latch-chart {
  position: relative;
  margin: 8px 0 0;
  padding: 0;
}

.latch-chart__svg {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
  outline-offset: 3px;
  cursor: crosshair;
}

/* A failed check is marked, and it pulses so the eye finds it without reading the axis. */
.latch-chart__fail {
  animation: latch-pulse 2.4s ease-in-out infinite;
}

@keyframes latch-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* Hover/focus readout. Exact values, mono, because they are data. */
.latch-chart__tip {
  position: absolute;
  top: -4px;
  transform: translateX(-50%);
  padding: 5px 9px;
  border: 1px solid var(--hairline);
  border-radius: 7px;
  background: var(--panel-alt);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  white-space: nowrap;
  pointer-events: none;
  z-index: 2;
}

.latch-chart__toggle {
  margin-top: 10px;
  padding: 5px 12px !important;
  font-size: 0.72rem !important;
}

.latch-chart__table {
  width: 100%;
  margin-top: 10px;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ink);
}

.latch-chart__table th,
.latch-chart__table td {
  padding: 5px 8px;
  border-bottom: 1px solid var(--hairline);
  text-align: left;
}

.latch-chart__table th {
  color: var(--muted);
  font-weight: 500;
}

/* The honest empty / error state, and the provenance line every chart here carries. */
.latch-chart__empty,
.latch-chart__prov {
  margin: 10px 0 0;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.72rem;
}

.latch-chart__empty {
  padding: 22px 0;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .latch-chart__fail { animation: none; }
}

/* ==================================================================== footer

   Injected as static HTML before </body> by the nginx skin, so it sits OUTSIDE the Vue root and
   survives every re-render with no JavaScript. */

.latch-foot {
  position: relative;
  z-index: 1;
  max-width: 1100px;
  margin: 28px auto 56px;
  padding: 22px 16px 0;
  border-top: 1px solid var(--hairline-soft);
  text-align: center;
}

.latch-foot__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 20px;
  margin-bottom: 12px;
}

.latch-foot a {
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 0.84rem;
  text-decoration: none;
  transition: color 0.16s ease;
}

.latch-foot a:hover,
.latch-foot a:focus-visible {
  color: var(--blue-signal);
}

.latch-foot__row--quiet a,
.latch-foot__credit {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--muted);
  opacity: 0.85;
}

/* Gatus keeps its credit here — named and linked. What it loses is being the page's ONLY outbound
   link, which is what the corner icon made it. */
.latch-foot__credit a {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Gatus's own corner GitHub icon STAYS (owner, 2026-09-20: keep it). It was hidden for one
   revision on the reasoning that a page representing Latch should not have somebody else's
   project as its only outbound link — but that problem is solved by the footer above carrying
   ours, not by removing theirs. Running an open-source project and hiding its one link back is a
   poor trade for a page whose whole subject is being straight with people.

   It is only made quieter, so it reads as a credit rather than a call to action. */
a[href*="TwiN/gatus"]:not(.latch-foot__credit a) {
  opacity: 0.45;
  transition: opacity 0.16s ease;
}

a[href*="TwiN/gatus"]:not(.latch-foot__credit a):hover,
a[href*="TwiN/gatus"]:not(.latch-foot__credit a):focus-visible {
  opacity: 1;
}

/* ==================================================================== uptime strip, v2

   The check marks were the problem. Gatus draws a ✓ or ✗ inside every slot, which at twenty slots
   a row is twenty glyphs competing with the one signal that matters — the colour. The row read as
   a toolbar of buttons rather than as a timeline.

   So: the glyph is moved out of view (NOT deleted — `text-indent` keeps it in the accessible tree,
   so a screen reader still hears "healthy"/"failed" per slot, and Gatus's own hover tooltip still
   carries the timestamp and response), the slots become thin bars that share the width evenly, and
   the eye reads left-to-right as time.

   ⚠ ONE THING DELIBERATELY NOT DONE: an opacity ramp fading older checks. It looks good and it is
   the obvious flourish — and on a STATUS page it is exactly wrong, because the thing it fades is a
   past failure. A red bar from six hours ago must be as loud as one from a minute ago. */

.status-over-time {
  display: flex !important;
  align-items: flex-end;
  gap: 2px !important;
  padding-top: 6px;
}

.status-over-time > * {
  /* Share the row evenly however many checks there are, instead of a fixed chunky width. */
  flex: 1 1 0 !important;
  min-width: 0 !important;
  width: auto !important;
  height: 30px !important;
  border-radius: 3px !important;

  /* The glyph leaves the page but stays in the accessible tree. */
  overflow: hidden;
  text-indent: -9999px;
  white-space: nowrap;

  transform-origin: bottom center;
  position: relative;
}

/* Hover/focus lifts the bar and brightens it, which is also the affordance that invites Gatus's
   own tooltip. `z-index` so a grown bar is never clipped by its neighbour. */
.status-over-time > *:hover {
  transform: scaleY(1.16);
  filter: brightness(1.2) saturate(1.1);
  z-index: 3;
}

/* An empty slot is "no data yet" and must never read as a failure: a hairline ghost, not a mark. */
.status-over-time > .border-dashed,
.status-over-time > [class*="dashed"] {
  height: 18px !important;
  border: 0 !important;
  background: var(--hairline) !important;
  opacity: 0.5;
}

/* The most recent check, marked. On a status page "is it up RIGHT NOW" is the actual question, and
   without this the newest bar is just the rightmost of twenty identical ones. */
.status-over-time > *:last-child {
  box-shadow: 0 0 0 1px var(--blue), 0 0 10px -2px var(--blue);
}

/* A failure keeps full weight and grows slightly, so a single bad check in a green row is findable
   without hunting. The pulse is defined further up and is off under reduced motion. */
.status-over-time > .status-failure,
.status-over-time > .bg-failure,
.status-over-time > [class*="bg-red"] {
  height: 34px !important;
}

/* ==================================================================== masthead v2 — nav on top

   Owner: put the navigation at the top. Gatus renders two stacked rows inside the card — the
   masthead (logo slot) and, under it, the `ui.buttons` row that carries our nav. Stacked, the nav
   reads as page content rather than as navigation, and it pushed the first status group a long way
   down.

   They are siblings, so the fix is to make their PARENT the flex row: lockup left, nav right, one
   line, which is also how latches.fun's own header is built. It wraps to two rows on a narrow
   screen by itself.

   ⚠ SCOPED TO `.container > .mb-2`, NOT `.mb-2`. `mb-2` is a Tailwind margin utility that Gatus
   uses in several places; turning every `.mb-2` on the page into a flex row would quietly relayout
   things that have nothing to do with the header. The header is the one that is a direct child of
   the card. */

.container > .mb-2 {
  display: flex !important;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 28px;
  padding-bottom: 16px;
  margin-bottom: 20px !important;
  border-bottom: 1px solid var(--hairline-soft);
}

/* The masthead row keeps the lockup and its descriptor, but gives up the border and spacing it
   owned when it was the whole header — the parent carries those now. */
.container > .mb-2 > .flex.flex-wrap:first-child {
  flex: 1 1 auto;
  padding: 0 !important;
  margin-bottom: 0 !important;
  border-bottom: 0 !important;
}

/* The nav row sits at the end of the line, and stays a single row of its own when the header
   wraps on a narrow screen. */
.container > .mb-2 > .flex.flex-wrap:last-child {
  flex: 0 0 auto;
  margin-left: auto;
  padding-bottom: 0 !important;
}

/* The descriptor is allowed to wrap under the lockup now that the row is shared. At the width
   where it would collide with the nav it drops to its own line instead of squeezing either. */
.container > .mb-2 > .flex > .w-1\/4 {
  flex-wrap: wrap !important;
  gap: 6px 16px;
}

@media (max-width: 900px) {
  /* Nav below the lockup, full width, left aligned — the wrap happens naturally, this just stops
     it sitting hard right under a left-aligned lockup. */
  .container > .mb-2 > .flex.flex-wrap:last-child {
    margin-left: 0;
    width: 100%;
  }
}

/* --- masthead v2, correction: the nav wrapped instead of sitting beside the lockup ---------
   The masthead row was `flex: 1 1 auto` and its descriptor is a long line, so together they
   consumed the row and pushed the nav onto its own line with a wide gap above it — the stacked
   layout again, just taller. Measured at 1319px: lockup ~196 + descriptor ~450 + nav ~700 does not
   fit, so something had to give.

   The descriptor gives. It drops to a second line UNDER the lockup, which is where a subtitle
   belongs anyway, and the nav takes the space it frees on line one. */

.container > .mb-2 > .flex.flex-wrap:first-child {
  flex: 0 1 auto;
}

/* Was 100% while this row was the whole header; now it shares the line, so it takes only the
   width it needs. */
.container > .mb-2 > .flex > .w-1\/4 {
  width: auto !important;
}

/* `flex-basis: 100%` forces the descriptor onto its own line inside the lockup's box, rather than
   letting it stretch the row. */
.container > .mb-2 > .flex > .w-1\/4::after {
  flex-basis: 100%;
  white-space: normal;
  padding-top: 0;
}


/* --- masthead v3: the descriptor moves to the footer -------------------------------------------
   MEASURED, not guessed: the card is `container-xs` and only 998px wide. The masthead row was
   473px (almost all of it the descriptor) and the nav 569px — 1070px with the gap, so the nav
   wrapped no matter how the flex was arranged. Shrinking the nav would have been the wrong lever;
   it is the navigation.

   The descriptor loses. It is a CAVEAT — "checked from Latch infrastructure" is the page admitting
   it cannot report an outage that takes the host with it — and a caveat belongs with the other
   caveats in the footer, not competing with the navigation for the widest line on the page. It is
   still on the page, still first-person, just where a reader looks for small print. */
.container > .mb-2 > .flex > .w-1\/4::after {
  content: none;
}
