/* ============================================================
   Plants Whisperer — Catalog page (Herbarium Folio)
   Loaded after identity-v2.css; catalog.html only.
   The rail is a typeset magazine index — no boxes, no widgets.
   ============================================================ */

/* ---------- page frame ---------- */
.catalog {
  background: var(--archive-paper);
  border-bottom: 1px solid var(--archive-line);
}

.cat-wrap {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 34px 110px;
}

/* ---------- masthead ---------- */
.cat-masthead {
  padding: 46px 0 30px;
  border-bottom: 1px solid var(--archive-line);
}

.cat-notation {
  display: block;
  margin-bottom: 18px;
  color: var(--archive-clay-deep);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.64rem;
  letter-spacing: 0.08em;
}

.cat-masthead h1 {
  margin: 0 0 12px;
  color: var(--archive-ink);
  font-size: clamp(3.4rem, 6vw, 6.4rem);
  font-weight: 500;
  line-height: 0.9;
  letter-spacing: -0.045em;
}

.cat-mast-count {
  margin: 0 0 10px;
  color: var(--archive-ink-soft);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
}

.cat-statement {
  max-width: 560px;
  margin: 0;
  color: var(--archive-ink-soft);
  font-size: 0.9rem;
  line-height: 1.9;
}

/* ---------- layout: rail + main ---------- */
.cat-layout {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  gap: 0 40px;
  align-items: start;
  padding-top: 34px;
}

/* ---------- index rail (desktop) ---------- */
.cat-rail {
  position: sticky;
  top: calc(var(--pw-nav-h, 64px) + 20px);
  max-height: calc(100dvh - var(--pw-nav-h, 64px) - 40px);
  overflow-y: auto;
  scrollbar-width: none;
  padding-inline-end: 24px;
  border-inline-end: 1px solid var(--archive-line);
}
.cat-rail::-webkit-scrollbar { display: none; }

.rail-caption {
  margin-bottom: 20px;
  color: var(--archive-clay-deep);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.14em;
}

.rail-group {
  margin: 22px 0 4px;
  color: var(--archive-ink-soft);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.56rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.7;
}
.rail-group:first-of-type { margin-top: 0; }

.rail-sec {
  padding: 14px 0;
  border-bottom: 1px solid var(--archive-line-soft);
}
.rail-slot .rail-sec:last-child { border-bottom: 0; }

.rail-h {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 10px;
  color: var(--archive-ink);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0;
}

.rail-num {
  color: var(--archive-clay-deep);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6rem;
  font-weight: 400;
}

/* search drawn as an index line, not a widget */
.rail-search-wrap input {
  width: 100%;
  padding: 8px 2px;
  color: var(--archive-ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--archive-line);
  border-radius: 0;
  font-family: inherit;
  font-size: 0.85rem;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.rail-search-wrap input:focus-visible {
  border-bottom-color: var(--archive-clay);
  box-shadow: 0 1px 0 var(--archive-clay);
}
.rail-search-wrap input::placeholder { color: var(--archive-ink-soft); opacity: 0.7; }
.rail-search-wrap input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* index rows with leader dots */
.rail-rows { display: flex; flex-direction: column; }

.rail-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 10px 6px;
  color: var(--archive-ink-soft);
  background: transparent;
  border: 0;
  border-radius: 0;
  font-family: inherit;
  font-size: 0.8rem;
  text-align: start;
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease,
              scale 130ms cubic-bezier(.22, .9, .24, 1);
}
.rail-row:hover { color: var(--archive-ink); }
.rail-row.active {
  color: var(--archive-paper);
  background: var(--archive-ink);
}
.rail-row:focus-visible {
  outline: 2px solid var(--archive-clay);
  outline-offset: -2px;
}

.row-code {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  align-self: center;
  color: var(--archive-paper);
  border-radius: 50%;
  font-family: var(--archive-display-en);
  font-size: 0.6rem;
}

.row-label { flex: 0 1 auto; }

.row-leader {
  flex: 1 1 12px;
  align-self: center;
  min-width: 12px;
  border-bottom: 1px dotted var(--archive-line);
  transform: translateY(-3px);
}
.rail-row.active .row-leader { border-bottom-color: rgba(240, 236, 226, 0.4); }

.row-count {
  flex: 0 0 auto;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.62rem;
}

.rail-rows-inline { flex-direction: row; gap: 4px; }
.rail-rows-inline .rail-row { width: auto; flex: 1 1 auto; justify-content: center; padding: 10px 8px; }

/* ---------- mobile control strip ---------- */
.cat-strip {
  display: none;
  position: sticky;
  top: var(--pw-nav-h, 64px);
  z-index: 30;
  background: var(--archive-paper);
  border-top: 1px solid var(--archive-line);
  border-bottom: 1px solid var(--archive-line);
}

.strip-cells {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.strip-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 56px;
  padding: 0 8px;
  color: var(--archive-ink);
  background: transparent;
  border: 0;
  border-radius: 0;
  border-inline-end: 1px solid var(--archive-line-soft);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.72rem;
  cursor: pointer;
}
.strip-btn:last-child { border-inline-end: 0; }
.strip-btn:active { background: var(--archive-paper-deep); }
.strip-btn:focus-visible { outline: 2px solid var(--archive-clay); outline-offset: -2px; }
.strip-btn svg { width: 15px; height: 15px; flex: 0 0 auto; }

.strip-count[hidden] { display: none; }
.strip-count {
  display: inline-grid;
  place-items: center;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  color: var(--archive-paper);
  background: var(--archive-clay-deep);
  font-style: normal;
  font-size: 0.6rem;
}

/* in-place expanding search */
.strip-search-row {
  display: none;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 16px;
}
.cat-strip.searching .strip-cells { display: none; }
.cat-strip.searching .strip-search-row { display: flex; }
.strip-search-row .rail-sec { flex: 1 1 auto; padding: 0; border: 0; }
.strip-search-row .rail-h { display: none; }
.strip-search-row .rail-search-wrap input { font-size: 1rem; min-height: 44px; }

.strip-cancel {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 6px;
  color: var(--archive-clay-deep);
  background: transparent;
  border: 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.7rem;
  cursor: pointer;
}

/* ---------- results band ---------- */
.cat-band {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  margin-bottom: 26px;
  padding: 8px 0;
  border-bottom: 1px solid var(--archive-line);
}

.cat-count {
  flex: 0 0 auto;
  color: var(--archive-ink-soft);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.66rem;
  letter-spacing: 0.04em;
}

.cat-chips {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cat-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  color: var(--archive-ink);
  background: transparent;
  border: 1px solid var(--archive-line);
  border-radius: 0;
  font-family: inherit;
  font-size: 0.7rem;
  cursor: pointer;
}
.cat-chip em { font-style: normal; color: var(--archive-clay-deep); font-size: 0.62rem; }
.cat-chip:hover { border-color: var(--archive-ink); }

.cat-view {
  flex: 0 0 auto;
  display: flex;
  border: 1px solid var(--archive-line);
}
.cat-view button {
  display: grid;
  place-items: center;
  width: 40px;
  height: 34px;
  color: var(--archive-ink-soft);
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
}
.cat-view button + button { border-inline-start: 1px solid var(--archive-line); }
.cat-view button[aria-pressed="true"] {
  color: var(--archive-paper);
  background: var(--archive-ink);
}
.cat-view button:focus-visible { outline: 2px solid var(--archive-clay); outline-offset: -2px; }
.cat-view svg { width: 15px; height: 15px; }

/* ---------- grid (3-col with rail) ----------
   #grid.cat-grid: identity-v2 has #grid rules (ID specificity, some
   !important) — catalog grid rules must match or exceed that weight. */
#grid.cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 54px 18px; }

/* The card component itself now lives in assets/card.css, because the home
   grid draws the same card and should not have to pull in the masthead,
   the rail, the strip and the list view to get it. What stays here is
   catalogue-only: this grid's own columns, the plate spreads, the list
   view and the loading skeletons. */

/* ---------- plate spreads (grail, default view only) ----------
   #grid prefix: identity-v2 targets card internals with #grid (ID
   specificity), so the spread overrides must outrank it. */
.plate-spread { grid-column: span 2; }
#grid .plate-spread .card-media { aspect-ratio: 7 / 5; }
#grid .plate-spread .card-media::before {
  content: '';
  position: absolute;
  inset: 14px;
  z-index: 1;
  pointer-events: none;
  border: 1px solid rgba(255, 253, 247, 0.5);
}

/* ---------- list view: the ledger ---------- */
#grid.cat-grid.is-list { display: block; }

.is-list .cat-card {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  border-bottom: 1px solid var(--archive-line-soft);
  animation: none;
}
.is-list .cat-card:first-child { border-top: 1px solid var(--archive-line-soft); }

.is-list .cat-link {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
  gap: 18px;
  align-items: center;
  padding: 14px 0;
}
.is-list .card-media { width: 120px; aspect-ratio: 4 / 5; margin: 0; }
.is-list .cat-caption { border-top: 0; margin-top: 0; padding: 0 56px 0 0; }
html[dir='ltr'] .is-list .cat-caption { padding: 0 0 0 56px; }
.is-list .cat-meta { max-width: 380px; }
.is-list .cat-add { bottom: 50%; transform: translateY(50%); }
#grid.is-list .plate-spread .card-media { aspect-ratio: 4 / 5; }
#grid.is-list .plate-spread .card-media::before { display: none; }
#grid.is-list .card-media { aspect-ratio: 4 / 5; }

/* ---------- skeleton plates ---------- */
.cat-skel { border-bottom: 0; }
.sk-media {
  aspect-ratio: 4 / 5;
  background: var(--archive-paper-deep);
  border: 1px solid var(--archive-line-soft);
}
.sk-bar {
  height: 11px;
  margin-top: 12px;
  background: var(--archive-paper-deep);
}
.sk-bar.w60 { width: 60%; margin-top: 16px; }
.sk-bar.w40 { width: 40%; }
.sk-bar.w80 { width: 80%; }
.sk-media, .sk-bar {
  background-image: linear-gradient(100deg, transparent 30%, rgba(255, 253, 247, 0.65) 50%, transparent 70%);
  background-size: 220% 100%;
  animation: cat-shimmer 1.6s ease-in-out infinite;
}
@keyframes cat-shimmer {
  from { background-position: 130% 0; }
  to { background-position: -70% 0; }
}

/* ---------- empty state: the empty mounted plate ---------- */
.cat-empty { padding: 26px 0 10px; text-align: center; }

.empty-plate {
  max-width: 420px;
  margin: 0 auto;
  background: var(--archive-paper-deep);
  border: 1px solid var(--archive-line);
}

.empty-frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  aspect-ratio: 4 / 5;
  margin: 16px;
  padding: 20px;
  border: 1px solid rgba(255, 253, 247, 0.7);
}

.empty-mono {
  color: var(--archive-clay-deep);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
}

.empty-title {
  margin: 0;
  color: var(--archive-ink);
  font-family: var(--archive-display-ar);
  font-size: 1.5rem;
  font-weight: 600;
}
html[dir='ltr'] .empty-title { font-family: var(--archive-display-en); }

/* The preparing state carries a line of prose where the filtered state carries
   a button. Held to a readable measure so it never runs the full plate width,
   and kept quiet — the plate is doing the talking. */
.empty-body {
  max-width: 30ch;
  margin: 0;
  color: var(--archive-ink-soft);
  font-size: 0.85rem;
  line-height: 1.75;
  text-wrap: balance;
}

.empty-clear {
  min-height: 48px;
  padding: 0 26px;
  color: var(--archive-ink);
  background: transparent;
  border: 1px solid var(--archive-line);
  border-radius: 0;
  font-family: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}
.empty-clear:hover { color: var(--archive-paper); background: var(--archive-ink); border-color: var(--archive-ink); }

.empty-wa {
  margin: 22px 0 0;
  color: var(--archive-ink-soft);
  font-size: 0.85rem;
}
.empty-wa a { color: var(--archive-clay-deep); text-decoration: underline; text-underline-offset: 4px; }

/* ---------- load error ---------- */
.cat-load-error {
  grid-column: 1 / -1;
  padding: 60px 20px;
  text-align: center;
  color: var(--archive-ink-soft);
}
.cat-load-error span {
  display: block;
  margin-bottom: 10px;
  color: var(--archive-clay-deep);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.14em;
}
.cat-load-error p { margin: 0 0 18px; font-size: 0.9rem; }
.cat-load-error button {
  min-height: 48px;
  padding: 0 26px;
  color: var(--archive-ink);
  background: transparent;
  border: 1px solid var(--archive-line);
  border-radius: 0;
  font-family: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}
.cat-load-error button:hover { color: var(--archive-paper); background: var(--archive-ink); }

/* ---------- mobile sheets: the index, folded into a drawer ---------- */
.cat-sheet {
  border-radius: 0;
  border-top: 1px solid var(--archive-line);
  background: var(--archive-paper);
  max-height: 78dvh;
  display: flex;
  flex-direction: column;
}
.cat-sheet-title {
  margin: 4px 20px 6px;
  color: var(--archive-ink);
  font-size: 1.6rem;
  font-weight: 500;
  letter-spacing: -0.02em;
}
.cat-sheet-body {
  flex: 1 1 auto;
  overflow-y: auto;
  scrollbar-width: none;
  padding: 0 20px 12px;
}
.cat-sheet-body::-webkit-scrollbar { display: none; }
.cat-sheet-body .rail-sec { padding: 14px 0; }
.cat-sheet-body .rail-row { min-height: 52px; font-size: 0.9rem; }
.cat-sheet-body .rail-h { font-size: 0.85rem; }

.cat-sheet-foot {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 10px;
  padding: 12px 20px calc(14px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--archive-line);
  background: var(--archive-paper);
}
.cat-sheet-clear,
.cat-sheet-apply {
  min-height: 56px;
  border-radius: 0;
  font-family: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}
.cat-sheet-clear {
  color: var(--archive-ink);
  background: transparent;
  border: 1px solid var(--archive-line);
}
.cat-sheet-apply {
  color: var(--archive-paper);
  background: var(--archive-ink);
  border: 1px solid var(--archive-ink);
}

/* ============================================================
   Responsive
   ============================================================ */

/* narrow desktop: rail 240px, plates 2-up */
@media (max-width: 1199px) {
  .cat-layout { grid-template-columns: 240px minmax(0, 1fr); gap: 0 32px; }
  #grid.cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* tablet: rail folds into the strip, 3-up grid */
@media (max-width: 1040px) {
  .cat-layout { display: block; padding-top: 0; }
  .cat-rail { display: none; }
  .cat-strip { display: block; margin: 0 -34px; padding: 0 34px; }
  .cat-band { margin-top: 18px; }
  #grid.cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 44px 14px; }
  .cat-masthead { padding: 34px 0 24px; border-bottom: 0; }
}

/* mobile: 2-up, tighter */
@media (max-width: 760px) {
  .cat-wrap { padding: 0 16px 90px; }
  .cat-strip { margin: 0 -16px; padding: 0 16px; }
  .cat-masthead { padding: 26px 0 18px; }
  .cat-masthead h1 { font-size: clamp(2.2rem, 10vw, 3.2rem); }
  .cat-statement { font-size: 0.84rem; }
  #grid.cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 12px; }
  /* wraps naturally in DOM order — no `order` anywhere (DOM = visual) */
  .cat-band { flex-wrap: wrap; row-gap: 4px; }
  /* card typography and the quick-add target moved to card.css */

  /* spreads: full width, 3/2 (the engine caps mobile at one spread,
     placed only at a row start, so no grid holes are possible) */
  .plate-spread { grid-column: 1 / -1; }
  #grid .plate-spread .card-media { aspect-ratio: 3 / 2; }

  .is-list .cat-card { grid-template-columns: 84px minmax(0, 1fr); }
  .is-list .cat-link { gap: 14px; padding: 12px 0; }
  .is-list .card-media { width: 84px; }
  .is-list .cat-caption { padding: 0 48px 0 0; }
  html[dir='ltr'] .is-list .cat-caption { padding: 0 0 0 48px; }
}

@media (max-width: 390px) {
  .cat-grid { gap: 36px 12px; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .cat-card { animation: none; }
  .sk-media, .sk-bar { animation: none; background-image: none; }
  .cat-add, .rail-row { transition: none; }
}

/* ============================================================
   iOS Safari input zoom floor
   ------------------------------------------------------------
   Safari zooms the entire page whenever a focused field renders
   under 16px, and every control on this site sat at 13.6-14.7px.
   The page then stays zoomed until the reader pinches back out —
   worst on checkout, where five fields follow one another.

   A floor, not a redesign: 16px is the threshold Safari checks,
   so anything already larger is untouched.
   ============================================================ */
@media (max-width: 1024px) {
  /* :is() carries the highest specificity of its arguments, so one selector
     covers all three controls and still outranks page rules like
     `.field textarea { font-size: 0.9rem }` that would otherwise win. */
  :is(input, select, textarea):not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
    font-size: 16px;
  }
}
