/* Catalog pages: the tool list and its filters, a tool, a category, a model, search results.
   Tokens come from site.css; nothing here defines a colour that is not derived from one. */

.cat, .tool { padding-block: 2rem 4rem; }
.sec-h { font-family: var(--serif); font-size: 1.4rem; margin: 2rem 0 1rem; }

/* --- breadcrumbs --- */
.crumbs {
  display: flex; align-items: center; gap: .35rem; flex-wrap: wrap;
  font-size: .85rem; color: var(--muted); margin-bottom: 1.25rem;
}
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
.crumbs svg { width: 14px; height: 14px; opacity: .5; }

/* --- filters: a plain GET form, so the URL is the state --- */
.filters {
  display: flex; flex-wrap: wrap; gap: .75rem 1rem; align-items: end;
  padding: 1rem 1.15rem; margin-bottom: 1.5rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow);
}
.filter { display: flex; flex-direction: column; gap: .3rem; min-width: 0; flex: 1 1 11rem; }
.filter label { font-size: .75rem; font-weight: 600; letter-spacing: .02em; color: var(--muted); }
.filter select {
  font: inherit; font-size: .9rem; color: var(--text);
  padding: .5rem .6rem; border: 1px solid var(--border); border-radius: 9px;
  background: var(--bg); max-width: 100%;
}
.filter select:focus-visible, .filters button:focus-visible, .searchbox input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.filters button {
  display: inline-flex; align-items: center; gap: .4rem;
  font: inherit; font-size: .9rem; font-weight: 600; cursor: pointer;
  padding: .55rem 1rem; border: 0; border-radius: 9px;
  background: var(--accent); color: var(--on-accent);
}
.filters button svg { width: 16px; height: 16px; }
.filter-clear { font-size: .85rem; color: var(--muted); align-self: center; }

.machine-note {
  display: flex; gap: .6rem; align-items: start;
  font-size: .9rem; color: var(--muted); line-height: 1.55;
  padding: .85rem 1rem; margin-bottom: 1.25rem;
  background: var(--accent-soft); border-radius: 12px;
}
.machine-note svg { width: 18px; height: 18px; flex: none; margin-top: .15rem; color: var(--accent); }
.machine-note strong { color: var(--text); }

.count { font-size: .85rem; color: var(--muted); margin: 0 0 1rem; }
.empty { color: var(--muted); padding: 2rem 0; }

/* --- the tool grid --- */
.tgrid, .cgrid, .mgrid, .hits { list-style: none; margin: 0; padding: 0; }
.tgrid, .cgrid, .mgrid {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
}
.tgrid-item { display: flex; flex-direction: column; }
.tcard, .ccard, .mcard {
  display: flex; flex-direction: column; gap: .55rem; height: 100%;
  padding: 1.1rem 1.15rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow);
}
.tcard.is-featured { border-color: var(--accent); }
.tcard-name, .mcard h2, .ccard h2 { font-family: var(--serif); font-size: 1.1rem; margin: 0; line-height: 1.3; }
.tcard-name a, .mcard h2 a, .ccard h2 a { color: var(--text); text-decoration: none; }
.tcard-name a:hover, .mcard h2 a:hover, .ccard h2 a:hover { color: var(--accent); }
.tcard-sum, .mcard-sum, .ccard p { margin: 0; font-size: .9rem; line-height: 1.55; color: var(--muted); }
.tcard-meta, .mcard-meta {
  display: flex; flex-wrap: wrap; gap: .5rem .9rem; align-items: baseline;
  margin: auto 0 0; padding-top: .5rem; font-size: .8rem; color: var(--muted);
}
.tcard-cat { color: var(--accent); text-decoration: none; }
.tcard-cat:hover { text-decoration: underline; }
.tcard-vram { margin-left: auto; font-family: var(--mono); font-size: .75rem; }

/* --- pills: one fact each, colour-coded by meaning --- */
.pills { display: flex; flex-wrap: wrap; gap: .35rem; list-style: none; margin: 0; padding: 0; }
.pill {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .7rem; font-weight: 600; letter-spacing: .02em;
  padding: .22rem .55rem; border-radius: 999px;
  background: var(--accent-soft); color: var(--text);
}
.pills-big .pill { font-size: .78rem; padding: .3rem .7rem; }
.pill svg { width: 13px; height: 13px; }
.pill-host[data-host="self_hosted"] { background: color-mix(in oklab, var(--good) 16%, transparent); color: var(--good-ink); }
.pill-stance[data-stance="refused"], .pill-status[data-status="abandoned"],
.pill-status[data-status="possibly_dead"], .pill-status[data-status="archived"] {
  background: color-mix(in oklab, var(--muted) 18%, transparent); color: var(--muted);
}
.pill-stance[data-stance="allowed"] { background: color-mix(in oklab, var(--good) 16%, transparent); color: var(--good-ink); }
.pill-stance[data-stance="unknown"] { background: transparent; border: 1px dashed var(--border); color: var(--muted); }

/* --- hardware fit verdict --- */
.fit {
  margin: .5rem 0 0; padding: .35rem .7rem; border-radius: 9px;
  font-size: .78rem; font-weight: 600;
}
.fit-yes { background: color-mix(in oklab, var(--good) 14%, transparent); color: var(--good-ink); }
.fit-tight { background: var(--accent-soft); color: var(--accent); }
.fit-unknown { background: transparent; border: 1px dashed var(--border); color: var(--muted); }
.fit-no { display: none; } /* filtered out server-side; the rule is here so a stray one is not shouted about */

/* --- categories --- */
.ccard h2 a { display: inline-flex; align-items: center; gap: .5rem; }
.ccard h2 svg { width: 20px; height: 20px; color: var(--accent); }
.ccount { font-size: .8rem; color: var(--muted); margin: auto 0 0 !important; padding-top: .5rem; }
.csub { list-style: none; margin: .4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .2rem; }
.csub li { display: flex; justify-content: space-between; font-size: .85rem; }
.csub a { color: var(--accent); text-decoration: none; }
.csub a:hover { text-decoration: underline; }
.csub span { color: var(--muted); font-size: .75rem; }

/* --- one tool, one model --- */
.tool-head { margin-bottom: 2rem; }
.tool-head h1 { font-family: var(--serif); font-size: clamp(1.9rem, 5vw, 2.6rem); margin: 0 0 .5rem; line-height: 1.15; }
.tool-head .lede { font-size: 1.05rem; line-height: 1.6; color: var(--muted); margin: 0 0 1rem; max-width: 60ch; }
.tool-links { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1.1rem 0 0; }
.btn {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .85rem; font-weight: 600; text-decoration: none;
  padding: .5rem .9rem; border-radius: 9px;
  background: var(--accent); color: var(--on-accent);
}
.btn svg { width: 15px; height: 15px; }
.btn-quiet { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
.btn:hover { filter: brightness(1.08); }

.facts { margin: 0 0 2rem; }
.facts h2, .limits h2, .chips-sec h2 {
  display: flex; align-items: center; gap: .45rem;
  font-family: var(--serif); font-size: 1.25rem; margin: 0 0 .9rem;
}
.facts h2 svg, .limits h2 svg { width: 19px; height: 19px; color: var(--accent); }
.fact-grid {
  display: grid; gap: 1px; margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  background: var(--border); border: 1px solid var(--border); border-radius: 14px; overflow: hidden;
}
.fact { background: var(--surface); padding: .85rem 1rem; }
.fact-wide { grid-column: 1 / -1; }
.fact dt { font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.fact dd { margin: .25rem 0 0; font-size: .95rem; font-weight: 600; }
.fact-means { display: block; margin-top: .2rem; font-size: .8rem; font-weight: 400; line-height: 1.5; color: var(--muted); }
.run-note { display: flex; gap: .5rem; align-items: center; font-size: .85rem; color: var(--muted); margin: .8rem 0 0; }
.run-note svg { width: 15px; height: 15px; }

/* Signs of life: the freshness engine's readings. The sparkline is an inline SVG with a fixed viewBox,
   so it reserves its own height and cannot move anything below it while the page settles (D8). */
.life-lede { font-size: .85rem; color: var(--muted); margin: -.4rem 0 .9rem; max-width: 60ch; }
.life-num { font-variant-numeric: tabular-nums; font-size: 1.15rem; }
.spark {
  display: block; width: 100%; max-width: 240px; height: 40px; margin: .35rem 0 0;
  color: var(--accent); opacity: .85;
}
.life .fact dd a { display: inline-flex; align-items: center; gap: .35rem; }
.life .fact dd a svg { width: 15px; height: 15px; }

.tool-body { margin: 0 0 2rem; max-width: 68ch; }

.limits { margin: 0 0 2rem; }
.limit-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .6rem; }
.limit-list li {
  padding: .8rem 1rem; border-left: 3px solid var(--accent);
  background: var(--surface); border-radius: 0 12px 12px 0; font-size: .92rem; line-height: 1.55;
}
.limit-list strong { display: block; }
.limit-list span { color: var(--muted); }
.src { display: inline-flex; align-items: center; gap: .25rem; margin-left: .4rem; font-size: .78rem; color: var(--accent); text-decoration: none; }
.src svg { width: 12px; height: 12px; }
.src:hover { text-decoration: underline; }

.chips-sec { margin: 0 0 2rem; }
.chips { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; margin: 0; padding: 0; }
.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .85rem; padding: .35rem .75rem; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border);
}
.chip svg { width: 14px; height: 14px; color: var(--good); }
.chip a { color: var(--accent); text-decoration: none; }
.chip a:hover { text-decoration: underline; }
.rel-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .45rem; font-size: .95rem; }
.rel-phrase { color: var(--muted); }
.rel-note { color: var(--muted); font-size: .85rem; }

.page-foot { margin-top: 3rem; padding-top: 1.25rem; border-top: 1px solid var(--border); font-size: .88rem; color: var(--muted); }

/* --- search --- */
.searchbox { display: flex; gap: .5rem; margin: 0 0 1.5rem; }
.searchbox input {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: 1rem; color: var(--text);
  padding: .7rem .9rem; border: 1px solid var(--border); border-radius: 11px; background: var(--surface);
}
.searchbox button {
  display: inline-flex; align-items: center; gap: .4rem;
  font: inherit; font-size: .95rem; font-weight: 600; cursor: pointer;
  padding: .7rem 1.2rem; border: 0; border-radius: 11px; background: var(--accent); color: var(--on-accent);
}
.searchbox button svg { width: 16px; height: 16px; }
.hits { display: flex; flex-direction: column; gap: .9rem; }
.hit { padding: 1rem 1.15rem; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; }
.hit h2 { font-family: var(--serif); font-size: 1.05rem; margin: 0 0 .35rem; display: flex; align-items: baseline; gap: .6rem; }
.hit h2 a { color: var(--text); text-decoration: none; }
.hit h2 a:hover { color: var(--accent); }
.hit-kind { font-family: var(--sans); font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.hit-snip { margin: 0; font-size: .9rem; line-height: 1.6; color: var(--muted); }
.hit-snip mark { background: var(--accent-soft); color: var(--text); padding: 0 .15em; border-radius: 3px; }

/* ── The 18+ interstitial (/go/{slug}, PLAN.md D7) ───────────────────────────────────────────────
   A calm page, not a scare screen. It is narrow, it says the three things it has to say, and the way
   onward is the biggest thing on it. Nothing here animates and nothing here flashes: an interstitial
   that feels like an alarm gets clicked through without being read, which defeats the point of it. */
.leaving { max-width: 44rem; padding-block: clamp(2rem, 6vw, 4rem) 3rem; }
.leaving h1 { font: 700 var(--text-3xl)/var(--leading-snug) var(--serif); letter-spacing: var(--tracking-tight); margin: 0 0 .7rem; }
.leaving .lede { font-size: var(--text-lg); color: var(--muted); margin: 0 0 1.4rem; max-width: 60ch; }

/* The destination, shown once, in mono — a hostname is a fact, and mono is how the rest of the site
   writes facts. It is not a link: the link is the button, after the reading. */
.leaving-dest {
  display: inline-flex; align-items: center; gap: .5rem;
  margin: 0 0 1.5rem; padding: .55rem .9rem;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--shadow);
  font: 500 var(--text-sm)/1.2 var(--mono); color: var(--text);
  overflow-wrap: anywhere;
}
.leaving-dest svg { width: 16px; height: 16px; color: var(--accent); flex: none; }

.leaving-facts { margin: 0 0 1.8rem; padding: 0 0 0 1.1rem; color: var(--muted); max-width: 62ch; }
.leaving-facts li { margin-bottom: .5rem; line-height: var(--leading-body); }
.leaving-facts li::marker { color: var(--accent); }

.leaving-go { display: flex; flex-wrap: wrap; gap: .7rem; align-items: center; margin: 0 0 1.2rem; }
.btn-big { font-size: var(--text-base); padding: .75rem 1.3rem; border: 0; cursor: pointer; font-family: inherit; }

.leaving-note { margin: 0; color: var(--muted); font-size: var(--text-sm); line-height: var(--leading-body); max-width: 62ch; }

/* --- a category card's artwork -----------------------------------------------------------------
   Full-bleed across the top of the card, which is why the card's own padding is cancelled on it. As
   on the home page, `has-art` is only present when a picture is live: a card with none keeps exactly
   the padding and spacing it has always had. */
.ccard.has-art { padding-top: 0; overflow: hidden; }

.ccard-art {
  margin: 0 -1.15rem .2rem;
  aspect-ratio: 8 / 5;
  overflow: hidden;
  background: var(--bg);
}

.ccard-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Held back so the card is a card with a picture on it rather than a picture with words under it.
     It comes up on hover, which is the only motion here and is composited. */
  opacity: .8;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.ccard:hover .ccard-img { opacity: 1; transform: scale(1.03); }

@media (prefers-reduced-motion: reduce) {
  .ccard-img { transition: none; }
  .ccard:hover .ccard-img { transform: none; }
}
