/* ══════════════════════════════════════════════════════════════════
   kitaabi — the contact sheet

   Every jacket face-on, filed under a visible subject heading. Replaced the
   horizontally scrolling rack + sticky pane on 2026-08-27: the rack put 45
   books in a ~2,140px strip inside a ~669px column, so two thirds of the
   shelf was off-screen behind a 3px scrollbar and you could not tell what was
   there. See the ⚠️ at the top of kitaabi.py for the full autopsy.

   Everything here works with JavaScript off — the sheet is plain markup and
   plain grid. kitaabi.js only adds filtering and the deep-link highlight.
   ═══════════════════════════════════════════════════════════════════ */

.kt-page {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.5rem, 7vh, 5rem) var(--gut) clamp(3rem, 8vh, 6rem);
}
/* the header reads as prose, so it keeps a prose measure — but stays flush
   left with the shelf below it rather than centring in its own column */
.kt-page .note__kicker,
.kt-page .note__title,
.kt-page .idx__lede,
.kt-page .gsearch-wrap { max-width: 54ch; }
.kt-page .idx__lede { margin-bottom: 1.6rem; }

/* Search hides cards with the hidden attribute, and a class that sets display
   outranks the browser's own [hidden] rule — so say it here or filtering
   silently does nothing. */
.kt__bk[hidden], .kt__cert[hidden], .kt__band[hidden] { display: none; }

/* ── the head ─────────────────────────────────────────────────────── */
.kt-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 2rem; flex-wrap: wrap; margin-bottom: clamp(1.6rem, 4vh, 2.6rem);
}
.kt-head .gsearch-wrap { max-width: 22ch; flex: 0 1 auto; }

/* The search field's styles used to come from notes.css, which /kitaabi/ loaded
   and the home page does not. Now that the module lives on home, they travel
   with it — copied rather than linked, because pulling all of notes.css onto the
   front page for one input would be the wrong trade. The garden keeps its own
   copy in notes.css; if one changes, check the other. */
.gsearch-wrap { margin: 1.4rem 0 .2rem; }
.gsearch {
  width: 100%; max-width: 24rem; font-family: var(--serif); font-size: 1.02rem;
  padding: .2rem 0 .5rem; border: none; border-bottom: 1px solid var(--line);
  background: transparent; color: var(--ink); border-radius: 0;
  -webkit-appearance: none; appearance: none; transition: border-color .2s;
}
.gsearch:focus { outline: none; }
.gsearch:focus-visible { outline: none; border-bottom-color: var(--accent); }
.gsearch::placeholder { color: var(--muted); font-style: italic; }
.gsearch::-webkit-search-cancel-button { -webkit-appearance: none; }
.gsearch-count {
  font-family: var(--mono); font-size: .64rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); margin: .5rem 0 0;
}
.gsearch-empty {
  font-family: var(--serif); font-style: italic; font-size: .98rem;
  color: var(--muted); margin: 1rem 0 0;
}

/* ── the block gets the whole width ───────────────────────────────────
   .block is a `--rail 1fr` grid, so section 02's body was ~748px — five
   jackets across. The Sound band already opts out of that grid the same way
   (.block--invert), so this is the site's existing move, not a new one: the
   rail sits above and the sheet runs the full measure, ~1,020px, eight
   across. This is what dropping the sticky pane bought. */
.block--kitaabi { display: block; }
.block--kitaabi .block__rail { margin-bottom: 1.8rem; }
.block--kitaabi .gsearch-wrap { max-width: 24rem; }

/* ── a subject band ───────────────────────────────────────────────────
   ⚠️ The heading is the point. Cluster ordering was pulled on 2026-08-24
   because the alphabet restarted five times down the rack with nothing
   saying why — unlabelled grouping is not grouping, it is noise. Grouping
   is back only because each run now says what it is. */
.kt__room { margin-top: 0; }
.kt__band + .kt__band { margin-top: 2.8rem; }
.kt__bh { display: flex; align-items: baseline; gap: .8rem; margin: 0 0 1.1rem; }
.kt__bn {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink); white-space: nowrap;
}
.kt__br { flex: 1; height: 1px; background: var(--line); }
.kt__bc { font-family: var(--mono); font-size: .66rem; color: var(--muted); }

/* ── the sheet ────────────────────────────────────────────────────────
   auto-fill, so the shelf reflows to the window instead of being pinned to a
   column count. --cell is a MINIMUM; the tracks stretch to fill the row. */
.kt__sheet {
  display: grid; gap: 1.5rem .95rem;
  grid-template-columns: repeat(auto-fill, minmax(var(--cell, 116px), 1fr));
}

/* ⚠️ A COMMON BASELINE. The covers run 0.68 to 1.68 in aspect ratio, so left
   to themselves every caption in a row lands at a different height and the row
   reads as rubble. The slot is the tallest jacket a cell can hold and each one
   sits on its floor — books on a shelf stand on a line. Keep --slot ≈ --cell
   × 1.68 (the tallest jacket on file, `nectar in a sieve`) or the tall ones
   will crop. */
.kt__slot { display: flex; align-items: flex-end; height: var(--slot, 196px); }
.kt__plate {
  position: relative; display: block; width: 100%; background: var(--paper-2);
  box-shadow: 3px 3px 0 var(--line);
  transition: transform .14s ease, box-shadow .14s ease;
}
.kt__plate img { display: block; width: 100%; height: auto; }
.kt__set {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 150px; padding: .7rem .5rem;
  font-family: var(--serif); font-size: .66rem; line-height: 1.3;
  color: var(--ink-soft); border: 1px solid var(--line);
}
.kt__bk:hover .kt__plate {
  transform: translate(-2px, -2px); box-shadow: 5px 5px 0 var(--accent);
}

/* ── the caption ──────────────────────────────────────────────────────
   ⚠️ IDENTIFICATION ONLY — title, author, and whether it is open on the desk.
   This is NOT the write-ups coming back; those were pulled on 2026-08-09
   because they were not Pranish's own writing, and that still holds. If a
   future note IS his writing, that is a fresh decision, not a bug fix.

   Two lines then clamp: 45 titles at one line each would ellipsis most of the
   shelf ("from here to eternity - traveling the world…"), and three lines
   would make the caption taller than some of the jackets. */
.kt__t {
  font-family: var(--serif); font-weight: 400; font-size: .72rem; line-height: 1.24;
  margin: .5rem 0 .1rem; font-variation-settings: "opsz" 90, "SOFT" 30, "WONK" 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.kt__a {
  font-family: var(--mono); font-size: .58rem; color: var(--muted); margin: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kt__m {
  font-family: var(--mono); font-size: .56rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); margin: .18rem 0 0;
}

/* the highlight a shared /#the-kite-runner link lands on */
.kt__bk.is-target .kt__plate { box-shadow: 5px 5px 0 var(--accent); }
.kt__bk.is-target .kt__t { color: var(--accent); }

/* ── the coursework band ──────────────────────────────────────────────
   A certificate is landscape and prints its own name across the middle, so it
   gets a wider cell, no baseline slot and no caption (2026-08-09: "thumbnails
   only, no text at all"). The document itself is the link out to Coursera —
   a claim on this site should be checkable. */
.kt__band--cert .kt__sheet { --cell: 168px; gap: 1rem .95rem; }
.kt__cert {
  display: block; position: relative; text-decoration: none;
  transition: transform .16s ease;
}
/* ⚠️ The ↗ is drawn here, not by the global a[target="_blank"] rule, which
   would hang it on its own line under the tile. It stays visible at rest
   (2026-08-09): a hover-only cue on an image nobody knows is clickable is not
   an affordance. */
.kt__go {
  position: absolute; top: .4rem; right: .4rem;
  font-family: var(--mono); font-size: .7rem; line-height: 1;
  color: var(--accent); background: var(--paper);
  border: 1px solid var(--line); border-radius: 2px; padding: .18rem .26rem;
  transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.kt__cert:hover .kt__go, .kt__cert:focus-visible .kt__go {
  background: var(--accent); color: var(--paper); border-color: var(--accent);
}
.kt__cert img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); box-shadow: 3px 3px 0 var(--line);
  transition: border-color .16s ease, box-shadow .16s ease;
}
.kt__cert:hover, .kt__cert:focus-visible { transform: translateY(-3px); outline: none; }
.kt__cert:hover img, .kt__cert:focus-visible img {
  border-color: var(--accent); box-shadow: 5px 5px 0 var(--accent);
}

/* ── narrow ───────────────────────────────────────────────────────────
   The sheet reflows on its own — auto-fill does the work. All these do is
   keep the jacket big enough to recognise as the row count drops, and keep
   --slot locked to --cell × 1.68 so nothing crops. */
@media (max-width: 820px) {
  .kt__sheet { --cell: 104px; --slot: 176px; gap: 1.3rem .8rem; }
  .kt__band--cert .kt__sheet { --cell: 150px; }
}
@media (max-width: 560px) {
  /* three across on a phone, which is where a cover is still legible. The rack
     used to "work" here only because sideways scrolling is native on touch —
     and hiding two thirds of the shelf is not working. */
  .kt__sheet { --cell: 92px; --slot: 156px; gap: 1.1rem .7rem; }
  .kt__band--cert .kt__sheet { --cell: 130px; }
  .kt__t { font-size: .68rem; }
}

@media (prefers-reduced-motion: reduce) {
  .kt__plate, .kt__cert, .kt__cert img { transition: none; }
  .kt__bk:hover .kt__plate { transform: none; }
  .kt__cert:hover, .kt__cert:focus-visible { transform: none; }
}
