:root {
  font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

* { box-sizing: border-box; }

/* An element's own display rule (e.g. .loading-overlay's `display: flex`)
   otherwise beats the browser's default `[hidden] { display: none }` UA
   style, since both are author-origin-equivalent specificity — without
   this, "hidden" elements like the loading overlay or toast would still
   render (and, worse, still intercept clicks) whenever they also carry a
   class that sets `display`. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
}

.muted { color: var(--grey); font-size: 0.92em; }
.error-text { color: var(--red); font-size: 0.92em; }
/* .warn-text and .ok-text live in css/brand.css — every module needs them. */

/* ---------------- Buttons ---------------- */
.btn {
  border: none;
  border-radius: var(--radius);
  padding: 9px 16px;
  font-size: 0.95em;
  cursor: pointer;
  font-weight: 600;
}
.btn-primary { background: var(--action); color: #fff; }
.btn-primary:hover { background: var(--action-hover); }
.btn-ghost { background: transparent; color: var(--navy); border: 1px solid var(--border); }
.btn-ghost:hover { background: var(--grey-light); }
.btn-danger { background: var(--red-bg); color: var(--red); }
.btn-success { background: var(--green-bg); color: var(--green); }
.btn-sm { padding: 5px 10px; font-size: 0.85em; }
.btn-block { width: 100%; }

/* ---------------- Login screen ---------------- */
.login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, var(--navy) 0%, var(--navy-dark) 100%);
}
.login-card {
  background: #fff;
  border-radius: 12px;
  padding: 40px;
  width: 360px;
  text-align: center;
  box-shadow: 0 20px 50px rgba(0,0,0,0.25);
}
.login-logo { max-width: 160px; max-height: 70px; margin-bottom: 12px; }
.login-card h1 { font-size: 1.1em; margin: 0 0 2px; color: var(--navy); }
.login-card h2 { margin: 18px 0 4px; color: var(--ink); }
#login-error { margin-top: 12px; }

/* ---------------- Top bar ---------------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #fff;
  border-bottom: 1px solid var(--border);
  padding: 10px 24px;
}
.topbar-left { display: flex; align-items: center; gap: 12px; }
.topbar-logo { max-height: 34px; }
.topbar-title { font-weight: 700; color: var(--navy); }
.topbar-subtitle { font-size: 0.8em; color: var(--grey); }
.topbar-right { display: flex; align-items: center; gap: 14px; }
.topbar-user { font-size: 0.9em; color: var(--grey); }

/* ---------------- Tabs ---------------- */
.tabs {
  display: flex;
  gap: 4px;
  background: #fff;
  border-bottom: 1px solid var(--border);
  padding: 0 20px;
  overflow-x: auto;
}
.tab-btn {
  background: none;
  border: none;
  padding: 12px 16px;
  font-size: 0.95em;
  cursor: pointer;
  color: var(--grey);
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}
.tab-btn:hover { color: var(--navy); }
.tab-btn.active { color: var(--action); border-bottom-color: var(--action); font-weight: 600; }

/* ---------------- Content ---------------- */
.content { padding: 24px; max-width: 1100px; margin: 0 auto; }
.panel { display: none; }
.panel.active { display: block; }

.banner {
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: 18px;
  font-size: 0.92em;
}
.banner-warning { background: var(--amber-bg); color: var(--amber); }
.banner-info { background: var(--blue-light); color: var(--navy); }

.card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 20px;
}
.card h3 { margin-top: 0; color: var(--navy); }
.card h4 { color: var(--navy); margin: 20px 0 8px; font-size: 1em; }

.cards-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}
.stat-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  text-align: center;
}
.stat-card .stat-value { font-size: 1.7em; font-weight: 700; color: var(--navy); }
.stat-card .stat-label { font-size: 0.82em; color: var(--grey); margin-top: 4px; }

/* ---------------- Forms ---------------- */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.form-grid label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 0.88em;
  color: #333;
  font-weight: 600;
}
.form-grid input, .form-grid select, .form-grid textarea {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 0.95em;
  font-weight: 400;
  font-family: inherit;
}
.form-grid .full-width { grid-column: 1 / -1; }
.field-hint { font-size: 0.82em; font-weight: 400; color: var(--grey); }

/* ---------------- Signers, in order ----------------
   One row per person, numbered, because the order is not decoration:
   it decides who sees whose signature. The number is the only thing
   on screen that says so, so it is given its own column rather than
   left to be inferred from the order of the boxes. */
.signer-row {
  display: grid;
  grid-template-columns: 28px minmax(160px, 1fr) minmax(200px, 1.4fr) auto;
  gap: 10px;
  align-items: start;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.signer-row:last-child { border-bottom: 0; }
.signer-order {
  margin-top: 26px;
  font-weight: 700;
  color: var(--navy);
  text-align: center;
}
.signer-row .signer-remove { margin-top: 24px; }
.signers-add { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* Narrow screens: stacking is the only honest option, and the number
   moves to the top of its own row so it still reads as a heading for
   the two boxes under it rather than as a stray digit. */
@media (max-width: 640px) {
  .signer-row { grid-template-columns: 1fr; }
  .signer-order { margin-top: 0; text-align: left; }
  .signer-row .signer-remove { margin-top: 0; justify-self: start; }
}

.handover-later-title { margin: 18px 0 8px; font-size: 1.02em; color: var(--navy); }

/* A link, but a button underneath: it runs a fetch rather than going
   anywhere, and a screen reader should be told which of those it is. */
.link-button {
  background: none;
  border: 0;
  padding: 0;
  margin-top: 2px;
  font: inherit;
  font-size: 0.86em;
  color: var(--navy);
  text-decoration: underline;
  cursor: pointer;
}
.link-button:disabled { color: var(--grey); cursor: default; text-decoration: none; }
/* Red, because it is the only control on this screen that destroys
   something, and it sits in a row of ones that do not. */
.link-danger { color: var(--danger); }

/* ---------------- Placing the signatures ----------------
   The document, at a size somebody can actually read, with a box per
   signer dropped on top of it. */
.place-signers { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.place-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 999px;
  padding: 6px 12px;
  font: inherit;
  font-size: 0.88em;
  cursor: pointer;
}
.place-chip-n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--border);
  font-size: 0.82em;
  font-weight: 700;
}
.place-chip-where { color: var(--grey); font-size: 0.86em; }
/* Placed and armed are different states and must not look alike: one
   says "this is done", the other says "your next click goes here". */
.place-chip.is-placed { border-color: var(--green); }
.place-chip.is-placed .place-chip-n { background: var(--green); color: #fff; }
.place-chip.is-armed {
  border-color: var(--navy);
  box-shadow: 0 0 0 2px rgba(28, 54, 94, 0.18);
}
.place-chip.is-armed .place-chip-n { background: var(--navy); color: #fff; }

.place-pages {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  max-height: 70vh;
  overflow: auto;
  background: #f4f5f7;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
}
.place-page {
  position: relative;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.16);
  /* The whole page is a target while a signer is armed, and nothing in
     it should be selectable mid-drag — a drag that selects the page
     text instead of drawing a box looks like the tool is broken. */
  user-select: none;
}
.place-page canvas { display: block; }
.place-page-number {
  position: absolute;
  top: 6px;
  left: 6px;
  background: rgba(28, 54, 94, 0.82);
  color: #fff;
  font-size: 0.72em;
  padding: 2px 7px;
  border-radius: 4px;
  pointer-events: none;
}

.place-box {
  position: absolute;
  border: 2px solid var(--navy);
  background: rgba(28, 54, 94, 0.12);
  border-radius: 3px;
}
.place-box-name {
  position: absolute;
  top: -9px;
  left: 4px;
  background: var(--navy);
  color: #fff;
  font-size: 0.68em;
  padding: 1px 6px;
  border-radius: 3px;
  white-space: nowrap;
}
.place-box-x {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--grey);
  font-size: 0.9em;
  line-height: 1;
  cursor: pointer;
}
/* The box being dragged out, before the mouse comes up. Dashed so it
   reads as not yet real. */
.place-drawing { border-style: dashed; background: rgba(28, 54, 94, 0.07); }
.checkbox-label { flex-direction: row !important; align-items: center; gap: 8px !important; }
.days-preview { font-size: 0.9em; color: var(--navy); font-weight: 600; }

/* ---------------- Tables ---------------- */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92em;
}
.data-table th {
  text-align: left;
  background: var(--grey-light);
  padding: 8px 10px;
  color: #444;
  font-weight: 600;
}
.data-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.data-table tr:last-child td { border-bottom: none; }

/* ---------------- Status badges ---------------- */
.badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 0.8em;
  font-weight: 600;
}
.badge-pending { background: var(--amber-bg); color: var(--amber); }
.badge-approved { background: var(--green-bg); color: var(--green); }
.badge-rejected { background: var(--red-bg); color: var(--red); }
.badge-cancelled { background: var(--grey-light); color: var(--grey); }

/* ---------------- Toast / loading ---------------- */
.toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  background: var(--navy-dark);
  color: #fff;
  padding: 12px 18px;
  border-radius: 8px;
  font-size: 0.92em;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
  max-width: 320px;
  z-index: 50;
}
.toast.toast-error { background: var(--red); }

.loading-overlay {
  position: fixed;
  inset: 0;
  background: rgba(255,255,255,0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 40;
}
.spinner {
  width: 34px; height: 34px;
  border: 4px solid var(--blue-light);
  border-top-color: var(--navy);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (max-width: 640px) {
  .content { padding: 14px; }
  .topbar { padding: 10px 14px; }
}


/* Card heading with an action beside it. Wraps rather than squashing the
   button, since the heading and the button are both a fixed size. */
.card-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
}
.card-head-row h3 { margin: 0; }
#check-addresses-note { margin: 10px 0 0; white-space: pre-line; }

/* =====================================================================
   People and access — master/detail
   =====================================================================

   Replaces the old access-grid table: one row per person, one column per
   system. With twelve systems that table could only scroll sideways, so
   most of somebody's access sat off-screen and each cell was too narrow to
   show the roles inside it. Nobody read it across anyway — the question is
   always "what can this one person get at".
   ===================================================================== */

.ac-split {
  display: grid;
  grid-template-columns: minmax(220px, 300px) 1fr;
  gap: 20px;
  align-items: start;
}

/* ---------------- the people list ---------------- */

.ac-search {
  width: 100%;
  padding: 8px 10px;
  margin-bottom: 8px;
  font: inherit;
  border: 1px solid var(--border, #e2e5ea);
  border-radius: var(--radius, 8px);
}

.ac-people-list {
  /* Tall enough to be worth scrolling, short enough that the detail pane
     stays beside it rather than below the fold. */
  max-height: 60vh;
  overflow-y: auto;
  border: 1px solid var(--border, #e2e5ea);
  border-radius: var(--radius, 8px);
}

.ac-person {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 10px 12px;
  text-align: left;
  font: inherit;
  background: none;
  border: none;
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--border, #e2e5ea);
  cursor: pointer;
}
.ac-person:last-child { border-bottom: none; }
.ac-person:hover { background: var(--grey-light, #f3f4f6); }
.ac-person:focus-visible { outline: 2px solid var(--navy, #1f3864); outline-offset: -2px; }

/* The selected person is marked by the navy rail and a tinted ground, not
   by colour alone — the rail is what still reads at a glance when the list
   is long. */
.ac-person.active {
  background: var(--blue-light, #dce6f1);
  border-left-color: var(--navy, #1f3864);
}

.ac-person-name { font-weight: 600; color: var(--navy, #1f3864); }
.ac-person-email { font-size: 0.86em; color: var(--ink-muted, #5b6472); word-break: break-all; }
.ac-person-count { font-size: 0.8em; color: var(--ink-muted, #5b6472); }

/* Someone with nothing at all is the state that quietly breaks a person, so
   it is called out rather than left to read as an ordinary row. */
.ac-person-count.none { color: var(--orange, #b25e09); font-weight: 600; }

.ac-you {
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 0.72em;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  background: var(--navy, #1f3864);
  border-radius: 999px;
  vertical-align: middle;
}

.ac-empty { padding: 14px 12px; margin: 0; }

/* ---------------- the detail pane ---------------- */

.ac-detail {
  min-width: 0;   /* lets the grid column shrink instead of forcing a scroll */
}

.ac-detail-empty {
  padding: 28px 20px;
  text-align: center;
  border: 1px dashed var(--border, #e2e5ea);
  border-radius: var(--radius, 8px);
}

.ac-detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border, #e2e5ea);
}
.ac-detail-name { margin: 0; color: var(--navy, #1f3864); }
.ac-detail-email { font-size: 0.9em; color: var(--ink-muted, #5b6472); word-break: break-all; }
.ac-detail-hint { margin: 10px 0 0; }
.ac-detail-updated { margin: 14px 0 0; font-size: 0.85em; }

.ac-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 12px 0 10px;
  font-size: 0.85em;
  color: var(--ink-muted, #5b6472);
}

.ac-systems {
  display: grid;
  gap: 1px;
  background: var(--border, #e2e5ea);
  border: 1px solid var(--border, #e2e5ea);
  border-radius: var(--radius, 8px);
  overflow: hidden;
}

/* Name, level, roles. Each system gets a full row, which is the whole point:
   the roles are readable instead of crammed into a table cell. */
.ac-system {
  display: grid;
  grid-template-columns: minmax(140px, 1.2fr) 150px minmax(0, 1.6fr);
  gap: 10px 14px;
  align-items: center;
  padding: 10px 12px;
  background: #fff;
}
.ac-system-label { font-weight: 600; }
.ac-system-roles { min-width: 0; }

/* A level set with no roles ticked grants less than it looks like it does
   — see rolesLookWrong() in js/app.js. This has to read as a warning at a
   glance, because the whole failure is somebody reading "Superuser" and
   believing it. */
.btn-roles-warn { border-color: var(--red); color: var(--red); }
.ac-roles-warning {
  margin: 4px 0 0 0;
  color: var(--red);
  font-size: 0.85em;
  line-height: 1.35;
}
.ac-no-roles { font-size: 0.9em; }

@media (max-width: 1100px) {
  .ac-split { grid-template-columns: 1fr; }
  .ac-people-list { max-height: 40vh; }
}

@media (max-width: 720px) {
  .ac-system {
    grid-template-columns: 1fr;
    gap: 6px;
  }
}

/* =====================================================================
   Document Signing — what this screen needs beyond the shared set.
   ===================================================================== */

/* The shared sheet calls the small button .btn-sm; this app's markup uses
   .btn-small, which is what Fleet and the Job Console use. Both, rather
   than renaming one of them and leaving the other looking wrong. */
.btn-small { padding: 5px 10px; font-size: 0.85em; }

.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 10px;
}
.filter-row input[type="search"] { flex: 1 1 240px; }
.filter-row .inline { display: flex; gap: 6px; align-items: center; font-size: 0.92em; color: var(--grey); }

.table-wrap { overflow-x: auto; }
.form-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }

/* Status. Four tones, and nothing invented: these are the same four the
   rest of the suite uses for ok / waiting / wrong / nothing-to-say. */
.pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.82em;
  font-weight: 600;
  white-space: nowrap;
}
.pill-ok { background: var(--green-bg); color: var(--green); }
.pill-warn { background: var(--amber-bg); color: var(--amber); }
.pill-bad { background: var(--danger-bg); color: var(--danger); }
.pill-muted { background: var(--grey-light); color: var(--grey); }

/* ---- the one time the code is on screen ---------------------------
   Deliberately the loudest thing on the page. It is the only moment the
   link and the code exist outside the server, there is nowhere to look
   them up afterwards, and somebody who scrolls past it has to withdraw
   the request and start again. */
.card-handover {
  border: 2px solid var(--action);
  background: #fffdfc;
}
.handover-warning {
  background: var(--amber-bg);
  color: var(--amber);
  border-radius: var(--radius);
  padding: 10px 12px;
  font-size: 0.95em;
}
.handover-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.handover-label {
  flex: 0 0 150px;
  font-weight: 600;
  font-size: 0.9em;
  color: var(--grey);
}
.handover-value {
  flex: 1 1 260px;
  /* Selectable and wrappable: if the clipboard is blocked — an insecure
     origin, a locked-down browser — reading it off the screen has to
     work, and a link that overflows its box cannot be read at all. */
  word-break: break-all;
  user-select: all;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.92em;
}
.handover-code {
  font-size: 1.5em;
  letter-spacing: 0.3em;
  font-weight: 700;
  color: var(--navy);
}

/* Did the link actually go out. Loud either way — the expensive failure
   here is the quiet one, where nobody sends it and everybody waits. */
.handover-posted {
  border-radius: var(--radius);
  padding: 9px 12px;
  font-size: 0.93em;
  font-weight: 600;
}
.handover-posted.ok { background: var(--green-bg); color: var(--green); }
.handover-posted.warn { background: var(--amber-bg); color: var(--amber); }
