/* ===================== Admin nav ===================== */

.admin-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6em;
  margin-bottom: 2em;
}

/* ===================== Statistics cards ===================== */

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: 1.1em;
}

.stat-card {
  position: relative;
  text-align: center;
  padding: 1.75em 1.15em;
  overflow: hidden;
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out),
    border-color 0.3s var(--ease-out);
}

/* Gradient hairline along the top edge, revealed on hover. */
.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--gradient-brand);
  opacity: 0;
  transition: opacity 0.3s var(--ease-out);
}

.stat-card:hover::before {
  opacity: 1;
}

.stat-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--sh-3), var(--glass-highlight);
  border-color: var(--line-strong);
}

.stat-value {
  display: block;
  font-size: var(--text-2xl);
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 1.05;
  color: var(--ink);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.9);
}

.stat-label {
  display: block;
  font-size: var(--text-2xs);
  color: var(--ink-muted);
  margin-top: 0.6em;
  font-weight: 500;
  letter-spacing: 0.01em;
}

/* ===================== Forms ===================== */

.upload-form {
  max-width: 580px;
}

.edit-preview {
  width: 100%;
  max-width: 320px;
  border-radius: var(--r-lg);
  margin-bottom: 1.5em;
  box-shadow: var(--sh-2);
}

/* ===================== Two-column admin layout ===================== */

.admin-categories-layout {
  display: grid;
  grid-template-columns: minmax(280px, 370px) 1fr;
  gap: 1.75em;
  align-items: start;
}

@media (max-width: 900px) {
  .admin-categories-layout {
    grid-template-columns: 1fr;
  }
}

/* ===================== Categories ===================== */

.category-table {
  display: flex;
  flex-direction: column;
  gap: 0.75em;
}

.category-row-wrap {
  padding: 1.1em 1.3em;
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.category-row-wrap:hover {
  border-color: var(--line-strong);
  box-shadow: var(--sh-2);
  transform: translateY(-2px);
}

.category-row {
  display: flex;
  align-items: center;
  gap: 1em;
}

.category-row .field-hint {
  margin: 0;
  flex: 1;
}

.category-edit {
  margin-top: 1em;
}

.category-edit form {
  margin-top: 1.1em;
  padding-top: 1.1em;
  border-top: 1px solid var(--line);
}

/* ===================== Ads ===================== */

.ad-row {
  display: flex;
  align-items: center;
  gap: 1.1em;
  padding: 1.1em 1.3em;
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.ad-row:hover {
  border-color: var(--line-strong);
  box-shadow: var(--sh-2);
  transform: translateY(-2px);
}

.ad-row-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.4em;
  min-width: 0;
}

.ad-row-info .field-hint {
  margin-top: 0;
}

/* ===================== Tables ===================== */

.table-scroll {
  overflow-x: auto;
  padding: 0.6em;
  /* Wide admin tables scroll inside their own card; the page body never
     scrolls sideways. */
  -webkit-overflow-scrolling: touch;
}

.admin-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}

.admin-table th,
.admin-table td {
  text-align: left;
  padding: 0.95em 1em;
  border-bottom: 1px solid var(--line);
  font-size: var(--text-sm);
  vertical-align: middle;
}

.admin-table th {
  color: var(--ink-muted);
  font-weight: 700;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 1;
}

.admin-table tbody tr {
  transition: background var(--dur) var(--ease-out);
}

.admin-table tbody tr:hover {
  background: var(--glass-bg-strong);
}

.admin-table tbody tr:last-child td {
  border-bottom: none;
}

.admin-table img.thumb-cell {
  width: 58px;
  height: 58px;
  object-fit: cover;
  border-radius: var(--r-sm);
  transition: transform var(--dur) var(--ease-spring);
}

.admin-table img.thumb-cell:hover {
  transform: scale(1.08);
}

.table-actions {
  display: flex;
  gap: 1em;
  align-items: center;
  white-space: nowrap;
}

/* ===================== Badges ===================== */

.badge {
  display: inline-block;
  padding: 0.28em 0.75em;
  border-radius: var(--r-full);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.015em;
  border: 1px solid transparent;
}

.badge-published {
  background: rgba(52, 211, 153, 0.14);
  border-color: rgba(52, 211, 153, 0.32);
  color: var(--success);
}

.badge-hidden {
  background: rgba(248, 113, 113, 0.13);
  border-color: rgba(248, 113, 113, 0.3);
  color: var(--danger);
}

/* Statuses are rendered as badge-<status>, so every value post.status can hold
   needs a rule here or it falls back to the unstyled base badge. */
.badge-pending {
  background: rgba(250, 204, 21, 0.13);
  border-color: rgba(250, 204, 21, 0.32);
  color: var(--warning);
}

.badge-rejected {
  background: rgba(148, 163, 184, 0.14);
  border-color: rgba(148, 163, 184, 0.3);
  color: var(--ink-muted);
}

.badge-admin {
  background: var(--brand-soft);
  border-color: var(--brand-ring);
  color: var(--brand-text);
}

.danger-text {
  color: var(--danger);
  font-weight: 600;
}

.danger-text:hover {
  color: var(--danger);
  opacity: 0.72;
}

/* ===================== Reports ===================== */

.report-list {
  display: flex;
  flex-direction: column;
  gap: 1em;
}

.report-card {
  display: flex;
  gap: 1.25em;
  align-items: flex-start;
  padding: 1.25em 1.4em;
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.report-card:hover {
  border-color: var(--line-strong);
  box-shadow: var(--sh-2);
}

.report-card-media img {
  width: 76px;
  height: 76px;
  object-fit: cover;
  border-radius: var(--r-md);
}

.report-card-body {
  flex: 1;
  min-width: 0;
}

.report-card-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55em;
  font-weight: 600;
  margin-bottom: 0.35em;
}

.report-card-title a:hover {
  color: var(--brand-text);
}

.report-card-note {
  margin: 0.75em 0;
  padding: 0.85em 1em;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  white-space: pre-wrap;
}

.report-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65em;
  align-items: center;
  margin-top: 1em;
}

.report-actions .button-secondary {
  padding: 0.55em 1.05em;
  font-size: var(--text-xs);
}

/* ===================== Settings ===================== */

.legal-note {
  padding: 1.05em 1.15em;
  background: rgba(251, 191, 36, 0.08);
  border: 1px solid rgba(251, 191, 36, 0.24);
  border-left: 3px solid var(--warning);
  border-radius: var(--r-md);
  margin: 1.4em 0;
  line-height: 1.7;
}

.legal-note code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: var(--glass-bg-strong);
  padding: 0.1em 0.4em;
  border-radius: 4px;
}

/* ===================== Backups ===================== */

.backup-total {
  margin: 0;
  align-self: center;
}

.backup-tables {
  display: flex;
  flex-direction: column;
  gap: 0.75em;
}

.backup-table {
  padding: 1.1em 1.3em;
}

.backup-table summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.8em;
}

.backup-table summary::-webkit-details-marker {
  display: none;
}

.backup-table summary::before {
  content: '▸';
  color: var(--ink-muted);
  transition: transform var(--dur) var(--ease-out);
}

.backup-table[open] summary::before {
  transform: rotate(90deg);
}

.backup-table-name {
  font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--text-sm);
}

.backup-table summary .field-hint {
  margin: 0;
}

.backup-table[open] summary {
  margin-bottom: 1em;
  padding-bottom: 0.9em;
  border-bottom: 1px solid var(--line);
}

.backup-empty {
  margin: 0;
}

.moderation-intro {
  margin-top: -1em;
  margin-bottom: 1.5em;
  max-width: 68ch;
}

/* Badge rendered as a link in the posts table -- keep it looking like a badge. */
a.badge {
  transition: opacity var(--dur) var(--ease-out);
}

a.badge:hover {
  opacity: 0.75;
}

/* ===================== SMTP settings ===================== */

.smtp-intro {
  margin-top: -0.5em;
  margin-bottom: 1.4em;
}

.smtp-intro code,
.legal-note code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: var(--glass-bg-strong);
  padding: 0.1em 0.4em;
  border-radius: 4px;
}

.smtp-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1em;
  align-items: start;
}

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

.smtp-secure,
.smtp-clear {
  margin-bottom: 0;
  margin-top: 0.5em;
}

.smtp-test-form {
  margin-top: 1.75em;
  padding-top: 1.5em;
  border-top: 1px solid var(--line);
}

/* ===================== Responsive ===================== */

@media (max-width: 600px) {
  .report-card {
    flex-direction: column;
    gap: 0.9em;
  }
  .report-card-media img {
    width: 100%;
    height: 150px;
  }
  .stats-grid {
    grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: 0.8em;
  }
  .stat-card {
    padding: 1.35em 0.9em;
  }
}

/* ===================== Admin list search ===================== */

.admin-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6em;
  margin-bottom: 1.5em;
}

.admin-search input[type='search'] {
  flex: 1;
  min-width: 220px;
  max-width: 460px;
  border-radius: var(--r-full);
  padding: 0.65em 1.2em;
}

.admin-search button[type='submit'] {
  padding: 0.62em 1.25em;
  font-size: var(--text-xs);
}

.admin-search-clear {
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.admin-search-count {
  margin: 0 0 0 auto;
  white-space: nowrap;
}

@media (max-width: 620px) {
  .admin-search-count {
    margin-left: 0;
    flex-basis: 100%;
  }
}

/* ===================== Bulk actions ===================== */

.bulk-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6em;
  padding: 0.9em 1.1em;
  margin-bottom: 1em;
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
}

.bulk-select-all {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  margin: 0;
}

.bulk-count {
  margin: 0 auto 0 0;
}

.bulk-bar .button-secondary {
  padding: 0.5em 1em;
  font-size: var(--text-xs);
}

/* Row-action forms live outside the bulk form and are referenced by id. */
.hidden-form {
  display: none;
}

.purge-panel {
  margin-bottom: 1.5em;
  max-width: 620px;
}

.purge-panel summary {
  cursor: pointer;
  font-weight: 700;
  font-size: var(--text-sm);
}

.purge-panel[open] summary {
  margin-bottom: 1.2em;
  padding-bottom: 1em;
  border-bottom: 1px solid var(--line);
}

.audit-when {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.maintenance-banner {
  margin-bottom: 1.5em;
}

.maintenance-copy {
  max-width: 46ch;
  margin: 0 auto 1.5em;
}

/* ===================== Explore page config ===================== */

.chip-config-list,
.pinned-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.chip-config-row {
  display: flex;
  align-items: center;
  gap: 0.8em;
  padding: 0.6em 0;
  border-bottom: 1px solid var(--line);
}

.chip-config-row:last-child {
  border-bottom: none;
}

.chip-config-label {
  display: flex;
  align-items: center;
  gap: 0.7em;
  cursor: pointer;
  margin: 0;
  flex: 1;
  min-width: 0;
}

.chip-config-row .field-hint {
  margin: 0;
  white-space: nowrap;
}

/* Qualified with the element and attribute deliberately: the base stylesheet sets
   `input[type="number"] { width: 100% }`, which at (0,1,1) outranks a bare class at
   (0,1,0) regardless of source order. Without this the position box stretches to
   fill the row and pushes the page into horizontal scroll. */
input.chip-config-position[type='number'] {
  width: 4.2rem;
  flex-shrink: 0;
  padding: 0.45em 0.6em;
  text-align: center;
}

.pinned-list {
  margin: 1em 0 1.5em;
  display: flex;
  flex-direction: column;
  gap: 0.6em;
}

.pinned-list li {
  display: flex;
  align-items: center;
  gap: 0.8em;
  font-size: var(--text-sm);
  font-weight: 600;
}

.pinned-list img,
.thumb-cell-empty {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  object-fit: cover;
  border-radius: var(--r-sm);
}

/* Stand-in for a pinned post whose thumbnail is gone, so the row keeps its
   alignment instead of collapsing where the image would have been. */
.thumb-cell-empty {
  display: inline-block;
  background: var(--surface-2);
  border: 1px dashed var(--line);
}

.pinned-list li > button {
  margin-left: auto;
  flex-shrink: 0;
}

.explore-subheading {
  flex-basis: 100%;
}

/* Mirrors how the heading renders on the real front page, at a size that fits
   inside the settings card. */
.explore-preview {
  margin: 0 0 1.4em;
  padding: 1.1em 1.2em;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
}

.explore-preview > .field-hint {
  margin: 0 0 0.5em;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.7rem;
}

.explore-preview h3 {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.explore-preview p {
  margin: 0.35em 0 0;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

.explore-preview p:empty {
  display: none;
}

/* ===================== Visitors ===================== */

.country-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5em 1.5em;
}

.country-list li {
  display: flex;
  align-items: baseline;
  gap: 0.45em;
  font-size: var(--text-sm);
}

.visitor-day-picker {
  flex-wrap: wrap;
}

.visitor-day-picker label {
  margin: 0;
  align-self: center;
  font-weight: 600;
  font-size: var(--text-sm);
}

/* Descendant selector, not a class on the element: base.css sets width:100% on a
   grouped `select` selector, and a bare class would tie on specificity and lose on
   source order. This keeps the day picker inline instead of full width. */
.visitor-day-picker select {
  width: auto;
  min-width: 12rem;
}

/* Long paths and user agents must not stretch the table past the viewport. */
.visitor-path,
.visitor-agent {
  display: inline-block;
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

.visitor-delete-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6em;
}

/* Visitor network label. Colour carries the meaning at a glance, but the word is
   always there too -- a badge that only differs by hue is unreadable to anyone
   who cannot separate them. */
.net-tag {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--r-full);
  font-size: 0.66rem;
  font-weight: bold;
  letter-spacing: 0.02em;
  white-space: nowrap;
  border: 1px solid transparent;
}

.net-direct     { background: #e4f0e5; color: #1f5222; border-color: #b9d8bb; }
.net-datacenter { background: #fdeaea; color: #93231f; border-color: #f0bcba; }
.net-proxy      { background: #fdf0dd; color: #7d4b0c; border-color: #eed3a6; }
.net-crawler    { background: #e3ecee; color: #14464c; border-color: #b8ced2; }
.net-unknown    { background: #eeece8; color: #626269; border-color: #d8d4cc; }

/* The address in the visitor list, when there is a location to open on a map.
 *
 * Kept as the same monospace code text it was before, with an underline to show
 * it does something -- not recoloured into a blue link. A whole column of blue
 * would pull the eye to the addresses, which are the least interesting thing in
 * the row; the counts and the times are what gets read. */
.ip-map {
  color: inherit;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
  text-decoration-color: var(--ink-muted);
}

.ip-map:hover,
.ip-map:focus-visible {
  text-decoration-style: solid;
  text-decoration-color: currentColor;
}

/* Bio editor in the users table. The textarea is only in the DOM once the row
 * is opened, so the table keeps its normal density until someone needs it. */
.bio-edit summary {
  cursor: pointer;
  list-style: none;
}

.bio-edit summary::-webkit-details-marker {
  display: none;
}

.bio-edit textarea {
  display: block;
  width: 260px;
  max-width: 100%;
  margin: 6px 0;
  font: inherit;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  resize: vertical;
}

/* Traffic source tag in the visitor list. Reddit gets its own colour because it
 * is the one being actively promoted; everything else shares a neutral chip so
 * the eye lands on the campaign rather than on the noise. */
.src-tag {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--r-full);
  font-size: 0.66rem;
  font-weight: bold;
  background: #E7E7EA;
  color: #3A3A42;
  white-space: nowrap;
}

.src-reddit {
  background: #FFE2D4;
  color: #8A2B00;
}

.src-none {
  color: #626269;
}
