/* Home "Featured" card carousel (views/site/_showcase*.php, js/modules/carousel.js)
 * and the banner card preview of /admin/banners (views/adminBanners/form.php).
 *
 * Compact cards: a title is a 2:3 cover (rank badge, "Read" on hover / keyboard focus) + a two-line title + one meta
 * line: 6 titles and a peek of the next from 1280 px, 5 from 1100, 4 from 900, 3 on tablets, ~2.3 on phones.
 * A promo banner ("dark poster" in both themes) is two cards wide and exactly as tall as a title card:
 * card width w = (track - n*gap) / per; title card = 1.5*w (cover) + --nbc-meta-h; banner = 2*w + gap wide.
 * Cards use container queries (.nbc-slide is the container), so the admin preview renders the same banner.
 * This file loads before nb.css: rules inside cards are prefixed with .nbc-card to outrank nb.css / review.css. */

.nbc { --nbc-gap: 14px; --nbc-per: 6.25; --nbc-n: 6; --nbc-meta-h: 66px; --nbc-fade: 44px; --nbc-interval: 4s; position: relative; margin: -4px 0 0; }
@media (max-width: 1279.98px) { .nbc { --nbc-per: 5.25; --nbc-n: 5; } }
@media (max-width: 1099.98px) { .nbc { --nbc-per: 4.25; --nbc-n: 4; } }
@media (max-width: 899.98px) { .nbc { --nbc-per: 3.3; --nbc-n: 3; } }
@media (max-width: 639.98px) { .nbc { --nbc-gap: 12px; --nbc-per: 2.6; --nbc-n: 2; } }
@media (max-width: 479.98px) { .nbc { --nbc-per: 2.3; } }

/* ------------------------------------------------------------ header: title, "Full ranking", controls */
.nbc-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px 16px; margin: 0 0 12px; }
.nbc-title { display: flex; align-items: center; gap: 9px; margin: 0; font-size: 20px; line-height: 1.2; letter-spacing: -0.02em; }
.nbc-title svg { color: var(--muted-foreground); flex-shrink: 0; }
.nbc-tools { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.nbc-more { display: inline-flex; align-items: center; gap: 3px; font-size: 13px; font-weight: 550; color: var(--muted-foreground); white-space: nowrap; }
.nbc-more:hover, .nbc-more:focus-visible { color: var(--foreground); }
.nbc-ctrl { display: flex; gap: 6px; }
.nbc-btn {
	display: inline-grid; place-items: center; width: 34px; height: 34px; padding: 0; box-sizing: border-box;
	border: 1px solid var(--border); border-radius: var(--radius); background: var(--card-solid); color: var(--foreground);
	box-shadow: var(--elev-1); cursor: pointer; transition: background .15s, border-color .15s;
}
.nbc-btn:hover { background: var(--muted); border-color: color-mix(in oklab, var(--foreground) 22%, transparent); }
.nbc-btn:active { transform: translateY(1px); }
.nbc-btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.nbc-btn svg { display: block; }
.nbc-play .i-pause, .nbc-play .i-play { display: inline-grid; place-items: center; }
.nbc-play .i-play, .nbc.is-user-paused .nbc-play .i-pause { display: none; }
.nbc.is-user-paused .nbc-play .i-play { display: inline-grid; }
@media (max-width: 479.98px) {
	.nbc-title { font-size: 18px; }
	.nbc-tools { gap: 10px; }
	.nbc-btn { width: 32px; height: 32px; }
}
/* nothing to scroll (all cards fit): keep the space, hide the controls */
.nbc.is-static .nbc-ctrl, .nbc.is-static .nbc-dots { visibility: hidden; }

/* ------------------------------------------------------------ track */
.nbc-track {
	position: relative; display: flex; align-items: stretch; gap: var(--nbc-gap); margin: -6px; padding: 6px;
	overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory; scroll-padding-inline: 6px;
	scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.nbc-track::-webkit-scrollbar { display: none; }
/* the page has no global [hidden] rule and these parts set display (also used by the admin preview) */
.nbc [hidden], .nbc-card [hidden], .nbc-card[hidden] { display: none !important; }
/* js/modules/carousel.js animates scrollLeft itself (eased); snapping is off meanwhile so it cannot fight the animation */
.nbc-track.is-animating { scroll-snap-type: none; }
/* author display rules below would otherwise beat the UA [hidden] rule (loop clones, preview layers) */
.nbc-slide[hidden], .nbc-card [hidden] { display: none !important; }
/* the looping track always has a card peeking on the right: fade it out at the edge */
.nbc.is-ready:not(.is-static) .nbc-track {
	-webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--nbc-fade)), transparent 100%);
	mask-image: linear-gradient(to right, #000 calc(100% - var(--nbc-fade)), transparent 100%);
}
.nbc-slide {
	flex: 0 0 calc((100% - var(--nbc-gap) * var(--nbc-n)) / var(--nbc-per)); min-width: 0; display: flex;
	scroll-snap-align: start; container-type: inline-size;
}
.nbc-slide.is-wide { flex-basis: calc((100% - var(--nbc-gap) * var(--nbc-n)) / var(--nbc-per) * 2 + var(--nbc-gap)); }

/* ------------------------------------------------------------ card (shared) */
.nbc-card { position: relative; display: flex; flex-direction: column; flex: 1 1 auto; width: 100%; min-width: 0; box-sizing: border-box; text-decoration: none; }
.nbc-card a:focus-visible, a.nbc-card:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.nbc-card .nb-btn {
	height: 36px; padding: 0 14px; gap: 7px; font-size: 13.5px; font-weight: 600; border-radius: var(--radius);
	box-shadow: none; text-decoration: none; transition: background .15s, color .15s, border-color .15s;
}
.nbc-card .nbc-cta { background: #fff; color: #111; border: 1px solid transparent; }

/* ------------------------------------------------------------ novel card: cover + title + meta */
.nbc-novel { color: var(--foreground); }
.nbc-novel-art { position: relative; flex: none; }
.nbc-novel-cover { display: block; }
.nbc-card .nbc-novel-cover .nb-cover { box-shadow: var(--elev-1); transition: transform .25s ease, box-shadow .25s ease; }
.nbc-novel:hover .nbc-novel-cover .nb-cover, .nbc-novel:focus-within .nbc-novel-cover .nb-cover { transform: translateY(-3px); box-shadow: var(--elev-3); }
.nbc-rank {
	position: absolute; left: 7px; top: 7px; z-index: 1; display: inline-flex; align-items: center; height: 22px; min-width: 22px; padding: 0 7px;
	box-sizing: border-box; border-radius: var(--radius-sm); background: #fff; color: #111; font-size: 12.5px; font-weight: 800;
	font-variant-numeric: tabular-nums; letter-spacing: -0.01em; box-shadow: 0 4px 12px -4px oklch(0 0 0 / .55); pointer-events: none;
	transition: transform .25s ease;
}
.nbc-rank.is-kind {
	height: 20px; padding: 0 6px; background: oklch(0.16 0.01 265 / .78); color: #fff; font-size: 10px; font-weight: 700;
	letter-spacing: .07em; text-transform: uppercase; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.nbc-novel:hover .nbc-rank, .nbc-novel:focus-within .nbc-rank { transform: translateY(-3px); }
.nbc-card .nbc-read {
	position: absolute; left: 8px; right: 8px; bottom: 8px; z-index: 2; display: flex; align-items: center; justify-content: center; gap: 6px;
	height: 34px; box-sizing: border-box; border-radius: var(--radius); background: #fff; color: #111; font-size: 13px; font-weight: 650;
	text-decoration: none; box-shadow: 0 8px 20px -8px oklch(0 0 0 / .6);
	opacity: 0; transform: translateY(4px); transition: opacity .18s ease, transform .25s ease, background .15s;
}
.nbc-novel:hover .nbc-read, .nbc-novel:focus-within .nbc-read { opacity: 1; transform: translateY(-3px); }
.nbc-card .nbc-read:hover, .nbc-card .nbc-read:focus-visible { background: oklch(0.92 0 0); color: #111; text-decoration: none; }
.nbc-card a.nbc-read:focus-visible { outline: 2px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 4px var(--ring); }
/* touch screens: no hover, so a small round "Read" button stays on the cover */
@media (hover: none) {
	.nbc-card .nbc-read { left: auto; width: 34px; padding: 0; border-radius: 999px; opacity: 1; transform: none; }
	.nbc-card .nbc-read span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
.nbc-novel-text { height: var(--nbc-meta-h); padding-top: 9px; box-sizing: border-box; min-width: 0; overflow: hidden; }
.nbc-card .nbc-novel-title { margin: 0; font-size: 13.5px; line-height: 1.35; font-weight: 600; letter-spacing: -0.005em; color: var(--foreground); }
/* the link is the whole two-line block: a click anywhere on the title (also beside a short last line) opens the title */
.nbc-card .nbc-novel-title a {
	color: inherit; text-decoration: none; overflow-wrap: anywhere;
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.nbc-card .nbc-novel-title a:hover { color: var(--foreground); text-decoration: underline; text-underline-offset: 3px; }
.nbc-meta { display: flex; align-items: center; margin: 3px 0 0; font-size: 12px; line-height: 1.4; color: var(--muted-foreground); white-space: nowrap; overflow: hidden; }
.nbc-meta > span { flex: none; }
.nbc-meta > span:last-child { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.nbc-meta > span + span::before { content: "\00B7"; margin: 0 6px; color: color-mix(in oklab, var(--muted-foreground) 70%, transparent); }
.nbc-star { display: inline-flex; align-items: center; gap: 3px; font-weight: 650; color: var(--foreground); }
.nbc-star svg { color: oklch(0.78 0.16 78); fill: oklch(0.78 0.16 78); }
.nbc-st.is-completed { color: var(--success); font-weight: 600; }
.nbc-st.is-ongoing { color: var(--foreground); font-weight: 600; }
.nbc-st.is-paused { color: var(--warning); font-weight: 600; }
/* narrow phone cards: the status becomes a coloured dot (its word stays for screen readers), so "604 chapters" fits */
@container (max-width: 159px) {
	.nbc-st { display: inline-flex; align-items: center; font-size: 0; }
	.nbc-st::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
	.nbc-meta > .nbc-st + span::before { content: none; }
	.nbc-meta > .nbc-st + span { margin-left: 6px; }
}

/* ------------------------------------------------------------ promo banner card */
/* the banner slide is 2*w + gap wide (100cqi of its slide), so it is as tall as a title card: 1.5*w + --nbc-meta-h */
.nbc-banner {
	min-height: calc((100cqi - var(--nbc-gap, 14px)) * .75 + var(--nbc-meta-h, 66px));
	isolation: isolate; overflow: hidden; border-radius: var(--radius-lg); border: 1px solid var(--border); box-shadow: var(--elev-2);
	transition: box-shadow .25s ease;
	--nbc-accent: oklch(0.45 0.13 275); --nbc-accent-ink: #fff;
	--nbc-deep: color-mix(in oklab, var(--nbc-accent) 30%, oklch(0.12 0.01 265));
	color: #fff; cursor: pointer;
	background: linear-gradient(135deg, color-mix(in oklab, var(--nbc-accent) 82%, black) 0%, color-mix(in oklab, var(--nbc-accent) 34%, black) 100%);
}
a.nbc-banner:hover, a.nbc-banner:focus, a.nbc-banner:active { color: #fff; text-decoration: none; }
a.nbc-banner:hover { box-shadow: var(--elev-3); }
.nbc-banner.is-plain::after {
	content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
	background:
		radial-gradient(55% 75% at 88% 12%, color-mix(in oklab, var(--nbc-accent) 55%, transparent), transparent 70%),
		radial-gradient(40% 60% at 70% 110%, color-mix(in oklab, white 12%, transparent), transparent 70%),
		repeating-linear-gradient(135deg, oklch(1 0 0 / .035) 0 2px, transparent 2px 14px);
}
.nbc-banner-media { position: absolute; inset: 0; z-index: -2; display: block; overflow: hidden; }
.nbc-banner-media img { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; transition: transform .8s cubic-bezier(.2, .7, .2, 1); }
a.nbc-banner:hover .nbc-banner-media img { transform: scale(1.035); }
.nbc-banner-shade { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.nbc-banner.is-image .nbc-banner-shade {
	background:
		linear-gradient(90deg, color-mix(in oklab, var(--nbc-deep) 86%, transparent) 0%, color-mix(in oklab, var(--nbc-deep) 52%, transparent) 42%, transparent 74%),
		linear-gradient(0deg, oklch(0.1 0 0 / .62) 0%, oklch(0.1 0 0 / .18) 42%, transparent 60%);
}
.nbc-banner-bookbg { position: absolute; inset: 0; z-index: -2; overflow: hidden; background: linear-gradient(150deg, oklch(0.55 0.12 var(--ph-h, 250)), oklch(0.28 0.09 calc(var(--ph-h, 250) + 40))); }
.nbc-banner-bookbg img { position: absolute; left: -40px; top: -40px; width: calc(100% + 80px); height: calc(100% + 80px); max-width: none; object-fit: cover; filter: blur(28px) saturate(1.3); }
.nbc-banner.is-book .nbc-banner-shade {
	background: linear-gradient(95deg, color-mix(in oklab, var(--nbc-deep) 94%, transparent) 0%, color-mix(in oklab, var(--nbc-deep) 72%, transparent) 55%, color-mix(in oklab, var(--nbc-deep) 42%, transparent) 100%);
}
.nbc-banner-cover {
	--nbc-cover-w: clamp(96px, 24cqi, 150px);
	position: absolute; z-index: 0; right: clamp(20px, 5.5cqi, 36px); top: 50%; width: var(--nbc-cover-w);
	transform: translateY(-50%) rotate(4deg); transition: transform .45s ease;
}
.nbc-card .nbc-banner-cover .nb-cover { border: 0; box-shadow: 0 26px 50px -18px oklch(0 0 0 / .85), 0 0 0 1px oklch(1 0 0 / .16); }
a.nbc-banner:hover .nbc-banner-cover { transform: translateY(-50%) rotate(1.5deg) scale(1.02); }

.nbc-banner-top {
	position: absolute; z-index: 1; top: clamp(14px, 3.4cqi, 20px); left: clamp(16px, 4cqi, 26px); right: clamp(14px, 3.4cqi, 20px);
	display: flex; align-items: flex-start; gap: 8px; pointer-events: none;
}
.nbc-badge {
	display: inline-flex; align-items: center; height: 24px; max-width: 70%; padding: 0 10px; box-sizing: border-box;
	border-radius: var(--radius-sm); background: #fff; color: #111; font-size: 11.5px; font-weight: 750; letter-spacing: .06em;
	text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; box-shadow: 0 6px 16px -8px oklch(0 0 0 / .6);
}
.nbc-banner.has-accent .nbc-badge { background: var(--nbc-accent); color: var(--nbc-accent-ink); }
.nbc-ad {
	margin-left: auto; display: inline-flex; align-items: center; height: 20px; padding: 0 7px; box-sizing: border-box;
	border-radius: var(--radius-sm); border: 1px solid oklch(1 0 0 / .28); background: oklch(0 0 0 / .45); color: oklch(1 0 0 / .92);
	font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
	-webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}

.nbc-banner-body {
	position: relative; z-index: 1; flex: 1 1 auto; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start;
	gap: 8px; box-sizing: border-box; padding: 58px clamp(16px, 4cqi, 26px) clamp(16px, 4cqi, 26px);
}
.nbc-banner.is-image .nbc-banner-body { max-width: max(68cqi, 300px); }
.nbc-banner.is-book .nbc-banner-body { padding-right: calc(clamp(96px, 24cqi, 150px) + clamp(20px, 5.5cqi, 36px) + 18px); }
.nbc-card .nbc-banner-title {
	margin: 0; color: #fff; font-size: clamp(22px, 5.2cqi, 32px); line-height: 1.1; letter-spacing: -0.028em; font-weight: 750;
	text-wrap: balance; overflow-wrap: anywhere; text-shadow: 0 2px 18px oklch(0 0 0 / .35);
	display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.nbc-banner-sub {
	margin: 0; max-width: 48ch; font-size: 14.5px; line-height: 1.5; color: oklch(1 0 0 / .86); overflow-wrap: anywhere;
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.nbc-card .nbc-cta { margin-top: 8px; max-width: 100%; }
.nbc-card .nbc-cta > span:first-child { overflow: hidden; text-overflow: ellipsis; }
.nbc-cta-ico { display: inline-flex; transition: transform .2s ease; }
a.nbc-banner:hover .nbc-cta, a.nbc-banner:focus-visible .nbc-cta { background: oklch(0.92 0 0); }
a.nbc-banner:hover .nbc-cta-ico { transform: translateX(3px); }

@container (max-width: 459px) {
	.nbc-banner.is-image .nbc-banner-shade {
		background:
			linear-gradient(0deg, color-mix(in oklab, var(--nbc-deep) 92%, transparent) 0%, color-mix(in oklab, var(--nbc-deep) 62%, transparent) 42%, transparent 72%),
			linear-gradient(180deg, oklch(0.1 0 0 / .35) 0%, transparent 30%);
	}
	.nbc-banner.is-image .nbc-banner-body { max-width: none; }
	.nbc-banner-cover { --nbc-cover-w: clamp(64px, 24cqi, 92px); top: 14px; right: 14px; transform: rotate(4deg); }
	a.nbc-banner:hover .nbc-banner-cover { transform: rotate(1.5deg) scale(1.02); }
	.nbc-banner.is-book .nbc-banner-body { padding-right: clamp(16px, 4cqi, 26px); }
	.nbc-banner.is-book .nbc-banner-top { right: calc(var(--nbc-cover-w, 92px) + 26px); }
	/* the title of a title-linked banner keeps clear of the cover in the top right corner */
	.nbc-banner.is-book .nbc-banner-title { padding-right: calc(clamp(64px, 24cqi, 92px) + 4px); }
	.nbc-card .nbc-banner-title { font-size: clamp(19px, 7cqi, 23px); }
	.nbc-card .nbc-cta { align-self: stretch; }
}

/* ------------------------------------------------------------ dots: one per card, the cards in view are highlighted */
.nbc-dots { display: flex; justify-content: center; flex-wrap: wrap; gap: 0 2px; margin-top: 12px; }
.nbc-dot { display: inline-grid; place-items: center; height: 22px; min-width: 16px; padding: 0 2px; border: 0; background: none; cursor: pointer; border-radius: var(--radius-sm); }
.nbc-dot i {
	position: relative; display: block; width: 6px; height: 6px; overflow: hidden; border-radius: var(--radius-sm);
	background: color-mix(in oklab, var(--foreground) 16%, transparent); transition: width .3s ease, background .2s;
}
.nbc-dot:hover i { background: color-mix(in oklab, var(--foreground) 45%, transparent); }
.nbc-dot.is-visible i { width: 14px; background: color-mix(in oklab, var(--foreground) 34%, transparent); }
.nbc-dot.is-active i { width: 26px; background: color-mix(in oklab, var(--foreground) 22%, transparent); }
.nbc-dot.is-active i::after { content: ""; position: absolute; inset: 0; background: var(--foreground); transform-origin: left center; }
.nbc.is-playing .nbc-dot.is-active i::after { animation: nbc-fill var(--nbc-interval) linear both; }
.nbc-dot:focus-visible { outline: 2px solid var(--ring); outline-offset: 0; }
@keyframes nbc-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (prefers-reduced-motion: reduce) {
	.nbc-play { display: none; }
	.nbc-card, .nbc-card *, .nbc-dot i { transition: none !important; }
	.nbc-dot i::after { animation: none !important; }
}

/* ------------------------------------------------------------ touch screens and phones
   Controls grow from 32 to 36 px (gaps shrink so title, "Full ranking" and the three buttons still share one row
   down to 360 px), the dots get a 32 px tall hit area (the bars look the same), "Read" on the cover is 38 px. */
@media (max-width: 760px), (pointer: coarse) {
	.nbc-btn { width: 36px; height: 36px; }
	.nbc-ctrl { gap: 4px; }
	.nbc-more { padding: 10px 0; margin: -10px 0; }
	.nbc-dots { margin-top: 7px; }
	.nbc-dot { height: 32px; }
}
@media (max-width: 399.98px) {
	.nbc-head { column-gap: 10px; }
	.nbc-tools { gap: 8px; }
	.nbc-ctrl { gap: 2px; }
}
@media (hover: none) {
	.nbc-card .nbc-read { width: 38px; height: 38px; }
}
