/* GlockCollector registry -- minimal, legible styling for the public
   browse/search pages. No framework; kept small and hand-written so it's
   easy to restyle later once real branding/UI work happens. */

:root {
  --ink: #1c1f24;
  --ink-soft: #52585f;
  --line: #dcdfe3;
  --bg: #ffffff;
  --bg-soft: #f5f6f8;
  --accent: #2f4858;
  --accent-soft: #eef2f4;
  --tag-confirmed: #1f7a4d;
  --tag-probable: #a3690f;
  --tag-reported: #7a7f85;
  --tag-featured: #a3690f;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--bg-soft);
  line-height: 1.5;
}

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

.site-header {
  background: var(--accent);
  color: #fff;
  padding: 0.9rem 1.25rem;
}

.site-header .header-inner {
  max-width: 1000px;
  margin: 0 auto;
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.site-header a {
  color: #fff;
}

.site-title {
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  row-gap: 0.6rem;
  font-size: 0.92rem;
  opacity: 0.92;
  /* Wraps instead of overflowing once the dropdowns + search box + Log
     in/username don't all fit on one line -- without this, the search box
     (added after this nav was originally sized) pushed Log in/username
     off the right edge of the header on narrow screens. */
  flex-wrap: wrap;
}

/* Header dropdowns (Registry / Research) -- plain <details>/<summary>, no
   JS required to open/close; style.css just gives it a menu look instead
   of the default browser triangle-and-list. */
.nav-dropdown {
  position: relative;
}

.nav-dropdown > summary {
  cursor: pointer;
  list-style: none;
  color: #fff;
}

.nav-dropdown > summary::-webkit-details-marker {
  display: none;
}

.nav-dropdown > summary::after {
  content: " \25BE";
  font-size: 0.7em;
}

.nav-dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 0.6rem;
  background: var(--bg);
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
  padding: 0.35rem 0;
  min-width: 150px;
  display: flex;
  flex-direction: column;
  z-index: 20;
}

.nav-dropdown-menu a {
  color: var(--ink);
  padding: 0.5rem 0.9rem;
  font-size: 0.9rem;
  white-space: nowrap;
}

.nav-dropdown-menu a:hover {
  background: var(--accent-soft);
  text-decoration: none;
}

main {
  max-width: 1000px;
  margin: 0 auto;
  padding: 1.75rem 1.25rem 3rem;
}

.page-title {
  margin: 0 0 0.25rem;
  font-size: 1.5rem;
}

.page-subtitle {
  color: var(--ink-soft);
  margin: 0 0 1.5rem;
  font-size: 0.95rem;
}

.card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.25rem 1.4rem;
  margin-bottom: 1.25rem;
}

.hero {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 2rem 1.75rem;
  margin-bottom: 1.75rem;
}

.hero h1 {
  margin: 0 0 0.4rem;
  font-size: 1.6rem;
}

.hero p {
  color: var(--ink-soft);
  margin: 0 0 1.25rem;
  max-width: 55ch;
}

.stat-row {
  display: flex;
  gap: 2rem;
  margin-top: 1.25rem;
  flex-wrap: wrap;
}

.stat {
  min-width: 100px;
}

.stat .num {
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--accent);
}

.stat .label {
  font-size: 0.82rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.button {
  display: inline-block;
  background: var(--accent);
  color: #fff !important;
  border-radius: 6px;
  padding: 0.55rem 1.1rem;
  font-size: 0.92rem;
  font-weight: 600;
  text-decoration: none !important;
}

.button.secondary {
  background: var(--accent-soft);
  color: var(--accent) !important;
}

.filter-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-end;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1rem 1.1rem;
  margin-bottom: 1.25rem;
}

.filter-form .field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
}

.filter-form label {
  color: var(--ink-soft);
  font-weight: 600;
}

.filter-form input[type="text"],
.filter-form select {
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 0.92rem;
  min-width: 8rem;
}

.filter-form button {
  padding: 0.45rem 1rem;
  border: none;
  border-radius: 5px;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
  font-size: 0.9rem;
}

.filter-form .clear-link {
  font-size: 0.85rem;
  align-self: center;
}

table.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}

table.data-table th,
table.data-table td {
  text-align: left;
  padding: 0.6rem 0.8rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.92rem;
}

table.data-table th {
  background: var(--bg-soft);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

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

table.data-table tr:hover td {
  background: var(--accent-soft);
}

.table-scroll {
  overflow-x: auto;
}

table.data-table.centered-table th,
table.data-table.centered-table td {
  text-align: center;
}

/* SN Graphic page */

.sn-legend-table {
  border-collapse: collapse;
  margin-bottom: 1rem;
}

.sn-legend-table td {
  border: 1px solid var(--line);
  padding: 0.1rem 0.5rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
}

.sn-legend-table .legend-row-label {
  font-weight: 600;
  text-align: right;
  background: var(--bg);
  border: none;
  padding-right: 0.75rem;
  white-space: nowrap;
}

table.sn-graphic-table th,
table.sn-graphic-table td {
  text-align: center;
  vertical-align: middle;
}

table.sn-graphic-table td {
  padding-top: 0.1rem;
  padding-bottom: 0.1rem;
}

table.sn-graphic-table td.year-cell {
  padding-left: 0.05rem;
  padding-right: 0.05rem;
}

table.sn-graphic-table .proof-header {
  background: #eaf5ea;
}

table.sn-graphic-table .import-header {
  background: #eaf1fa;
}

table.sn-graphic-table td.month-cell {
  white-space: nowrap;
  font-size: 0.72rem;
  font-weight: 600;
  background: var(--bg);
  width: 6.5rem;
}

.year-cell {
  width: 0.7rem;
  overflow: hidden;
  text-align: center;
  vertical-align: middle;
}

.year-cell.year-dark {
  background: #6b6f75;
}

.year-cell.year-dark .year-label {
  color: #ffffff;
}

.year-cell.year-light {
  background: #d9dce0;
}

.year-cell.year-light .year-label {
  color: var(--ink);
}

.year-label {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  transform: rotate(-90deg);
}

.chip-cell {
  min-width: 12rem;
}

.chip-cell.proof-cell {
  background: #f3faf3;
}

.chip-cell.import-cell {
  background: #f2f7fc;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem;
}

.proof-cell .chip-row {
  justify-content: flex-end;
}

.import-cell .chip-row {
  justify-content: flex-start;
}

.sn-chip {
  display: inline-block;
  box-sizing: border-box;
  padding: 0.12rem 0.22rem;
  border-radius: 3px;
  border: 1px solid rgba(11, 11, 11, 0.15);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.4;
  text-decoration: none;
  white-space: nowrap;
  text-align: center;
}

.sn-chip:hover {
  outline: 2px solid var(--accent);
  text-decoration: none;
}

.multiselect-dropdown {
  position: relative;
  display: inline-block;
  min-width: 160px;
}

.multiselect-toggle {
  width: 100%;
  text-align: left;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--bg);
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
}

.multiselect-toggle::after {
  content: "\25BE";
  float: right;
  color: var(--ink-soft);
  margin-left: 0.5rem;
}

.multiselect-panel {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 20;
  margin-top: 0.25rem;
  min-width: 180px;
  max-height: 220px;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 5px;
  box-shadow: 0 4px 10px rgba(11, 11, 11, 0.12);
  padding: 0.35rem;
}

.multiselect-option {
  display: block;
  padding: 0.3rem 0.4rem;
  font-size: 0.9rem;
  white-space: nowrap;
  cursor: pointer;
  border-radius: 3px;
}

.multiselect-option:hover {
  background: var(--accent-soft);
}

.multiselect-option input {
  margin-right: 0.4rem;
}

.model-swatch {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  border: 1px solid rgba(11, 11, 11, 0.15);
  margin-right: 0.4rem;
  vertical-align: middle;
}

table.sortable-table th[data-sort] {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

table.sortable-table th[data-sort]:hover {
  color: var(--accent);
}

table.sortable-table th[data-sort].sorted-asc::after {
  content: " \25B2";
}

table.sortable-table th[data-sort].sorted-desc::after {
  content: " \25BC";
}

.tag {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
}

.tag.confirmed { background: var(--tag-confirmed); }
.tag.probable { background: var(--tag-probable); }
.tag.reported { background: var(--tag-reported); }
.tag.featured { background: var(--tag-featured); }

.featured-books-section {
  border: 1px solid var(--tag-featured);
  background: var(--accent-soft);
  border-radius: 10px;
  padding: 1.25rem;
  margin-bottom: 1.5rem;
}

.featured-books-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-top: 0.75rem;
}

.featured-book-tile {
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  background: var(--bg);
  border-radius: 8px;
  padding: 0.85rem;
  max-width: 360px;
  text-decoration: none;
  color: inherit;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}

.featured-book-tile .book-tile-cover,
.featured-book-tile .book-tile-cover-fallback {
  width: 72px;
  height: 108px;
  flex-shrink: 0;
}

.empty-state {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--ink-soft);
}

.pagination {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: center;
  margin-top: 1.25rem;
  font-size: 0.9rem;
  flex-wrap: wrap;
}

.pagination-jump {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: 0.5rem;
  padding-left: 0.75rem;
  border-left: 1px solid var(--line);
}

.pagination-jump-input {
  width: 3.5rem;
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 0.9rem;
  text-align: center;
}

.pagination-jump-btn {
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--bg-soft);
  font-size: 0.9rem;
  cursor: pointer;
}

.pagination-jump-btn:hover {
  background: var(--accent-soft);
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.9rem 1.5rem;
  margin: 1rem 0;
}

.detail-grid .item .label {
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.detail-grid .item .value {
  font-size: 1rem;
  margin-top: 0.15rem;
}

.section-title {
  font-size: 1.05rem;
  margin: 1.75rem 0 0.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}

.breadcrumb {
  font-size: 0.85rem;
  margin-bottom: 1rem;
  color: var(--ink-soft);
}

.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 0.75rem;
  margin: 1rem 0 1.75rem;
}

.photo-grid .photo {
  display: block;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg);
}

.photo-grid .photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.photo-grid .photo-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 0.5rem;
  text-align: center;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* Lead photo gallery: a large focus image with thumbnails underneath,
   clicking the focus image opens a full-screen lightbox with arrow nav. */

.gallery {
  margin: 1rem 0 1.75rem;
}

.gallery-focus {
  display: block;
  width: 100%;
  max-width: 640px;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-soft);
  padding: 0;
  margin: 0 0 0.75rem;
  cursor: zoom-in;
}

.gallery-credit {
  max-width: 640px;
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin: -0.4rem 0 0.75rem;
}

.gallery-focus img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gallery-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  max-width: 640px;
}

.gallery-thumb {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-soft);
  cursor: pointer;
}

.gallery-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gallery-thumb:hover {
  border-color: var(--accent);
}

.gallery-thumb.active {
  border-color: var(--accent);
}

.lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  z-index: 1000;
  padding: 2rem;
}

.lightbox[hidden] {
  display: none;
}

.lightbox-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  max-height: calc(100% - 2.5rem);
}

.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
  cursor: zoom-in;
  -webkit-user-drag: none;
  user-select: none;
}

.lightbox-credit {
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.85rem;
  text-align: center;
  max-width: 90%;
}

.lightbox-credit a {
  color: #fff;
}

.lightbox-img.zoomed {
  cursor: grab;
}

.lightbox-img.zoomed.dragging {
  cursor: grabbing;
}

.lightbox-close {
  position: absolute;
  top: 0.75rem;
  right: 1rem;
  background: none;
  border: none;
  color: #fff;
  font-size: 2.25rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}

.lightbox-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.15);
  border: none;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  cursor: pointer;
}

.lightbox-arrow:hover {
  background: rgba(255, 255, 255, 0.3);
}

.lightbox-prev {
  left: 0.75rem;
}

.lightbox-next {
  right: 0.75rem;
}

@media (max-width: 640px) {
  .gallery-focus,
  .gallery-thumbs {
    max-width: 100%;
  }

  .lightbox-arrow {
    width: 2.5rem;
    height: 2.5rem;
    font-size: 1.6rem;
  }

  .lightbox {
    padding: 1rem;
  }
}

.auth-card {
  max-width: 420px;
}

.form-field {
  margin-bottom: 1rem;
}

.form-field label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 0.3rem;
}

.form-field input[type="text"],
.form-field input[type="password"],
.form-field input[type="email"],
.form-field input[type="url"],
.form-field input[type="file"],
.form-field select,
.form-field textarea {
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 0.95rem;
  font-family: inherit;
  resize: vertical;
}

/* Elements only shown once a staff viewer turns on the page's "Edit" mode
   (see page-edit-toggle in specimen_detail.html) -- the !important guards
   against a class on the same element (e.g. .button, .card) setting an
   explicit display value that would otherwise win over the plain [hidden]
   attribute. */
.page-edit-only[hidden] {
  display: none !important;
}

/* The read-only counterpart to .page-edit-only -- a value's normal display,
   hidden the same way once the page's Edit mode is switched on, so a field
   shows either its static text or its input, never both at once. See
   page-edit-toggle's script in specimen_detail.html. */
.page-view-only[hidden] {
  display: none !important;
}

/* Inline-edit inputs that replace a .detail-grid item's read-only .value in
   place, once Edit mode is on -- sized to sit comfortably in a grid cell
   rather than a full-width form. */
.detail-grid .item .value-edit {
  margin-top: 0.15rem;
}

.detail-grid .item .value-edit input[type="text"],
.detail-grid .item .value-edit input[type="number"],
.detail-grid .item .value-edit select,
.detail-grid .item .value-edit textarea {
  width: 100%;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 0.95rem;
  font-family: inherit;
  resize: vertical;
}

/* Inline-edit inputs dropped directly into a data-table cell (Provenance
   rows and the always-present "add a new event" row) -- compact enough to
   fit several to a row, since a table cell is much narrower than a
   detail-grid item. */
table.data-table td input[type="text"],
table.data-table td input[type="number"],
table.data-table td input[type="date"],
table.data-table td select {
  width: 100%;
  min-width: 6.5rem;
  padding: 0.3rem 0.45rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 0.85rem;
  font-family: inherit;
}

/* Price/currency and source-text/source-url each pack two inputs into one
   cell -- keep the second (currency, source_url) narrower than the first
   rather than splitting the cell evenly, since those hold much shorter
   values. */
table.data-table td.prov-price-edit input:first-child,
table.data-table td .prov-price-edit input:first-child {
  width: 65%;
}

table.data-table td.prov-price-edit input:last-child,
table.data-table td .prov-price-edit input:last-child {
  width: 30%;
  min-width: 3.5rem;
  margin-left: 0.3rem;
}

table.data-table td.prov-source-edit input,
table.data-table td .prov-source-edit input {
  margin-bottom: 0.25rem;
}

.edit-toggle-btn {
  background: none;
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 0.3rem 0.75rem;
  font-size: 0.85rem;
  cursor: pointer;
  color: var(--ink-soft);
}

.edit-toggle-btn:hover {
  background: var(--bg-soft, #f4f4f4);
}

.form-help {
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin-top: 0.25rem;
}

.comment-list {
  list-style: none;
  margin: 0 0 1.25rem;
  padding: 0;
}

.comment {
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--line);
}

.comment:last-child {
  border-bottom: none;
}

.comment-meta {
  font-size: 0.85rem;
  margin-bottom: 0.25rem;
}

.comment-meta strong {
  color: var(--ink);
}

.comment-date {
  color: var(--ink-soft);
  margin-left: 0.5rem;
}

.comment-edited {
  color: var(--ink-soft);
  margin-left: 0.5rem;
  font-style: italic;
}

.comment-body {
  margin: 0 0 0.4rem;
  white-space: pre-wrap;
}

.comment-actions {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.comment-action-form {
  display: inline;
  margin: 0;
}

.comment-action {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  font-size: 0.82rem;
  color: var(--ink-soft);
  cursor: pointer;
}

.comment-action:hover {
  color: var(--accent);
  text-decoration: underline;
}

.comment-action.active {
  color: var(--accent);
  font-weight: 600;
}

.comment-action-static {
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.comment-action-danger {
  color: #b3261e;
}

.comment-action-danger:hover {
  color: #b3261e;
  text-decoration: underline;
}

.reply-form,
.edit-form {
  margin: 0.6rem 0 0;
}

.reply-form textarea,
.edit-form textarea {
  width: 100%;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 0.9rem;
  font-family: inherit;
  resize: vertical;
}

.reply-form button,
.edit-form button[type="submit"] {
  margin-top: 0.4rem;
  padding: 0.4rem 0.9rem;
  border: none;
  border-radius: 5px;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}

.link-button {
  background: none;
  border: none;
  padding: 0;
  margin: 0.4rem 0 0 0.7rem;
  font: inherit;
  font-size: 0.85rem;
  color: var(--ink-soft);
  cursor: pointer;
  text-decoration: underline;
}

.link-button:hover {
  color: var(--accent);
}

.comment-replies {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0 0 0 1.25rem;
  border-left: 2px solid var(--line);
}

.comment-replies .comment {
  padding: 0.6rem 0;
}

.comment-replies .comment:last-child {
  border-bottom: none;
}

.form-errors {
  color: #b3261e;
  font-size: 0.85rem;
  margin-top: 0.25rem;
}

.dropzone {
  border: 2px dashed var(--line);
  border-radius: 8px;
  padding: 1.75rem 1rem;
  text-align: center;
  cursor: pointer;
  background: var(--bg-soft);
  transition: border-color 0.15s ease, background 0.15s ease;
  margin-bottom: 0.75rem;
}

.dropzone:hover {
  border-color: var(--accent);
}

.dropzone.dragover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.dropzone-text {
  margin: 0 0 0.25rem;
  font-weight: 600;
  color: var(--ink);
}

.dropzone-hint {
  margin: 0;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.file-list {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  font-size: 0.85rem;
}

.file-list:empty {
  margin: 0;
}

.file-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.3rem 0.6rem;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 5px;
  margin-bottom: 0.3rem;
  color: var(--ink-soft);
}

/* Higher-specificity ".file-list .file-list-remove" (rather than the bare
   class) so this small inline "remove" control doesn't get swept up by the
   generic ".auth-card button" rule further down, which styles real
   submit-style buttons (like this page's own "Upload" button) as solid
   accent-colored pills. */
.file-list .file-list-remove {
  flex: none;
  background: none;
  border: none;
  padding: 0 0.2rem;
  margin-right: 0;
  font-size: 1rem;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
}

.file-list .file-list-remove:hover {
  color: var(--ink);
}

.auth-card button,
.card form button[type="submit"] {
  padding: 0.5rem 1.1rem;
  border: none;
  border-radius: 5px;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
  font-size: 0.92rem;
  margin-right: 0.75rem;
}

.messages {
  list-style: none;
  margin: 0 0 1.25rem;
  padding: 0;
}

.messages .message {
  padding: 0.65rem 0.9rem;
  border-radius: 6px;
  font-size: 0.9rem;
  margin-bottom: 0.5rem;
  background: var(--accent-soft);
  color: var(--accent);
}

.messages .message.error {
  background: #fbe9e7;
  color: #b3261e;
}

.site-nav span {
  opacity: 0.85;
}

/* Header search box -- see search_results.html/registry.views.search.
   Semi-transparent white against the header's accent-color background,
   matching the "site-header a { color: #fff; }" treatment the rest of the
   header uses rather than a stark white input box. */
.site-search-form {
  margin: 0;
  /* Shrinks instead of forcing the nav wider than the viewport, and grows
     to fill any slack on a wide header -- a fixed width is what caused
     the mobile overflow (see .site-nav above). */
  flex: 1 1 140px;
  min-width: 0;
}
.site-search-input {
  box-sizing: border-box;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  color: #fff;
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
  width: 100%;
}
.site-search-input::placeholder {
  color: rgba(255, 255, 255, 0.75);
}
.site-search-input:focus {
  outline: none;
  background: rgba(255, 255, 255, 0.28);
  border-color: #fff;
}

.search-section-more {
  margin: 0.5rem 0 1.75rem;
  font-size: 0.88rem;
}

.logout-form {
  display: inline;
  margin: 0;
}

.site-nav .link-button {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: none;
}

.site-nav .link-button:hover {
  text-decoration: underline;
}

.site-footer {
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.82rem;
  padding: 1.5rem 1rem 2.5rem;
}

.site-footer p {
  margin: 0.2rem 0;
}

.site-footer .copyright {
  font-size: 0.78rem;
}

@media (max-width: 640px) {
  .stat-row { gap: 1.25rem; }
  .filter-form { flex-direction: column; align-items: stretch; }
  .filter-form .field { width: 100%; }
  .multiselect-dropdown { width: 100%; }

  /* Header nav on mobile, per explicit request: the search box stays
     inline with Registry/Literature/avatar on one row, positioned between
     Literature and the avatar -- its natural position in the HTML source
     order. order:0 (the flex default) keeps it from being pushed after
     them the way an earlier order:10/full-width rule did. The flex-basis
     is cut to 70px here (half of the 140px desktop default) -- at the
     140px basis the box was still wide enough to push Log in/the avatar
     onto their own line on a 375px-wide screen, per explicit follow-up
     request to reduce it by half; confirmed via live visual check before
     shipping. */
  .site-search-form {
    order: 0;
    flex: 1 1 70px;
  }

  /* Just the avatar/initials tile on mobile -- the username text next to
     it is dropped so that link stays compact enough to share a line with
     Registry/Literature. aria-label on the link itself (see base.html)
     keeps it accessible with the visible text gone. Unaffected above this
     breakpoint -- desktop still shows the full username. */
  .site-nav-username {
    display: none;
  }
}

/* Prefix-page "sale price over time" chart */

.sales-chart-subtitle {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0 0 1rem;
}

.sales-chart-caption {
  font-size: 0.82rem;
  color: var(--ink-soft);
  margin: 0.6rem 0 1.25rem;
}

.sales-chart {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1rem 1.25rem 0.75rem;
}

.sales-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 0.5rem;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.sales-chart-legend-item {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.sales-chart-legend-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: none;
  display: inline-block;
}

.sales-chart svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.sales-chart .axis-label {
  font-size: 10px;
  fill: var(--ink-soft);
}

.sales-chart .grid-line {
  stroke: var(--line);
  stroke-width: 1;
}

.sales-chart .baseline {
  stroke: var(--ink-soft);
  stroke-width: 1;
}

.sales-chart .sale-dot-link {
  cursor: pointer;
}

.sales-chart .sale-dot-link:hover,
.sales-chart .sale-dot-link:focus {
  filter: brightness(1.2);
  outline: none;
}

.sales-chart-tooltip {
  position: fixed;
  background: var(--ink);
  color: var(--bg);
  font-size: 0.78rem;
  padding: 0.4rem 0.65rem;
  border-radius: 6px;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -100%);
  transition: opacity 0.08s ease;
  z-index: 20;
  white-space: nowrap;
}

.sales-chart-tooltip.visible {
  opacity: 1;
}

.sales-chart-tooltip .tt-serial {
  font-weight: 600;
}

.sales-chart-tooltip .tt-price {
  font-weight: 700;
}

.sales-chart-tooltip .tt-line {
  margin-top: 0.1rem;
  opacity: 0.85;
}

/* Books page: a grid of cover-photo tiles, a detail page with a larger
   cover beside the book's own fields, and a shared star-rating look used
   for both a book's average and one member's own review. */

.book-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1.25rem;
  margin: 1rem 0 1.75rem;
}

.book-tile {
  display: block;
  color: inherit;
}

.book-tile:hover {
  text-decoration: none;
}

.book-tile:hover .book-tile-title {
  text-decoration: underline;
  color: var(--accent);
}

.book-tile-cover {
  aspect-ratio: 2 / 3;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg);
  margin-bottom: 0.5rem;
}

.book-tile-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.book-tile-cover-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 0.5rem;
  text-align: center;
  font-size: 0.82rem;
  color: var(--ink-soft);
  background: var(--bg-soft);
}

.book-tile-title {
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.3;
}

.book-tile-author {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0.1rem 0 0.35rem;
}

.book-detail-layout {
  display: flex;
  gap: 1.75rem;
  flex-wrap: wrap;
  /* Without this, flexbox's default cross-axis behavior (stretch) pulls
     .book-detail-cover down to match .book-detail-info's height whenever
     the info column runs longer (a description, buy/download links, a
     wide detail-grid) -- flex-start lets the cover frame size to its own
     2:3 shape instead of trailing empty background space to the bottom of
     the section. */
  align-items: flex-start;
}

.book-detail-cover {
  flex: 0 0 auto;
  width: 200px;
  aspect-ratio: 2 / 3;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-soft);
}

.book-detail-cover img {
  width: 100%;
  height: 100%;
  /* contain, not cover -- the frame box above is a fixed 2:3 shape for
     layout consistency, but the cover photo itself is scaled to fit
     entirely inside it at its own true aspect ratio (letterboxed if it
     isn't already 2:3) rather than being cropped/stretched to fill the
     frame, which is what made off-ratio covers look distorted. Top-
     aligned (object-position) rather than centered, so a cover shorter
     than the frame sits flush with the title/spine art at the top instead
     of floating in the middle with an even gap above and below. */
  object-fit: contain;
  object-position: top;
  display: block;
}

.book-detail-info {
  flex: 1 1 320px;
  min-width: 260px;
}

.star-rating {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.4rem 0 0.9rem;
}

.star-row {
  letter-spacing: 0.1em;
  font-size: 1.05rem;
}

.star-row .star {
  color: var(--line);
}

.star-row .star.filled {
  color: var(--tag-probable);
}

.star-rating-text {
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.star-picker {
  display: flex;
  align-items: center;
  gap: 0.2rem;
}

.star-picker-btn {
  background: none;
  border: none;
  padding: 0;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--line);
  cursor: pointer;
}

.star-picker-btn.filled {
  color: var(--tag-probable);
}

.star-picker-label {
  margin-left: 0.5rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.book-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1rem;
}

/* Accessory reference pop-up: the small "?" icon next to an Example's
   Accessories/Components field values, and the shared modal it opens
   showing that variant's reference photo + caption. */
.accessory-ref-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1rem;
  height: 1.1rem;
  margin-left: 0.4rem;
  border-radius: 50%;
  border: 1px solid var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.7rem;
  line-height: 1;
  font-weight: 700;
  cursor: pointer;
  padding: 0;
  vertical-align: middle;
}

.accessory-ref-btn:hover {
  background: var(--accent);
  color: var(--bg);
}

.accessory-ref-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

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

.accessory-ref-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
}

.accessory-ref-modal-content {
  position: relative;
  background: var(--bg);
  border-radius: 10px;
  padding: 1.25rem;
  max-width: 420px;
  width: 100%;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
}

.accessory-ref-modal-images {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
}

.accessory-ref-modal-images img {
  display: block;
  flex: 1 1 0;
  min-width: 0;
  max-height: 60vh;
  object-fit: contain;
  border-radius: 6px;
  cursor: zoom-in;
}

/* Stacks above .accessory-ref-modal (same z-index as .lightbox) so clicking
   a photo in the small pop-up opens full-screen on top of it, not behind
   it -- see the lightbox markup/script in specimen_detail.html. */
#accessory-ref-lightbox {
  z-index: 1100;
}

.accessory-ref-modal-images img[hidden] {
  display: none;
}

.accessory-ref-modal-caption {
  margin: 0.75rem 0 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
  text-align: center;
}

.accessory-ref-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.6rem;
  background: none;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-soft);
}

/* Analytics consent banner -- see base.html's {% if umami_website_id %}
   block. Fixed to the bottom of the viewport, above everything else, until
   dismissed via Accept/Decline (then it's simply hidden and never shown
   again, per the localStorage choice). */
.consent-banner[hidden] {
  display: none;
}
.consent-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.25rem;
  padding: 0.9rem 1.25rem;
  background: var(--ink);
  color: #fff;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15);
}
.consent-banner p {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.4;
  max-width: 62ch;
}
.consent-banner a {
  color: #fff;
  text-decoration: underline;
}
.consent-banner-actions {
  display: flex;
  gap: 0.6rem;
  flex-shrink: 0;
}
.consent-btn {
  padding: 0.45rem 1rem;
  border-radius: 5px;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
}
.consent-btn-primary {
  background: #fff;
  color: var(--ink);
  border-color: #fff;
}
.consent-btn-secondary {
  background: transparent;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.5);
}

/* Examples list: table/card view toggle -- see specimen_list.html and the
   "view" GET param read in specimen_list (views.py). */
.view-toggle {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 1rem;
}
.view-toggle-link {
  padding: 0.4rem 1rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
}
.view-toggle-link:hover {
  text-decoration: none;
  color: var(--ink);
}
.view-toggle-link.active {
  background: var(--ink);
  color: #fff;
}

/* Examples list, card view -- a "baseball card" per Example, standing in
   for a row of the data-table above when "Cards" is selected. */
.specimen-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.25rem;
  margin: 0 0 1.75rem;
}
.specimen-card {
  position: relative;
  display: flex;
  flex-direction: column;
  color: inherit;
  text-decoration: none;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}
.specimen-card:hover {
  text-decoration: none;
  box-shadow: 0 2px 8px rgba(28, 31, 36, 0.12);
}
.specimen-card-banner {
  padding: 0.85rem 1rem;
}
.specimen-card-banner-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}
.specimen-card-serial {
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.specimen-card-banner-sub {
  font-size: 0.78rem;
  font-weight: 700;
  margin-top: 0.25rem;
  opacity: 0.85;
}
.specimen-card-photo {
  position: relative;
  width: 100%;
  height: 160px;
  flex-shrink: 0;
  background: var(--bg-soft);
  display: flex;
  align-items: center;
  justify-content: center;
}
.specimen-card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.specimen-card-photo-fallback {
  font-size: 0.72rem;
  color: var(--ink-soft);
  text-align: center;
  max-width: 80%;
}
.specimen-card-body {
  padding: 0.9rem 1rem 1rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}
/* My Collection, card view only -- the body sits outside the card's <a>
   now (see my_collection.html) so the Prefix stat can be its own link;
   cursor:pointer signals the rest of the body still navigates to the
   specimen via its click handler there. The shared card grid partial
   (_specimen_card_grid.html) keeps its body inside its <a>, where this
   rule has no visible effect since the whole thing is already a link. */
.specimen-card-body[data-specimen-href] {
  cursor: pointer;
}
.specimen-card-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem 1rem;
}
.specimen-card-stat-wide {
  grid-column: span 2;
}
.specimen-card-stat-label {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.specimen-card-stat-value {
  font-size: 0.85rem;
  font-weight: 600;
  margin-top: 0.1rem;
}
.specimen-card-notes {
  margin-top: 0.65rem;
}
.specimen-card-notes-text {
  font-size: 0.78rem;
  margin-top: 0.15rem;
  max-height: 3.4rem;
  overflow-y: auto;
  line-height: 1.4;
  padding-right: 0.25rem;
}
.specimen-card-footer {
  margin-top: auto;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.specimen-card-status {
  font-size: 0.78rem;
  color: var(--ink-soft);
}

/* My Collection, card view -- a small circular remove button overlaid on
   the card banner. Lives outside the card's own <a> (see my_collection.html)
   since a <form>/<button> can't validly nest inside an anchor; its click
   handler posts the matching hidden per-card remove form instead. */
.specimen-card-remove {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.specimen-card-remove:hover {
  background: rgba(0, 0, 0, 0.7);
}

/* "Set as main photo" badge in the staff Manage-photos table -- see
   media_set_primary and _photo_gallery.html. */
.media-primary-badge {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--tag-probable);
  margin-top: 0.2rem;
  white-space: nowrap;
}
