/* site.css: base styles composed from tokens.css only (contracts/theme.md §1).
   No raw color, size, space, radius, or shadow value is declared here -- every
   value is a var(--...). Mobile-first. */

/* ---- reset & base ---- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  color-scheme: light dark;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  text-wrap: pretty;
}

h1, h2, h3 {
  font-family: var(--font-display);
  line-height: var(--leading-tight);
  text-wrap: balance;
  margin: 0 0 var(--space-4);
}

h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }

p { margin: 0 0 var(--space-4); }

a {
  color: inherit;
}

img, svg {
  max-width: 100%;
  display: block;
}

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

main {
  display: block;
}

/* ---- layout shell ---- */
.shell {
  max-width: 72rem;
  margin-inline: auto;
  padding-inline: var(--space-5);
}

/* ---- header ---- */
.site-header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-line);
}

.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-4);
}

.site-header__wordmark {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  letter-spacing: 0.02em;
  color: var(--color-ink);
  text-decoration: none;
  min-height: 44px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.site-header__wordmark small {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.site-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  min-width: 44px;
  padding-inline: var(--space-3);
  text-decoration: none;
  font-size: var(--text-sm);
  color: var(--color-ink);
  border-radius: var(--radius-sm);
  transition: background-color var(--dur-fast) var(--ease-standard);
}

.site-nav__link:hover {
  background: var(--color-surface-raised);
}

.site-nav__account {
  font-weight: 600;
}

/* ---- footer ---- */
.site-footer {
  background: var(--color-surface);
  color: var(--color-ink);
  border-top: 1px solid var(--color-line);
  margin-top: var(--space-12);
}

.site-footer__grid {
  display: grid;
  gap: var(--space-6);
  padding-block: var(--space-10);
  grid-template-columns: 1fr;
}

@media (min-width: 48rem) {
  .site-footer__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.site-footer h2 {
  font-size: var(--text-base);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-brand);
}

.site-footer__placeholder {
  color: var(--color-ink-muted);
  font-style: italic;
}

.site-footer__legal {
  border-top: 1px solid var(--color-line);
  padding-block: var(--space-4);
  font-size: var(--text-xs);
  color: var(--color-ink-muted);
}

/* ---- hero ---- */
.hero {
  padding-block: var(--space-12);
  text-align: center;
}

.hero .tagline {
  font-size: var(--text-lg);
  color: var(--color-ink-muted);
  max-width: 40ch;
  margin-inline: auto;
}

/* ---- how it works ---- */
.how-it-works {
  padding-block: var(--space-12);
  border-top: 1px solid var(--color-line);
}

.how-it-works__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-6);
}

@media (min-width: 48rem) {
  .how-it-works__list {
    grid-template-columns: repeat(3, 1fr);
  }
}

.how-it-works__step {
  padding: var(--space-6);
  background: var(--color-surface);
  border-radius: var(--radius-md);
}

.how-it-works__number {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  color: var(--color-brand);
  display: block;
  margin-bottom: var(--space-2);
}

/* ---- featured lots grid ---- */
.featured-lots {
  padding-block: var(--space-12);
  border-top: 1px solid var(--color-line);
}

.featured-lots__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 48rem) {
  .featured-lots__grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.lot-card {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-1);
}

.lot-card__media {
  aspect-ratio: 1 / 1;
  background: var(--color-charcoal);
  overflow: hidden;
}

.lot-card__media .image-pending,
.lot-card__media img {
  width: 100%;
  height: 100%;
}

.lot-card__media img {
  object-fit: cover;
}

.lot-card__body {
  padding: var(--space-3);
}

.lot-card__title {
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
  margin: 0;
}

/* ---- forms ---- */
label {
  display: block;
  font-size: var(--text-sm);
  margin-bottom: var(--space-1);
}

input, textarea, select {
  font: inherit;
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-ink);
}

/* Architect fix at W2.5 grading (2026-09-09): the rule above made checkboxes and radios
   375px wide on a phone (the first page with a checkbox overflowed to a 382px layout
   viewport). Native toggles keep their intrinsic size; the 44px target comes from the label. */
input[type="checkbox"],
input[type="radio"] {
  width: auto;
  min-height: 0;
  padding: 0;
  margin-inline-end: var(--space-2);
  accent-color: var(--color-accent);
}

/* ---- buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding-inline: var(--space-5);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}

.btn--primary {
  background: var(--color-accent);
  color: var(--color-surface);
}

.btn--primary:hover {
  background: var(--color-charcoal);
}

.btn--secondary {
  background: transparent;
  color: var(--color-ink);
  border-color: var(--color-line);
}

.btn--secondary:hover {
  background: var(--color-surface);
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* ---- image-pending placeholder label ---- */
.image-pending {
  position: relative;
}

.image-pending__label {
  position: absolute;
  inset-block-end: var(--space-2);
  inset-inline-start: var(--space-2);
  background: var(--color-ink);
  color: var(--color-bg);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
}

/* ---- hijack banner (markup owned by W1.4; classes styled here per
   contracts/audit.md §4 -- do not add rules keyed on any other selector) ---- */
.hijack-banner {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  background: var(--color-danger);
  color: var(--color-surface);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

.hijack-banner__text {
  margin: 0;
}

.hijack-banner__release {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--space-4);
  background: var(--color-surface);
  color: var(--color-danger);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-weight: 600;
}

/* ---- reduced motion: belt and suspenders alongside the zeroed duration tokens ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ================================================================
   Catalog: LotList, category pages, lot detail (W2.6)
   ================================================================ */

.catalog-layout > h1 {
  margin-bottom: var(--space-6);
}

.catalog-toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.catalog-toolbar label {
  margin-bottom: 0;
}

.sort-control {
  width: auto;
}

/* facet rail: a checkbox-driven disclosure on phone (closed by default -- the panel is a
   plain block, hidden by an ordinary `display: none` until the checkbox behind the visible
   "Filters" label is checked; a native <details> was tried first, but Chrome's newer
   `::details-content` collapse mechanism uses `content-visibility` internally and cannot be
   forced open by an author `display` rule on the child -- found by measuring, not assumed).
   At desktop the toggle is hidden and the panel is always shown. */
.facet-rail {
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-6);
}

.facet-rail__checkbox {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.facet-rail__toggle {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-weight: 600;
  cursor: pointer;
}

.facet-rail__checkbox:focus-visible ~ .facet-rail__toggle {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

.facet-rail__panel {
  display: none;
  padding-top: var(--space-4);
  gap: var(--space-4);
}

.facet-rail__checkbox:checked ~ .facet-rail__panel {
  display: grid;
}

.facet-rail__group h2 {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-ink-muted);
  margin-bottom: var(--space-2);
}

.facet-option {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--text-sm);
  margin-bottom: 0;
}

.facet-rail__note {
  font-size: var(--text-xs);
  color: var(--color-ink-muted);
  font-style: italic;
}

@media (min-width: 48rem) {
  .facet-rail__toggle {
    display: none;
  }

  .facet-rail__panel {
    display: grid !important;
  }
}

/* lot grid (list page and related lots) */
.lot-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 48rem) {
  .lot-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.lot-grid__empty {
  color: var(--color-ink-muted);
  padding-block: var(--space-6);
}

.lot-card__price {
  font-size: var(--text-sm);
  font-weight: 600;
  margin: var(--space-1) 0 0;
}

/* pagination */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding-block: var(--space-8);
}

.pagination__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--space-4);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  text-decoration: none;
}

.pagination__status {
  color: var(--color-ink-muted);
  font-size: var(--text-sm);
}

/* lot detail */
.lot-detail__breadcrumb {
  display: flex;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
  margin-block: var(--space-4);
}

.lot-detail__breadcrumb a {
  text-decoration: none;
}

.lot-detail__layout {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: 1fr;
}

@media (min-width: 48rem) {
  .lot-detail__layout {
    grid-template-columns: 1fr 1fr;
  }
}

.lot-gallery__main {
  background: var(--color-charcoal);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.lot-gallery__main img {
  width: 100%;
  height: auto;
}

.lot-gallery__thumbs {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
  margin: var(--space-3) 0 0;
  padding: 0;
}

.lot-gallery__thumbs img {
  border-radius: var(--radius-sm);
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.lot-facts {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-4) 0;
}

.lot-facts > div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  border-bottom: 1px solid var(--color-line);
  padding-block: var(--space-1);
}

.lot-facts dt {
  color: var(--color-ink-muted);
}

.lot-facts dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
}

.action-panel {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  margin-top: var(--space-6);
  display: grid;
  gap: var(--space-3);
}

.action-panel__price {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  margin: 0;
}

.action-panel__meta,
.action-panel__countdown {
  margin: 0;
  color: var(--color-ink-muted);
  font-size: var(--text-sm);
}

.related-lots {
  margin-top: var(--space-12);
  border-top: 1px solid var(--color-line);
  padding-top: var(--space-8);
}

/* ================================================================
   Public bidding UI: bid box, watch, live state (W3.7, additive)
   ================================================================ */

.action-panel__messages {
  display: grid;
  gap: var(--space-2);
}

.action-panel__message {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.action-panel__message--success {
  background: var(--color-surface-raised);
  color: var(--color-success);
  border: 1px solid var(--color-success);
}

.action-panel__message--error {
  background: var(--color-surface-raised);
  color: var(--color-danger);
  border: 1px solid var(--color-danger);
}

.action-panel__leading {
  margin: 0;
  color: var(--color-success);
  font-size: var(--text-sm);
  font-weight: 600;
}

.action-panel__approval-prompt {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
}

.lot-countdown--urgent {
  color: var(--color-danger);
  font-weight: 600;
}

.bid-form {
  display: grid;
  gap: var(--space-2);
}

/* Architect fix (2026-09-22): the fixed-price branch of the action panel never got the layout
   its auction sibling `.bid-form` has, so `.offer-form` fell back to block flow and the submit
   button sat flush on the input -- 0px, where every other gap in the panel is 8 or 12. Same grid
   and gap as `.bid-form`; `justify-items: start` additionally keeps the button shrink-to-fit so it
   matches the compact `Buy now` and `Watch this lot` buttons it is stacked with (the auction
   branch is never rendered beside them, so the two forms differing here is not a seam). The
   full-width input is unaffected: `width: 100%` (site.css:277) is a definite size and still
   resolves against the whole grid area. */
.offer-form {
  display: grid;
  gap: var(--space-2);
  justify-items: start;
}

.watch-form {
  margin: 0;
}

/* facet rail -> left sidebar at desktop (design finding from the lots-1280-light.png review:
   the rail no longer needs to sit above the grid once there is room beside it). The grid gets
   the room; the rail stays open, sticky, and narrow. Phone and tablet (below 64rem) behavior
   is unchanged from W2.6 -- .catalog-layout__grid only becomes a two-column grid here.
   `.catalog-filters` (the <form> wrapping the toolbar and the rail) is given `display: contents`
   so its two children become direct items of the parent grid without moving any form field,
   name, or the query itself (architect note: structural wrapper only). */
@media (min-width: 64rem) {
  .catalog-layout__grid {
    display: grid;
    grid-template-columns: 16rem 1fr;
    align-items: start;
    gap: var(--space-8);
  }

  .catalog-filters {
    display: contents;
  }

  .facet-rail {
    grid-column: 1;
    grid-row: 1 / span 2;
    position: sticky;
    top: var(--space-4);
    max-height: calc(100vh - var(--space-8));
    overflow-y: auto;
  }

  .catalog-toolbar {
    grid-column: 2;
    grid-row: 1;
  }

  .lot-grid {
    grid-column: 2;
    grid-row: 2;
  }

  .pagination {
    grid-column: 2;
    grid-row: 3;
  }
}

/* ================================================================
   Buyer invoices and checkout (W4.5, additive)
   ================================================================ */

.invoices-mine__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
}

.invoices-mine__item {
  display: flex;
  flex-wrap: wrap;
  /* b7.3 CSS pass: was `baseline`, which was correct while every child was a line of text.
     The row now leads with a 64px thumbnail, and baseline-aligning a 64px box against small
     text pushes the text to the image's last line box. Centring is what a media row wants. */
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface);
  border-radius: var(--radius-md);
}

/* b7.3 CSS pass. The template shipped these four classes with no rules, so the thumbnail
   collapsed to the placeholder's intrinsic size and the title carried a default <p> margin.
   Deliberately NOT reusing the catalog's `lot-card__*` rules: those class names contain the
   substring "card", and billing/tests/test_views.py::test_no_card_field_in_any_billing_template
   is a banned-word grep over billing/templates/billing/*.html that matches on substring. */
.invoices-mine__media {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--color-surface-raised);
}

.invoices-mine__media img,
.invoices-mine__media svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.invoices-mine__details {
  /* Takes the slack so the number, total, status and due date keep their natural widths and
     the due date's `margin-inline-start: auto` still pins it to the right edge. */
  flex: 1 1 12rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.invoices-mine__title {
  margin: 0;
  font-weight: 600;
  line-height: var(--leading-tight);
  overflow-wrap: anywhere;
}

.invoices-mine__kind {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-ink-muted);
}

/* b7.3 CSS pass, caught in a 400px capture: as one wrapping flex line, 64px of thumbnail plus
   a 12rem details basis plus the number, total, status and due date could not fit a phone, and
   the row overflowed the viewport with the invoice number clipped off the right edge. Below
   40rem the row becomes an explicit two-column grid -- thumbnail spanning the left, everything
   else stacked in the right column -- so nothing is ever wider than the screen. */
@media (max-width: 40rem) {
  .invoices-mine__item {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    align-items: start;
    column-gap: var(--space-3);
    row-gap: var(--space-1);
  }

  .invoices-mine__media {
    grid-row: 1 / span 2;
  }

  .invoices-mine__details,
  .invoices-mine__number,
  .invoices-mine__total,
  .invoices-mine__status,
  .invoices-mine__due {
    grid-column: 2;
  }

  .invoices-mine__due {
    /* The desktop rule pins this right with `auto`; in the grid it just sits in the stack. */
    margin-inline-start: 0;
  }
}

.invoices-mine__number {
  font-weight: 600;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.invoices-mine__total {
  font-family: var(--font-display);
}

.invoices-mine__status {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-ink-muted);
}

.invoices-mine__status--paid {
  color: var(--color-success);
}

.invoices-mine__status--void,
.invoices-mine__status--merged {
  color: var(--color-danger);
}

.invoices-mine__due {
  margin-inline-start: auto;
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
}

.invoice-detail__status,
.invoice-detail__dates {
  color: var(--color-ink-muted);
  font-size: var(--text-sm);
}

/* b7.4 CSS pass: the return links shipped as bare underlined text butted against the
   fulfillment panel. They are navigation away from a finished transaction, so they read as a
   quiet footer rule rather than as buttons competing with Pay. */
.invoice-detail__return {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-block-start: var(--space-6);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--color-line);
}

.invoice-detail__return-link {
  /* 44px keeps these inside the project's touch-target floor, same as the invoice number link
     in the purchases list. */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
  text-decoration: none;
  border-block-end: 1px solid var(--color-line);
}

.invoice-detail__return-link:hover,
.invoice-detail__return-link:focus-visible {
  color: var(--color-ink);
  border-block-end-color: currentColor;
}

.invoice-detail__return-link:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

.invoice-detail__messages {
  display: grid;
  gap: var(--space-2);
  margin-block: var(--space-4);
}

.invoice-detail__message {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.invoice-detail__message--success {
  background: var(--color-surface-raised);
  color: var(--color-success);
  border: 1px solid var(--color-success);
}

.invoice-detail__message--error {
  background: var(--color-surface-raised);
  color: var(--color-danger);
  border: 1px solid var(--color-danger);
}

.invoice-detail__lines {
  width: 100%;
  border-collapse: collapse;
  margin-block: var(--space-5);
  font-size: var(--text-sm);
}

.invoice-detail__lines th,
.invoice-detail__lines td {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-line);
}

.invoice-detail__lines td:last-child,
.invoice-detail__lines th:last-child {
  text-align: right;
}

.invoice-detail__totals {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  margin: 0 0 var(--space-5);
  display: grid;
  gap: var(--space-2);
}

.invoice-detail__totals-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  margin: 0;
}

.invoice-detail__totals-row dt,
.invoice-detail__totals-row dd {
  margin: 0;
  font-weight: 400;
}

.invoice-detail__totals-row--total {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  border-top: 1px solid var(--color-line);
  padding-top: var(--space-2);
}

.invoice-detail__pay {
  margin-bottom: var(--space-6);
}

.fulfillment-options {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  display: grid;
  gap: var(--space-3);
}

.fulfillment-options__choice,
.fulfillment-options__pickup {
  display: grid;
  gap: var(--space-3);
}

.fulfillment-options__option {
  display: flex;
  align-items: center;
  min-height: 44px;
  gap: var(--space-2);
}

.invoice-paid {
  padding-block: var(--space-6);
}

.invoice-paid__status {
  font-size: var(--text-lg);
}

/* ---- trust-layer content pages and the results archive (W5.1) ---- */

/* A slot with no confirmed text yet, wherever `{% slot %}` renders it -- the same muted,
   italic treatment the footer's own pending lines already used (contracts/launch.md §1). */
.slot-pending {
  color: var(--color-ink-muted);
  font-style: italic;
}

.page-content {
  padding-block: var(--space-8);
  max-width: 60rem;
}

.page-content h2 {
  margin-top: var(--space-8);
}

.results-page {
  padding-block: var(--space-8);
}

.results-page__intro {
  color: var(--color-ink-muted);
  max-width: 40rem;
  margin-bottom: var(--space-6);
}

/* ================================================================
   Authentication and account pages (additive)
   `auth_base.html` and the allauth layout override both set
   body.auth-page, so one block serves the pages this project wrote
   and the ones allauth ships. Tokens only (contracts/theme.md §1).
   The page was previously unstyled scaffold: base.html gives each
   page only `<main>`, and none of these templates carried `.shell`,
   so the form ran the full width of the viewport.
   ================================================================ */
.auth-page #main {
  max-width: 26rem;
  margin-inline: auto;
  padding: var(--space-8) var(--space-5) var(--space-12);
}

/* Prose pages (settings, bidding approval, the MFA index) carry more than a
   credential form and need a readable measure rather than a narrow card. */
.auth-page--wide #main {
  max-width: 40rem;
}

.auth-page #main h1 {
  font-size: var(--text-xl);
  margin: 0 0 var(--space-5);
}

.auth-page #main p {
  line-height: var(--leading-body);
}

.auth-page form {
  display: grid;
  gap: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  padding: var(--space-6);
}

.auth-page form .btn {
  width: 100%;
}

.auth-page--wide form .btn {
  width: auto;
  justify-self: start;
}

.field {
  display: grid;
  gap: var(--space-1);
}

.field--checkbox label {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin-bottom: 0;
  line-height: var(--leading-body);
}

.field--checkbox input {
  margin-block-start: var(--space-1);
}

.field__help {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-ink-muted);
}

.field__error {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-danger);
}

.field--invalid :is(input, select, textarea) {
  border-color: var(--color-danger);
}

.form-errors {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: var(--space-3);
  list-style: none;
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-sm);
  background: var(--color-surface-raised);
  color: var(--color-danger);
  font-size: var(--text-sm);
}

.auth-messages {
  display: grid;
  gap: var(--space-2);
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
}

.auth-messages__item {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-surface-raised);
  font-size: var(--text-sm);
}

.auth-messages__item--success {
  color: var(--color-success);
  border-color: var(--color-success);
}

.auth-messages__item--error {
  color: var(--color-danger);
  border-color: var(--color-danger);
}

.auth-aside {
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
}

.auth-page :is(input, select, textarea, .btn, a):focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

/* ================================================================
   Lot gallery: thumbnail switching and magnifier (additive)
   The thumbnails were plain <img> with no handler and nothing ever
   swapped the main image, so a lot's other photos were unreachable.
   ================================================================ */
.lot-gallery__main {
  position: relative;
}

.lot-gallery__main--zoomable {
  cursor: zoom-in;
  touch-action: pan-y;
}

/* The magnified view fills the frame rather than floating in a small lens: on a condition-led
   catalogue the buyer wants the largest possible read of one region, and a full-frame pane has
   no edge cases at the corners of the image. It is decorative -- every photo it can show is
   already reachable through the thumbnails -- so it is hidden from assistive technology. */
.lot-gallery__lens {
  position: absolute;
  inset: 0;
  opacity: 0;
  background-color: var(--color-charcoal);
  background-repeat: no-repeat;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-standard);
}

.lot-gallery__main.is-zooming .lot-gallery__lens {
  opacity: 1;
}

.lot-gallery__hint {
  position: absolute;
  inset-block-end: var(--space-2);
  inset-inline-start: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-ink);
  color: var(--color-bg);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-standard);
}

.lot-gallery__main.is-zooming .lot-gallery__hint {
  opacity: 0;
}

.lot-gallery__thumb {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease-standard);
}

.lot-gallery__thumb:hover {
  border-color: var(--color-line);
}

.lot-gallery__thumb[aria-current="true"] {
  border-color: var(--color-accent);
}

.lot-gallery__thumb:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

/* ---- site search (W7.5) -------------------------------------------------------------
   One seam, two controls. `.site-search` (the inline field) and `.site-search__link` (the
   icon that opens /search/) are mutually exclusive, switched at the measured width below.
   Icon-first: the icon is the default and the field is what gets switched on, because
   `.site-nav` already wraps to three rows at 375px and an input beside it would swallow the
   viewport. No JavaScript is involved in the swap -- CSP is
   `script-src 'self'` with no `unsafe-inline`, so anything that needed a handler would be
   silently dead here. */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.site-search {
  display: none;
}

.site-search__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  color: var(--color-ink);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-standard);
}

.site-search__link:hover {
  background: var(--color-surface-raised);
}

/* 75rem, not the 48rem this stylesheet uses elsewhere, and the number is measured rather
   than chosen: the bar caps at 1112px of content, where the wordmark (323px) and a one-line
   nav (425px anonymous, 515px with the authenticated Purchases link) plus two 16px gaps
   already claim 780-870px. Below ~1200px there is no room left for a field anyone could
   type in -- at 768px it shrank to a 26px stub (measured). Everything under this width gets
   the icon, which is a complete control, not a degraded one. */
@media (min-width: 75rem) {
  .site-search {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    /* The field takes the space the wordmark and the nav do not want, and gives it back
       first when the bar gets tight: `flex-grow: 1` fills the gap at wide widths, the high
       `flex-shrink: 4` means the field -- not the nav -- absorbs the squeeze. A fixed basis
       here pushed `.site-nav` onto a second line at 1280px by 11px (measured), and the
       authenticated nav is one link wider still. */
    flex: 1 4 8rem;
    min-width: 10rem;
    max-width: 24rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
    padding-inline: var(--space-2);
  }

  .site-search:focus-within {
    border-color: var(--color-focus);
  }

  .site-search__input {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 40px;
    border: 0;
    background: transparent;
    color: var(--color-ink);
    font-family: var(--font-body);
    font-size: var(--text-sm);
  }

  .site-search__input:focus {
    outline: none;
  }

  .site-search__submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 40px;
    min-width: 40px;
    border: 0;
    background: transparent;
    color: var(--color-ink-muted);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: color var(--dur-fast) var(--ease-standard);
  }

  .site-search__submit:hover {
    color: var(--color-ink);
  }

  .site-search__link {
    display: none;
  }
}

/* ---- search entry page (W7.5) ---- */

.search-page {
  padding-block: var(--space-10);
  max-width: 40rem;
}

.search-page__form {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-6);
}

.search-page__input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding-inline: var(--space-3);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
}

.search-page__input:focus {
  outline: 2px solid var(--color-focus);
  outline-offset: 1px;
}

.search-page__hint {
  margin-top: var(--space-3);
  color: var(--color-ink-muted);
  font-size: var(--text-sm);
}
