/* ==========================================================================
   NOCTURN — base: reset, typography, layout primitives
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  background: var(--c-bg);
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--c-bg);
  color: var(--c-text);
  font: 400 var(--t-body)/1.5 var(--f-ui);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

body.has-tabbar { padding-bottom: calc(var(--tabbar-h) + var(--safe-b)); }
body.is-locked { overflow: hidden; }
/* reserve the scrollbar's lane so locking scroll doesn't nudge the layout */
html { scrollbar-gutter: stable; }

/* Page-to-page: a short crossfade, with the header and tab bar held still.
   Same-origin navigations only (no effect when opened from file://). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: 160ms ease both vt-out; }
  ::view-transition-new(root) { animation: 260ms var(--ease) both vt-in; }
  .site-header { view-transition-name: site-header; }
  .tabbar { view-transition-name: tabbar; }
  ::view-transition-group(site-header), ::view-transition-group(tabbar) { animation-duration: 0s; }
}
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; transform: translateY(8px); } }

/* <details> open and close smoothly where the browser can animate to auto */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  details::details-content { block-size: 0; overflow-y: clip; transition: block-size .32s var(--ease), content-visibility .32s allow-discrete; }
  details[open]::details-content { block-size: auto; }
}

img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration: none; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
button:disabled { cursor: default; }

h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }

::selection { background: rgba(242, 138, 60, .32); color: #fff; }

[hidden] { display: none !important; }

:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 3px;
  border-radius: 6px;
}

input::placeholder, textarea::placeholder { color: var(--c-text-3); opacity: 1; }

/* Native scrollbars: quiet, dark */
* { scrollbar-color: var(--c-line) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--c-line); border-radius: 10px; border: 2px solid var(--c-bg); }
::-webkit-scrollbar-track { background: transparent; }

.no-scrollbar { scrollbar-width: none; -ms-overflow-style: none; }
.no-scrollbar::-webkit-scrollbar { display: none; }

/* ---- Icons ----------------------------------------------------------- */
.icon {
  width: 20px;
  height: 20px;
  flex: none;
  display: inline-block;
  vertical-align: middle;
}
.icon--sm { width: 16px; height: 16px; }
.icon--xs { width: 14px; height: 14px; }
.icon--lg { width: 24px; height: 24px; }

/* Stroke width is set here, not on the symbol, because the icons are drawn
   on a 24px grid and then shown at four sizes. One fixed 1.7 meant the 14px
   icons rendered at 1.7 × 14/24 ≈ 1.0px — technically legible, visually
   faint, which is exactly how they looked inside small buttons. These values
   land every size at roughly 1.4px on screen. */
.icon { stroke-width: 1.7; }
.icon--sm { stroke-width: 2.1; }
.icon--xs { stroke-width: 2.4; }
.icon--lg { stroke-width: 1.5; }

/* ---- Layout ---------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; gap: var(--s-2); }

.page { padding-bottom: var(--s-20); }
.page-sections {
  display: flex;
  flex-direction: column;
  gap: var(--section-gap);
}
/* Hold the page's height until the script fills it. Without this the footer
   is painted just below the hero, then shoved down a whole screen when the
   shelves arrive — one layout shift worth 0.197 on the home page, which is
   most of the way into Google's "poor" band on its own.

   Purely transitional: :empty stops matching the moment content lands, so
   none of this touches the finished layout. */
.page-sections:empty { min-height: 100vh; }

/* The same reservation for the pages that fill a container of their own.
   One entry per page — the block that carries its bulk — because reserving
   on every injection point would hold several screens where the page needs
   one. Listed here rather than per page so the set stays visible and
   reviewable in a single place. */
#home-shelves:empty,
#cat-shelves:empty,
#cat-list:empty,
#col-grid:empty,
#col-list:empty,
#creator-grid:empty,
#panel:empty,
#lib-panel:empty,
#notif-list:empty,
#set-body:empty,
#studio-main:empty,
#search-body:empty,
#ds-body:empty,
#mod-body:empty,
#auth-forms:empty,
#onb-body:empty,
#comments:empty {
  min-height: 100vh;
}

/* Blocks that sit above one of those and push it down when they arrive.
   Heights are measured from the rendered pages, not guessed, and they differ
   enough between desktop and phone to need both. */
.tabs:empty { min-height: 31px; }
#col-head:empty { min-height: 352px; }
#mod-nav:empty { min-height: 320px; }
#set-nav:empty { min-height: 421px; }
#col-hero:empty { min-height: 435px; }
#lib-head:empty { min-height: 283px; }
#mod-head:empty { min-height: 188px; }
#studio-head:empty { min-height: 154px; }
#creator-banner:empty { min-height: 282px; }
#creator-head:empty { min-height: 200px; }
#watch-info:empty { min-height: 557px; }

@media (max-width: 767px) {
  .tabs:empty { min-height: 45px; }
  #col-head:empty { min-height: 614px; }
  #mod-nav:empty { min-height: 65px; }
  #set-nav:empty { min-height: 57px; }
  #col-hero:empty { min-height: 317px; }
  #lib-head:empty { min-height: 376px; }
  #mod-head:empty { min-height: 227px; }
  #studio-head:empty { min-height: 200px; }
  #creator-banner:empty { min-height: 180px; }
  #creator-head:empty { min-height: 430px; }
  #watch-info:empty { min-height: 562px; }
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--min, 240px), 1fr));
  gap: var(--grid-gap);
}

/* ---- Typography primitives ------------------------------------------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  font: 400 var(--t-micro)/1.2 var(--f-mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--c-text-3);
}
.eyebrow--accent { color: var(--c-accent); }
.eyebrow .sep { color: var(--c-text-4); }
.eyebrow .dim { color: var(--c-text-2); }

.display {
  font: 500 var(--t-display)/1.02 var(--f-display);
  letter-spacing: -.03em;
  text-wrap: balance;
}
.h1 {
  font: 500 var(--t-h1)/1.05 var(--f-display);
  letter-spacing: -.025em;
  text-wrap: balance;
}
.h2 {
  font: 500 var(--t-h2)/1.1 var(--f-display);
  letter-spacing: -.015em;
}
.h3 {
  font: 500 var(--t-h3)/1.2 var(--f-display);
  letter-spacing: -.01em;
}
.lead {
  font-size: var(--t-body-l);
  line-height: 1.6;
  color: var(--c-text-2);
  max-width: 560px;
  text-wrap: pretty;
}
.muted { color: var(--c-text-2); }
.dim { color: var(--c-text-3); }
.mono { font-family: var(--f-mono); }
.tnum { font-variant-numeric: tabular-nums; }

.text-link { color: var(--c-text); transition: color var(--d-fast) var(--ease); }
.text-link:hover { color: var(--c-accent); }
.accent-link { color: var(--c-accent); font-weight: 500; }
.accent-link:hover { color: var(--c-accent-hover); }

.clamp-1, .clamp-2, .clamp-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.clamp-1 { -webkit-line-clamp: 1; line-clamp: 1; }
.clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed;
  left: 16px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: var(--r-pill);
  background: var(--c-on);
  color: var(--c-ink);
  font-weight: 500;
  transition: top var(--d-base) var(--ease);
}
.skip-link:focus-visible { top: 12px; }

/* ---- Page header (title blocks on index pages) ------------------------ */
.page-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding-block: clamp(34px, 5vw, 64px) clamp(24px, 3vw, 36px);
}
.page-head .lead { max-width: 540px; }
.page-head__row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-6);
  flex-wrap: wrap;
}

/* ---- Reduced motion --------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
