/* Shared presentation for release rails and the character library. */
[data-catalog-home-only][hidden] { display: none !important; }
.category-back {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 0 var(--catalog-gutter) 8px;
  color: #b1b1bb;
  font: 600 14px/1.4 var(--c-sans);
  text-decoration: none;
}
.category-back:hover { color: #f65265; }
.category-back:focus-visible { outline: 2px solid #f65265; outline-offset: 2px; }
.catalog-section {
  --catalog-columns: 3;
  --catalog-gap: 10px;
  --catalog-gutter: 16px;
  --catalog-radius: 10px;
  --catalog-title-size: 14px;
  min-width: 0;
}
.catalog-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 var(--catalog-gutter) 16px;
}
.catalog-heading > div:first-child { min-width: 0; }
.catalog-eyebrow { margin: 0 0 5px; color: #97979f; font: 500 13px/1.5 var(--c-sans); letter-spacing: -.015em; }
.catalog-title { margin: 0; color: #f3f3f5; font: 800 20px/1.35 var(--c-sans); letter-spacing: -.035em; word-break: keep-all; }
/* Korean headings break between words, never inside one ("연락했 / 을까"). */
.rail-label { word-break: keep-all; }
.catalog-actions { display: flex; gap: 4px; flex: none; }
.catalog-actions button, .catalog-sort {
  min-height: 44px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid #ffffff20;
  border-radius: 8px;
  background: transparent;
  color: #c6c6cd;
  font: 600 13px/1 var(--c-sans);
  cursor: pointer;
}
.catalog-actions button { width: 32px; padding: 0; }
.catalog-actions i { font-size: 18px; }
.catalog-sort { flex: none; white-space: nowrap; }
.catalog-sort i { color: #f65265; }
.catalog-actions button:disabled { opacity: .28; cursor: default; }
.nox-release-rail, .character-library {
  display: grid;
  gap: 24px var(--catalog-gap);
  padding: 2px var(--catalog-gutter) 8px;
  box-sizing: border-box;
  min-width: 0;
}
.nox-release-rail {
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - (var(--catalog-columns) - 1) * var(--catalog-gap)) / var(--catalog-columns));
  align-items: start;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-padding-inline: var(--catalog-gutter);
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  touch-action: auto;
  scrollbar-width: none;
  cursor: grab;
}
.nox-release-rail::-webkit-scrollbar { display: none; }
.nox-release-rail.is-dragging { scroll-snap-type: none; cursor: grabbing; user-select: none; }
.character-library {
  grid-template-columns: repeat(var(--catalog-columns), minmax(0, 1fr));
  align-items: start;
}
.nox-release-card, .character-grid-card {
  appearance: none;
  min-width: 0;
  display: grid;
  align-content: start;
  gap: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  scroll-snap-align: start;
  -webkit-tap-highlight-color: transparent;
}
.character-grid-card[hidden], .nox-release-card[hidden], .character-grid-card.is-paged-out { display: none; }
/* Infinite scroll loader shared by the story library and the character roster. */
.catalog-more[hidden] { display: none; }
.catalog-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 26px 0 8px;
  color: #8e8e97;
  font: 500 13px/1.4 var(--c-sans);
}
.catalog-more-spinner {
  width: 16px;
  height: 16px;
  box-sizing: border-box;
  border: 2px solid #ffffff24;
  border-top-color: #f04a5c;
  border-radius: 50%;
  animation: catalog-more-spin .8s linear infinite;
}
@keyframes catalog-more-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .catalog-more-spinner { animation: none; } }
.nox-release-cover, .character-grid-cover {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 2 / 3;
  box-sizing: border-box;
  margin-bottom: 0;
  overflow: hidden;
  isolation: isolate;
  border: 1px solid #ffffff24;
  border-radius: var(--catalog-radius);
  background: #1b1b20;
}
.nox-release-cover > img, .character-grid-cover > img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 18%;
  -webkit-user-drag: none;
}
.nox-release-copy { display: grid; gap: 3px; min-width: 0; }
.nox-release-copy > strong, .character-grid-card > strong {
  color: #f3f3f5;
  font: 700 var(--catalog-title-size)/1.4 var(--c-sans);
  letter-spacing: -.025em;
}
.nox-release-copy > small, .nox-release-copy > span, .character-grid-card > span:not(.character-grid-cover) {
  color: #bcbcc4;
  font: 400 13px/1.5 var(--c-sans);
  word-break: keep-all;
}
/* One spacing rhythm under every thumbnail, at every width:
   image, 8px, stats, 5px, title, 3px, summary, 3px, meta. Titles clamp to two lines but never reserve a
   blank second line, so a one-line title is not followed by a gap it has no text for. */
.nox-release-cover + .thumb-stat-row, .character-grid-cover + .thumb-stat-row { margin-top: 8px; }
.nox-release-cover + .nox-release-copy, .character-grid-cover + strong { margin-top: 9px; }
.thumb-stat-row + .nox-release-copy, .thumb-stat-row + strong { margin-top: 5px; }
.character-grid-card > strong + span, .character-grid-card > span + small { margin-top: 3px; }
.nox-release-copy > strong, .character-grid-card > strong {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}
/* Summaries are strictly one line with an ellipsis at every width, so no card reserves blank lines
   for text it does not have. The stat row is exempt: it is its own flex line below the image. */
.nox-release-copy > small:not(.thumb-stat-row),
.nox-release-copy > span:not(.thumb-stat-row),
.character-grid-card > span:not(.character-grid-cover):not(.thumb-stat-row) {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow-wrap: normal;
}
.nox-release-copy > em, .character-grid-card > small {
  color: #93939d;
  font: 500 11px/1.45 var(--c-sans);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.catalog-actions button:focus-visible, .catalog-sort:focus-visible,
.nox-release-card:focus-visible, .character-grid-card:focus-visible, .nox-release-rail:focus-visible {
  outline: 2px solid #f65265;
  outline-offset: 2px;
  border-radius: 8px;
}
@media (hover: hover) {
  .catalog-actions button:hover:not(:disabled), .catalog-sort:hover { background: #f6526517; border-color: #f6526580; }
  .nox-release-card:hover .nox-release-cover, .character-grid-card:hover .character-grid-cover { border-color: #f6526580; }
}
/* Phones stay at two columns. Tablets (600-767px) step up to three, because two columns rendered
   their 2:3 covers larger than either the phone or the desktop grid. */
@media (max-width: 599px) {
  .catalog-section { --catalog-columns: 2; --catalog-gap: 10px; --catalog-title-size: 14px; }
}
@media (min-width: 600px) and (max-width: 767px) {
  .catalog-section { --catalog-columns: 3; --catalog-gap: 10px; --catalog-title-size: 14px; }
}
@media (max-width: 767px) {
  .nox-release-copy > small, .nox-release-copy > span, .character-grid-card > span:not(.character-grid-cover) { font-size: 12.5px; }
}
@media (min-width: 768px) {
  .catalog-section { --catalog-columns: 5; --catalog-gutter: 0px; --catalog-title-size: 15px; }
  .catalog-title { font-size: 21px; }
}

/* Card stats: comment and image counts pinned to the bottom-right of every story thumbnail. */
.card-stats { position: absolute; right: 6px; top: 6px; z-index: 3; display: flex; gap: 3px; pointer-events: none; opacity: .82; }
.card-stat { display: inline-flex; align-items: center; gap: 3px; padding: 3px 5px; border-radius: 5px; background: rgba(8, 8, 10, .45); color: #fff; font: 700 9.5px/1 var(--c-sans, sans-serif); letter-spacing: -.01em; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.card-stat i { font-size: 9.5px; line-height: 1; opacity: .9; }
.card-stat b { font-weight: 700; }
.rank10-poster .card-stats { right: 5px; top: 5px; }

/* Stats inside every thumbnail: a small dark translucent rounded badge in the bottom-right corner.
   It sits above the art and the HTML title layer; that layer's caption is lifted so the two never overlap. */
.rank10-poster > .thumb-stat-row,
.nox-release-cover > .thumb-stat-row,
.character-grid-cover > .thumb-stat-row {
  position: absolute;
  z-index: 7;
  right: 6px;
  bottom: 6px;
  display: inline-flex;
  align-items: center;
  width: max-content;
  max-width: calc(100% - 12px);
  gap: 8px;
  padding: 4px 8px;
  box-sizing: border-box;
  border: 1px solid #ffffff1f;
  border-radius: 999px;
  background: rgba(5, 5, 6, .78);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  overflow: hidden;
  pointer-events: none;
}
.thumb-stat-row .card-stat { gap: 4px; color: #e4e4e9; font: 650 10.5px/1.2 var(--c-sans); letter-spacing: -.01em; }
.thumb-stat-row .card-stat i { color: #b4b4bd; font-size: 11px; line-height: 1; }
.thumb-stat-row .card-stat b { color: #fff; font-weight: 700; font-variant-numeric: tabular-nums; }
.has-story-preview:has(> .thumb-stat-row) .thumb-story-copy { bottom: 34px; }
.rank10-poster.has-story-preview:has(> .thumb-stat-row) .thumb-story-copy { bottom: auto; }
@media (max-width: 479px) {
  .rank10-poster > .thumb-stat-row,
  .nox-release-cover > .thumb-stat-row,
  .character-grid-cover > .thumb-stat-row { right: 5px; bottom: 5px; gap: 6px; padding: 3px 7px; }
  .thumb-stat-row .card-stat { gap: 3px; font-size: 9.5px; }
  .thumb-stat-row .card-stat i { font-size: 10px; }
  .has-story-preview:has(> .thumb-stat-row) .thumb-story-copy { bottom: 30px; }
}
