/* ══════════════════════════════════════════════════════════════════
   kitaabi — the reading room

   The shelf on the left, one book open on the right. Built as progressive
   enhancement: without JavaScript every panel renders stacked down the page
   (which is also what a crawler and a reader-mode reader get). kitaabi.js
   sets .kt-js on <html> before paint, and only then do the panels collapse
   into a single pane. Nothing here is hidden from the document.
   ═══════════════════════════════════════════════════════════════════ */

.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 rows 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__spine[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 rack ─────────────────────────────────────────────────────────
   Redesigned 2026-08-09. This was a grid of covers face-on, 6-7 across and
   six rows deep, and a grid is additive — more books, more rows, always. That
   is what held the page at 2,635px however much text came off it.

   Books on a real shelf are not displayed flat: they are packed, you see the
   edge of each one, and you PULL ONE OUT to look at it. So the jackets overlap
   and show a sliver; hover or focus slides one up and out and the rack parts
   just after it. 42 books live in one row at any width.

   The whole interaction is CSS. The parting is `:hover + .kt__spine` — the
   next book drops its negative margin, so the shelf opens where your cursor
   is. No JS is involved in the movement at all. */
/* Racks on the left, the thing you picked on the right (Pranish, 2026-08-09).
   Both racks are only ~200px tall, so the left column is short — which is the
   whole point: the page stops growing with the collection. ⚠️ minmax(0, …) on
   both tracks, or the rack's very wide flex content refuses to shrink and
   blows the grid open. */
.kt__room { margin-top: 0; }
.kt-js .kt__room {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, clamp(260px, 38%, 460px));
  gap: clamp(1.5rem, 4vw, 3.2rem);
  align-items: start;
}
.kt__racks { min-width: 0; }

.kt__rack {
  --w: clamp(84px, 9vw, 116px);      /* a jacket's real width           */
  --sliver: 46px;                    /* how much of it the rack shows   */
  display: flex; align-items: flex-end;
  overflow-x: auto; overflow-y: hidden;
  padding: 16px 0 12px;              /* room for a book to rise         */
  scroll-snap-type: x proximity;
  /* the fade says the rack continues; .is-end lifts it at the last book */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 68px), transparent 100%);
          mask-image: linear-gradient(to right, #000 calc(100% - 68px), transparent 100%);
  scrollbar-width: thin;
}
.kt__rack.is-end { -webkit-mask-image: none; mask-image: none; }
.kt__rack:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.kt__rack::-webkit-scrollbar { height: 3px; }
.kt__rack::-webkit-scrollbar-thumb { background: var(--line); }
.kt__rack::-webkit-scrollbar-track { background: transparent; }
.kt__rack + .kt__rack { margin-top: .4rem; }
/* a certificate is landscape and there are only 17, so it can afford to show
   more of itself than a book does */
.kt__rack--cert { --w: clamp(120px, 13vw, 168px); --sliver: 64px; }

.kt__spine {
  all: unset; box-sizing: border-box; cursor: pointer; position: relative;
  flex: 0 0 auto; width: var(--w);
  margin-left: calc(var(--sliver) - var(--w));
  scroll-snap-align: start;
  border: 1px solid var(--line); background: var(--paper-2);
  /* the edge shadow is what makes the overlap read as depth rather than as a
     stack of flat rectangles — it is the detail that sells the shelf */
  box-shadow: -7px 0 12px -7px rgba(0,0,0,.55);
  transition: transform .24s cubic-bezier(.2,.9,.3,1),
              margin-left .24s cubic-bezier(.2,.9,.3,1);
}
.kt__spine:first-child { margin-left: 0; }
/* ⚠️ …and the first VISIBLE spine once search has hidden the ones before it.
   [hidden] siblings stay in the DOM, so :first-child keeps matching a book you
   cannot see and the real first result is left tucked under the rack's edge.
   kitaabi.js marks it; there is no previous-sibling selector to do it here.
   Declared after the [data-open] rule so it wins on order at equal specificity. */
/* ⚠️ Subject grouping with no heading: the first book of each cluster opens a
   wider gap. The structure is still there, told in spacing instead of words. */
.kt__spine[data-open]:not(:first-child) { margin-left: calc(var(--sliver) - var(--w) + 22px); }
.kt__rack .kt__spine.is-lead { margin-left: 0; }

.kt__spine img {
  width: 100%; height: auto; display: block;
  filter: grayscale(1) contrast(1.04); opacity: .66;
  transition: filter .2s ease, opacity .2s ease;
}

/* the pull-out — the one move this page is remembered by */
.kt__spine:hover,
.kt__spine:focus-visible,
.kt__spine[aria-current="true"] { transform: translateY(-14px); z-index: 3; }
.kt__spine:hover img,
.kt__spine:focus-visible img,
.kt__spine[aria-current="true"] img { filter: none; opacity: 1; }
.kt__spine:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.kt__spine[aria-current="true"] { outline: 2px solid var(--accent); outline-offset: 2px; }
/* the rack parts just after whichever book is out */
.kt__spine:hover + .kt__spine,
.kt__spine:focus-visible + .kt__spine,
.kt__spine[aria-current="true"] + .kt__spine { margin-left: 0; }

/* ── the printed spine ────────────────────────────────────────────────
   Added 2026-08-17. The rack showed a ~46px sliver of each jacket's LEFT
   EDGE, greyscaled to .66 — and a cover puts its title in the MIDDLE, so the
   strip on show was the least identifying part of every book. Forty-four
   anonymous grey strips: browsable, not findable.

   A real bookshelf is navigable because the spine is printed. So print it.
   At rest the rack reads as paper spines with titles; pull one out and the
   label clears for the colour jacket underneath. Same footprint, same scroll.

   ⚠️ writing-mode lives on the INNER span, never on .kt__label — putting it
   on a flex container swaps which axis justify-content/align-items control
   and the centring silently inverts. The label box stays horizontal: it
   centres the span across the sliver (justify-content) and pins it to the
   top (align-items). */
.kt__label {
  /* ⚠️ inset:0 — the label papers the WHOLE jacket, not just the visible
     sliver. Covering only the sliver leaks raw colour art in two places, and
     the second one is not obvious: jackets have DIFFERENT ASPECT RATIOS, the
     rack is align-items:flex-end, so a shorter next book leaves the taller
     one's cover exposed along its top. Any width tied to --sliver has to
     chase that; papering the whole spine simply cannot leak. */
  position: absolute; inset: 0;
  display: flex; justify-content: flex-start; align-items: flex-start;
  /* the type still has to land in the strip the rack SHOWS, so centre it
     there by hand — the vertical line box is ~1em wide */
  padding-left: calc((var(--sliver) - 1em) / 2);
  overflow: hidden; pointer-events: none;
  /* ~88% lets a ghost of the cover through: texture, not information */
  background: color-mix(in srgb, var(--paper-2) 88%, transparent);
  font-size: .63rem;              /* the 1em above resolves against this */
  transition: opacity .2s ease;
}
.kt__label > span {
  writing-mode: vertical-rl;      /* top-to-bottom, the way a spine reads */
  max-height: 100%; padding: 10px 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: var(--serif); font-size: inherit; line-height: 1;
  letter-spacing: .012em; color: var(--ink-soft);
}
/* pulled out — you're looking at the jacket now, so get out of its way */
.kt__spine:hover .kt__label,
.kt__spine:focus-visible .kt__label,
.kt__spine[aria-current="true"] .kt__label { opacity: 0; }

.kt__name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.kt__spine .kt__set {
  position: absolute; inset: 0; display: flex; align-items: flex-end; padding: .35rem;
  font-family: var(--serif); font-size: .56rem; line-height: 1.15; color: var(--ink-soft);
}

/* ── the book held up ─────────────────────────────────────────────────
   Caption LEFT, jacket RIGHT. Stacking them cost ~200px of height for no
   reason once the racks freed up the width. */
/* sticky so the preview stays with you while you browse the racks */
.kt-js .kt__pane { position: sticky; top: 5rem; }
.kt__panel { display: block; }
.kt-js .kt__panel { display: none; }
.kt-js .kt__panel.is-open { display: grid; }
.kt__panel + .kt__panel { margin-top: 3rem; padding-top: 3rem; border-top: 1px solid var(--line); }
.kt-js .kt__panel + .kt__panel { margin-top: 0; padding-top: 0; border-top: 0; }

.kt__plate { margin-top: 1.1rem; }
.kt__big, .kt__bigset {
  width: min(100%, 300px); display: block;
  border: 1px solid var(--line); box-shadow: 12px 12px 0 var(--line);
}
.kt__big { height: auto; }
.kt__bigset {
  aspect-ratio: 2 / 3; display: flex; align-items: flex-end; padding: 1rem;
  background: var(--paper-2);
  font-family: var(--mono); font-size: .6rem; letter-spacing: .06em; color: var(--muted);
}
.kt__mark {
  font-family: var(--mono); font-size: .6rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 .5rem;
}
.kt__t {
  font-family: var(--serif); font-size: clamp(1.02rem, 1.5vw, 1.24rem); font-weight: 400;
  line-height: 1.2; margin: 0 0 .35rem; font-variation-settings: "opsz" 90, "SOFT" 30, "WONK" 0;
  /* ⚠️ ONE LINE, whatever the length (Pranish, 2026-08-09) — "global diplomacy —
     diplomacy in the modern world" wrapped to three lines and shouted over the
     document it was labelling. The full title stays reachable: it is in the h2's
     title= attribute, and in the spine's tooltip. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kt__a { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* a certificate is landscape, so it fills the column at its own proportions */
.kt__big--cert { width: 100%; box-shadow: 10px 10px 0 var(--line); }
/* ⚠️ The document itself is the outbound link, and it is the ONLY way off the
   site from here — a spine opens this preview first, always. The old
   "verify on coursera" text line was removed 2026-08-09 (Pranish: "make the
   certificate the link, so that space can be utilised as well"), so the corner
   ↗ is now the whole affordance. Keep it visible at rest; a hover-only cue on
   an image nobody knows is clickable is not an affordance. */
.kt__certlink { display: block; position: relative; text-decoration: none;
  transition: transform .16s ease; }
.kt__certlink:hover, .kt__certlink:focus-visible { transform: translateY(-3px); outline: none; }
.kt__certlink:hover .kt__big--cert,
.kt__certlink:focus-visible .kt__big--cert { border-color: var(--accent); box-shadow: 10px 10px 0 var(--accent); }
.kt__go {
  position: absolute; top: .5rem; right: .5rem;
  font-family: var(--mono); font-size: .78rem; line-height: 1;
  color: var(--accent); background: var(--paper);
  border: 1px solid var(--line); border-radius: 2px; padding: .2rem .3rem;
  transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.kt__certlink:hover .kt__go, .kt__certlink:focus-visible .kt__go {
  background: var(--accent); color: var(--paper); border-color: var(--accent);
}
.kt__a {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin: 0;
}
.kt__a b { color: var(--ink-soft); font-weight: 400; }

/* The coursework section (.kt__gyaan / .kt__gh2 / .kt__cgroup / .kt__wall /
   .kt__seal2 …) is gone — certificates are spines in the second rack, so they
   need no section, no heading and no grid. Recover from git if wanted. */

/* ── narrow ───────────────────────────────────────────────────────────
   The racks already scroll sideways, which is the native gesture on a phone —
   they need nothing. Only the detail stacks. */
@media (max-width: 820px) {
  .kt-js .kt__room { grid-template-columns: 1fr; }
  .kt-js .kt__pane { position: static; }
  .kt__pane { margin-top: 2rem; padding-top: 1.6rem; border-top: 1px solid var(--line); }
  .kt__big, .kt__bigset { width: min(62%, 240px); }
  .kt__big--cert { width: 100%; }
}
@media (max-width: 699px) {
  .kt__rack { --w: clamp(76px, 26vw, 100px); --sliver: 40px; }
  .kt__rack--cert { --w: clamp(110px, 38vw, 150px); --sliver: 56px; }
  .kt__big, .kt__bigset { width: min(58%, 210px); box-shadow: 8px 8px 0 var(--line); }
  .kt-head { gap: 1rem; }
  /* a narrower rack is a SHORTER spine too (the jacket keeps its 2:3), so the
     label's runway shrinks with it — buy the characters back in type size */
  .kt__label > span { font-size: .55rem; padding: 7px 0; letter-spacing: 0; }
}

@media (prefers-reduced-motion: reduce) {
  /* the pull-out is the page's one motion — with this on, a book still comes
     forward, it just does not travel */
  .kt__spine, .kt__spine img { transition: none; }
  .kt__spine:hover, .kt__spine:focus-visible,
  .kt__spine[aria-current="true"] { transform: none; }
  .kt__rack { scroll-behavior: auto; }
}
