/* Unity Photos — design system.
 *
 * Matches the Unity Payment System shell: a fixed left sidebar with grouped
 * navigation, the signed-in user at the top right, and a three-way theme
 * switcher pinned to the bottom of the sidebar.
 *
 * Every colour is a token on :root, redefined once for dark. Nothing below the
 * token block hard-codes a colour, so the two themes cannot drift apart.
 *
 * Dark is defined twice on purpose: once behind prefers-color-scheme for
 * people who have left the switcher on System, and once behind [data-theme] so
 * an explicit choice beats the operating system in both directions.
 */

/* ---------- tokens ---------- */

:root {
  /* Brand, taken from the logo: deep blue turning to cyan. */
  --brand-900: #062B8C;
  --brand-800: #0B3BC4;
  --brand-700: #0E4AD8;
  --brand-600: #1257F0;
  --brand-500: #2B7BFF;
  --brand-400: #62A6FF;
  --brand-300: #9CC8FF;
  --cyan-500:  #12A9F0;
  --cyan-400:  #28C8F5;

  /* The suite's primary, from the branding kit's login template. */
  --primary:       #2F54EB;
  --primary-hover: #1D3FD1;
  --primary-soft:  #EAF0FF;

  --brand-gradient: linear-gradient(135deg, #2F54EB, #12A9F0);

  /* Light theme. */
  --bg:            #F4F7FB;
  --surface:       #FFFFFF;
  --surface-2:     #F7FAFD;
  --surface-hover: #F0F6FC;
  --border:        #DCE5F0;
  --border-strong: #C3D2E5;

  --text:          #0E1B33;
  --text-muted:    #5A6B86;
  --text-subtle:   #8496AF;

  --accent:        var(--primary);
  --accent-hover:  var(--primary-hover);
  --accent-soft:   var(--primary-soft);
  --accent-ring:   rgba(47, 84, 235, .28);

  --ok:   #0B7A4B;  --ok-soft:   #DCF5E8;
  --warn: #8A5A00;  --warn-soft: #FDF0D2;
  --bad:  #B3261E;  --bad-soft:  #FDE4E1;
  --info: #075E8C;  --info-soft: #DDF0FB;

  /* The sidebar keeps its own scale: it is dark in both themes, like the
     Payment System, so the chrome stays constant while the content flips. */
  --nav-bg:       #0C1220;
  --nav-border:   #1B2537;
  --nav-text:     #C6D2E4;
  --nav-muted:    #6E809C;
  --nav-label:    #66799A;
  --nav-hover:    rgba(255, 255, 255, .06);
  --nav-active:   rgba(43, 123, 255, .16);
  --nav-active-text: #7FB4FF;

  --radius:    12px;
  --radius-sm: 8px;
  --radius-lg: 14px;

  --shadow-sm: 0 1px 2px rgba(11, 27, 58, .06);
  --shadow:    0 1px 3px rgba(11, 27, 58, .08), 0 6px 18px -8px rgba(11, 27, 58, .14);

  --sidebar-width: 236px;

  /* Inter is the suite's typeface; Segoe UI carries it when offline. */
  --font: "Inter", "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont,
          Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:            #171B24;
    --surface:       #1C212C;
    --surface-2:     #222836;
    --surface-hover: #273040;
    --border:        #2C3444;
    --border-strong: #3B465A;

    --text:          #E4EAF3;
    --text-muted:    #97A6BC;
    --text-subtle:   #6F8099;

    --accent:        #6E8DFF;
    --accent-hover:  #93AAFF;
    --accent-soft:   #1A2447;
    --accent-ring:   rgba(110, 141, 255, .38);

    --ok:   #4ADE9B;  --ok-soft:   #10301F;
    --warn: #F5C359;  --warn-soft: #33270B;
    --bad:  #FF8B81;  --bad-soft:  #3A1512;
    --info: #6FD0F5;  --info-soft: #0C2939;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow:    0 1px 3px rgba(0, 0, 0, .4), 0 8px 24px -10px rgba(0, 0, 0, .6);

    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --accent:        #6E8DFF;
  --accent-hover:  #93AAFF;
  --accent-soft:   #1A2447;
  --accent-ring:   rgba(110, 141, 255, .38);
  --bg:            #171B24;
  --surface:       #1C212C;
  --surface-2:     #222836;
  --surface-hover: #273040;
  --border:        #2C3444;
  --border-strong: #3B465A;

  --text:          #E4EAF3;
  --text-muted:    #97A6BC;
  --text-subtle:   #6F8099;

  --ok:   #4ADE9B;  --ok-soft:   #10301F;
  --warn: #F5C359;  --warn-soft: #33270B;
  --bad:  #FF8B81;  --bad-soft:  #3A1512;
  --info: #6FD0F5;  --info-soft: #0C2939;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow:    0 1px 3px rgba(0, 0, 0, .4), 0 8px 24px -10px rgba(0, 0, 0, .6);

  color-scheme: dark;
}

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 var(--font);
  -webkit-font-smoothing: antialiased;
}

body.theme-transition, body.theme-transition * {
  transition: background-color .16s ease, border-color .16s ease, color .16s ease;
}

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

h1 { font-size: 22px; font-weight: 650; letter-spacing: -.01em; margin: 0 0 4px; }
h2 { font-size: 16px; font-weight: 650; margin: 28px 0 12px; }
h3 { font-size: 14px; font-weight: 640; margin: 0 0 10px; }
.sub { color: var(--text-muted); margin: 0 0 20px; font-size: 14px; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* ---------- shell ---------- */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-width);
  flex: 0 0 var(--sidebar-width);
  background: var(--nav-bg);
  border-right: 1px solid var(--nav-border);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; bottom: 0; left: 0;
  z-index: 40;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 16px 16px 18px;
  text-decoration: none;
}
.sidebar-brand:hover { text-decoration: none; }
.sidebar-brand img { width: 30px; height: 30px; flex-shrink: 0; }
.sidebar-brand .lines { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.sidebar-brand .app { color: #fff; font-weight: 660; font-size: 14px; letter-spacing: -.01em; }
.sidebar-brand .org { color: var(--nav-muted); font-size: 11.5px; }

.sidebar-nav { flex: 1; overflow-y: auto; padding: 0 12px 12px; }
.sidebar-nav::-webkit-scrollbar { width: 8px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: #23304a; border-radius: 4px; }

.nav-group-label {
  color: var(--nav-label);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 0 10px;
  margin: 20px 0 7px;
}
.sidebar-nav > .nav-group-label:first-child { margin-top: 6px; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  color: var(--nav-text);
  text-decoration: none;
  font-size: 13.5px;
  margin-bottom: 1px;
}
.nav-item:hover { background: var(--nav-hover); color: #fff; text-decoration: none; }
.nav-item.active { background: var(--nav-active); color: var(--nav-active-text); font-weight: 600; }
.nav-item svg { width: 17px; height: 17px; flex-shrink: 0; opacity: .85; }
.nav-item.active svg { opacity: 1; }
.nav-item .count {
  margin-left: auto;
  background: var(--bad);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
}

/* Three-way theme switcher, pinned to the foot of the sidebar. */
.theme-switch {
  margin: 0 12px 14px;
  padding-top: 14px;
  border-top: 1px solid var(--nav-border);
  display: flex;
  gap: 2px;
  background: transparent;
}
.theme-switch button {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 7px 0;
  background: rgba(255, 255, 255, .04);
  border: 0;
  color: var(--nav-muted);
  cursor: pointer;
  border-radius: 0;
}
.theme-switch button:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.theme-switch button:last-child  { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.theme-switch button:hover { background: rgba(255, 255, 255, .1); color: var(--nav-text); }
.theme-switch button[aria-pressed="true"] {
  background: var(--nav-active);
  color: var(--nav-active-text);
}
.theme-switch svg { width: 16px; height: 16px; }

/* ---------- content ---------- */

.content {
  flex: 1;
  min-width: 0;
  margin-left: var(--sidebar-width);
  display: flex;
  flex-direction: column;
}

/* Stays put while the page scrolls under it, so the account menu is always
   reachable. Opaque, or the content would show through. */
.content-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 10px 22px;
  min-height: 58px;
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

/* One control, not a chip plus a sign-out button: the chevron opens a menu.
   <details> gives the open/closed behaviour natively, so it works with the
   keyboard and without JavaScript. */
.user-menu { position: relative; }
.user-menu > summary {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 6px 10px 6px 6px;
  border-radius: 999px;
  cursor: pointer;
  list-style: none;
  color: var(--text);
}
.user-menu > summary::-webkit-details-marker { display: none; }
.user-menu > summary:hover { background: var(--surface-hover); }
.user-menu[open] > summary { background: var(--surface-hover); }

.user-menu .lines { display: flex; flex-direction: column; line-height: 1.25; }
.user-menu .name { font-size: 13.5px; font-weight: 640; }
.user-menu .role { font-size: 11.5px; color: var(--text-muted); }
.user-menu .chev { color: var(--text-subtle); display: flex; margin-left: 10px; }
.user-menu .chev svg { width: 15px; height: 15px; transition: transform .15s; }
.user-menu[open] .chev svg { transform: rotate(180deg); }

.user-menu .menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 232px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 6px;
  z-index: 50;
}
.user-menu .menu .who {
  padding: 8px 10px 10px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}
.user-menu .menu .who strong { display: block; font-size: 13.5px; }
.user-menu .menu .who span { font-size: 12px; color: var(--text-muted); word-break: break-all; }
.user-menu .menu a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13.5px;
  text-decoration: none;
}
.user-menu .menu a:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.user-menu .menu a svg { width: 16px; height: 16px; color: var(--text-muted); }
.user-menu .menu a.danger { color: var(--bad); }
.user-menu .menu a.danger svg { color: var(--bad); }

.avatar {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--brand-gradient);
  color: #fff;
  display: grid; place-items: center;
  font-size: 12.5px; font-weight: 700; letter-spacing: .03em;
  flex-shrink: 0;
}

main { padding: 4px 26px 64px; width: 100%; min-width: 0; }
main.narrow { max-width: 440px; margin: 0 auto; }

.page-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
.page-head .spacer { flex: 1; }

.mobile-bar { display: none; }
.scrim { display: none; }

/* ---------- cards, tables ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 20px;
  margin-bottom: 18px;
}
.card h2:first-child, .card h3:first-child { margin-top: 0; }

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.card .table-wrap { border: 0; border-radius: 0; background: transparent; }

table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th, td { text-align: left; padding: 11px 14px; vertical-align: top; }
thead th {
  background: var(--surface-2);
  color: var(--text-muted);
  font-weight: 620;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .055em;
  border-bottom: 1px solid var(--border);
}
tbody tr { border-bottom: 1px solid var(--border); }
tbody tr:last-child { border-bottom: 0; }
tbody tr:hover { background: var(--surface-hover); }
tbody th { color: var(--text-muted); font-weight: 600; width: 1%; white-space: nowrap; }

/* ---------- forms ---------- */

label {
  display: block;
  font-size: 12.5px;
  font-weight: 620;
  color: var(--text);
  margin-bottom: 6px;
  /* One line's worth, so every label in a row occupies the same height and
     the inputs beneath them line up even when one label wraps. */
  min-height: 18px;
}

input[type=text], input[type=email], input[type=password], input[type=date],
input[type=search], input[type=file], select, textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font: inherit;
  font-size: 14px;
  color: var(--text);
  transition: border-color .12s, box-shadow .12s;
}
input::placeholder, textarea::placeholder { color: var(--text-subtle); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
input:disabled, select:disabled { background: var(--surface-2); color: var(--text-subtle); }

select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%237F8DA3' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  padding-right: 32px;
}
input[type=checkbox] { accent-color: var(--accent); width: 15px; height: 15px; }

.field { margin-bottom: 16px; }
.hint { color: var(--text-muted); font-size: 12.5px; margin-top: 6px; line-height: 1.45; }

/* Fields laid out in columns.
 *
 * Aligned to the top, not the bottom. Aligning to the bottom looks tidy until
 * one field has a hint under it and the next does not - then the shorter field
 * drops down the row and the whole form looks scattered. Top alignment keeps
 * every label on one line and every input on the next, whatever is underneath.
 */
.form-grid {
  display: grid;
  gap: 18px 20px;
  align-items: start;
  margin-bottom: 4px;
}
.form-grid > .field { margin-bottom: 0; min-width: 0; }
.form-grid.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-grid.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.form-grid .span-2 { grid-column: span 2; }
@media (max-width: 1024px) {
  .form-grid.cols-3, .form-grid.cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .form-grid.cols-2, .form-grid.cols-3, .form-grid.cols-4 { grid-template-columns: 1fr; }
  .form-grid .span-2 { grid-column: span 1; }
}

/* A row of controls that ends in a button - the search bar. Bottom-aligned on
   purpose here, because the button has no label above it. */
.filters { display: grid; grid-template-columns: 2.2fr 1fr 1fr 1fr auto; gap: 12px 16px; align-items: end; }
.filters > div { min-width: 0; }

/* Section heading inside a card, with a rule under it. */
.form-section {
  font-size: 13px;
  font-weight: 660;
  color: var(--text);
  margin: 26px 0 14px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--border);
}
.form-section:first-child { margin-top: 0; }
.form-actions {
  display: flex; gap: 10px; flex-wrap: wrap;
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--border);
}
@media (max-width: 1000px) { .filters { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .filters { grid-template-columns: 1fr; } }

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

button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 16px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .12s, border-color .12s;
}
button:hover, .btn:hover { background: var(--accent-hover); color: #fff; text-decoration: none; }
button:disabled, .btn:disabled { opacity: .5; cursor: not-allowed; }
button svg, .btn svg { width: 16px; height: 16px; }

.btn-primary-gradient { background: var(--brand-gradient); border: 0; }
.btn-primary-gradient:hover { filter: brightness(1.08); background: var(--brand-gradient); }

.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
.btn-secondary:hover { background: var(--surface-hover); color: var(--text); border-color: var(--accent); }

.btn-ghost { background: transparent; color: var(--text-muted); border-color: transparent; }
.btn-ghost:hover { background: var(--surface-hover); color: var(--text); }

.btn-danger { background: var(--bad); }
.btn-danger:hover { background: var(--bad); filter: brightness(1.1); }

.btn-sm { padding: 5px 11px; font-size: 12.5px; }
.btn-block { width: 100%; }

/* ---------- alerts, badges ---------- */

.alert {
  padding: 12px 15px;
  border-radius: var(--radius-sm);
  margin-bottom: 18px;
  font-size: 13.5px;
  border: 1px solid;
  border-left-width: 3px;
  line-height: 1.5;
}
.alert ul { margin: 7px 0 0; padding-left: 19px; }
.alert-error { background: var(--bad-soft);  border-color: var(--bad);  color: var(--bad); }
.alert-ok    { background: var(--ok-soft);   border-color: var(--ok);   color: var(--ok); }
.alert-info  { background: var(--info-soft); border-color: var(--info); color: var(--info); }
.alert-warn  { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }

.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: .035em;
  text-transform: uppercase;
  background: var(--surface-2);
  color: var(--text-muted);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.badge-ok     { background: var(--ok-soft);   color: var(--ok);   border-color: transparent; }
.badge-warn   { background: var(--warn-soft); color: var(--warn); border-color: transparent; }
.badge-bad    { background: var(--bad-soft);  color: var(--bad);  border-color: transparent; }
.badge-ocr    { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.badge-time   { background: var(--info-soft); color: var(--info); border-color: transparent; }
.badge-manual { background: var(--warn-soft); color: var(--warn); border-color: transparent; }

.vrm {
  display: inline-block;
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 1.4px;
  background: #FFD400;
  color: #111;
  border: 1px solid #C9A900;
  border-radius: 4px;
  padding: 2px 9px;
  font-size: 13.5px;
}

.mono { font-family: var(--font-mono); font-size: 12.5px; }
code.path {
  font-family: var(--font-mono);
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 12px;
  word-break: break-all;
  color: var(--text-muted);
}

/* ---------- stats ---------- */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 22px; }
.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
}
.stat::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--brand-gradient);
  opacity: 0;
}
.stat.accent::before { opacity: 1; }

/* Label first, then the figure, then what it means - the reading order of the
   Payment System's tiles. */
.stat .k {
  color: var(--text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .07em;
  font-weight: 700;
}
.stat .n {
  font-size: 30px;
  font-weight: 680;
  line-height: 1.15;
  letter-spacing: -.02em;
  margin: 10px 0 6px;
}
.stat .note { color: var(--text-muted); font-size: 12.5px; }
.stat a { color: inherit; text-decoration: none; }
.stat a:hover { color: var(--accent); }
.stat .n.good { color: var(--ok); }
.stat .n.warn { color: var(--warn); }
.stat .n.bad  { color: var(--bad); }

/* ---------- search results ---------- */

.results { display: flex; flex-direction: column; gap: 12px; }
.result {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 16px 18px;
}
.result:hover { border-color: var(--border-strong); box-shadow: var(--shadow); }
@media (max-width: 800px) { .result { grid-template-columns: 1fr; } }

.result .headline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.result .headline a { font-weight: 660; font-size: 16px; }
.result dl { display: flex; flex-wrap: wrap; gap: 5px 22px; margin: 10px 0 0; font-size: 13px; }
.result dl div { display: flex; gap: 6px; }
.result dt { color: var(--text-muted); }
.result dd { margin: 0; }

/* ---------- images ---------- */

.thumbs { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-start; }
.thumbs img {
  width: 104px; height: 78px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
}
.thumbs a:hover img { border-color: var(--accent); }

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 16px; }
.shot {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  margin: 0;
}
.shot:hover { border-color: var(--border-strong); }
.shot img { width: 100%; height: 168px; object-fit: cover; display: block; background: var(--surface-2); }
.shot .meta { padding: 11px 13px; font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.shot .meta strong { color: var(--text); display: block; font-size: 13px; word-break: break-all; margin-bottom: 3px; }

/* ---------- misc ---------- */

.empty { text-align: center; color: var(--text-muted); padding: 52px 24px; }
.empty strong { color: var(--text); display: block; margin-bottom: 6px; font-size: 15px; }
.empty svg { width: 38px; height: 38px; color: var(--text-subtle); margin-bottom: 14px; }

/* The pager says how much is left, not only whether there is more: somebody
   working a review queue down needs to know what they have taken on. */
.pager {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 24px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.pager-count { color: var(--text-muted); font-size: 13px; }
.pager-count strong { color: var(--text); font-variant-numeric: tabular-nums; }

.pager-size { display: flex; align-items: center; gap: 8px; margin: 0; }
.pager-size label { margin: 0; font-size: 12.5px; color: var(--text-muted); }
.pager-size select { width: auto; padding: 5px 9px; }

.pager-steps { display: flex; align-items: center; gap: 8px; }

@media (max-width: 640px) {
  .pager { gap: 10px; }
  .pager .spacer { display: none; }
  .pager-count { flex: 1 1 100%; text-align: center; }
  .pager-size { flex: 1 1 100%; justify-content: center; }
  .pager-steps { flex: 1 1 100%; justify-content: center; flex-wrap: wrap; }
  .pager-steps .btn { flex: 1 1 auto; text-align: center; }
}
.row-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.inline-form { display: flex; gap: 6px; align-items: center; }
.inline-form input[type=text] { width: auto; min-width: 128px; padding: 5px 9px; font-size: 13px; }

details.danger { margin-top: 10px; }
details.danger summary {
  cursor: pointer; color: var(--bad); font-size: 12.5px; font-weight: 620;
  list-style: none; display: inline-flex; align-items: center; gap: 5px;
}
details.danger summary::-webkit-details-marker { display: none; }
details.danger summary::before { content: "\26A0"; }
details.danger .body {
  margin-top: 10px; padding: 13px;
  background: var(--bad-soft);
  border: 1px solid var(--bad);
  border-radius: var(--radius-sm);
}

/* ---------- sign-in pages ----------
 *
 * The shared Unity Services sign-in look, from the branding kit: brand panel
 * left, card right, split 1.1fr / 1fr and collapsing to the card alone below
 * 900px. Gradient, glow and proportions are the kit's, so this page matches
 * Unity Payments, Unity Comms and ZatPark.
 */

.auth {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  background: var(--bg);
}
@media (max-width: 900px) { .auth { grid-template-columns: 1fr; } }

.auth-brand {
  background:
    radial-gradient(900px 500px at -10% -10%, rgba(79, 124, 255, .35), transparent 60%),
    linear-gradient(160deg, #0B1220, #131C31 60%, #1C2A4A);
  color: #fff;
  display: flex;
  align-items: center;
  padding: 48px;
}
@media (max-width: 900px) { .auth-brand { display: none; } }

.auth-brand-inner { max-width: 440px; }

/* The mark is lit from behind rather than sitting flat - two drop-shadows,
   one cyan and close, one deep blue and offset down. */
.brand-mark {
  display: block;
  width: 220px;
  max-width: 70%;
  height: auto;
  filter:
    drop-shadow(0 0 30px rgba(0, 190, 255, .55))
    drop-shadow(0 16px 36px rgba(0, 70, 220, .45));
}
.brand-word {
  margin-top: 22px;
  font-size: 12.5px;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: #8FD3FF;
  font-weight: 600;
}
.auth-brand h1 {
  font-size: 30px;
  margin: 8px 0 10px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: #fff;
}
.auth-brand p { color: #B6C2D9; font-size: 15px; line-height: 1.6; margin: 0; }

.auth-panel { display: flex; align-items: center; justify-content: center; padding: 32px; }

.auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 1px 3px rgba(15, 23, 42, .06);
  padding: 30px;
}
:root[data-theme="dark"] .auth-card,
:root:not([data-theme="light"]) .auth-card {
  box-shadow: 0 18px 44px -20px rgba(0, 0, 0, .6);
}

.auth-card .card-mark { width: 48px; height: 48px; object-fit: contain; display: block; }
.auth-card h1 { font-size: 20px; font-weight: 600; margin: 14px 0 6px; }
.auth-card .sub { color: var(--text-muted); font-size: 13.5px; margin: 0 0 22px; }
.auth-card .field { margin-bottom: 16px; }
.auth-card label { font-weight: 500; color: var(--text-muted); }
.auth-card input[type=email],
.auth-card input[type=password],
.auth-card input[type=text] { padding: 10px 12px; }

.auth-card .btn-signin {
  width: 100%;
  padding: 10px 14px;
  font-size: 14px;
  font-weight: 500;
  background: var(--primary);
  border: 1px solid var(--primary);
  margin-top: 4px;
}
.auth-card .btn-signin:hover { background: var(--primary-hover); border-color: var(--primary-hover); }

.auth-foot {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  text-align: center;
}
.auth-foot a { font-weight: 600; color: var(--accent); }
.auth-foot a:hover { text-decoration: underline; }

.auth .theme-switch {
  position: fixed; top: 16px; right: 16px; margin: 0;
  padding: 0; border: 1px solid var(--border); border-radius: var(--radius-sm);
  overflow: hidden; background: var(--surface); z-index: 5;
}
.auth .theme-switch button { background: transparent; color: var(--text-subtle); padding: 7px 11px; }
.auth .theme-switch button:hover { background: var(--surface-hover); color: var(--text); }
.auth .theme-switch button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); }

/* ---------- screens ----------
 *
 * Three sizes that matter: a desk (sidebar in place), a tablet in portrait or
 * a narrow window (sidebar becomes a drawer), and a phone (everything stacks,
 * tables scroll sideways rather than squashing).
 */

/* Laptops: give the content back the space the sidebar takes. */
@media (max-width: 1400px) {
  :root { --sidebar-width: 220px; }
  main { padding-left: 22px; padding-right: 22px; }
}

/* Tablets in portrait, and any narrow window. */
@media (max-width: 1024px) {
  .sidebar {
    transform: translateX(-100%);
    transition: transform .22s ease;
    width: 264px;
    flex-basis: 264px;
  }
  .sidebar.open { transform: translateX(0); box-shadow: 0 0 48px rgba(0, 0, 0, .55); }

  /* Dims the page behind the open drawer and closes it when tapped. */
  .scrim {
    position: fixed;
    inset: 0;
    background: rgba(6, 12, 24, .5);
    z-index: 35;
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s ease;
  }
  .sidebar.open ~ .content .scrim,
  body.nav-open .scrim { opacity: 1; pointer-events: auto; }

  .content { margin-left: 0; }
  .mobile-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    background: var(--nav-bg);
    color: #fff;
    position: sticky;
    top: 0;
    z-index: 25;
  }
  .mobile-bar img { width: 26px; height: 26px; }
  .mobile-bar .app { font-weight: 650; font-size: 14px; }
  .mobile-bar button {
    background: rgba(255, 255, 255, .08); border: 0; color: #fff;
    width: 36px; height: 36px; padding: 0; display: grid; place-items: center;
  }
  .content-head { padding: 10px 18px; min-height: 0; }
  main { padding: 4px 18px 56px; }
}

/* Phones. */
@media (max-width: 640px) {
  h1 { font-size: 19px; }
  .sub { font-size: 13.5px; }

  main { padding: 4px 14px 48px; }
  .content-head { padding: 8px 14px; }

  /* The name and role take too much of a small bar; the avatar is enough. */
  .user-menu .lines { display: none; }
  .user-menu > summary { padding: 6px; gap: 0; }
  .user-menu .chev { margin-left: 4px; }
  .user-menu .menu { min-width: min(280px, calc(100vw - 28px)); }

  .page-head { gap: 10px; }
  .page-head .spacer { display: none; }
  .page-head > .btn, .page-head form, .page-head .row-actions { width: 100%; }
  .page-head .btn { width: 100%; }

  .panel-head { flex-wrap: wrap; padding: 13px 14px; }
  .panel-head .spacer { display: none; }
  .panel-head .meta { order: 3; width: 100%; }
  .panel-head .btn, .panel-head button { width: 100%; }

  .panel tbody td, th, td { padding: 10px 12px; }

  /* Actions wrap onto their own line rather than forcing a wide scroll. */
  td.actions { white-space: normal; }
  .actions .btn, .actions button { margin: 2px 0 2px 4px; }

  .stats { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
  .stat { padding: 13px 14px; }
  .stat .n { font-size: 22px; }

  .gallery { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
  .shot img { height: 120px; }
  .thumbs img { width: 76px; height: 58px; }

  .result { padding: 13px 14px; }
  .result .headline a { font-size: 15px; }

  .row-actions { width: 100%; }
  .inline-form { flex-wrap: wrap; }
  .inline-form input[type=text] { flex: 1; min-width: 0; }

  dialog.changelog { width: calc(100vw - 20px); max-height: calc(100vh - 40px); }
  .changelog-body { padding: 4px 16px 18px; max-height: calc(100vh - 110px); }
  .changelog-head { padding: 14px 16px; }

  .auth-panel { padding: 28px 16px; }
  .auth .theme-switch { top: 10px; right: 10px; }
}

/* Very small phones: stop the filter grid squeezing two columns in. */
@media (max-width: 400px) {
  .filters { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr 1fr; }
}

@media print {
  .sidebar, .content-head, .pager, .row-actions, .mobile-bar { display: none !important; }
  .content { margin-left: 0; }
  body { background: #fff; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}

/* ---------- panels ----------
 *
 * A titled card whose table runs edge to edge inside it: heading and primary
 * action in the header bar, column heads directly beneath, rows below. This is
 * the standard layout for every list in the portal.
 */

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  margin-bottom: 20px;
  overflow: hidden;
}

.panel-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.panel-head h2, .panel-head h1 { margin: 0; font-size: 15.5px; font-weight: 650; }
.panel-head .spacer { flex: 1; }
.panel-head .meta { color: var(--text-muted); font-size: 12.5px; }

.panel > .table-wrap { border: 0; border-radius: 0; background: transparent; }
.panel table { font-size: 13.5px; }
.panel thead th { background: transparent; border-bottom: 1px solid var(--border); }
.panel tbody td { padding: 13px 14px; }
.panel .panel-foot {
  padding: 13px 18px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 12.5px;
}
.panel .empty { padding: 44px 24px; }

/* Two-line cell: the thing, and its qualifier underneath. */
.cell-primary { font-weight: 640; color: var(--text); display: block; }
.cell-primary a { font-weight: 640; }
.cell-secondary { color: var(--text-muted); font-size: 12.5px; display: block; margin-top: 2px; }

/* Actions sit on one line at the right-hand end of a row, all the same size,
   outlined rather than filled - a row of solid buttons fights the content. */
td.actions { text-align: right; white-space: nowrap; width: 1%; }
.actions .btn, .actions button { margin-left: 6px; }

.btn-outline {
  background: transparent;
  color: var(--text);
  border-color: var(--border-strong);
  font-weight: 600;
  padding: 6px 12px;
  font-size: 12.5px;
}
.btn-outline:hover { background: var(--surface-hover); color: var(--text); border-color: var(--accent); }
.btn-outline.warn { color: var(--warn); border-color: var(--border-strong); }
.btn-outline.warn:hover { border-color: var(--warn); background: var(--warn-soft); color: var(--warn); }
.btn-outline.danger { color: var(--bad); border-color: var(--border-strong); }
.btn-outline.danger:hover { border-color: var(--bad); background: var(--bad-soft); color: var(--bad); }

/* Inline controls inside a table cell stay compact. */
td select, td input[type=text] {
  padding: 6px 10px;
  font-size: 13px;
  width: auto;
  min-width: 120px;
}
td select { padding-right: 28px; }

/* A quiet pill for a state that is not a warning, e.g. 2FA "Off". */
.pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 600;
}
.pill-warn { border-color: transparent; background: var(--warn-soft); color: var(--warn); }
.pill-ok   { border-color: transparent; background: var(--ok-soft);   color: var(--ok); }
.pill-bad  { border-color: transparent; background: var(--bad-soft);  color: var(--bad); }

.tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 5px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 11.5px;
  margin: 1px 3px 1px 0;
}
.you-tag {
  display: inline-block;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 700;
  margin-left: 6px;
}

/* ---------- version and changelog ---------- */

.version-link {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 12px 10px;
  padding: 8px 11px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--nav-muted);
  font-size: 12px;
  cursor: pointer;
  width: calc(100% - 24px);
  text-align: left;
}
.version-link:hover { background: var(--nav-hover); color: var(--nav-text); }
.version-link svg { width: 14px; height: 14px; }
.version-link .num { font-family: var(--font-mono); font-weight: 600; }

dialog.changelog {
  width: min(680px, calc(100vw - 32px));
  max-height: min(80vh, 760px);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 24px 64px -16px rgba(0, 0, 0, .5);
}
dialog.changelog::backdrop { background: rgba(6, 12, 24, .58); backdrop-filter: blur(2px); }

.changelog-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--surface);
}
.changelog-head h2 { margin: 0; font-size: 17px; }
.changelog-head .spacer { flex: 1; }
.changelog-head button {
  background: transparent; border: 0; color: var(--text-muted);
  width: 32px; height: 32px; padding: 0; display: grid; place-items: center;
  border-radius: var(--radius-sm);
}
.changelog-head button:hover { background: var(--surface-hover); color: var(--text); }

.changelog-body { padding: 4px 22px 22px; overflow-y: auto; max-height: calc(80vh - 70px); }

.release { padding: 18px 0; border-bottom: 1px solid var(--border); }
.release:last-child { border-bottom: 0; }
.release-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.release-head .v {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 14px;
  background: var(--accent-soft);
  color: var(--accent);
  padding: 2px 9px;
  border-radius: 5px;
}
.release-head .when { color: var(--text-muted); font-size: 12.5px; }
.release-head .current {
  background: var(--ok-soft); color: var(--ok);
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; padding: 2px 8px; border-radius: 999px;
}
.release .summary { color: var(--text-muted); font-size: 13.5px; margin: 8px 0 0; }

.change-group { margin-top: 14px; }
.change-label {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  padding: 2px 9px;
  border-radius: 999px;
  margin-bottom: 8px;
}
.change-new     { background: var(--ok-soft);     color: var(--ok); }
.change-changed { background: var(--info-soft);   color: var(--info); }
.change-fixed   { background: var(--warn-soft);   color: var(--warn); }
.change-removed { background: var(--bad-soft);    color: var(--bad); }

.change-group ul { margin: 0; padding-left: 20px; }
.change-group li { font-size: 13.5px; margin-bottom: 6px; line-height: 1.5; }

/* ---------- icon actions ----------
   Row actions are icons so a table of feeds stays readable at a glance and
   does not need a horizontal scroll to reach the last button. The label is
   still in the markup: it becomes a tooltip on hover and focus, is read out
   by a screen reader, and turns back into visible text on a phone, where
   there is no hover to discover it with. */

.btn-icon {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.btn-icon + .btn-icon, form + .btn-icon, .btn-icon + form { margin-left: 6px; }
.btn-icon svg { width: 17px; height: 17px; }
.btn-icon:hover {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  color: var(--text);
}
.btn-icon:focus-visible {
  outline: 2px solid var(--accent-ring);
  outline-offset: 1px;
  color: var(--text);
}
.btn-icon.is-on { color: var(--ok); }
.btn-icon.danger:hover { color: var(--bad); border-color: var(--bad); background: var(--bad-soft); }

/* The tooltip. Positioned above the button, and never wide enough to push the
   table sideways. */
.btn-icon-label {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(2px);
  z-index: 5;
  padding: 5px 9px;
  border-radius: 6px;
  background: var(--nav-bg);
  color: #fff;
  font-size: 11.5px;
  font-weight: 560;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .12s, transform .12s, visibility .12s;
}
.btn-icon:hover .btn-icon-label,
.btn-icon:focus-visible .btn-icon-label {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

/* A feed that is switched off still belongs in the list - it is only quieter. */
tbody tr.row-off td { opacity: .62; }
tbody tr.row-off td.actions { opacity: 1; }

.col-actions { width: 1%; white-space: nowrap; }

/* ---------- tables on a phone ----------
   A six-column table cannot shrink to 380px, and a sideways scroll hides the
   very buttons people came for. Below this width each row becomes its own
   card, with the column heading printed against each value. */

@media (max-width: 760px) {
  .table-wrap:has(table.stacked) { overflow-x: visible; border: 0; background: transparent; }

  table.stacked thead { display: none; }
  table.stacked, table.stacked tbody, table.stacked tr, table.stacked td { display: block; }
  table.stacked tr {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    margin-bottom: 10px;
    padding: 2px 0;
  }
  table.stacked tr:hover { background: var(--surface); }
  table.stacked tr:last-child { margin-bottom: 0; }

  table.stacked td {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 9px 14px;
    border: 0;
    border-bottom: 1px solid var(--border);
  }
  table.stacked td:last-child { border-bottom: 0; }
  table.stacked td::before {
    content: attr(data-label);
    flex: 0 0 38%;
    color: var(--text-muted);
    font-weight: 620;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .055em;
  }
  table.stacked td:not([data-label])::before { content: none; }

  /* With no hover on a touch screen, the tooltip has to become a real label. */
  table.stacked td.actions { flex-wrap: wrap; gap: 8px; padding: 12px 14px; }
  table.stacked .btn-icon {
    width: auto;
    height: 34px;
    gap: 7px;
    grid-auto-flow: column;
    padding: 0 12px;
    color: var(--text);
  }
  table.stacked .btn-icon + .btn-icon,
  table.stacked form + .btn-icon,
  table.stacked .btn-icon + form { margin-left: 0; }
  table.stacked .btn-icon-label {
    position: static;
    transform: none;
    opacity: 1;
    visibility: visible;
    padding: 0;
    background: none;
    color: inherit;
    font-size: 13px;
    border-radius: 0;
  }
  table.stacked form[style*="contents"] { display: contents; }
}

/* ---------- what needs fixing ----------
   A feed can be misconfigured in ways that throw no error: photos go quietly
   to the review queue, a date column stays empty. The list says so directly,
   under the row it belongs to, rather than leaving somebody to work it out
   from an empty result. */

tr.issue-row td {
  background: var(--surface-2);
  border-top: 0;
  padding: 0 14px 12px;
}
tr.issue-row:hover td { background: var(--surface-2); }

ul.issues { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }

.issue {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 13px;
}
.issue-error { border-left-color: var(--bad); }
.issue-warn  { border-left-color: var(--warn); }

.issue-where {
  flex: 0 0 auto;
  min-width: 120px;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 620;
  text-transform: uppercase;
  letter-spacing: .055em;
  padding-top: 2px;
}
.issue-what { flex: 1 1 auto; min-width: 0; color: var(--text); }
.issue-fix {
  display: block;
  margin-top: 2px;
  color: var(--text-muted);
  font-size: 12.5px;
}
.issue .btn { flex: 0 0 auto; }

@media (max-width: 760px) {
  tr.issue-row td { padding: 0 12px 12px; }
  table.stacked tr.issue-row { border: 0; margin-top: -12px; }
  table.stacked tr.issue-row td { display: block; }
  table.stacked tr.issue-row td::before { content: none; }
  .issue { flex-wrap: wrap; gap: 6px; }
  .issue-where { min-width: 0; flex: 1 1 100%; }
  .issue .btn { width: 100%; text-align: center; }
}

/* ---------- a run in progress ----------
   The question this answers is "can I restart the server?", so it shows real
   counts rather than a spinner: how many references are filed, how many photos
   have moved, and how far through it is. */

.panel.running { border-color: var(--accent); }
.running-body { padding: 4px 20px 20px; }

.running-stage {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  font-weight: 560;
  color: var(--text);
}

.spinner {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.bar {
  height: 8px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  overflow: hidden;
}
.bar > span {
  display: block;
  height: 100%;
  background: var(--brand-gradient);
  transition: width .4s ease;
}

.running-detail {
  margin: 10px 0 0;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  font-size: 13.5px;
}

@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-top-color: var(--border-strong); }
  .bar > span { transition: none; }
}

/* ---------- arriving from a "Fix" link ----------
   Landing on a long form with nothing marked leaves somebody hunting for the
   part they were sent to. The section they came for says so, and stays said
   until they scroll away from it. */

.card:target {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
  scroll-margin-top: 78px;   /* clear the sticky header */
}
.card:target > h2::after {
  content: "the section you came to fix";
  display: inline-block;
  margin-left: 10px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 11px;
  font-weight: 620;
  letter-spacing: .02em;
  text-transform: uppercase;
  vertical-align: 3px;
}

@media (max-width: 640px) {
  .card:target > h2::after { display: block; margin: 6px 0 0; }
}

/* ---------- nothing wider than the screen ----------
   A UNC path is one unbroken token. Left alone it sets the width of whatever
   holds it, and on a phone that means the whole page scrolls sideways to
   accommodate a folder name. These are the places long paths turn up. */

.tag, .mono, .cell-secondary, .issue-what, .running-detail {
  overflow-wrap: anywhere;
  word-break: break-word;
}
.tag { max-width: 100%; }

/* The last resort: no element may set the page wider than the viewport. Tables,
   diagrams and code blocks scroll inside their own container instead. */
html, body { overflow-x: hidden; }
main, .panel, .card { min-width: 0; }

@media (max-width: 640px) {
  /* Inputs at less than 16px make iOS zoom the page on focus, and it does not
     zoom back out. */
  input[type=text], input[type=email], input[type=password], input[type=date],
  input[type=number], input[type=search], select, textarea { font-size: 16px; }

  /* A comfortable target on a touch screen. */
  .btn, .btn-icon, button { min-height: 38px; }

  .gallery { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
  .table-wrap { -webkit-overflow-scrolling: touch; }
}

/* ---------- the photo viewer ----------
   A panel over the page rather than the whole screen: the page underneath
   stays visible, so it is obvious this is a viewer you close and not a
   separate place you have navigated to. */

body.lightbox-open { overflow: hidden; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(8, 12, 22, .72);
  backdrop-filter: blur(3px);
}
/* `display` on a class beats the browser's own [hidden] rule, so without this
   the viewer never goes away and Close looks broken. */
.lightbox[hidden] { display: none !important; }

.lightbox-panel {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  width: min(78vw, 1200px);
  height: min(80vh, 900px);
  border-radius: var(--radius);
  background: #0E1524;
  border: 1px solid rgba(255, 255, 255, .14);
  box-shadow: 0 24px 64px rgba(0, 0, 0, .5);
  overflow: hidden;
}

.lightbox-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border-bottom: 1px solid rgba(255, 255, 255, .1);
  color: #E6ECF7;
  font-size: 13px;
}
.lightbox-spacer { flex: 1 1 auto; }
.lightbox-counter {
  font-variant-numeric: tabular-nums;
  color: #9FB0CC;
  white-space: nowrap;
}
.lightbox-caption {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.lightbox-btn {
  flex: 0 0 auto;
  padding: 7px 14px;
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .06);
  color: #E6ECF7;
  font: inherit;
  font-weight: 560;
  text-decoration: none;
  cursor: pointer;
}
.lightbox-btn:hover { background: rgba(255, 255, 255, .16); }
.lightbox-btn:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; }

.lightbox-stage {
  display: grid;
  place-items: center;
  min-height: 0;
  padding: 14px;
}
.lightbox-stage img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
}

.lightbox-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 46px;
  height: 46px;
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: 50%;
  background: rgba(14, 21, 36, .82);
  color: #E6ECF7;
  font-size: 27px;
  line-height: 1;
  cursor: pointer;
}
.lightbox-arrow:hover { background: rgba(255, 255, 255, .18); }
.lightbox-arrow.prev { left: 12px; }
.lightbox-arrow.next { right: 12px; }

@media (max-width: 760px) {
  .lightbox { padding: 0; }
  .lightbox-panel {
    width: 100%;
    height: 100%;
    border: 0;
    border-radius: 0;
  }
  .lightbox-bar { padding-top: max(11px, env(safe-area-inset-top, 0px)); }
  .lightbox-caption { display: none; }
  .lightbox-arrow {
    top: auto;
    bottom: max(16px, env(safe-area-inset-bottom, 0px));
    transform: none;
  }
}

/* ---------- a record's details, side by side ----------
   One long column of label-and-value leaves most of a wide screen empty and
   pushes the photos below the fold, which are the thing people came for. */

.detail-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  align-items: start;
}
.detail-pair > .card { margin: 0; }

.detail-head {
  margin: 0;
  padding: 14px 18px 12px;
  font-size: 13px;
  font-weight: 620;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
}
.detail-pair th { width: 46%; white-space: normal; }

@media (max-width: 860px) {
  .detail-pair { grid-template-columns: 1fr; gap: 12px; }
}

/* A photo with no preview. The browser's broken-image glyph reads as a fault
   in the portal; this says what is actually the matter. */
.shot-missing {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 6px;
  width: 100%;
  min-height: 120px;
  padding: 16px 10px;
  background: var(--surface-2);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-subtle);
  text-align: center;
}
.shot-missing svg { width: 26px; height: 26px; }
.shot-missing span { font-size: 11.5px; font-weight: 560; }

/* The thumbnail standing in while the full-size photo arrives. Softened just
   enough to read as "still loading" without hiding what is there. */
.lightbox-stage img.is-loading {
  filter: blur(1px);
  opacity: .82;
  transition: opacity .15s;
}
