/* Provenance Of
   Typography of the late 1920s: Jost (after Futura, 1927) for everything we
   say, Bodoni Moda (after Bauer Bodoni, 1926) for every title of a work. That
   one rule replaces italics: a book's name is always set in the didone, in
   running text, in the tree, on the cards. No italics anywhere.
   Cool archival paper, ink, and one accent, lapis, for the thing being
   pointed at. Covers carry the colour; where a work has no cover, a
   typographic plate tinted by era stands in. */

/* Both families are OFL, vendored in app/assets/fonts and installed in the
   production image so the share cards match the page. */
@font-face {
  font-family: "Jost";
  src: url("/assets/jost-var-fd217326.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bodoni Moda";
  src: url("/assets/bodonimoda-var-52134b04.ttf") format("truetype");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --paper: #f3f2ee;
  --paper-2: #e9e7e1;
  --ink: #1f1d1a;
  --ink-2: #5c5751;
  --rule: #cfcbc2;
  --lapis: #1f3a93;
  --lapis-2: #4b63b8;
  --lapis-soft: rgba(31, 58, 147, 0.1);
  --sans: "Jost", "Futura", "Century Gothic", "Avenir Next", sans-serif;
  --didone: "Bodoni Moda", "Bodoni 72", "Didot", "Bodoni MT", serif;
  --measure: 64ch;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  /* Plate colours by era, for works without a cover. */
  --era-ancient: #8a3b2e;
  --era-medieval: #2f5d4e;
  --era-renaissance: #22408f;
  --era-enlightenment: #5a3a5e;
  --era-nineteenth: #7d5d1c;
  --era-modern: #234a55;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #15181f;
    --paper-2: #1d2129;
    --ink: #ebe8e1;
    --ink-2: #9c988f;
    --rule: #333843;
    --lapis: #8ca6ff;
    --lapis-2: #6f89e8;
    --lapis-soft: rgba(140, 166, 255, 0.14);
  }
}

* { box-sizing: border-box; }

html { background: var(--paper); }

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
}

/* The body is a column flexbox (for the sticky footer); a main with auto
   margins would otherwise size to its max-width rather than the viewport. */
body > main { width: 100%; }

a { color: var(--lapis); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--lapis-2); }
:focus-visible { outline: 2px solid var(--lapis); outline-offset: 3px; border-radius: 2px; }

h1, h2, h3 { font-weight: 500; margin: 0; line-height: 1.15; text-wrap: balance; }
p { margin: 0 0 1em; }

/* The house rule: titles of works are Bodoni, upright. */
cite, .title {
  font-family: var(--didone);
  font-style: normal;
  font-weight: 500;
  font-optical-sizing: auto;
  letter-spacing: 0;
}
.num { font-variant-numeric: lining-nums tabular-nums; }

button, .button, input[type="text"], input[type="search"] {
  font: inherit;
  color: inherit;
}

/* ---- Chrome ------------------------------------------------------------ */

.site-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 1.1rem var(--gutter) 0.9rem;
  border-bottom: 1px solid var(--rule);
}
/* The wordmark: the one place for Deco tracking. */
.site-name {
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
}
.site-nav { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.2rem 1.4rem; }
.site-nav a, .site-nav .nav-button { color: var(--ink-2); text-decoration: none; }
.site-nav .nav-button { border: 0; background: none; padding: 0; cursor: pointer; }
.site-nav .nav-button:hover { color: var(--ink); }
.site-nav a:hover { color: var(--ink); }

.flash {
  margin: 0;
  padding: 0.75rem var(--gutter);
  background: var(--lapis-soft);
  color: var(--ink);
}

.site-foot {
  margin-top: auto;
  padding: 2.5rem var(--gutter) 3rem;
  border-top: 1px solid var(--rule);
  color: var(--ink-2);
  font-size: 0.9rem;
  max-width: calc(var(--measure) + 2 * var(--gutter));
}
.site-foot p:last-child { margin-bottom: 0; }

/* ---- Home -------------------------------------------------------------- */

.home {
  padding: clamp(3rem, 11vh, 7rem) var(--gutter) 4rem;
  max-width: 60rem;
  margin: 0 auto;
}
.home-intro { max-width: 40rem; }
/* The headline is the Deco moment: high-contrast Bodoni at display size. */
.home-lede {
  font-family: var(--didone);
  font-weight: 600;
  font-size: clamp(2.6rem, 8vw, 4.75rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
  margin-bottom: 0.4em;
}
.home-sub {
  font-size: 1.2rem;
  font-weight: 350;
  color: var(--ink-2);
  max-width: 34rem;
  margin-bottom: 2.25rem;
}

.search {
  display: flex;
  border-bottom: 2px solid var(--ink);
  margin-bottom: 1rem;
  max-width: 40rem;
}
.search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  padding: 0.5rem 0;
  font-family: var(--didone);
  font-size: 1.75rem;
  font-weight: 500;
}
.search input::placeholder { color: var(--ink-2); opacity: 0.7; }
.search input:focus { outline: none; }
.search button {
  border: 0;
  background: transparent;
  padding: 0.5rem 0 0.5rem 1rem;
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--lapis);
  cursor: pointer;
  white-space: nowrap;
}
.search button:hover { color: var(--lapis-2); }

.examples {
  color: var(--ink-2);
  font-size: 0.98rem;
  max-width: 40rem;
  margin-bottom: 3.75rem;
}
.examples form { display: inline; }
.examples button {
  border: 0;
  background: none;
  padding: 0;
  color: var(--lapis);
  font-family: var(--didone);
  font-weight: 500;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

/* The shelf: finished lineages, face out. */
.shelf { margin-bottom: 3rem; }
.shelf h2 { font-size: 1rem; font-weight: 500; color: var(--ink-2); margin-bottom: 1rem; }
.shelf ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.25rem, 1fr));
  gap: 1.75rem 1.25rem;
}
.shelf li a { display: block; color: var(--ink); text-decoration: none; }
.shelf .cover-box { margin-bottom: 0.6rem; }
.shelf li a:hover .cover-box > * { outline: 2px solid var(--lapis); outline-offset: 3px; }
.shelf .shelf-title { display: block; font-size: 1.05rem; line-height: 1.25; }
.shelf .meta { display: block; color: var(--ink-2); font-size: 0.85rem; margin-top: 0.2rem; line-height: 1.4; }

/* ---- Covers and plates --------------------------------------------------- */

/* Every cover gets a 2:3 space so a shelf of mixed editions lines up, but is
   shown whole at its own proportions inside it, never cropped. On the shelf
   covers stand on a common baseline, like books; on a card they hang from
   the top. The shadow belongs to the cover, not the space. */
.cover-box {
  aspect-ratio: 2 / 3;
  width: 100%;
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* The plate inside is sized in units of this box's width (cqi). */
  container-type: inline-size;
}
.shelf .cover-box { align-items: flex-end; }
.cover-box img,
.cover-box .plate {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 6px 14px -8px rgba(0, 0, 0, 0.35);
}
.cover-box img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  background: var(--paper-2);
}

/* No cover: a plate in the manner of a 1930s cloth binding, tinted by era,
   with a thin double frame. Sized with container units so it reads at any
   width, from the shelf to the card. */
.plate {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 7cqi;
  width: 100%;
  height: 100%;
  padding: 16cqi 12cqi;
  text-align: center;
  color: #f3f0e8;
  background: var(--plate, var(--era-modern));
  box-shadow:
    inset 0 0 0 4cqi var(--plate, var(--era-modern)),
    inset 0 0 0 calc(4cqi + 1px) rgba(243, 240, 232, 0.7),
    inset 0 0 0 7cqi var(--plate, var(--era-modern)),
    inset 0 0 0 calc(7cqi + 1px) rgba(243, 240, 232, 0.45),
    0 1px 2px rgba(0, 0, 0, 0.18), 0 6px 14px -8px rgba(0, 0, 0, 0.35);
}
.plate-title {
  font-family: var(--didone);
  font-weight: 600;
  font-size: 13cqi;
  line-height: 1.08;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.plate-rule { width: 22cqi; height: 1px; background: currentColor; opacity: 0.7; }
.plate-author { font-size: 8.5cqi; font-weight: 400; letter-spacing: 0.04em; opacity: 0.9; line-height: 1.25; }
.plate.era-ancient { --plate: var(--era-ancient); }
.plate.era-medieval { --plate: var(--era-medieval); }
.plate.era-renaissance { --plate: var(--era-renaissance); }
.plate.era-enlightenment { --plate: var(--era-enlightenment); }
.plate.era-nineteenth { --plate: var(--era-nineteenth); }
.plate.era-modern { --plate: var(--era-modern); }

/* ---- Candidates -------------------------------------------------------- */

.candidates {
  padding: 3rem var(--gutter) 4rem;
  max-width: 44rem;
  margin: 0 auto;
}
.candidates h1 { font-family: var(--didone); font-weight: 600; font-size: 2.2rem; margin-bottom: 0.3em; }
.candidates .lede { color: var(--ink-2); margin-bottom: 1.5rem; }
.candidates ol { list-style: none; margin: 0; padding: 0; }
.candidates li { border-top: 1px solid var(--rule); }
.candidates li:last-child { border-bottom: 1px solid var(--rule); }
.candidates button {
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  padding: 0.9rem 0;
  cursor: pointer;
}
.candidates button:hover .cand-title { color: var(--lapis); }
.cand-title { font-size: 1.4rem; }
.cand-by { color: var(--ink-2); }
.cand-desc { margin: 0.15rem 0 0; color: var(--ink-2); font-size: 0.95rem; }
.candidates .again { margin-top: 1.5rem; color: var(--ink-2); }

/* ---- Waiting / failed / busy ------------------------------------------- */

.waiting {
  padding: 3rem var(--gutter) 4rem;
  max-width: 44rem;
  margin: 0 auto;
}
.waiting h1 { font-family: var(--didone); font-weight: 600; font-size: clamp(2.2rem, 7vw, 3.25rem); margin-bottom: 0.2em; }
.waiting .by { color: var(--ink-2); font-size: 1.15rem; margin-bottom: 2rem; }
.waiting-line {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: 1.25rem;
  align-items: start;
}
.waiting-line svg { width: 2.5rem; height: 16rem; overflow: visible; }
.waiting-line .grow {
  stroke: var(--lapis);
  stroke-width: 1.5;
  stroke-dasharray: 240;
  stroke-dashoffset: 240;
  animation: grow 150s linear forwards;
}
.waiting-line .tick { stroke: var(--rule); stroke-width: 1; }
.waiting-line .root { fill: var(--ink); }
@keyframes grow { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) {
  .waiting-line .grow { animation: none; stroke-dashoffset: 0; }
}
.waiting-text p { max-width: 34rem; }
.waiting-text .status { font-weight: 500; color: var(--lapis); min-height: 1.6em; }
.waiting-text .small { color: var(--ink-2); font-size: 0.95rem; }

.button {
  display: inline-block;
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: transparent;
  padding: 0.45rem 1rem;
  text-decoration: none;
  color: var(--ink);
  font-weight: 500;
  cursor: pointer;
}
.button:hover { background: var(--paper-2); color: var(--ink); }

/* ---- Viewer ------------------------------------------------------------ */

.viewer { padding: 2.25rem var(--gutter) 5rem; }

/* Running head: small, quiet. The card below carries the large type. */
.running-head {
  max-width: calc(300px + 2rem + var(--measure));
  margin: 0 auto 1.75rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--rule);
}
.running-head h1 { font-size: 1.1rem; font-weight: 400; color: var(--ink-2); margin-bottom: 0.15rem; }
.running-head h1 cite { color: var(--ink); font-size: 1.12em; }
.running-head .stats { font-size: 0.95rem; color: var(--ink-2); margin: 0; max-width: var(--measure); }

.viewer-body {
  max-width: calc(300px + 2rem + var(--measure));
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem 2rem;
}
@media (min-width: 60rem) {
  .viewer-body { grid-template-columns: 300px minmax(0, var(--measure)); align-items: start; }
}

/* The tree. Sticky beside the reading column on wide screens; on narrow
   ones it hides behind the "tree" control in the step bar. */
.stemma {
  position: sticky;
  top: 1rem;
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  scrollbar-width: thin;
  padding-right: 0.25rem;
}
.stemma svg { width: 100%; height: auto; display: block; }
.stemma .edge { fill: none; stroke: var(--ink-2); stroke-opacity: 0.6; stroke-linecap: round; }
.stemma .edge.disputed { stroke-dasharray: 3 3; }
.stemma .edge.on-thread { stroke: var(--lapis); stroke-opacity: 1; }
.stemma .node { cursor: pointer; }
.stemma .node:focus { outline: none; }
/* The whole row is the target; it shows only when pointed at or current. */
.stemma .node .hit { fill: transparent; }
.stemma .node:is(:hover, :focus-visible) .hit { fill: var(--paper-2); }
.stemma .node[aria-current="step"] .hit { fill: var(--lapis-soft); }
.stemma .node .dot { fill: var(--paper); stroke: var(--ink); stroke-width: 1.4; }
.stemma .node.terminal .dot,
.stemma .node.root .dot { fill: var(--ink); }
.stemma .node[aria-current="step"] .dot { fill: var(--lapis); stroke: var(--lapis); }
.stemma .node text { font-size: 12.5px; fill: var(--ink); }
.stemma .node .t { font-family: var(--didone); font-weight: 500; }
.stemma .node .yr { font-family: var(--sans); fill: var(--ink-2); font-size: 10.5px; }
.stemma .node[aria-current="step"] .t { fill: var(--lapis); }
.stemma .node.off-thread text { fill: var(--ink-2); }
.stemma a { text-decoration: none; }
.stemma-note { color: var(--ink-2); font-size: 0.85rem; margin: 0.5rem 0 0; }
.reading { scroll-margin-top: 1rem; }
@media (max-width: 59.98rem) {
  /* On a phone the tree waits behind "Show the tree" and opens above the
     card, full width. */
  .stemma { position: static; max-height: none; display: none; padding: 0.5rem 0 1rem; border-bottom: 1px solid var(--rule); }
  .stemma.is-open { display: block; }
}

/* Steps: every work rendered; one shown at a time. */
.steps { list-style: none; margin: 0; padding: 0; }
.step[hidden] { display: none; }
.step-article { max-width: var(--measure); }

/* Cover beside the work's name. */
.step-head {
  display: grid;
  grid-template-columns: clamp(5.5rem, 22vw, 8rem) minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
  margin-bottom: 1.4rem;
}
.step-year { font-size: 0.95rem; color: var(--ink-2); margin-bottom: 0.25rem; }
.step-title {
  font-family: var(--didone);
  font-weight: 600;
  font-size: clamp(1.75rem, 5.5vw, 2.6rem);
  line-height: 1.08;
  margin-bottom: 0.3em;
}
.step-by { font-size: 1.15rem; margin-bottom: 0.15rem; }
.step-where { color: var(--ink-2); font-size: 0.95rem; margin: 0; }
.step-blurb { margin-bottom: 1.5rem; }

.handed h2, .drew h2 {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ink-2);
  border-top: 1px solid var(--rule);
  padding-top: 0.9rem;
  margin: 1.75rem 0 0.75rem;
}
.handed h3 { font-size: 1.05rem; font-weight: 400; margin-bottom: 0.1rem; }
.handed h3 cite { font-size: 1.12em; }
.handed .kind { color: var(--ink-2); font-size: 0.92rem; margin-bottom: 0.4rem; }
.handed .kind.low { color: var(--ink-2); }
.handed article { margin-bottom: 1.4rem; }
.handed p { max-width: var(--measure); }

.drew ul { list-style: none; margin: 0; padding: 0; }
.drew li { padding: 0.4rem 0; display: flex; flex-wrap: wrap; gap: 0.25rem 0.9rem; align-items: baseline; }
.drew li a.go { color: var(--ink); text-decoration: none; }
.drew li a.go cite { font-size: 1.12rem; }
.drew li a.go:hover cite { text-decoration: underline; text-decoration-thickness: 1px; }
.drew li .yr { color: var(--ink-2); font-size: 0.92rem; }
.drew li .thread { font-size: 0.9rem; }
.drew .stops { color: var(--ink-2); }

.step-actions { margin-top: 1.75rem; display: flex; gap: 1rem 1.5rem; flex-wrap: wrap; align-items: baseline; }
.step-actions .amazon { font-size: 0.95rem; }

/* Step bar: inline on wide screens, pinned to the bottom on phones. */
.stepbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}
.stepbar .counter { color: var(--ink-2); text-align: center; margin: 0; }
.stepbar a, .stepbar button {
  color: var(--ink);
  text-decoration: none;
  border: 0;
  background: none;
  padding: 0.25rem 0;
  cursor: pointer;
  font-size: 1.05rem;
  font-weight: 500;
}
.stepbar a:hover, .stepbar button:hover { color: var(--lapis); }
.stepbar .older { text-align: right; }
.stepbar .is-disabled { color: var(--rule); pointer-events: none; }
.stepbar .tree-toggle { display: none; font-size: 0.9rem; font-weight: 400; color: var(--ink-2); }
@media (max-width: 59.98rem) {
  .viewer { padding-bottom: 7rem; }
  .stepbar {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    margin: 0;
    padding: 0.6rem var(--gutter) calc(0.6rem + env(safe-area-inset-bottom, 0px));
    background: var(--paper);
    border-top: 1px solid var(--rule);
    z-index: 2;
  }
  .stepbar .tree-toggle { display: inline; }
}

.thread-crumb {
  color: var(--ink-2);
  font-size: 0.95rem;
  margin-bottom: 1.25rem;
}
.thread-crumb a { margin-left: 0.5rem; }

/* Share */
.share {
  max-width: calc(300px + 2rem + var(--measure));
  margin: 3rem auto 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
}
@media (min-width: 60rem) { .share { padding-left: calc(300px + 2rem); } }
.share h2 { font-size: 0.95rem; font-weight: 500; color: var(--ink-2); margin-bottom: 0.5rem; }
.share ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem; }
.share a, .share button {
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--lapis); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.18em;
}
.share .card-preview { margin-top: 1rem; max-width: 30rem; }
.share .card-preview img { width: 100%; height: auto; display: block; border: 1px solid var(--rule); }

/* ---- About ------------------------------------------------------------- */
.prose { padding: 3rem var(--gutter) 4rem; max-width: calc(var(--measure) + 2 * var(--gutter)); margin: 0 auto; }
.prose h1 { font-family: var(--didone); font-weight: 600; font-size: 2.6rem; margin-bottom: 0.5em; }
.prose h2 { font-size: 1.2rem; margin: 1.75rem 0 0.5rem; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation-duration: 0.001s !important; }
}

/* ---- Small shared pieces ------------------------------------------------ */

/* A form that sits in a line of text or a row of actions. */
form.inline { display: inline; }
/* A button that reads as a link (it posts, so it cannot be one). */
button.linkish {
  border: 0;
  background: none;
  padding: 0;
  color: var(--lapis);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
button.linkish:hover { color: var(--lapis-2); }

/* The one solid button on the site: the way to the work itself. */
.amazon-button, .primary-button {
  display: inline-block;
  border: 0;
  background: var(--lapis);
  color: var(--paper);
  padding: 0.5rem 1.1rem;
  border-radius: 2px;
  text-decoration: none;
  font-weight: 500;
  letter-spacing: 0.01em;
  cursor: pointer;
}
.amazon-button:hover, .primary-button:hover { background: var(--lapis-2); color: var(--paper); }

.step-actions .linkish { font-size: 0.95rem; }

/* ---- Home: the one form, an example, how it works ----------------------- */

/* Says what the site is before the headline asks its question. */
.home-kicker {
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: 1rem;
}

/* The form: a labelled field and a solid button, so there is no doubt where
   to type or what happens next. */
.ask { max-width: 40rem; margin-bottom: 0.9rem; }
.ask label { display: block; font-weight: 500; margin-bottom: 0.5rem; }
.ask-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.ask input[type="text"] {
  flex: 1 1 16rem;
  min-width: 0;
  background: transparent;
  border: 1px solid var(--ink-2);
  border-radius: 2px;
  padding: 0.6rem 0.85rem;
  font-family: var(--didone);
  font-size: 1.35rem;
  font-weight: 500;
}
.ask input[type="text"]::placeholder { color: var(--ink-2); opacity: 0.6; }
.ask input[type="text"]:focus { outline: 2px solid var(--lapis); outline-offset: 1px; border-color: var(--lapis); }
.ask .primary-button { padding: 0.6rem 1.4rem; font-size: 1.08rem; }
.ask-note { color: var(--ink-2); font-size: 0.95rem; max-width: 40rem; margin-bottom: 0.6rem; }
.home .examples { margin-bottom: 3.5rem; }
/* On the lineage page the note is the last thing before the shelves. */
.home-intro > .ask-note:last-child { margin-bottom: 3.5rem; }

.sample { max-width: 46rem; margin-bottom: 3rem; }
.sample h2, .how h2 {
  font-family: var(--didone);
  font-weight: 600;
  font-size: 1.6rem;
  margin-bottom: 0.5rem;
}
.sample .pick:last-child { border-bottom: 1px solid var(--rule); }
.sample-more { color: var(--ink-2); font-size: 0.95rem; margin-top: 1rem; }

.how { max-width: 40rem; margin-bottom: 3rem; }
.how-steps { margin: 0.75rem 0 0; padding-left: 1.3rem; color: var(--ink-2); }
.how-steps li { margin-bottom: 0.8rem; padding-left: 0.3rem; }
.how-steps strong { color: var(--ink); font-weight: 500; }

.elsewhere { color: var(--ink-2); border-top: 1px solid var(--rule); padding-top: 2rem; max-width: 40rem; }
.elsewhere h2 { font-family: var(--didone); font-weight: 600; font-size: 1.6rem; color: var(--ink); margin-bottom: 0.5rem; }
.elsewhere p:last-child { margin-bottom: 0; }

/* ---- A visitor's page: shelf, keeping it, picks, rated ------------------- */

.profile {
  padding: 2.5rem var(--gutter) 4rem;
  max-width: 60rem;
  margin: 0 auto;
}
.profile-head { max-width: 40rem; margin-bottom: 2.25rem; }
.profile-head h1 {
  font-family: var(--didone);
  font-weight: 600;
  font-size: clamp(2.1rem, 6.5vw, 3.25rem);
  line-height: 1.05;
  margin-bottom: 0.4em;
}
.profile-head .lede { color: var(--ink-2); font-size: 1.1rem; margin: 0; }
.profile h2 { font-size: 1rem; font-weight: 500; color: var(--ink-2); margin-bottom: 1rem; }
.profile .empty { color: var(--ink-2); max-width: 36rem; }

/* The shelf of favorites: the home page's shelf, with each one's status. */
.shelf.mine { margin-bottom: 2.5rem; }
.shelf.mine li { display: block; }
/* A visitor's own favorites are the input, not the show: smaller than the
   recommendations below them, so thirty of them still leave those in reach. */
.shelf.mine ol { grid-template-columns: repeat(auto-fill, minmax(6.25rem, 1fr)); gap: 1.5rem 1rem; max-width: 80rem; }
.shelf.mine .shelf-title { font-size: 0.95rem; }
.shelf.mine .meta { font-size: 0.8rem; }
.shelf-full { color: var(--ink-2); margin: 1.5rem 0 0; }
.shelf-status { display: block; font-size: 0.85rem; color: var(--ink-2); margin-top: 0.2rem; }
.shelf-status.is-pending { color: var(--lapis); }
@media (prefers-reduced-motion: no-preference) {
  .shelf-status.is-pending { animation: breathe 2.4s ease-in-out infinite; }
}
@keyframes breathe { 50% { opacity: 0.45; } }
.shelf-actions { display: flex; flex-wrap: wrap; gap: 0.1rem 0.75rem; margin-top: 0.25rem; }
.shelf-actions button { white-space: nowrap; }
.shelf-actions form { display: inline; }
.shelf-actions button, .rated-actions button {
  border: 0;
  background: none;
  padding: 0;
  font-size: 0.85rem;
  color: var(--ink-2);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.shelf-actions button:hover, .rated-actions button:hover { color: var(--lapis); }
.search.add { margin: 1.75rem 0 0; max-width: 30rem; border-bottom-width: 1px; }
.search.add input { font-size: 1.3rem; }

.keep {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 1.5rem 0;
  margin-bottom: 2.5rem;
  max-width: 40rem;
}
/* After the picks (nothing pending), it closes the list instead. */
.picks-section + .keep { margin-top: 2.5rem; }
.picks .pick:last-child { border-bottom: 1px solid var(--rule); }
.picks-section + .keep { border-top: 0; }
.keep h2 { color: var(--ink); font-size: 1.1rem; margin-bottom: 0.3rem; }
.keep p { color: var(--ink-2); margin-bottom: 0.9rem; }
.keep-form { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 1rem; }
.keep-form input[type="email"] {
  flex: 1 1 14rem;
  min-width: 0;
  font: inherit;
  color: inherit;
  background: transparent;
  border: 1px solid var(--ink-2);
  border-radius: 2px;
  padding: 0.45rem 0.7rem;
}
.keep-form input[type="email"]:focus { outline: 2px solid var(--lapis); outline-offset: 1px; border-color: var(--lapis); }
.keep-form button {
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: transparent;
  padding: 0.45rem 1rem;
  font-weight: 500;
  cursor: pointer;
}
.keep-form button:hover { background: var(--paper-2); }
/* The field only a bot fills in: off the page, not display:none (which some
   bots skip). */
.hp { position: absolute; left: -200vw; width: 1px; height: 1px; overflow: hidden; }
.keep-link { font-size: 0.9rem; margin: 0; }
.keep-link .address { display: block; color: var(--ink); overflow-wrap: anywhere; margin: 0.15rem 0; }
.keep-link button {
  border: 0;
  background: none;
  padding: 0;
  color: var(--lapis);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.pick-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  margin-bottom: 0.5rem;
  font-size: 0.95rem;
}
.pick-filters span { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; }
.pick-filters a { color: var(--ink-2); text-decoration: none; padding-bottom: 0.1rem; border-bottom: 1px solid transparent; }
.pick-filters a:hover { color: var(--ink); }
.pick-filters a.is-on { color: var(--ink); border-bottom-color: var(--ink); }

.picks { list-style: none; margin: 0; padding: 0; }
.pick {
  display: grid;
  grid-template-columns: clamp(5rem, 20vw, 8rem) minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
  padding: 1.75rem 0;
  border-top: 1px solid var(--rule);
  /* A link from the email lands here; leave air above it. */
  scroll-margin-top: 1rem;
}
.pick:target { background: linear-gradient(var(--lapis-soft), var(--lapis-soft)) no-repeat 0 0 / 3px 100%; padding-left: 1rem; }
.pick-body { max-width: var(--measure); }
.pick-label { font-size: 0.82rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2); margin-bottom: 0.3rem; }
.pick-label cite { letter-spacing: 0; text-transform: none; font-size: 1.15em; color: var(--ink); }
.pick-title {
  font-family: var(--didone);
  font-weight: 600;
  font-size: clamp(1.45rem, 4.5vw, 2rem);
  line-height: 1.1;
  margin-bottom: 0.2em;
}
.pick-by { color: var(--ink-2); margin-bottom: 0.75rem; }
.pick-why { margin-bottom: 0.5rem; }
.pick-pitch { color: var(--ink-2); margin-bottom: 0; }
.pick-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.5rem; margin-top: 1.1rem; }
.pick-actions .linkish { font-size: 0.95rem; }
.rate { display: flex; flex-wrap: wrap; gap: 0.4rem 0.5rem; margin-top: 0.9rem; }
.rate button {
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: transparent;
  padding: 0.2rem 0.65rem;
  font-size: 0.88rem;
  color: var(--ink-2);
  cursor: pointer;
}
.rate button:hover { border-color: var(--ink); color: var(--ink); }

.rated { margin-top: 2.5rem; border-top: 1px solid var(--rule); padding-top: 1rem; max-width: 44rem; }
.rated summary { cursor: pointer; color: var(--ink-2); }
.rated ul { list-style: none; margin: 0.75rem 0 0; padding: 0; }
.rated li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.25rem 1.5rem; padding: 0.4rem 0; }
.rated .said { color: var(--ink-2); }
.rated-actions { display: flex; gap: 1rem; }
.rated-actions form { display: inline; }

/* ---- Waiting on a trace -------------------------------------------------- */

/* The wait must look like work: a bar that moves, a line that changes. */
.working {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--lapis);
  padding: 1.1rem 1.25rem 1.2rem;
  margin-bottom: 2.25rem;
  max-width: 40rem;
  background: var(--lapis-soft);
}
.profile .working h2 { color: var(--ink); font-size: 1.15rem; margin-bottom: 0.85rem; }
.working h2 cite { font-size: 1.1em; }
.working .dots i { font-style: normal; opacity: 0.2; }
.progress { height: 4px; background: var(--rule); border-radius: 2px; overflow: hidden; margin-bottom: 0.85rem; }
.progress span { display: block; height: 100%; width: 6%; background: var(--lapis); border-radius: 2px; }
.working-status { color: var(--lapis); font-weight: 500; margin-bottom: 0.3rem; min-height: 1.6em; }
.working-note { color: var(--ink-2); font-size: 0.95rem; margin: 0; }
@media (prefers-reduced-motion: no-preference) {
  /* Fast at first, slowing toward the end: most finish in 60-80s and the
     bar should never reach the end before the page changes. */
  .progress span { animation: fill 130s cubic-bezier(0.2, 0.7, 0.3, 1) forwards; }
  .working .dots i { animation: dot 1.4s infinite; }
  .working .dots i:nth-child(2) { animation-delay: 0.2s; }
  .working .dots i:nth-child(3) { animation-delay: 0.4s; }
  .ph { animation: breathe 1.6s ease-in-out infinite; }
  .shelf-status.is-pending::before { animation: spin 0.9s linear infinite; }
}
@media (prefers-reduced-motion: reduce) { .progress span { width: 60%; } }
@keyframes fill { from { width: 4%; } to { width: 96%; } }
@keyframes dot { 0%, 60%, 100% { opacity: 0.2; } 30% { opacity: 1; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* A small turning ring beside a favorite that is being traced. */
.shelf-status.is-pending::before {
  content: "";
  display: inline-block;
  width: 0.7em;
  height: 0.7em;
  margin-right: 0.4em;
  border: 1.5px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  vertical-align: -0.05em;
}
/* The ring turns; the text beside it no longer needs to pulse. */
.shelf-status.is-pending { animation: none; }

/* Empty rows where the picks will be. */
.picks.placeholder .pick { border-bottom: 0; }
.ph { background: var(--paper-2); border-radius: 2px; }
.ph-cover { aspect-ratio: 2 / 3; width: 100%; }
.ph-line { height: 0.85rem; margin-bottom: 0.7rem; max-width: 28rem; }
.ph-line.short { width: 9rem; height: 0.65rem; }
.ph-line.title { height: 1.5rem; width: 16rem; max-width: 80%; margin-bottom: 1rem; }

/* ---- Recommendations as a grid (wide screens) ---------------------------- */

/* The title of a pick is a button, for opening its card from the keyboard;
   it reads as the title it is. */
.pick-more {
  border: 0;
  background: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: inherit;
  line-height: inherit;
  cursor: text;
  user-select: text;
}

@media (min-width: 60rem) {
  /* The list page may use the whole window; its paragraphs keep their own
     measures, and the grid takes the rest. */
  .profile { max-width: 112rem; }

  .picks.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr));
    gap: 2.75rem 1.75rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--rule);
  }
  .picks.grid .pick {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    padding: 0;
    border: 0;
    cursor: pointer;
    min-width: 0;
  }
  .picks.grid .pick:last-child { border-bottom: 0; }
  .picks.grid .pick:target { background: none; padding-left: 0; }
  .picks.grid .pick:target .cover-box > * { outline: 2px solid var(--lapis); outline-offset: 3px; }
  /* Covers stand on a common baseline, as on a shelf. Every card's cover
     space is the same 2:3, whatever the image's own shape: without the
     min-height a tall image would stretch its space and push its card's
     text out of line with its neighbours'. */
  .picks.grid .cover-box { align-items: flex-end; flex: none; min-height: 0; }
  .picks.grid .pick:hover .cover-box > * { outline: 2px solid var(--lapis); outline-offset: 3px; }
  .picks.grid .pick-body { display: flex; flex-direction: column; flex: 1; max-width: none; }
  .picks.grid .pick-label { font-size: 0.72rem; letter-spacing: 0.12em; margin-bottom: 0.3rem; }
  .picks.grid .pick-title { font-size: 1.3rem; line-height: 1.15; margin-bottom: 0.15em; }
  .picks.grid .pick-more { cursor: pointer; }
  .picks.grid .pick:hover .pick-title { color: var(--lapis); }
  .picks.grid .pick-by { font-size: 0.9rem; margin-bottom: 0; }
  /* The rest waits in the dialog. */
  .picks.grid .pick-why,
  .picks.grid .pick-pitch,
  .picks.grid .rate,
  .picks.grid .pick-actions form { display: none; }
  /* The way to the work stays on the card, at its foot. */
  .picks.grid .pick-actions { margin-top: auto; padding-top: 0.8rem; }
  .picks.grid .amazon-button { font-size: 0.92rem; padding: 0.4rem 0.85rem; }
}

/* The dialog a card opens. */
.pick-dialog {
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 0;
  width: min(48rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.55);
}
.pick-dialog::backdrop { background: rgba(10, 12, 16, 0.62); }
.pick-dialog-panel { position: relative; padding: 2.25rem 2.25rem 2rem; }
.pick-dialog-close {
  position: absolute;
  top: 0.9rem;
  right: 1.1rem;
  border: 0;
  background: none;
  padding: 0.2rem;
  color: var(--ink-2);
  font-size: 0.9rem;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.pick-dialog-close:hover { color: var(--ink); }
.pick.in-dialog {
  grid-template-columns: clamp(8rem, 30%, 13rem) minmax(0, 1fr);
  gap: 1.75rem;
  padding: 0;
  border: 0;
}
.pick.in-dialog .cover-box { align-items: flex-start; }
.pick.in-dialog .pick-title { font-size: clamp(1.6rem, 3.5vw, 2.2rem); padding-right: 3rem; }
.pick.in-dialog .pick-more { cursor: text; }
.pick.in-dialog .pick-why { font-size: 1.08rem; }
