/* Admin screen styling (issue #7).
 *
 * Deliberately one small hand-written sheet with no framework and no build
 * step, for the same reason `app/ui/router.py` serves static files instead
 * of standing up a Next.js app: the page is a table, a few forms and a tab
 * strip. Colours are declared once as custom properties so the dark scheme
 * below is a variable swap rather than a second copy of every rule.
 */

:root {
  /* Tells the browser both schemes are supported, which is what makes the
   * NATIVE controls follow the palette below: without it, a `<select>`
   * dropdown and the `datetime-local` calendar stay light-on-white inside an
   * otherwise dark page. The filter rows on this screen are almost entirely
   * those two controls, so it is not a subtle mismatch. */
  color-scheme: light dark;

  --bg: #f6f7f9;
  --surface: #ffffff;
  --border: #d8dce2;
  --text: #1c2024;
  --muted: #5c6570;
  --accent: #2563eb;
  --accent-text: #ffffff;
  --danger: #b3261e;
  --ok: #16794c;
  --warn-bg: #fff4e5;
  --warn-border: #e0a355;
  --row-hover: #f0f3f8;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14171a;
    --surface: #1c2024;
    --border: #333a42;
    --text: #e6e8eb;
    --muted: #9aa4b0;
    --accent: #4f8cf7;
    --accent-text: #0b0d0f;
    --danger: #ef8a82;
    --ok: #57c795;
    --warn-bg: #33280f;
    --warn-border: #8a6a2c;
    --row-hover: #23282e;
  }
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", "Hiragino Sans", "Noto Sans JP", sans-serif;
}

noscript {
  display: block;
  padding: 16px;
}

header.topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

header.topbar h1 {
  font-size: 15px;
  margin: 0;
  font-weight: 600;
}

header.topbar .spacer {
  flex: 1;
}

header.topbar .who {
  color: var(--muted);
  font-size: 13px;
}

main {
  padding: 16px;
  max-width: 1200px;
}

nav.tabs {
  display: flex;
  gap: 4px;
  padding: 0 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

nav.tabs button {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 10px 14px;
  font: inherit;
  color: var(--muted);
  cursor: pointer;
}

nav.tabs button[aria-current="page"] {
  color: var(--text);
  border-bottom-color: var(--accent);
  font-weight: 600;
}

section.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 14px;
  margin-bottom: 16px;
}

section.panel > h2 {
  font-size: 14px;
  margin: 0 0 10px;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

th,
td {
  text-align: left;
  padding: 7px 8px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

th {
  color: var(--muted);
  font-weight: 600;
  white-space: nowrap;
}

tbody tr:hover {
  background: var(--row-hover);
}

td.mono,
span.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  word-break: break-all;
}

button,
input,
select {
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 5px 8px;
}

button {
  cursor: pointer;
}

button:disabled {
  opacity: 0.5;
  /* Not `progress`: that cursor means "working on it", and on a pager's
   * Previous/Next at the ends of the range it reads as a page that is still
   * loading rather than a button there is nothing behind. */
  cursor: not-allowed;
}

button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
  font-weight: 600;
}

button.danger {
  color: var(--danger);
}

/* Reserved for the one control on this screen that genuinely behaves like a
 * link (the language toggle). Everything in a table row changes state and is
 * styled as a button instead -- see `button.action`. */
button.link {
  border: none;
  background: none;
  color: var(--accent);
  padding: 2px 4px;
  text-decoration: underline;
}

/* Row actions: disable, rename, delete, revoke, rotate.
 *
 * These were underlined links, which said "this navigates" about controls
 * that disable a customer or destroy a credential. Same element, same
 * handler -- only the affordance was wrong. Sized down from the default
 * button so a row of three does not outweigh the row's own data. */
button.action {
  padding: 3px 8px;
  font-size: 12px;
  white-space: nowrap;
}

button.action + button.action {
  margin-left: 6px;
}

button.action.danger {
  border-color: var(--danger);
}

/* The customer / robot expander.
 *
 * Not a link either: it reveals a region on this page. The triangle is drawn
 * here from `aria-expanded` rather than written into the label, so the
 * control announces its own state instead of having a "▸" read out as text.
 */
button.disclosure {
  border: none;
  background: none;
  color: var(--text);
  font-weight: 600;
  padding: 2px 4px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

button.disclosure::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform 120ms ease;
}

button.disclosure[aria-expanded="true"]::before {
  transform: rotate(90deg);
}

button.disclosure:hover {
  text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
  button.disclosure::before {
    transition: none;
  }
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-end;
  margin-bottom: 10px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* The label text sits in a `<span>` because the `<label>` itself now wraps
 * the input it names (see `app.js`'s `field()`), so styling the label
 * directly would style the control too. */
.field > span {
  font-size: 12px;
  color: var(--muted);
}

.pill {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 12px;
  border: 1px solid var(--border);
}

.pill.on {
  color: var(--ok);
  border-color: var(--ok);
}

.pill.off {
  color: var(--danger);
  border-color: var(--danger);
}

/* Aligns a row that has no disclosure control with the ones that do, so the
 * target column does not look ragged when only some rows are expandable.
 *
 * 16px is `button.disclosure`'s own `padding-left` (4px) plus the triangle
 * (5px) plus the gap after it (7px) -- not the triangle and gap alone.
 * The weight and vertical padding are copied for the same reason as the
 * indent: aligning the left edge while leaving one row bold and a pixel
 * taller trades a ragged column for a striped one. */
.indent {
  display: inline-block;
  font-weight: 600;
  padding: 2px 4px 2px 16px;
}

.muted {
  color: var(--muted);
}

/* Text for assistive technology only. Used for the row-controls column
 * header, which is intentionally blank on screen but must not be an unnamed
 * column to a screen reader. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* An inline "you cannot do this yet, and here is why" next to the control it
 * blocks. Distinct from `.muted`, which the same slot uses for ordinary
 * information: the difference between "this key will be used" and "there is
 * no key" should not be a difference the operator has to read to notice. */
.warn {
  color: var(--danger);
}

.empty {
  color: var(--muted);
  padding: 10px 2px;
}

.notice {
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: 6px;
  padding: 10px 12px;
  margin-bottom: 16px;
  font-size: 13px;
}

.toast {
  position: fixed;
  right: 16px;
  bottom: 16px;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 4px;
  padding: 10px 12px;
  box-shadow: 0 4px 14px rgb(0 0 0 / 18%);
  font-size: 13px;
  white-space: pre-wrap;
}

.toast.error {
  border-left-color: var(--danger);
}

.login {
  max-width: 460px;
  margin: 64px auto;
  text-align: center;
}

.login p {
  color: var(--muted);
}

.subrow > td {
  background: var(--bg);
}

.pager {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  color: var(--muted);
  font-size: 13px;
}

/* Long opaque values (the device Safety ID is 32 hex characters) get an
   ellipsis rather than widening the table. The full value stays in the DOM,
   so the browser's own find still matches it -- which is the entire point of
   showing it in the list instead of behind the row expander -- and `title`
   makes hovering enough to read it without a click. */
td.truncate {
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
