/* Tokens come from Open Props v1.6.0, vendored as open-props.min.css
   (source: https://unpkg.com/open-props@1.6.0/open-props.min.css).

   Fonts are self-hosted from Google Fonts (fonts.gstatic.com), latin subset,
   variable woff2 files with the optical-size axis, downloaded 2026-10-24:
     Bodoni Moda, roman 500-700 and italic 500-600 (licence: SIL Open Font License 1.1)
     Source Serif 4, roman 400-600 (licence: SIL Open Font License 1.1)
   The original export also requested Source Serif 4 italic, which nothing on
   the page uses, so it is left out. */

@font-face {
  font-family: "Bodoni Moda";
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url("/fonts/bodoni-moda-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Bodoni Moda";
  font-style: italic;
  font-weight: 500 600;
  font-display: swap;
  src: url("/fonts/bodoni-moda-italic-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/fonts/source-serif-4-latin.woff2") format("woff2");
}

/* The site's own palette and faces. Light only: the design has no dark mode. */
:root {
  color-scheme: light;
  /* --paper is the film's border, sampled from frames 0-5 of
     media/hero-normal-19a8e578.mp4 (mean of a 40px strip on each side);
     --paper-worn is the darker, scorched edge the film's vignette fades to. */
  --paper: #e9c395;
  --paper-worn: #a97a43;
  --paper-deep: #c99655;
  --paper-rise: #f0d7ae;
  --ink: #1a1008;
  --ink-soft: #3d2916;
  --rule: #8d6230;
  --umber: #4a3010;
  --face-display: "Bodoni Moda", Didot, "Bodoni MT", "Times New Roman", serif;
  --face-serif: "Source Serif 4", Palatino, "Palatino Linotype", serif;
  --gutter: var(--size-4);
  --ease-quick: 180ms ease-out;
}

@media (min-width: 64rem) {
  :root {
    --gutter: 2.5rem;
  }
}

/* Reset: the subset of a preflight this page relies on. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

h1, h2, p, ul, ol, dl, dd, figure {
  margin: 0;
}

ul, ol {
  padding: 0;
  list-style: none;
}

svg, video {
  display: block;
}

html {
  /* Anchor targets land below the compact top bar. */
  scroll-padding-top: 4.5rem;
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  margin: 0;
  min-height: 100%;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--face-serif);
  font-size: 1.0625rem;
  line-height: 1.5;
}

/* Paper grain over everything, multiplied into the colour below it. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.22;
  background-image: url("/media/grain.svg");
  mix-blend-mode: multiply;
}

body > * {
  position: relative;
  z-index: 1;
}

a {
  color: inherit;
  text-decoration: none;
}

h1, h2, h3 {
  font-family: var(--face-display);
  font-weight: var(--font-weight-5);
  text-wrap: balance;
  letter-spacing: -0.02em;
  line-height: 1;
}

h1 {
  font-size: 2.25rem;
  color: var(--ink);
}

h2 {
  font-size: 1.875rem;
}

p {
  text-wrap: pretty;
}

::selection {
  background: var(--ink);
  color: var(--paper-rise);
}

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

/* Shared pieces */

.kicker {
  font-family: var(--face-serif);
  font-size: var(--font-size-0);
  font-weight: var(--font-weight-6);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--umber);
}

.rule {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.rule span {
  display: block;
  height: 1px;
  background: var(--rule);
}

.rule span:last-child {
  opacity: 0.45;
}

.page {
  min-height: 100vh;
  padding-bottom: 6rem;
}

/* No z-index: the sheet paints after the film and the veil in tree order
   without starting a stacking context of its own, so the hero mark's
   mix-blend-mode multiplies with the film and paper under it. */
.sheet {
  position: relative;
}

.wrap {
  max-width: 48rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* The scroll-scrubbed film behind the sheet (js/hero-film.js). The fixed
   layers (film, veil, worn edge) are placed by CSS alone, in svh units, which
   do not change while a phone's browser bars slide in and out, so nothing has
   to reposition them during a scroll. */

.film-ground {
  position: fixed;
  z-index: 0;
  left: 0;
  width: 100%;
  height: 150vw;
  top: calc(50svh - 75vw);
  margin: 0;
  overflow: hidden;
  pointer-events: none;
}

.film-video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}

/* Feather the film into the page so it has no hard edge. On a phone the film
   spans the width and sits mid-screen, so its top and bottom fade out (and its
   sides a little); on a desktop it fills the left of the screen and only its
   right edge fades. */
.film-ground {
  mask-image:
    linear-gradient(to bottom, transparent 0, #000 16%, #000 84%, transparent 100%),
    linear-gradient(to right, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-composite: intersect;
}

.film-veil {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: color-mix(in srgb, var(--paper-deep) 36%, transparent);
}

/* The worn edge of the page, over the film and the veil and under the text,
   like the darkened border of the film itself. */
.film-veil::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse 75% 70% at 50% 50%,
    transparent 55%,
    color-mix(in srgb, var(--paper-worn) 45%, transparent) 100%
  );
  box-shadow: inset 0 0 4rem color-mix(in srgb, var(--paper-worn) 40%, transparent);
}

@media (min-width: 64rem) and (min-aspect-ratio: 5/4) {
  .film-ground {
    top: 0;
    height: 100svh;
    width: auto;
    aspect-ratio: 2 / 3;
  }

  .film-ground {
    mask-image: linear-gradient(to right, #000 0, #000 72%, transparent 100%);
  }

  /* The column is centred in the viewport, over the right of the film on
     narrower desktops. A feathered band of paper behind it, part of the
     veil and so fixed, keeps the text readable where the two overlap. */
  .film-veil {
    background:
      linear-gradient(
        to right,
        transparent calc(50% - 30rem),
        color-mix(in srgb, var(--paper) 74%, transparent) calc(50% - 25rem),
        color-mix(in srgb, var(--paper) 74%, transparent) calc(50% + 25rem),
        transparent calc(50% + 30rem)
      ),
      color-mix(in srgb, var(--paper-deep) 36%, transparent);
  }
}

/* A longer page than the content needs, so the film's 145 frames span a
   comfortable scroll: on a desktop (below) the sheet is at least 360svh, a
   scroll of about 2.6 screen heights, some 14 px a frame at 800 px tall; on a
   phone 260svh, about 1.6 screen heights. The content stays at the top and
   the footer at the end. */
.sheet {
  display: flex;
  flex-direction: column;
  min-height: 260svh;
}

.sheet > .wrap {
  width: 100%;
}

.sheet > .colophon {
  margin-top: auto;
}

@media (min-width: 64rem) and (min-aspect-ratio: 5/4) {
  .sheet {
    min-height: 360svh;
  }
}

/* Masthead */

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

.brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  color: var(--ink);
}

/* The house mark: the ink logo's oval and figure, traced to one path
   (scripts/film/logo.py) and drawn in currentColor. */
.mark {
  flex: none;
  height: 2.6rem;
  width: auto;
  aspect-ratio: 71.3 / 116.9;
  color: var(--ink);
}

.brand-name {
  font-family: var(--face-display);
  font-size: 1.125rem;
  line-height: 1;
}

.brand-sub {
  display: block;
  margin-top: var(--size-1);
  font-family: var(--face-serif);
  font-size: var(--font-size-0);
  line-height: 1rem;
  font-weight: var(--font-weight-6);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--umber);
}

.masthead-end {
  display: flex;
  align-items: center;
  gap: var(--size-3);
}

/* Normal / Spicy: a two-segment pill. js/hero-film.js unhides it once a spicy
   film exists and sets data-mode on <html>. */
.mode-switch {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-round);
  background: color-mix(in srgb, var(--paper-rise) 55%, transparent);
}

.mode-switch[hidden] {
  display: none;
}

.mode-option {
  appearance: none;
  margin: 0;
  padding: 0.3rem 0.75rem;
  border: 0;
  border-radius: var(--radius-round);
  background: transparent;
  color: var(--umber);
  font-family: var(--face-serif);
  font-size: var(--font-size-0);
  font-weight: var(--font-weight-6);
  letter-spacing: 0.14em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background-color var(--ease-quick),
    color var(--ease-quick);
}

.mode-option:hover {
  color: var(--ink);
}

.mode-option[aria-pressed="true"] {
  background: var(--ink);
  color: var(--paper-rise);
}

.mode-option:focus-visible {
  outline-offset: 2px;
}

.brand-name,
.masthead .kicker {
  white-space: nowrap;
}

/* A phone has no room for the brand, the switch and the jump link on one
   line; the jump link goes, since the doors are just below. */
@media (max-width: 30rem) {
  .masthead-end:has(.mode-switch:not([hidden])) > .kicker {
    display: none;
  }

  .mode-option {
    padding-inline: 0.6rem;
    letter-spacing: 0.1em;
  }
}

[data-mode="normal"] [data-mode-only="spicy"],
[data-mode="spicy"] [data-mode-only="normal"] {
  display: none !important;
}

/* Hero mark: the wordmark of the aged-paper logo ("No Pants", "Vintage"
   and the flourishes), its paper keyed out to transparency ahead of time
   (scripts/film/logo.py), so it needs no blend mode over the film. */

.hero-mark {
  display: block;
  width: min(22rem, 88vw);
  height: auto;
  margin-inline: auto;
}

/* The same paper glow as the text halo, so the lettering reads over the
   film. */
.legible-halo .hero-mark {
  filter: drop-shadow(0 0 3px var(--paper)) drop-shadow(0 0 10px var(--paper));
}

@media (min-width: 64rem) and (min-aspect-ratio: 5/4) {
  .hero-mark {
    width: 30rem;
  }
}

/* Compact top bar (js/topbar.js): fixed, above the film, the veil and the
   worn edge, and out of the flow, so it shifts nothing. It slides in once the
   masthead has scrolled away; until then it is off screen and invisible, so
   its links cannot take focus. With a single destination on the page, the
   bar links the eBay store directly instead of opening a menu. */

.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid color-mix(in srgb, var(--rule) 55%, transparent);
  transform: translateY(-100%);
  visibility: hidden;
  transition:
    transform 220ms ease-out,
    visibility 0s linear 220ms;
}

.topbar.is-shown {
  transform: none;
  visibility: visible;
  transition:
    transform 220ms ease-out,
    visibility 0s;
}

.topbar-inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--size-3);
  min-height: 3.25rem;
}

.topbar-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--face-display);
  font-size: 1.0625rem;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink);
}

.topbar-brand .mark {
  height: 1.9rem;
}

.topbar-end {
  display: flex;
  align-items: center;
  gap: var(--size-2);
}

.topbar-store {
  padding: 0.45rem 0.2rem;
  font-family: var(--face-serif);
  font-size: var(--font-size-0);
  font-weight: var(--font-weight-6);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
  border-bottom: 1px solid var(--rule);
}

.topbar-store:hover {
  color: var(--umber);
}

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

/* A phone has no room for the name, the switch and the store link on one
   line: the name is left to screen readers and the house mark stays. */
@media (max-width: 30rem) {
  .topbar-brand span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .topbar .mode-option {
    padding-inline: 0.5rem;
  }
}

/* Main column */

.stack {
  display: flex;
  flex-direction: column;
  gap: 3.5rem;
}

.intro {
  display: flex;
  flex-direction: column;
  gap: var(--size-4);
}

.lede {
  max-width: 65ch;
  font-size: 1.125rem;
  line-height: 1.75rem;
  color: var(--ink-soft);
}

/* The doors */

.doors {
  scroll-margin-top: var(--size-5);
}

.doors-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--size-3);
  margin-bottom: var(--size-3);
}

.door-list li {
  border-bottom: 1px solid var(--rule);
}

.door {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 0.75rem;
  padding-block: var(--size-3);
  color: var(--ink);
  transition:
    background-color var(--ease-quick),
    color var(--ease-quick);
}

.door:hover {
  background-color: var(--paper-rise);
}

.door:active {
  scale: 0.96;
}

.door-index {
  font-family: var(--face-display);
  font-size: var(--font-size-3);
  line-height: 1.75rem;
  font-style: italic;
  color: var(--umber);
}

.door-name {
  display: block;
  font-family: var(--face-display);
  font-size: var(--font-size-4);
  line-height: 1;
}

.door-note {
  display: block;
  margin-top: var(--size-1);
  color: var(--ink-soft);
}

.door-arrow {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: var(--umber);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--ease-quick);
}

.door:hover .door-arrow,
.door:focus-visible .door-arrow {
  transform: translate(3px, -3px);
}

/* Current listings (Auction Nudge). The widget fills #auction-nudge-items with
   tables and inline sizes; the CSP drops those inline styles, so every
   dimension here comes from this file. */

.listings {
  margin-top: var(--size-5);
}

.listings > .kicker {
  margin-bottom: var(--size-3);
}

.auction-nudge:empty {
  min-height: 42rem;
}

.auction-nudge {
  color: var(--ink);
  font-size: var(--font-size-0);
}

.auction-nudge a {
  color: var(--ink);
}

.auction-nudge .an-ebay-top + div {
  margin-bottom: var(--size-3);
  color: var(--ink-soft);
  font-size: var(--font-size-00);
}

.an-controls-top {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: var(--size-2);
  margin-bottom: var(--size-3);
}

.an-cats-wrap {
  flex: 0 1 16rem;
}

.an-search-wrap {
  display: flex;
  flex: 1 1 14rem;
  gap: var(--size-2);
}

.an-cats-nav,
.an-search-box,
.an-search-submit {
  min-height: 2.75rem;
  border: 1px solid var(--rule);
  border-radius: 0;
  background-color: var(--paper-rise);
  color: var(--ink);
  font: inherit;
}

.an-cats-nav {
  width: 100%;
  padding-inline: var(--size-2);
}

.an-search-box {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.6rem var(--size-2);
  overflow: hidden;
  white-space: nowrap;
}

.an-search-submit {
  padding: 0.6rem var(--size-3);
  cursor: pointer;
  font-family: var(--face-display);
  letter-spacing: 0.04em;
  background-color: var(--ink);
  color: var(--paper-rise);
}

.an-search-submit:hover {
  background-color: var(--umber);
}

.an-page-wrap {
  display: flex;
  gap: var(--size-3);
  margin: 0 0 var(--size-3);
  padding: 0;
  list-style: none;
}

.an-page-bot {
  margin: var(--size-3) 0 0;
}

.an-page-prev,
.an-page-next {
  min-height: 2.75rem;
  padding: 0.6rem var(--size-3);
  border: 1px solid var(--rule);
  cursor: pointer;
  font-family: var(--face-display);
}

.an-page-prev:hover,
.an-page-next:hover {
  background-color: var(--paper-rise);
}

.an-page-wrap .an-inactive {
  opacity: 0.4;
  cursor: default;
}

.an-page-wrap .an-inactive:hover {
  background-color: transparent;
}

.an-item-wrap table,
.an-item-wrap tbody,
.an-item-wrap tr,
.an-item-wrap td {
  display: block;
  width: auto;
  padding: 0;
  border: 0;
}

.an-item-wrap table.grid > tbody {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--size-4) var(--size-3);
}

.an-item-wrap table.grid > tbody > tr {
  display: contents;
}

.an-item-wrap table.grid > tbody > tr > td > strong {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-bottom: var(--size-2);
  font-family: var(--face-display);
  font-weight: 500;
  line-height: 1.3;
  /* Two lines tall whether the title uses one or two, so rows line up. */
  min-height: 2.6em;
}

.an-item-wrap table.grid > tbody > tr > td > strong a {
  text-decoration: none;
}

.an-item-wrap .image-container,
.an-item-wrap .image-container a {
  display: block;
  width: 100%;
}

.an-item-wrap .image-container {
  aspect-ratio: 1;
  overflow: hidden;
  background-color: var(--paper-deep);
}

.an-item-wrap .image-container a {
  height: 100%;
}

.an-item-wrap .image-container img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.an-item-wrap .info {
  margin-top: var(--size-2);
}

.an-item-wrap .info a {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.listings-note,
.listings-more {
  margin-top: var(--size-3);
}

.listings-more a {
  font-family: var(--face-display);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

@media (min-width: 40rem) {
  .an-item-wrap table.grid > tbody {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  .an-item-wrap table.grid > tbody {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Footer */

.colophon {
  position: relative;
  z-index: 1;
  margin-top: var(--size-9);
}

.colophon-row {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding-block: var(--size-5);
}

.colophon-name {
  font-family: var(--face-display);
  font-size: var(--font-size-4);
  line-height: 1;
}

.colophon-line {
  display: block;
  max-width: 24rem;
  margin-top: var(--size-2);
  font-family: var(--face-serif);
  font-size: var(--font-size-1);
  line-height: 1.5rem;
  color: var(--ink-soft);
}

@media (min-width: 40rem) {
  h1 {
    font-size: var(--font-size-7);
  }

  .colophon-row {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }
}

/* Entrance */

.rise {
  animation: rise 560ms ease-out both;
}

.rise-2 {
  animation-delay: 90ms;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rise {
    animation: none;
    opacity: 1;
    transform: none;
  }

  .film-video,
  .topbar,
  .topbar.is-shown,
  .mode-option,
  .door,
  .door-arrow {
    transition: none;
  }

  .door:active {
    scale: 1;
  }
}

/* Legibility over the film. One class on <html> picks the variant:
   "legible-halo" (a paper-coloured glow behind the text, at every width,
   since the centred column also crosses the film on desktops) or
   "legible-panel" (a translucent paper panel behind the column, phones
   only). On a desktop the halo is lighter: there the column also has the
   veil's paper band behind it. */

.legible-halo .sheet :is(p, h1, h2, h3, li, .kicker, .brand, .door-name, .door-note, .door-index, .auction-nudge :is(strong, .info, .an-ebay-top + div)) {
  text-shadow:
    0 0 2px var(--paper),
    0 0 4px var(--paper),
    0 0 8px var(--paper),
    0 0 12px var(--paper),
    0 0 18px var(--paper),
    0 0 26px var(--paper);
}

@media (min-width: 64rem) and (min-aspect-ratio: 5/4) {
  .legible-halo .sheet :is(p, h1, h2, h3, li, .kicker, .brand, .door-name, .door-note, .door-index, .auction-nudge :is(strong, .info, .an-ebay-top + div)) {
    text-shadow:
      0 0 2px var(--paper),
      0 0 6px var(--paper),
      0 0 14px color-mix(in srgb, var(--paper) 70%, transparent);
  }
}

@media (max-width: 30rem) {
  .legible-panel .sheet {
    background: color-mix(in srgb, var(--paper) 78%, transparent);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    border-radius: var(--radius-3, 0.75rem);
    margin-inline: var(--size-2);
    padding-inline: var(--size-1);
  }
}
