/*
 * App components (ADR-196). No theme of its own: every colour, font and
 * spacing comes from the token contract of static/theme/<theme>.css.
 * base.html loads this file first and the theme after it, so a theme's
 * specific rules win over the generic components at equal specificity.
 * No inline styles anywhere (CSP style-src 'self').
 */

/* Page frame ------------------------------------------------------------ */
.layout-page {
  padding-block: var(--space-4) var(--space-6);
}
/* Every direct child keeps the page gutter; elements with a max-width of
   their own stay left-aligned. Full-bleed children (the reading-room band)
   reset margin-inline in the theme. */
main.layout-page > * {
  margin-inline: max(var(--space-4), calc((100% - var(--page-max)) / 2));
}
.layout-sidebar {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}
.layout-sidebar > main {
  min-width: 0;
  padding: var(--space-4);
}
.admin-nav {
  background: var(--color-panel);
  border-bottom: 1px solid var(--color-line);
  font-family: var(--font-ui);
  font-size: 0.9rem;
  padding: var(--space-3) var(--space-4);
}
.admin-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.admin-nav a {
  border-radius: var(--radius);
  color: var(--color-fg);
  display: block;
  min-height: 24px;
  padding: var(--space-1) var(--space-2);
  text-decoration: none;
}
.admin-nav a:hover {
  background: var(--color-accent-soft);
}
.admin-nav a[aria-current] {
  background: var(--color-accent);
  color: var(--color-accent-fg);
}
.admin-nav-group {
  color: var(--color-muted);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  margin: var(--space-3) 0 var(--space-1);
  text-transform: uppercase;
}
@media (min-width: 760px) {
  .layout-sidebar {
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
    min-height: 70vh;
  }
  .layout-sidebar > main {
    padding: var(--space-4) var(--space-5) var(--space-6);
  }
  .admin-nav {
    border-bottom: 0;
    border-inline-end: 1px solid var(--color-line);
    padding: var(--space-4) var(--space-3);
  }
  .admin-nav ul {
    display: grid;
    gap: 2px;
  }
}

/* Page head, breadcrumb ----------------------------------------------- */
.page-head {
  display: grid;
  gap: var(--space-1);
}
.page-head h1,
.object-head h1 {
  margin: var(--space-1) 0;
}
.sub {
  margin: 0;
}
.breadcrumb {
  color: var(--color-muted);
  font-family: var(--font-ui);
  font-size: 0.88rem;
  margin: 0 0 var(--space-2);
}
.object-id {
  color: var(--color-muted);
  font-family: var(--font-ui);
  font-size: 0.9rem;
  margin: 0;
}

/* Forms and controls ---------------------------------------------------- */
form.inline {
  display: inline;
}
form.stacked {
  display: grid;
  gap: var(--space-2);
  max-width: 30rem;
}
form.stacked label {
  font-family: var(--font-ui);
  font-weight: 500;
}
form.stacked button {
  justify-self: start;
}
form.search {
  max-width: 36rem;
}
.field {
  display: grid;
  gap: var(--space-1);
  margin-block: var(--space-3);
}
.field label {
  font-family: var(--font-ui);
}
fieldset {
  border: 1px solid var(--color-line);
  min-width: 0;
  border-radius: var(--radius);
  margin: var(--space-4) 0;
  padding: var(--space-2) var(--space-4) var(--space-3);
}
legend {
  font-family: var(--font-ui);
  font-weight: 600;
  padding-inline: var(--space-1);
}
textarea {
  width: 100%;
}
select {
  max-width: 100%;
  min-width: 0;
}
.hint {
  color: var(--color-muted);
  font-size: 0.9rem;
}
.confirm {
  background: var(--color-warning-bg);
  border-inline-start: 4px solid var(--color-warning-line);
  padding: var(--space-2) var(--space-3);
}
.confirm .hint {
  color: var(--color-fg);
}

/* Messages ------------------------------------------------------------- */
.notice {
  background: var(--color-warning-bg);
  border-inline-start: 4px solid var(--color-warning-line);
  color: var(--color-fg);
  padding: var(--space-2) var(--space-3);
}
.notice a {
  color: var(--color-fg);
}
.error,
.errors {
  border-inline-start: 4px solid var(--color-danger);
  color: var(--color-danger);
  padding: var(--space-1) var(--space-3);
}
[role="status"] {
  border-inline-start: 4px solid var(--color-success);
  padding: var(--space-1) var(--space-3);
}

/* Badges, pills, values ------------------------------------------------ */
.badge,
.status {
  border: 1px solid currentColor;
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  padding: 0 0.45rem;
  white-space: nowrap;
}
.status {
  color: var(--color-muted);
}
/* Seal state of the latest version in the editors (ADR-212). */
.badge.badge-provisional {
  background: var(--color-warning-bg);
  border-color: var(--color-warning-line);
  color: var(--color-fg);
}
.badge.badge-sealed {
  color: var(--color-success);
}
.status.ok {
  color: var(--color-success);
}
.pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  list-style: none;
  margin: var(--space-2) 0;
  padding: 0;
}
.pill {
  background: var(--color-panel);
  border: 1px solid var(--color-line);
  border-radius: 999px;
  color: var(--color-muted);
  font-family: var(--font-ui);
  font-size: 0.78rem;
  padding: 0.05rem 0.55rem;
}
.pill.pill-key {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-fg);
}
.uri {
  overflow-wrap: anywhere;
}
code.copyable {
  font-size: 0.8em;
  overflow-wrap: anywhere;
  user-select: all;
}
textarea.code,
pre.code {
  font-family: var(--font-mono);
  overflow-x: auto;
  white-space: pre;
  width: 100%;
}
pre.code {
  background: var(--color-panel);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
}

/* Definition lists and tables ------------------------------------------ */
dl {
  display: grid;
  gap: var(--space-1) var(--space-4);
  grid-template-columns: minmax(6rem, max-content) minmax(0, 1fr);
}
dt {
  color: var(--color-muted);
  font-family: var(--font-ui);
}
dd {
  margin: 0;
  min-width: 0;
}
.table-wrap {
  max-width: 100%;
  overflow-x: auto;
}
table {
  border-collapse: collapse;
  font-size: 0.92rem;
  width: 100%;
}
th,
td {
  border-bottom: 1px solid var(--color-line);
  padding: 0.45rem 0.55rem;
  text-align: left;
  vertical-align: top;
}
th {
  color: var(--color-muted);
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
tr.selected,
tr:target {
  background: var(--color-row-selected);
}
.paging {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  font-family: var(--font-ui);
  gap: var(--space-3);
}

/* Trees (node hierarchy; no inline styles: CSP style-src 'self') */
.tree li {
  list-style: none;
}
.depth-2 { margin-left: 1.5em; }
.depth-3 { margin-left: 3.0em; }
.depth-4 { margin-left: 4.5em; }
.depth-5 { margin-left: 6.0em; }
.depth-6 { margin-left: 7.5em; }
.depth-7 { margin-left: 9.0em; }
.depth-8 { margin-left: 10.5em; }
.depth-9 { margin-left: 12.0em; }
.depth-10 { margin-left: 13.5em; }
.depth-11 { margin-left: 15.0em; }
.depth-12 { margin-left: 16.5em; }
.depth-13 { margin-left: 18.0em; }
.depth-14 { margin-left: 19.5em; }
.depth-15 { margin-left: 21.0em; }
.depth-16 { margin-left: 22.5em; }

/* Root page, login, search --------------------------------------------- */
.hero-search h2 {
  margin-bottom: var(--space-2);
}
.persistence-note {
  color: var(--color-muted);
}
.auth-grid {
  display: grid;
  gap: var(--space-5) var(--space-6);
  grid-template-columns: minmax(0, 1fr);
  padding-block: var(--space-4);
}
.auth-grid section {
  align-content: start;
  display: grid;
  gap: var(--space-2);
}
.auth-grid h1,
.auth-grid h2 {
  margin: 0 0 var(--space-2);
}
@media (min-width: 760px) {
  .auth-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .auth-login {
    border-inline-end: 1px solid var(--color-line);
    padding-inline-end: var(--space-6);
  }
}
.search-results {
  list-style: none;
  padding: 0;
}
.search-results > li {
  border-bottom: 1px solid var(--color-line);
  display: grid;
  gap: var(--space-3);
  grid-template-columns: minmax(0, 1fr);
  padding-block: var(--space-2);
}
.search-results > li:has(.hit-thumb) {
  grid-template-columns: 3.4rem minmax(0, 1fr);
}
.hit-thumb img {
  aspect-ratio: 3 / 4;
  border: 1px solid var(--color-line);
  object-fit: cover;
  width: 100%;
}
.search-results small {
  color: var(--color-muted);
}
/* Search filters from the namespace field profiles (ADR-234). */
.search-filters {
  display: grid;
  gap: var(--space-2);
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
}
.search-filters .period {
  display: flex;
  gap: var(--space-1);
}
.search-filters .period input {
  width: 6em;
}
/* The source marker of a read-only profile field in the editor (ADR-234). */
.field-source {
  color: var(--color-muted);
  font-weight: normal;
}

/* Object page ------------------------------------------------------------ */
.object-head {
  display: grid;
  gap: var(--space-1);
}
.object-actions ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: var(--space-3) 0;
  padding: 0;
}
.object-actions a {
  align-items: center;
  background: var(--color-surface);
  border: 1px solid var(--color-control-border);
  border-radius: var(--radius);
  color: var(--color-fg);
  display: inline-flex;
  font-family: var(--font-ui);
  font-size: 0.88rem;
  min-height: 2.25rem;
  padding: 0.3rem 0.75rem;
  text-decoration: none;
}
.object-actions a:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}
.object-actions button {
  font-size: 0.88rem;
}
.landing section {
  margin-block: var(--space-4);
}
.landing section.citation dl {
  grid-template-columns: minmax(0, 1fr);
}

/* Slots for later pages (defined here, built with phase 2) ------------------ */
/* Viewer stage (PR 4 mounts into .object-stage [data-viewer]). */
.object-stage {
  background: var(--color-viewer-bg);
  color: var(--color-viewer-fg);
  display: flex;
  flex-direction: column;
  min-height: min(70vh, 48rem);
  min-width: 0;
}
.object-stage [data-viewer] {
  flex: 1;
  min-height: 0;
}
/* PDF.js in a same-origin frame (ADR-207); the frame fills the stage. */
.viewer-pdf {
  display: flex;
}
.viewer-pdf iframe {
  border: 0;
  flex: 1;
  min-height: min(70vh, 48rem);
  width: 100%;
}
/* TIFY in the stage (ADR-210): its own variables are set from the stage
   tokens, scoped to the stage; tify.css itself stays vendored unmodified. */
.viewer-iiif {
  --tify-base-color: var(--color-viewer-fg);
  --tify-bg-color: var(--color-viewer-bg);
  --tify-body-bg: var(--color-viewer-bg);
  --tify-text-color: var(--color-viewer-fg);
  --tify-link-color: var(--color-viewer-fg);
  min-height: min(70vh, 48rem);
  position: relative;
}
/* TIFY's root has height: 100%; an absolutely placed box gives it a
   definite height in the flexed stage (more specific than tify.css's
   own position: relative, which loads later). */
.object-stage .viewer-iiif > * {
  inset: 0;
  position: absolute;
}
/* Shown until TIFY mounts (and replaces it), or when it cannot start. */
.object-stage .viewer-iiif > .viewer-fallback {
  font-family: var(--font-ui);
  font-size: 0.9rem;
  inset: auto 0;
  margin: 0;
  padding: var(--space-4) var(--space-3);
  text-align: center;
}
.viewer-fallback a {
  color: var(--color-viewer-fg);
}
.viewer-credit {
  font-family: var(--font-ui);
  font-size: 0.8rem;
  margin: 0;
  padding: var(--space-1) var(--space-3);
}
.viewer-credit a {
  color: var(--color-viewer-fg);
}
/* The viewer-only page (?view): the stage fills the viewport. */
body[data-chrome="viewer"] {
  margin: 0;
}
.object-stage.viewer-page {
  height: 100vh;
  height: 100dvh;
  min-height: 0;
}
.viewer-page .viewer-pdf iframe,
.viewer-page .viewer-iiif {
  min-height: 0;
}
.viewer-bar {
  border-bottom: 1px solid var(--color-band-muted);
  display: flex;
  flex-wrap: wrap;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  gap: var(--space-2) var(--space-4);
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
}
.viewer-bar a {
  color: var(--color-viewer-fg);
}
.thumb-strip {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  padding: var(--space-2) var(--space-3);
}
.thumb {
  border: 2px solid transparent;
  border-radius: 2px;
  flex: 0 0 auto;
  width: 3rem;
}
.thumb[aria-current] {
  border-color: var(--color-viewer-fg);
}
/* Single-page view (ADR-198): the preview of a web image through ?raw
   sits in the stage until PR 4 puts the IIIF image there. */
.file-preview {
  align-items: center;
  display: flex;
  flex: 1;
  justify-content: center;
  margin: 0;
  min-height: 0;
  padding: var(--space-3);
}
.file-page .object-stage {
  margin-block-end: var(--space-4);
}
.file-preview img {
  display: block;
  height: auto;
  max-height: min(70vh, 48rem);
  max-width: 100%;
  object-fit: contain;
}
/* Single-page view: page numbers, citation of one page. */
.page-nav {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  font-family: var(--font-ui);
  gap: var(--space-2) var(--space-4);
}
/* Manifestation page: digitizations with an IIIF thumbnail. */
.item-list {
  display: grid;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
}
.item-list .item {
  border-bottom: 1px solid var(--color-line);
  display: grid;
  gap: var(--space-1) var(--space-3);
  grid-template-columns: 5rem minmax(0, 1fr);
  padding-block: var(--space-2);
}
.item-thumb {
  grid-row: span 3;
}
.item-thumb img {
  border: 1px solid var(--color-line);
  width: 100%;
}
.item-title {
  font-weight: 600;
}
.item-meta {
  color: var(--color-muted);
  font-family: var(--font-ui);
  font-size: 0.88rem;
}
.item-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
/* Collections: sidebar tree and member list with the current item marked. */
.collection-tree a[aria-current] {
  color: var(--color-fg);
  font-weight: 600;
}
.members {
  border-top: 1px solid var(--color-line);
  padding-top: var(--space-3);
}
.members [aria-current] {
  font-weight: 600;
}
/* Thumbnails of image members (PR 4b): the image service answers at most
   200 x 200 pixels; decorative, the link text names the member. */
.member-thumb {
  display: block;
  max-height: 200px;
  max-width: 200px;
  margin-block: var(--space-1);
}

/* Responsive ----------------------------------------------------------- */
@media (max-width: 760px) {
  /* Wide tables scroll inside .table-wrap instead of crushing their cells. */
  .table-wrap > table {
    min-width: 40rem;
  }
  dl {
    grid-template-columns: minmax(0, 1fr);
  }
  dd {
    margin-bottom: var(--space-2);
  }
}

/* Motion: transitions only for those who did not ask for less ------------- */
@media (prefers-reduced-motion: no-preference) {
  a,
  button,
  .object-actions a,
  .admin-nav a {
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
  }
}
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    scroll-behavior: auto !important;
    transition: none !important;
  }
}

/* Forced colours: keep the borders of pills and buttons ------------------- */
@media (forced-colors: active) {
  .pill,
  .badge,
  .status,
  button,
  .btn,
  .object-actions a {
    border: 1px solid ButtonText;
  }
  .admin-nav a[aria-current],
  .service-nav a[aria-current] {
    border: 1px solid Highlight;
  }
}
