/* ==========================================================================
   Panoculus — pale warm cream, ink line-art, Source Serif 4 display type.
   ========================================================================== */

:root {
  --cream:       #f6efe2;
  --cream-lift:  #fbf7ee;
  --cream-sink:  #ece1cd;
  --ink:         #17130e;
  --ink-soft:    #6b5f4e;
  --ink-faint:   #9c8f7b;
  --line:        #ddd0b8;
  --accent:      #8a6a3e;

  --serif: "Source Serif 4", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --sans:  ui-sans-serif, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --shell: 1180px;
  --radius: 14px;
}

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

html { -webkit-text-size-adjust: 100%; }

/* Scrollbars are hidden everywhere, but nothing is made unscrollable — wheel,
   touch, keyboard and programmatic scrolling all still work. Deliberately not
   `overflow: hidden`, which would strand content below the fold. */
* {
  scrollbar-width: none;        /* Firefox */
  -ms-overflow-style: none;     /* legacy Edge */
}
*::-webkit-scrollbar {          /* WebKit / Blink */
  width: 0;
  height: 0;
  display: none;
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* A very soft warm vignette so the flat cream doesn't read as dead space. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(120% 90% at 50% 8%, rgba(255, 252, 245, 0.85), transparent 62%),
    radial-gradient(90% 70% at 50% 108%, rgba(203, 183, 148, 0.35), transparent 60%);
}

body > * { position: relative; z-index: 1; }

a { color: inherit; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ============================================================ home / hero */

.page--home { display: flex; flex-direction: column; }

.hero {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(0.4rem, 1.5vw, 1rem);
  padding: clamp(2rem, 6vh, 4rem) 1.25rem 1rem;
  text-align: center;
}

.wordmark {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(2.6rem, 9vw, 5.4rem);
  line-height: 1;
  letter-spacing: 0.14em;
  text-indent: 0.14em;          /* balance the trailing letter-space */
  text-transform: uppercase;
  color: var(--ink);
}

/* ------------------------------------------------------------------ eyes */

.eyes {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 5vw, 4rem);
  width: min(100%, 720px);
  margin: 0 0 clamp(0.5rem, 2vh, 1.5rem);
}

.eye {
  width: min(42%, 290px);
  height: auto;
  overflow: visible;
}

/* Line-art palette. Everything is ink on cream; the sclera is the page. */
.eye .brow__body,
.eye .brow__hairs path,
.eye .lashes path,
.eye .lid--upper,
.eye .lash-line   { fill: var(--ink); stroke: none; }

.eye .sclera      { fill: var(--cream-lift); }

.eye .lid--lower,
.eye .crease {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.6;
  stroke-linecap: round;
}
.eye .crease { stroke-width: 1.9; }

.eye .waterline {
  fill: none;
  stroke: var(--ink);
  stroke-width: 3.5;
  stroke-linecap: round;
  opacity: 0.55;
}

.eye .iris__disc  { fill: var(--cream-lift); stroke: var(--ink); stroke-width: 1.4; }
.eye .iris__fibers path {
  stroke: var(--ink);
  stroke-width: 0.85;
  stroke-linecap: round;
  opacity: 0.62;
}
.eye .iris__ring  { fill: none; stroke: var(--ink); stroke-width: 3.2; opacity: 0.9; }
.eye .pupil       { fill: var(--ink); }
.eye .glint       { fill: #ffffff; transition: opacity 450ms ease; }
.eye .glint--sm   { opacity: 0.75; }

/* Open/closed states cross-fade for the blink. */
.eye .eye__open,
.eye .eye__closed { transition: opacity 70ms linear; }
.eye .eye__closed { opacity: 0; }

.eye.is-blinking .eye__open   { opacity: 0; }
.eye.is-blinking .eye__closed { opacity: 1; }

/* The iris is eased toward its target in a rAF loop (web/js/eyes.js), so it
   deliberately carries no CSS transition of its own. */
.eye .iris { will-change: transform; }

/* ---------------------------------------------------------- interest

   An occasional held gesture: the pupils blow wide until they nearly swallow
   the iris, and the whole eye scales up so it reads as leaning out of the
   screen toward you. Both directions are eased, and the return is slower than
   the onset — pupils dilate faster than they recover.

   Scaling the <svg> rather than anything inside it keeps the brow and lashes
   in proportion, and because transforms don't affect layout, nothing on the
   page reflows while it happens. */
.eye {
  transition: transform 1200ms cubic-bezier(0.33, 0, 0.35, 1);
  transform-origin: center 62%;   /* about the eye itself, not the brow */
}
.eye.is-interested {
  transform: scale(1.12);
  transition-duration: 850ms;
  transition-timing-function: cubic-bezier(0.16, 0.8, 0.3, 1);
}

/* fill-box so the circle scales about its own centre rather than the SVG
   origin. The .iris group's own translate is unaffected — a translate in px
   doesn't care about transform-origin. */
.eye .pupil {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 1100ms cubic-bezier(0.33, 0, 0.35, 1);
}
/* r=15.5 -> ~34, against an iris of r=38: a thin rim of iris survives. */
.eye.is-interested .pupil {
  transform: scale(2.2);
  transition-duration: 700ms;
  transition-timing-function: cubic-bezier(0.16, 0.8, 0.3, 1);
}

/* Catchlights go out as the pupil opens. A highlight sitting on a fully
   dilated pupil reads as gloss on a surface; without it the pupil reads as
   depth, which is what the gesture is after. Fades slightly faster than the
   dilation so it's gone by the time the pupil is wide. */
.eye.is-interested .glint { opacity: 0; }

/* On a phone the wordmark sits much closer, and a full 1.12 brings the brows
   up against it. The pupils carry the gesture anyway; the scale is only
   supporting it. */
@media (max-width: 640px) {
  .eye.is-interested { transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
  .eye,
  .eye .pupil,
  .eye .eye__open,
  .eye .eye__closed { transition: none; }
}

/* ---------------------------------------------------------------- search */

.search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: min(100%, 560px);
  padding: 0.35rem 0.35rem 0.35rem 1.25rem;
  background: var(--cream-lift);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset,
              0 10px 30px -18px rgba(60, 45, 20, 0.55);
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

.search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset,
              0 12px 34px -16px rgba(60, 45, 20, 0.6);
}

.search input {
  flex: 1;
  min-width: 0;
  padding: 0.7rem 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 1.02rem;
}
.search input::placeholder { color: var(--ink-faint); }
.search input:focus { outline: none; }
.search input::-webkit-search-cancel-button { -webkit-appearance: none; }

.search button {
  flex: none;
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border: 0;
  border-radius: 999px;
  background: var(--ink);
  color: var(--cream);
  cursor: pointer;
  transition: transform 140ms ease, background 140ms ease;
}
.search button:hover { transform: scale(1.06); background: #241d15; }
.search button:active { transform: scale(0.97); }
.search button svg {
  width: 19px; height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* ------------------------------------------------------- search previews */

.search { position: relative; }

.suggest {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  right: 0;
  z-index: 20;
  max-height: min(60vh, 26rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  text-align: left;
  background: var(--cream-lift);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 24px 48px -28px rgba(60, 45, 20, 0.75);
}

/* Row height is pinned so the "more" row can be exactly half of it. */
.suggest { --suggest-row: 5.15rem; }

.suggest__item {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: var(--suggest-row);
  padding: 0.4rem 0.55rem;
  border-radius: 12px;
  cursor: pointer;
}

/* Half-height row: three dots, centred both ways, leading to the full
   results page for the current query. */
.suggest__more {
  min-height: calc(var(--suggest-row) / 2);
  justify-content: center;
  gap: 0;
}

.suggest__dots { display: flex; align-items: center; gap: 6px; }
.suggest__dots i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink-faint);
  transition: background 140ms ease, transform 140ms ease;
}
.suggest__more[aria-selected="true"] .suggest__dots i { background: var(--ink); }
@media (hover: hover) {
  .suggest__more:hover .suggest__dots i { background: var(--ink); transform: scale(1.15); }
}
.suggest__item[aria-selected="true"] { background: var(--cream-sink); }
@media (hover: hover) {
  .suggest__item:hover { background: var(--cream-sink); }
}

.suggest__art {
  flex: none;
  width: 46px; height: 69px;
  overflow: hidden;
  border-radius: 5px;
  background: var(--cream-sink);
  border: 1px solid var(--line);
}
.suggest__art img { width: 100%; height: 100%; object-fit: cover; display: block; }

.suggest__text { min-width: 0; }
.suggest__title {
  display: block;
  font-family: var(--serif);
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1.25;
  /* Long titles must not widen the row and force the list to scroll sideways. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.suggest__meta {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

.hero__foot {
  padding: 1.25rem;
  text-align: center;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.hero__foot a { text-decoration: none; }
.hero__foot a:hover { color: var(--accent); }

/* ============================================================ inner pages */

.topbar {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 4vw, 2.5rem);
  max-width: var(--shell);
  margin: 0 auto;
  padding: 1.1rem clamp(1rem, 4vw, 2rem);
}

.topbar__mark {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: 1.4rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

.topbar .search {
  flex: 1;
  max-width: 520px;
  padding-left: 1rem;
}
.topbar .search input { padding: 0.5rem 0; font-size: 0.95rem; }
.topbar .search button { width: 36px; height: 36px; }

.shell {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 2rem) 4rem;
}

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 1.5rem 0 1.25rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--line);
}

.section-head h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.35rem;
  letter-spacing: 0.01em;
}
.section-head .count { color: var(--ink-faint); font-size: 0.88rem; }

/* ----------------------------------------------------------- result grid */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: clamp(1rem, 2.4vw, 1.75rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

.tile a {
  display: block;
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius);
}
.tile a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

.tile__art {
  position: relative;
  aspect-ratio: 2 / 3;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--cream-sink);
  border: 1px solid var(--line);
  box-shadow: 0 14px 30px -22px rgba(60, 45, 20, 0.8);
  transition: transform 220ms cubic-bezier(0.2, 0.7, 0.3, 1),
              box-shadow 220ms ease;
}
.tile a:hover .tile__art,
.tile a:focus-visible .tile__art {
  transform: translateY(-5px);
  box-shadow: 0 22px 40px -22px rgba(60, 45, 20, 0.85);
}

.tile__art img { width: 100%; height: 100%; object-fit: cover; display: block; }

.tile__art .noart {
  display: grid;
  place-items: center;
  height: 100%;
  padding: 1rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.9rem;
  color: var(--ink-faint);
  text-align: center;
}

.tile__kind {
  position: absolute;
  top: 0.55rem; left: 0.55rem;
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  background: rgba(23, 19, 14, 0.82);
  color: var(--cream);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.tile__name {
  margin: 0.6rem 0 0.1rem;
  font-family: var(--serif);
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1.3;
}
.tile__year { color: var(--ink-faint); font-size: 0.82rem; }

/* --------------------------------------------------------------- messages */

.note {
  margin: 3.5rem auto;
  max-width: 34rem;
  text-align: center;
  color: var(--ink-soft);
}
.note h2 {
  margin: 0 0 0.5rem;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: 1.5rem;
  color: var(--ink);
}
.note p { margin: 0.35rem 0; }

.spinner {
  width: 26px; height: 26px;
  margin: 3.5rem auto;
  border: 2px solid var(--line);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2s; }
  .tile__art { transition: none; }
}

/* ========================================================= sandbox probe */

.probe__intro { max-width: 62ch; color: var(--ink-soft); }

.probe { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 1.5rem; }

.probe__case {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--cream-lift);
}
.probe__case--risky { border-color: #c08a5a; }

.probe__head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: 0.9rem;
}

.probe__n {
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--cream);
  font-size: 0.85rem;
}

.probe__name { margin: 0; font-family: var(--serif); font-weight: 600; font-size: 1.05rem; }
.probe__note { margin: 0.15rem 0 0.4rem; font-size: 0.87rem; color: var(--ink-soft); }
.probe__tokens {
  display: inline-block;
  padding: 0.15rem 0.45rem;
  border-radius: 6px;
  background: var(--cream-sink);
  font-size: 0.76rem;
  word-break: break-word;
}

.probe__load {
  padding: 0.45rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--cream);
  color: var(--ink);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}
.probe__load:hover { border-color: var(--accent); }

.probe__frame:not(:empty) {
  position: relative;
  margin-top: 0.9rem;
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  overflow: hidden;
  background: #0d0b08;
}
.probe__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

@media (max-width: 560px) {
  .probe__head { grid-template-columns: auto 1fr; }
  .probe__load { grid-column: 2; justify-self: start; }
}

/* ============================================================ watch page */

.watch { max-width: var(--shell); margin: 0 auto; padding: 0 clamp(1rem, 4vw, 2rem) 4rem; }

.player {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: #0d0b08;
  box-shadow: 0 30px 60px -40px rgba(40, 30, 12, 0.9);
}
.player iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ---------------------------------------------------------- TV mode */

.tv-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
  padding: 0.55rem 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--cream-lift);
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease;
}
.tv-toggle:hover { border-color: var(--accent); }
.tv-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tv-toggle svg {
  width: 17px; height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

/* Fills the viewport for mirroring or casting a tab to a television. Works
   with or without the Fullscreen API — the layout doesn't depend on it. */
.stage--tv {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(0.75rem, 2vh, 1.5rem);
  padding: clamp(0.75rem, 2.5vw, 2rem);
  background: #0b0906;
}
.stage--tv .player {
  flex: 1;
  min-height: 0;
  aspect-ratio: auto;
  border: 0;
  border-radius: 10px;
}

  max-width: 60rem;
  width: 100%;
  margin: 0 auto;
  gap: clamp(0.6rem, 1.6vh, 1.1rem);
  padding: clamp(0.8rem, 2vh, 1.4rem) clamp(1rem, 3vw, 2rem);
  background: rgba(255, 252, 245, 0.06);
  border-color: rgba(255, 252, 245, 0.16);
}
  width: clamp(74px, 11vw, 104px);
  height: clamp(74px, 11vw, 104px);
  background: var(--cream);
  color: #0b0906;
}

.stage--tv .tv-toggle {
  align-self: center;
  margin: 0;
  background: rgba(255, 252, 245, 0.1);
  border-color: rgba(255, 252, 245, 0.22);
  color: var(--cream);
}

/* Everything else gets out of the way. */
body.is-tv > .topbar,
body.is-tv .watch > :not(.stage) { display: none; }
body.is-tv { overflow: hidden; }

.watch__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem;
  margin: 1.5rem 0 0.4rem;
}
.watch__head h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  line-height: 1.15;
}
.watch__head .year { color: var(--ink-faint); font-size: 1rem; }

.watch__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.1rem;
  margin: 0.5rem 0 1rem;
  color: var(--ink-soft);
  font-size: 0.88rem;
}
.watch__overview { max-width: 60ch; color: var(--ink-soft); }

.watch__source {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin: 1.1rem 0 0;
  font-size: 0.78rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Escape hatch for browsers that won't play the embed in a frame — notably
   iOS Safari, where cross-site iframes get partitioned storage. */
.watch__direct {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
}
.watch__direct:hover { color: var(--ink); }
.watch__direct:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* episode picker */
.picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin: 1.75rem 0 1rem;
}
.picker label { font-size: 0.85rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); }
.picker select {
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--cream-lift);
  color: var(--ink);
  font: inherit;
  font-size: 0.92rem;
  cursor: pointer;
}
.picker select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.episodes { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }

.episodes button {
  display: flex;
  gap: 0.9rem;
  width: 100%;
  padding: 0.7rem 0.9rem;
  border: 1px solid transparent;
  border-radius: 10px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}
.episodes button:hover { background: var(--cream-lift); border-color: var(--line); }
.episodes button[aria-current="true"] {
  background: var(--cream-lift);
  border-color: var(--accent);
}
.episodes .num {
  flex: none;
  width: 2.2rem;
  font-family: var(--serif);
  font-size: 1rem;
  color: var(--ink-faint);
}
.episodes .title { font-weight: 500; }
.episodes .still { color: var(--ink-faint); font-size: 0.84rem; }

@media (max-width: 640px) {
  .topbar { flex-wrap: wrap; }
  .topbar .search { order: 3; max-width: none; width: 100%; }
}

.probe__means {
  margin: 0 0 0.45rem;
  font-size: 0.85rem;
  color: var(--ink);
}
.probe__case--key { border-color: var(--ink); border-width: 2px; }
.probe__case--key .probe__means { font-weight: 600; }
