/* Sign-in, access request, password reset, and the admin panel.
 *
 * Standalone rather than an addition to map.css, which sets
 * `html, body { overflow: hidden }` for the map shell - correct there, and
 * wrong for every page here, all of which scroll. The token block is therefore
 * repeated instead of shared. That is a real duplication and the alternative
 * was worse: either fighting the map's layout rules on every page, or
 * splitting map.css into a tokens file and a layout file, which would touch the
 * one stylesheet the whole application already depends on.
 *
 * The values below must stay identical to the :root block in map.css. They are
 * the product's colours, not this page's. */

:root {
  --bg: #10141c;
  --panel: #171d28;
  --panel-2: #1e2634;
  --line: #2b3547;
  --text: #e6ebf2;
  --muted: #8e9bb0;
  --accent: #4da3ff;
  --warn: #f0932b;
  --error: #ff6b6b;
  --ok: #4ecb71;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        Helvetica, Arial, sans-serif;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.muted { color: var(--muted); }
.small { font-size: 12px; }
.mono  { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ centred pages */

.auth-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 16px 48px;
}

.auth-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 26px 26px 22px;
  width: 100%;
  max-width: 430px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .55);
}

/* The access-request form has nine fields and reads better in two columns on
   anything wider than a phone. */
.auth-card.wide { max-width: 620px; }

.brand {
  text-align: center;
  margin-bottom: 22px;
}

.brand .mark {
  font-size: 17px;
  font-weight: 650;
  letter-spacing: .2px;
}

.brand .sub {
  color: var(--muted);
  font-size: 12px;
  margin-top: 3px;
}

.auth-card h1 {
  font-size: 17px;
  margin: 0 0 6px;
}

.auth-card .lede {
  color: var(--muted);
  font-size: 12.5px;
  margin: 0 0 18px;
}

/* ------------------------------------------------------------------- fields */

.field { margin-bottom: 13px; }

.field label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 5px;
}

.field label .req { color: var(--accent); }

/* A tick box and its explanation on one line. Overrides the block label and the
   full-width input above, both of which are for text fields and turn a checkbox
   into a stretched grey bar. */
.field label.check {
  display: flex;
  gap: 8px;
  align-items: baseline;
  margin: 0 0 7px;
  color: var(--text);
  cursor: pointer;
}

.field label.check input[type="checkbox"] {
  width: auto;
  flex: none;
  margin: 0;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  padding: 9px 11px;
  font: inherit;
}

.field textarea { resize: vertical; min-height: 74px; }

.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(77, 163, 255, .13);
}

.field .hint {
  color: var(--muted);
  font-size: 11.5px;
  margin-top: 5px;
}

.field-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 14px;
}

@media (max-width: 560px) {
  .field-pair { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ buttons */

.btn {
  border-radius: 6px;
  padding: 9px 15px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
}

.btn:hover:not(:disabled) { border-color: var(--accent); }
.btn:disabled { opacity: .55; cursor: default; }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #08111c;
  font-weight: 650;
}

.btn-primary:hover:not(:disabled) { filter: brightness(1.08); }

.btn-danger { color: var(--error); }
.btn-danger:hover:not(:disabled) { border-color: var(--error); }

.btn-sm { padding: 4px 9px; font-size: 11.5px; }

.btn-block { width: 100%; display: block; }

.actions {
  display: flex;
  gap: 9px;
  align-items: center;
  margin-top: 18px;
}

.actions.end { justify-content: flex-end; }

/* ------------------------------------------------------------------ notices */

.notice {
  border-radius: 7px;
  padding: 10px 12px;
  font-size: 12.5px;
  margin-bottom: 15px;
  border: 1px solid var(--line);
  background: var(--panel-2);
}

.notice.err   { border-color: rgba(255, 107, 107, .5); color: var(--error); }
.notice.ok    { border-color: rgba(78, 203, 113, .5); color: var(--ok); }
.notice.warn  { border-color: rgba(240, 147, 43, .5); color: var(--warn); }
.notice[hidden] { display: none; }

.auth-links {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* ------------------------------------------------------------- admin layout */

body.admin { overflow-y: auto; }

.admin-shell {
  max-width: 1240px;
  margin: 0 auto;
  padding: 22px 20px 60px;
}

.admin-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  padding-bottom: 14px;
  margin-bottom: 20px;
}

.admin-head h1 { font-size: 18px; margin: 0; }
.admin-head .who { color: var(--muted); font-size: 12.5px; }

.admin-tabs {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

.admin-tabs button {
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 6px;
  padding: 6px 12px;
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}

.admin-tabs button.active {
  border-color: var(--accent);
  color: var(--accent);
}

.admin-tabs .count {
  display: inline-block;
  margin-left: 6px;
  background: var(--panel-2);
  border-radius: 9px;
  padding: 0 6px;
  font-size: 11px;
  color: var(--muted);
}

.admin-tabs button.active .count { color: var(--accent); }

.toolbar {
  display: flex;
  gap: 9px;
  align-items: center;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

/* An author `display` rule beats the user-agent rule the hidden attribute
   relies on, so hiding a .toolbar in script did nothing: the account search
   box has been sitting above the activity log all along. Spelled out here for
   the same reason .notice[hidden] and .modal-backdrop[hidden] already are. */
.toolbar[hidden] { display: none; }

.toolbar input[type=search] {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  padding: 7px 11px;
  font: inherit;
  font-size: 13px;
  min-width: 240px;
}

/* ------------------------------------------------------------- queue cards */

.section-title {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  margin: 26px 0 12px;
}

.queue { display: grid; gap: 12px; }

.queue-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--warn);
  border-radius: 9px;
  padding: 15px 17px;
}

.queue-card h3 {
  margin: 0 0 3px;
  font-size: 14.5px;
}

.queue-card .meta {
  color: var(--muted);
  font-size: 12.5px;
  margin-bottom: 10px;
}

.queue-card .said {
  background: var(--panel-2);
  border-radius: 6px;
  padding: 9px 11px;
  font-size: 12.5px;
  margin: 10px 0;
  white-space: pre-wrap;
  border: 1px solid var(--line);
}

.queue-card .row-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 12px;
}

.kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 3px 14px;
  font-size: 12.5px;
}

.kv dt { color: var(--muted); }
.kv dd { margin: 0; word-break: break-word; }

/* -------------------------------------------------------------- user table */

.table-wrap {
  border: 1px solid var(--line);
  border-radius: 9px;
  overflow: hidden;
  background: var(--panel);
}

table.users {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

table.users th {
  text-align: left;
  padding: 10px 12px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
}

table.users td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

table.users tr:last-child td { border-bottom: none; }
table.users tr:hover td { background: rgba(255, 255, 255, .015); }

table.users .name { font-weight: 550; }
table.users .sub { color: var(--muted); font-size: 11.5px; }
table.users .nowrap { white-space: nowrap; }

table.users select {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--text);
  padding: 3px 6px;
  font: inherit;
  font-size: 11.5px;
}

.cell-actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* ------------------------------------------------------------------ badges */

.badge {
  display: inline-block;
  border-radius: 20px;
  padding: 1px 9px;
  font-size: 11px;
  border: 1px solid var(--line);
  white-space: nowrap;
}

.badge.approved  { color: var(--ok);     border-color: rgba(78, 203, 113, .45); }
.badge.pending   { color: var(--warn);   border-color: rgba(240, 147, 43, .45); }
.badge.rejected  { color: var(--error);  border-color: rgba(255, 107, 107, .4); }
.badge.suspended { color: var(--error);  border-color: rgba(255, 107, 107, .4); }
.badge.locked    { color: var(--warn);   border-color: rgba(240, 147, 43, .45); }
.badge.admin     { color: var(--accent); border-color: rgba(77, 163, 255, .45); }

/* ------------------------------------------------------------------ events */

table.events { width: 100%; border-collapse: collapse; font-size: 12px; }
table.events th, table.events td {
  text-align: left;
  padding: 7px 12px;
  border-bottom: 1px solid var(--line);
}
table.events th { background: var(--panel-2); color: var(--muted); }
table.events .detail {
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  word-break: break-word;
}

/* ------------------------------------------------------------------- modal */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(6, 9, 14, .72);
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.modal-backdrop[hidden] { display: none; }

.modal {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 21px;
  width: 520px;
  max-width: 100%;
  max-height: calc(100vh - 60px);
  overflow-y: auto;
  box-shadow: 0 22px 64px rgba(0, 0, 0, .6);
}

.modal h2 { margin: 0 0 6px; font-size: 15.5px; }
.modal .lede { color: var(--muted); font-size: 12.5px; margin: 0 0 15px; }

/* A generated reset link, shown so it can be copied when mail is not
   configured or is not arriving. Selectable and wrapped, because the whole
   point is that somebody reads it off the screen. */
.copy-box {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 10px 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  word-break: break-all;
  user-select: all;
}

.empty {
  color: var(--muted);
  font-size: 13px;
  padding: 26px 12px;
  text-align: center;
}

.spinner { color: var(--muted); font-size: 12.5px; padding: 14px 0; }
