/*
 * platform/ui/collection.css
 *
 * The Phase-1 platform surface: a restrained typographic foundation, not a
 * finished art direction. Every decision that a later visual pass would want to
 * change is expressed as a custom property in :root below, so that pass edits
 * tokens rather than hunting through rules. The named extension points are
 * listed in docs/platform/PHASE1_HANDOFF.md.
 *
 * Deliberately absent: cover imagery. The 117 immersive assets are full-scene
 * WebP at ~1672x941 and must not be regenerated or altered in this phase, so
 * putting 117 of them on one page would be either ruinous to load or a breach
 * of that constraint. Card art is a documented extension point, not an omission.
 */

:root {
  /* --- Fable extension point: palette ------------------------------------ */
  --ink: #eef3ef;
  --ink-quiet: #9ab0b6;
  --ink-faint: #6d868d;
  --ground: #081013;
  --ground-raised: #0e191d;
  --ground-sunken: #060c0e;
  --edge: #22333a;
  --edge-strong: #304047;
  --accent: #cfe3d8;
  --focus: #7fd4c1;

  /* --- Fable extension point: type --------------------------------------- */
  --face-display: Georgia, "Times New Roman", serif;
  --face-text: system-ui, -apple-system, "Segoe UI", sans-serif;
  --face-label: ui-monospace, SFMono-Regular, Menlo, monospace;
  --label-tracking: 0.12em;

  /* --- Fable extension point: rhythm ------------------------------------- */
  --gutter: clamp(1.25rem, 4vw, 4rem);
  --stack: clamp(1.75rem, 3.5vw, 2.75rem);
  --card-min: 17rem;
  --radius: 2px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 1rem/1.55 var(--face-text);
  -webkit-text-size-adjust: 100%;
}

/* Reader-controlled motion is honoured everywhere; nothing here animates
   except the detail disclosure, and that is removed outright. */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

a { color: inherit; }

:where(a, button, input, summary):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Skip link: present in the DOM, revealed on focus. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ground-raised);
  color: var(--ink);
  padding: 0.75rem 1rem;
  z-index: 10;
}
.skip:focus { left: 0; }

.label {
  font: 500 0.68rem/1.4 var(--face-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--ink-quiet);
}

/* ---------------------------------------------------------------- shell -- */

.shell-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  align-items: baseline;
  padding: 0.9rem var(--gutter);
  border-bottom: 1px solid var(--edge);
  background: var(--ground-sunken);
}
.shell-bar a { text-decoration: none; }
.shell-bar a:hover { text-decoration: underline; }
.shell-mark { font: 600 0.78rem/1 var(--face-label); letter-spacing: 0.2em; text-transform: uppercase; }
.shell-here { color: var(--accent); }
.shell-links { margin-left: auto; display: flex; gap: 1.25rem; }

/* ----------------------------------------------------------------- head -- */

.masthead { padding: var(--stack) var(--gutter) 0; }
.masthead h1 {
  margin: 0.6rem 0 0;
  font: 400 clamp(2.4rem, 6.5vw, 4.25rem)/0.98 var(--face-display);
  letter-spacing: -0.01em;
}
.masthead-lede {
  margin: 0.9rem 0 0;
  max-width: 46ch;
  color: var(--ink-quiet);
  font-size: 1.05rem;
}
.masthead-publisher { margin-top: 1.1rem; display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: baseline; }
.publisher-handle { font-family: var(--face-label); color: var(--accent); }
.publisher-verified {
  border: 1px solid var(--edge-strong);
  border-radius: 999px;
  padding: 0.1rem 0.6rem;
  font: 500 0.62rem/1.6 var(--face-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--ink-quiet);
}

/* -------------------------------------------------------------- controls -- */

.controls { padding: var(--stack) var(--gutter) 0; }

.search-field { position: relative; max-width: 34rem; }
.search-field input {
  width: 100%;
  padding: 0.85rem 1rem;
  background: var(--ground-raised);
  border: 1px solid var(--edge-strong);
  border-radius: var(--radius);
  color: var(--ink);
  font: 400 1rem var(--face-text);
}
.search-field input::placeholder { color: var(--ink-faint); }

.facet-groups {
  margin-top: 1rem;
  display: grid;
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.facet-group > .label { display: block; margin-bottom: 0.5rem; }
.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip {
  display: inline-flex;
  gap: 0.45rem;
  align-items: baseline;
  padding: 0.32rem 0.7rem;
  background: transparent;
  border: 1px solid var(--edge-strong);
  border-radius: 999px;
  color: var(--ink-quiet);
  font: 400 0.8rem var(--face-text);
  cursor: pointer;
}
.chip:hover { color: var(--ink); border-color: var(--ink-faint); }
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--ground); }
.chip[data-empty="true"] { opacity: 0.35; }
.chip-count { font-family: var(--face-label); font-size: 0.68rem; }

.result-line {
  margin-top: 1.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  border-top: 1px solid var(--edge);
  padding-top: 0.9rem;
}
.clear-filters {
  background: none;
  border: 0;
  padding: 0;
  color: var(--ink-quiet);
  font: inherit;
  font-size: 0.85rem;
  text-decoration: underline;
  cursor: pointer;
}

/* ----------------------------------------------------------- collections -- */

.selections { padding: var(--stack) var(--gutter) 0; }
.selection-strip { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); margin-top: 0.9rem; }
.selection {
  text-align: left;
  padding: 1rem 1.1rem;
  background: var(--ground-raised);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.selection:hover { border-color: var(--edge-strong); }
.selection strong { display: block; font: 400 1.15rem var(--face-display); }
.selection p { margin: 0.4rem 0 0; color: var(--ink-quiet); font-size: 0.85rem; }
.selection[aria-pressed="true"] { border-color: var(--accent); }

/* --------------------------------------------------------------- results -- */

.results { padding: var(--stack) var(--gutter) calc(var(--stack) * 1.5); }
.grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; grid-template-columns: repeat(auto-fill, minmax(var(--card-min), 1fr)); background: var(--edge); border: 1px solid var(--edge); }
.card { background: var(--ground-raised); display: flex; flex-direction: column; }
.card[hidden] { display: none; }
.card-head { padding: 1.1rem 1.15rem 0; display: flex; justify-content: space-between; gap: 1rem; }
.card-number { font-family: var(--face-label); font-size: 0.68rem; letter-spacing: var(--label-tracking); color: var(--ink-faint); }
.card-title { margin: 0.55rem 0 0; padding: 0 1.15rem; font: 400 1.22rem/1.25 var(--face-display); }
.card-title a { text-decoration: none; }
.card-title a:hover { text-decoration: underline; }
.card-subtitle { margin: 0.5rem 0 0; padding: 0 1.15rem; color: var(--ink-quiet); font-size: 0.86rem; }
.card-facets { margin: 0.85rem 0 0; padding: 0 1.15rem; display: flex; flex-wrap: wrap; gap: 0.3rem; list-style: none; }
.card-facets li { font: 400 0.7rem var(--face-label); letter-spacing: 0.06em; color: var(--ink-quiet); border: 1px solid var(--edge-strong); border-radius: 999px; padding: 0.1rem 0.5rem; }
.card-foot { margin-top: auto; padding: 1rem 1.15rem 1.15rem; }

.card-detail { border-top: 1px solid var(--edge); margin-top: 1rem; }
.card-detail > summary { padding: 0.75rem 1.15rem; cursor: pointer; font: 500 0.68rem var(--face-label); letter-spacing: var(--label-tracking); text-transform: uppercase; color: var(--ink-quiet); }
.card-detail > summary:hover { color: var(--ink); }
.card-detail[open] > summary { color: var(--ink); }
.detail-body { padding: 0 1.15rem 1.1rem; display: grid; gap: 0.85rem; }
.detail-body dt { font: 500 0.65rem var(--face-label); letter-spacing: var(--label-tracking); text-transform: uppercase; color: var(--ink-faint); }
.detail-body dd { margin: 0.3rem 0 0; font-size: 0.85rem; color: var(--ink-quiet); }
.detail-body ul { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.85rem; color: var(--ink-quiet); }

.enter {
  display: inline-block;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--edge-strong);
  border-radius: var(--radius);
  font: 500 0.7rem var(--face-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  text-decoration: none;
}
.enter:hover { border-color: var(--accent); color: var(--accent); }

/* ------------------------------------------------------- states + footer -- */

.state { padding: 2.5rem 0; max-width: 48ch; }
.state h2 { margin: 0 0 0.6rem; font: 400 1.4rem var(--face-display); }
.state p { margin: 0 0 0.5rem; color: var(--ink-quiet); }
.state code { font-family: var(--face-label); color: var(--accent); }

.site-foot { border-top: 1px solid var(--edge); padding: var(--stack) var(--gutter); color: var(--ink-quiet); font-size: 0.85rem; }
.site-foot p { max-width: 62ch; }

@media (max-width: 30rem) {
  .grid { grid-template-columns: 1fr; }
  .shell-links { margin-left: 0; width: 100%; }
}

/* Search is an enhancement over an already-complete page: the field is inert
   until the derived index is in hand, and says so rather than silently
   swallowing keystrokes. If the index never arrives the message stays, and the
   117 cards below it remain fully browsable (§27, §33). */
.search-status { margin: 0.5rem 0 0; color: var(--ink-faint); font-size: 0.8rem; }
.search-status[hidden] { display: none; }
.search-field input:disabled { opacity: 0.6; cursor: progress; }

/* The filter rail is four groups of chips. On a phone that is most of a screen
   of chrome standing between the reader and the collection, so it is a native
   <details>: open on wide viewports (where the summary is hidden and it simply
   reads as a rail), closed on narrow ones. collection.js does the closing, so
   without JavaScript a phone reader still gets every filter — just expanded. */
.filters { margin-top: 1.5rem; }
.filters > summary {
  cursor: pointer;
  padding: 0.55rem 0;
  list-style: none;
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  border-bottom: 1px solid var(--edge);
}
.filters > summary::-webkit-details-marker { display: none; }
.filters > summary::after { content: "+"; margin-left: auto; font-family: var(--face-label); }
.filters[open] > summary::after { content: "\2212"; }
.filters-count { color: var(--accent); }
@media (min-width: 48rem) {
  .filters > summary { display: none; }
  .filters { margin-top: 0; }
}

/* ---------------------------------------------------------------------------
 * Surfaces beyond the collection home
 *
 * The publisher profile, the editorial selections and the browse pages share
 * the shell above and add only what they need: a breadcrumb, a link to search,
 * and lists of links where the home has script-driven chips. Nothing here
 * introduces a new token — a visual pass still edits :root and nothing else.
 * ------------------------------------------------------------------------- */

.shell-search {
  font: 500 0.68rem var(--face-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--ink-quiet);
  border: 1px solid var(--edge-strong);
  border-radius: var(--radius);
  padding: 0.3rem 0.7rem;
  text-decoration: none;
  white-space: nowrap;
}
.shell-search:hover { color: var(--accent); border-color: var(--accent); text-decoration: none; }
.shell-bar .shell-search { margin-left: 1.25rem; }

.crumbs { padding: 1rem var(--gutter) 0; }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.crumbs li { font: 400 0.72rem var(--face-label); letter-spacing: 0.06em; color: var(--ink-faint); }
.crumbs li + li::before { content: "/"; margin-right: 0.5rem; color: var(--edge-strong); }
.crumbs a { color: var(--ink-quiet); }

/* An editorial selection is a link to its own page now, not a filter toggle. */
a.selection { display: block; text-decoration: none; }
a.selection:hover { text-decoration: none; }

.explore { padding: var(--stack) var(--gutter) 0; }
.explore-links { list-style: none; margin: 0.55rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.explore-links a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  font: 400 0.78rem var(--face-text);
  color: var(--ink-quiet);
  border: 1px solid var(--edge-strong);
  border-radius: 999px;
  padding: 0.22rem 0.66rem;
  text-decoration: none;
}
.explore-links a:hover { color: var(--ink); border-color: var(--ink-faint); text-decoration: none; }

.publisher-facts { margin: 1.4rem 0 0; display: grid; gap: 0.85rem; max-width: 62ch; }
.publisher-facts dt { font: 500 0.65rem var(--face-label); letter-spacing: var(--label-tracking); text-transform: uppercase; color: var(--ink-faint); }
.publisher-facts dd { margin: 0.3rem 0 0; font-size: 0.88rem; color: var(--ink-quiet); }

.editorial-note { color: var(--ink-faint); font-size: 0.8rem; max-width: 62ch; }

.more { padding: 0 var(--gutter) var(--stack); }
.more p { color: var(--ink-quiet); font-size: 0.88rem; }

.share-line { margin: 0.6rem 0 0; color: var(--ink-faint); font-size: 0.8rem; }
.share-line[hidden] { display: none; }

.taxonomy-note { padding: 0 var(--gutter) var(--stack); margin: 0; color: var(--ink-faint); font-size: 0.8rem; max-width: 72ch; }

.results > h2:not(.sr-only) { margin: 0 0 0.4rem; font: 400 1.35rem var(--face-display); }
