/* SSL Monitor — deep-slate ops board.
   Palette: bg #1D2733, panel #26323F, ink #E9EEF3, muted #8FA0B0,
   ok #43C784, warn #F0B357, crit #E36049, accent #6FAEDB */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;600&family=IBM+Plex+Mono:wght@400;600&display=swap');

:root {
  --bg: #1D2733; --panel: #26323F; --panel-2: #2D3A49;
  --ink: #E9EEF3; --muted: #8FA0B0; --line: #37455566;
  --ok: #43C784; --warn: #F0B357; --crit: #E36049; --accent: #6FAEDB;
  --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
}

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 15px/1.5 "IBM Plex Sans", system-ui, sans-serif;
}
/* Fill the window.
 *
 * This was capped at 1100px, so a 2500px-wide monitor showed a 1100px column
 * with grey either side - and it was the real reason the certificate table had
 * to be squeezed and its buttons clipped. There was never too little room; the
 * page just refused to use it.
 *
 * Tables and tiles take the full width, because that is where more room
 * genuinely helps. Forms and prose do not: a 2500px-long input or line of text
 * is worse than a short one, so those are capped individually below. */
main { width: 100%; margin: 0; padding: 16px 24px; }
a { color: var(--accent); }
h2 { font-size: 17px; margin: 0; letter-spacing: .01em; }

/* ---------------------------------------------------------------- header
 * The nav items had no rule at all, so they were rendering as default browser
 * links - blue and underlined - which is why they looked out of place against
 * everything else on the page.
 *
 * Now a segmented control: one recessed track holding the sections, the
 * current one lit. It reads as a control rather than as prose, and the active
 * page is findable at a glance instead of needing to be read.
 */
.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 20px;
  padding: 10px 24px;
  background: rgba(29, 39, 51, .9);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--line);
}
/* Pushes sign-out to the far right whatever sits between. */
.topbar > .mainnav { margin-right: auto; }
.brand {
  font-family: var(--mono); font-weight: 600; letter-spacing: .06em;
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
}
.brand-lock { color: var(--ok); }
/* Sign out is an action, not a section, so it takes a button shape rather than
   a place in the segmented track. */
.quiet {
  color: var(--muted); text-decoration: none;
  padding: 7px 13px; border-radius: 8px;
  border: 1px solid var(--line); font-size: 13px;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.quiet:hover { color: var(--ink); background: var(--panel-2); border-color: var(--muted); }

.flash {
  background: var(--panel-2); border-left: 3px solid var(--accent);
  padding: 8px 12px; border-radius: 6px;
}
.flash.crit { border-left-color: var(--crit); }

.group {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 14px 16px; margin: 16px 0;
}
.group-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.group-dest { color: var(--muted); font-size: 13px; }
.crit-text { color: var(--crit); }
.warn-text { color: var(--warn); }
.ok-text { color: var(--ok); }
.idle-text { color: var(--muted); }

.table-wrap { overflow-x: auto; margin-top: 10px; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; color: var(--muted); font-weight: 400; font-size: 12px;
  text-transform: uppercase; letter-spacing: .07em;
  padding: 6px 10px; border-bottom: 1px solid var(--line);
}
td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
.row-paused td { opacity: .45; }

.mono { font-family: var(--mono); }
.muted { color: var(--muted); }
.days { font-size: 18px; font-weight: 600; }

.chip {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 12px; font-family: var(--mono);
  background: var(--panel-2); color: var(--muted);
}
.chip.ok   { color: #0E2A1C; background: var(--ok); }
.chip.warn { color: #33250A; background: var(--warn); }
.chip.crit { color: #33100A; background: var(--crit); }
.err-note { color: var(--crit); font-size: 12px; margin-top: 3px; max-width: 260px; }

.tag {
  font-family: var(--mono); font-size: 11px; color: var(--accent);
  border: 1px solid var(--accent); border-radius: 4px; padding: 0 5px; margin-left: 5px;
}

/* Signature element: the certificate's life, drawn as a bar.
   Fill = how much of the validity window is already gone. */
.lifebar {
  width: 130px; height: 8px; border-radius: 4px;
  background: var(--panel-2); overflow: hidden;
}
.lifebar-fill { height: 100%; border-radius: 4px; background: var(--ok); }
.lifebar-fill.warn { background: var(--warn); }
.lifebar-fill.crit { background: var(--crit); }

.row-actions form { display: flex; gap: 6px; }
button {
  font: inherit; color: var(--ink); background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 7px 14px; cursor: pointer;
}
button:hover { background: #354456; }
button:focus-visible, input:focus-visible, select:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.mini { padding: 3px 9px; font-size: 12px; }
.danger { color: var(--crit); border-color: #E3604966; }
.danger:hover { background: #E3604922; }

.inline-form { margin-top: 10px; }
.inline-form summary { color: var(--muted); font-size: 13px; cursor: pointer; }
.inline-form summary:hover { color: var(--ink); }

.row-form { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
input[type=text], input[type=email], input[type=number], input[type=password], select {
  font: inherit; color: var(--ink); background: var(--bg);
  border: 1px solid var(--line); border-radius: 6px; padding: 7px 10px;
}
input::placeholder { color: #6C7C8C; }
.check { color: var(--muted); font-size: 13px; display: flex; align-items: center; gap: 5px; }
.empty { padding: 8px 0 0; }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
@media (max-width: 860px) {
  .two-col { grid-template-columns: 1fr; }
  .hide-sm { display: none; }
}

/* Login */
.login-body { display: grid; place-items: center; min-height: 100vh; }
.login-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 28px; width: min(340px, 92vw);
}
.login-card .brand { margin-bottom: 18px; font-size: 17px; }
.login-card label { display: block; color: var(--muted); font-size: 13px; margin: 12px 0; }
.login-card input { width: 100%; margin-top: 4px; }
.login-card button { width: 100%; margin-top: 14px; background: var(--accent); color: #10222F; border: none; font-weight: 600; }
.login-card button:hover { filter: brightness(1.08); }

@media (prefers-reduced-motion: no-preference) {
  .lifebar-fill { transition: width .4s ease; }
}

/* ---------- SSO login ---------- */
.brand-up { color: #4f8ef7; font-weight: 700; }
.sso-row { display: flex; flex-direction: column; gap: 8px; margin: 14px 0 4px; }
.sso-btn {
  display: block; text-align: center; padding: 10px 12px; border-radius: 8px;
  border: 1px solid #2e3b52; background: #16202f; color: #e8edf5;
  text-decoration: none; font-weight: 600; font-size: 14px;
}
.sso-btn:hover { background: #1c2940; }
.login-divider { display: flex; align-items: center; gap: 10px; color: #6b7a90;
  font-size: 12px; margin: 14px 0; }
.login-divider::before, .login-divider::after { content: ""; flex: 1; height: 1px; background: #2e3b52; }

/* ---------- notification channels ---------- */
.chan-pill { display:inline-block; background:#16202f; border:1px solid #2e3b52;
  border-radius:12px; padding:2px 9px; margin:2px 3px 2px 0; font-size:12px; }
.chan-row { align-items:center; margin-bottom:6px; }
.chan-target { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.row-form input.wide { flex:2; min-width:260px; }
.chan-help { font-size:12px; margin:8px 2px 2px; }
.chan-help code { background:#16202f; padding:1px 5px; border-radius:4px; }
.auth-links { text-align:center; font-size:13px; margin-top:14px; }
.auth-links a { color:#7ea8ff; text-decoration:none; }
.auth-links a:hover { text-decoration:underline; }
.row-form input.narrow { max-width:150px; }
button.ghost { background:transparent; border:1px solid #2e3b52; }

/* ---- "Check now" on an unsaved monitor ---- */

/* A secondary action next to the primary one. It must not read as the button
   you press to finish - saving is still the thing being done. */
button.ghost {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--line);
}
button.ghost:hover:not(:disabled) { background: var(--panel-2); }
button:disabled { opacity: .55; cursor: default; }

.test-result {
  align-self: center;
  font-size: 13px;
  font-family: var(--mono);
  /* Long failure messages - a curl error, a keyword that was not found - wrap
     rather than stretching the form row off the edge of the panel. */
  max-width: 46ch;
  line-height: 1.35;
}
.test-result:empty { display: none; }
.test-result.testing { color: var(--muted); }
.test-result.pass    { color: var(--ok); }
.test-result.fail    { color: var(--crit); }

/* Empty group on the uptime page: the message, then the way out of it. */
.empty-state { margin: 10px 0 4px; }
.empty-state .empty { margin-bottom: 8px; }
.empty-state .row-form { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ---- headline tiles ---- */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 8px;
  margin: 0 0 14px;
}
.tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; padding: 12px 8px; text-align: center;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  text-decoration: none; color: var(--ink);
}
a.tile:hover { border-color: var(--accent); }
.tile-n { font-size: 26px; font-weight: 600; line-height: 1; font-family: var(--mono); }
.tile-label { font-size: 12px; color: var(--muted); line-height: 1.3; }
/* Red means something needs doing. A zero is never red, so the colour keeps
   its meaning instead of becoming wallpaper. */
.tile-bad { background: #3A2320; border-color: var(--crit); }
.tile-bad .tile-n { color: var(--crit); }
/* Nothing to click through to. */
.tile-idle { opacity: .8; }
.tile-on { border-color: var(--accent); box-shadow: inset 0 -2px 0 var(--accent); }

.filter-note { margin: -6px 0 12px; font-size: 13px; color: var(--muted); }

/* ---- installation state ---- */
.chip.inst-healthy { color: #0E2A1C; background: var(--ok); }
.chip.inst-bad     { color: #33100A; background: var(--crit); }
.chip.inst-unknown { color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); }

/* ---- keeping the certificate table inside the page ----
   Adding Installation and Certs-seen pushed the row actions off the right
   edge: the issuer cell was wrapping a full CA distinguished name over five
   lines, which made every row tall AND wide at the same time. Constrain the
   text columns, and never let the buttons be the thing that gets clipped. */
td.issuer-cell {
  max-width: 20ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
td.certs-cell { white-space: nowrap; }
.row-actions { white-space: nowrap; }
.row-actions form { display: flex; gap: 6px; flex-wrap: nowrap; }
.row-actions .mini { white-space: nowrap; }

/* Below this the table cannot fit however it is arranged, so let it scroll
   sideways rather than silently amputating the last column. */
@media (max-width: 1100px) {
  .table-wrap { -webkit-overflow-scrolling: touch; }
  .table-wrap table { min-width: 900px; }
}

/* Things that should not stretch to the width of a cinema screen. */
.stack-form,
.quickcheck,
.flash,
.filter-note,
.empty-state { max-width: 900px; }

/* Tiles stay a readable size rather than growing into billboards. */
.tiles { max-width: 1500px; }

/* ---- aligning the per-group tables ----
   Each group is its own <table>, so by default each sizes its columns from its
   own contents: 5Gstore's short hostnames gave it a narrow Endpoint column
   while CSG's long ones gave it a wide one, and nothing lined up down the page.
   Fixed layout plus pinned widths makes every group agree. The first column is
   left unsized on purpose - it absorbs the remaining space, so the names get
   whatever room the window has spare. */
/* width:auto, not the global 100%.
 *
 * Leaving the endpoint column unsized made it absorb every spare pixel, so on
 * a wide monitor it became a 700px column of whitespace while the last button
 * was pushed off the edge - the same clipping as before, arrived at from the
 * opposite direction. Every column is pinned now and the table is exactly as
 * wide as its contents need, left-aligned. Spare window width stays spare
 * instead of being dumped into whichever column was left flexible. */
table.grid-table { table-layout: fixed; width: auto; }
table.grid-table .c-endpoint{ width: 340px; }
table.grid-table .c-status  { width: 118px; }
table.grid-table .c-days    { width: 92px;  }
table.grid-table .c-window  { width: 150px; }
table.grid-table .c-issuer  { width: 200px; }
table.grid-table .c-install { width: 118px; }
table.grid-table .c-certs   { width: 152px; }
table.grid-table .c-when    { width: 104px; }
table.grid-table .c-pct     { width: 78px;  }
table.grid-table .c-actions { width: 258px; }

/* Fixed layout will not shrink a long hostname for you - it would just spill
   into the next column - so let the identifier wrap instead. */
table.grid-table td:first-child { word-break: break-word; }

/* Below this there is genuinely not enough width for nine columns, so scroll
   sideways rather than crushing them. */
@media (min-width: 861px) and (max-width: 1400px) {
  .table-wrap table.grid-table { min-width: 1320px; }
}

/* Below 860px the .hide-sm columns are removed from the rows entirely - but a
   <col> stays whether or not its cells are displayed, so the pinned widths
   would no longer describe the row and every remaining cell would land in the
   wrong column. Hand sizing back to the browser there: lining groups up
   matters less on a phone than the columns being right at all. */
@media (max-width: 860px) {
  table.grid-table { table-layout: auto; width: 100%; }
  table.grid-table col { width: auto; }
  .table-wrap table.grid-table { min-width: 0; }
  table.grid-table td:first-child { word-break: break-all; }
}

/* The Admin link sits apart from the tenant-facing nav, because it is a
   different kind of thing: those pages are your data, this one is everyone's. */
/* Admin is a different kind of destination - the other pages are your data,
   this one is everyone's - so it sits behind a divider with its own colour,
   without breaking the shape of the control. */
.mainnav .nav-admin { color: var(--warn); margin-left: 6px; position: relative; }
.mainnav .nav-admin::before {
  content: ""; position: absolute; left: -4px; top: 20%; bottom: 20%;
  width: 1px; background: var(--line);
}
.mainnav .nav-admin:hover { background: rgba(240, 179, 87, .12); color: var(--warn); }
.mainnav .nav-admin.active {
  background: rgba(240, 179, 87, .16); color: var(--warn);
  box-shadow: inset 0 0 0 1px rgba(240, 179, 87, .35);
}
.panel { margin-bottom: 18px; }

/* ---- the segmented nav ---- */
.mainnav {
  display: flex; align-items: center; gap: 2px;
  padding: 3px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.mainnav a {
  display: inline-flex; align-items: center;
  padding: 7px 14px; border-radius: 7px;
  font-size: 13.5px; font-weight: 500;
  color: var(--muted); text-decoration: none; white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}
.mainnav a:hover { background: var(--panel-2); color: var(--ink); }
/* The current section is tinted rather than merely bold, so it can be found
   without reading every label. */
.mainnav a.active {
  background: rgba(111, 174, 219, .16);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(111, 174, 219, .3);
}

/* A phone cannot fit six sections plus sign-out on one line. Scroll the track
   sideways rather than wrapping to two rows or shrinking the labels away. */
@media (max-width: 860px) {
  .topbar { gap: 12px; padding: 8px 12px; }
  .topbar .brand { font-size: 13px; }
  .mainnav { overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .mainnav::-webkit-scrollbar { display: none; }
  .mainnav a { padding: 7px 11px; font-size: 13px; }
}

.brand-tld { color: var(--muted); font-weight: 500; }

/* ---- collapsible groups ----
   The whole group header is the control, so the target is the width of the
   panel rather than a small chevron someone has to aim at. */
details.group > summary.group-head {
  cursor: pointer;
  list-style: none;               /* the default triangle sits badly in a flex row */
  padding: 4px 0;
  border-radius: 8px;
  transition: background .12s ease;
}
details.group > summary.group-head::-webkit-details-marker { display: none; }
details.group > summary.group-head:hover { background: var(--panel-2); }
/* Keyboard users need to see where they are; summary is focusable by default. */
details.group > summary.group-head:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* Our own marker, so it can sit before the name and rotate. */
details.group > summary.group-head h2::before {
  content: "";
  display: inline-block;
  width: 0; height: 0;
  margin-right: 9px;
  vertical-align: middle;
  border-left: 5px solid var(--muted);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform-origin: 25% 50%;
  transition: transform .15s ease;
}
details.group[open] > summary.group-head h2::before { transform: rotate(90deg); }

/* Closed, the header is the whole panel, so give it back its breathing room. */
details.group:not([open]) { padding-bottom: 4px; }

/* A closed group should still say whether anything is wrong inside it -
   collapsing is for tidiness, not for hiding problems. */
.group-count { color: var(--muted); font-size: 12px; font-family: var(--mono); }

/* The per-group certificate-transparency list. Its own table, not a grid-table:
   it has different columns from the endpoint table above it and lining the two
   up would imply a relationship between columns that do not correspond. */
.ct-list > summary { display: flex; align-items: center; gap: 10px; }
.ct-list table { font-size: 13px; }
.ct-list .table-wrap { max-height: 420px; overflow-y: auto; }
