@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/courier-prime-400.3e919e4831db.woff2") format('woff2');
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/courier-prime-700.3313e74393da.woff2") format('woff2');
}
@font-face {
  font-family: 'Libre Baskerville';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/libre-baskerville-400.054afe25df5f.woff2") format('woff2');
}
@font-face {
  font-family: 'Libre Baskerville';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/libre-baskerville-700.60f20b9c60e0.woff2") format('woff2');
}
/* Feed headlines set movie and shelf titles in italic. */
@font-face {
  font-family: 'Libre Baskerville';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/libre-baskerville-400-italic.df16207575db.woff2") format('woff2');
}

/* Tokens from docs/design/DESIGN.md. The accent is darkened from #1a8a6a so white button text passes AA. */
:root {
  --bg: #f7f7f5;
  --surface: #ffffff;
  --border: #e4e2dc;
  --border-strong: #c8c4bb;
  --text-primary: #1a1915;
  --text-secondary: #6b6760;
  --accent: #177a5d;
  --accent-hover: #126349;
  --accent-tint: #eef6f2;        /* pressed pills in the rating popup */
  --accent-line: #d3e4da;        /* lines and the count on a tinted panel (the feed's friend requests) */
  --accent-text: #ffffff;
  --error: #a52a1f;
  --nav-bg: #1a1915;
  --nav-border: #2e2c28;
  --nav-text: #f0ede8;
  --nav-sub: #b8b4ac;
  --nav-sep: #4a473f;
  --nav-accent: #3a9e7a;         /* accent lifted for AA on the dark nav */
  --nav-badge: #078755;          /* the nav accent's hue, more saturated: the Friends badge */
  --unread-dot: #d4a012;
  --star: #f4c34b;            /* flat gold, no gradient */
  --star-deep: #c9a13b;       /* the feed's stars: a deeper flat gold, no outline */
  --star-empty: #e4e2dc;      /* --border */
  --star-outline: #404040;    /* 1px, shared by the stars and the rating slider */
  /* The Recommend seal: its gold is the one gradient on the site, by design. */
  --seal-light: #fdeaa7;
  --seal-gold: #e8b735;
  --seal-dark: #b98516;
  --seal-line: #7a5410;
  --shelf-wood: #5e4027;        /* the plank under shelf posters: dark brown, a nod to wood */
  --shelf-wood-top: #7d5a3c;    /* the plank's lighter top face */
  --radius: 6px;
  --mono: 'Courier Prime', ui-monospace, monospace;
  --serif: 'Libre Baskerville', Georgia, serif;
  /* Auth card only (DESIGN.md, "Auth card"): the system sans, and soft field fill. */
  --sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --field-fill: #efeee9;
  --pill: 999px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text-primary);
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.6;
  /* A column the height of the window, so a page's dock sits at the bottom of short pages. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main { flex: 1 0 auto; }

a { color: var(--accent); }

h1 {
  margin: 0 0 4px;
  font-size: 22px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

p { margin: 0 0 1em; }

/* Nav bar */

/* Three columns: wordmark and breadcrumb, the links centred whatever the sides hold, the settings icon. */
.site-header {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 4px 24px;
  min-height: 52px;
  padding: 10px 40px;
  background: var(--nav-bg);
  border-bottom: 1px solid var(--nav-border);
  color: var(--nav-text);
  font-family: var(--mono);
  font-size: 14px;
}

.site-header-left, .site-links {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* A long breadcrumb ends in an ellipsis rather than running under the links. */
.site-header-left { overflow: hidden; }
.brand { flex-shrink: 0; }
.breadcrumbs { display: flex; min-width: 0; }
.breadcrumbs > * { flex: 0 100 auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
/* Earlier crumbs give way first, so the current page keeps its name longest. */
.breadcrumbs > :last-child { flex-shrink: 1; }

.brand {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--nav-text);
  text-decoration: none;
}

.brand span { color: var(--nav-accent); }

.breadcrumbs > *::before {
  content: "/";
  margin: 0 12px;
  color: var(--nav-sep);
}

.breadcrumbs a { color: var(--nav-sub); text-decoration: none; }
.breadcrumbs a:hover { color: var(--nav-text); }
.breadcrumbs [aria-current] { color: var(--nav-text); }

/* Feed, Browse, Friends and My Shelves sit together in the middle; the settings icon keeps to the right edge. */
.site-links { justify-content: center; gap: 20px; }
.site-links-main, .site-links-end { display: flex; align-items: center; gap: 20px; }
.site-links .nav-icon { position: absolute; top: 50%; right: 40px; translate: 0 -50%; }

/* The magnifying glass before Browse, sized to the nav text. */
.nav-glyph { margin-right: 5px; vertical-align: -1px; }

/* The four links fit one line on a phone. */
@media (max-width: 420px) {
  .site-links, .site-links-main, .site-links-end { gap: 8px; }
  .site-links .site-links-user { padding: 3px 8px; }
}

.site-links a, .site-links .link-button {
  color: var(--nav-sub);
  font-family: var(--mono);
  font-size: 13px;
  text-decoration: none;
}

.site-links a:hover, .site-links .link-button:hover { color: var(--nav-text); }
/* My Shelves, the viewer's own page, stands out: bright text in a hairline pill. */
.site-links .site-links-user {
  max-width: 220px;
  overflow: hidden;
  padding: 4px 12px;
  border: 1px solid var(--nav-sep);
  border-radius: var(--pill);
  color: var(--nav-text);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The current page's link: the bright nav text over a nav accent underline. */
.site-links a[aria-current="page"] {
  color: var(--nav-text);
  text-decoration: underline;
  text-decoration-color: var(--nav-accent);
  text-decoration-thickness: 3px;
  text-underline-offset: 6px;
}
/* On My Shelves the pill itself turns the nav accent instead of an underline. */
.site-links .site-links-user[aria-current="page"] { border-color: var(--nav-accent); text-decoration: none; }

.site-links .nav-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius);
}

.site-links .nav-icon:hover { background: var(--nav-border); }

/* Pending friend requests; the dot color passes AA as text on the dark nav. */
/* The Friends badge, like a phone's app badge: a green circle just after the word, raised a little,
   so it never covers the text. */
.nav-count {
  display: inline-block;
  position: relative;
  top: -3px;
  box-sizing: border-box;
  /* The mono space before it plus the ring would leave ~10px; close it to ~5px. */
  margin-left: -5px;
  min-width: 22px;
  height: 22px;
  padding: 0 5px;
  border: 2px solid var(--nav-bg);
  border-radius: var(--pill);
  background: var(--nav-badge);
  color: #ffffff;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Page */

.container {
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  padding: 40px 24px 0;
}

.page-header { margin-bottom: 24px; }

.meta, .muted {
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 12.5px;
}

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.inline { display: inline; margin: 0; }

/* Forms */

form p, form > div { margin: 0 0 18px; }

label {
  display: block;
  margin-bottom: 6px;
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

input[type="email"],
input[type="password"],
input[type="text"],
input[type="search"],
input[type="number"],
textarea {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  color: var(--text-primary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
}

input::placeholder { color: var(--text-secondary); }

textarea { display: block; line-height: 1.7; resize: vertical; }

input:focus, textarea:focus {
  border-color: var(--accent);
  outline: 1px solid var(--accent);
  outline-offset: 0;
}

input[type="checkbox"] { accent-color: var(--accent); }

button, .button {
  /* Flex so link buttons centre their text like real buttons at the 44px minimum. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 9px 16px;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.03em;
  line-height: 1.4;
  color: var(--accent-text);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  text-decoration: none;
  cursor: pointer;
}

button:hover, .button:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.button-secondary, button.button-secondary {
  color: var(--text-primary);
  background: var(--bg);
  border-color: var(--border-strong);
}

.button-secondary:hover, button.button-secondary:hover { background: var(--border); border-color: var(--border-strong); }

.link-button, .link-button:hover {
  min-height: 0;
  padding: 0;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--accent);
  background: none;
  border: 0;
}

.errorlist {
  margin: 4px 0;
  padding: 0;
  list-style: none;
  color: var(--error);
  font-size: 13px;
}

.helptext, .helptext ul { color: var(--text-secondary); font-size: 12.5px; }
.helptext ul { padding-left: 1.2em; }

/* Messages and notices */

.messages { margin: 0 0 24px; padding: 0; list-style: none; }

.message, .notice {
  margin: 0 0 8px;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: inset 4px 0 0 var(--accent);
  border-radius: var(--radius);
}

.message.error, .notice-error { box-shadow: inset 4px 0 0 var(--error); }

/* htmx's own indicator styles are inline, which the CSP blocks. */
.htmx-indicator { opacity: 0; transition: opacity 150ms ease-in; }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { opacity: 1; }

/* Posters: 2:3, hairline border; the fallback block shows the title when TMDB has no image. */

.poster {
  flex: none;
  display: block;
  width: 48px;
  aspect-ratio: 2 / 3;
  height: auto;
  object-fit: cover;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
}

.poster-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  overflow: hidden;
  color: var(--text-secondary);
  font-size: 7px;
  line-height: 1.3;
  text-align: center;
  overflow-wrap: anywhere;
}

/* Movie search */

.page-narrow { max-width: 760px; margin: 0 auto; }
.page-narrow.browse { max-width: 880px; }

.movie-search { position: relative; margin-bottom: 24px; }

input[type="search"] { padding: 12px 14px; font-size: 16px; }
.browse input[type="search"] { padding: 14px 16px 14px 46px; font-size: 17px; }

.search-glyph {
  position: absolute;
  top: 50%;
  left: 16px;
  color: var(--text-secondary);
  transform: translateY(-50%);
  pointer-events: none;
}

#search-spinner {
  position: absolute;
  right: 14px;
  bottom: 14px;
  pointer-events: none;
}

.movie-results { margin: 0; padding: 0; list-style: none; }

/* The rating popup reaches past the list, so the list can't clip its rows to the corners. */
.movie-results li:first-child, .movie-results li:first-child > a { border-radius: var(--radius) var(--radius) 0 0; }
.movie-results li:last-child, .movie-results li:last-child > a { border-radius: 0 0 var(--radius) var(--radius); }
.movie-results li:only-child, .movie-results li:only-child > a { border-radius: var(--radius); }

.movie-results li + li { border-top: 1px solid var(--border); }

.movie-results li > a {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 16px;
  color: var(--text-primary);
  text-decoration: none;
}

.movie-results li > a:hover, .movie-results li > a:focus-visible { background: var(--bg); }
.movie-results li > a:focus-visible { outline: none; box-shadow: inset 4px 0 0 var(--accent); }

/* Signed in, the poster is the rating popup's button and only the title is the link. */
.movie-results li.result-rateable { display: flex; align-items: center; padding: 12px 0 12px 16px; }
.movie-results li.result-rateable:hover { background: var(--bg); }
.movie-results li.result-rateable > a { flex: 1; align-self: stretch; margin: -12px 0; }

.result-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.result-title { font-size: 17px; font-weight: 700; line-height: 1.3; }

/* Movie page */

.movie { display: flex; gap: 32px; align-items: flex-start; padding: 28px 32px; }

.poster-large { width: 160px; }
.poster-large.poster-fallback { padding: 12px; font-size: 14px; }

.movie-info { min-width: 0; }
.movie-info h1 { margin-bottom: 6px; }
.year { color: var(--text-secondary); font-weight: 400; }
.movie-info .meta { margin-bottom: 16px; }
/* Directed by, Written by and Starring read as one block. */
.movie-info .movie-directors:has(+ .movie-writers, + .movie-cast),
.movie-info .movie-writers:has(+ .movie-cast) { margin-bottom: 6px; }

.reading { font-size: 15px; line-height: 1.7; }

.movie-links { display: flex; flex-wrap: wrap; gap: 16px; margin: 20px 0 0; font-family: var(--mono); font-size: 13px; letter-spacing: 0.03em; }
.movie-links a { color: var(--text-secondary); text-decoration: none; }
.movie-links a:hover { color: var(--text-primary); text-decoration: underline; }
.movie-seasons { margin-top: 24px; }
.movie-seasons .section-label { margin-bottom: 8px; }
.season-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--border); }
.season-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.season-name { margin-right: auto; }
.season-meta { color: var(--text-secondary); font-family: var(--mono); font-size: 12.5px; }

/* Signed out, one 760px column. Signed in, the movie and friends' reviews on the left and the
   review panel in a sticky right-hand column; below 900px one column in page order. */
.movie-layout { display: grid; gap: 32px; max-width: 760px; margin: 0 auto; }
.movie-layout-split { grid-template-columns: minmax(0, 1fr) 340px; grid-template-rows: auto auto 1fr; column-gap: 24px; max-width: none; }
.movie-layout-split .movie { grid-column: 1; grid-row: 1; }
.movie-layout-split .review-panel { grid-column: 2; grid-row: 1 / span 3; align-self: start; position: sticky; top: 24px; }
.movie-layout-split .movie-reviews { grid-column: 1; grid-row: 2; align-self: start; }
.movie-layout-split .movie-posts { grid-column: 1; grid-row: 3; align-self: start; }

@media (max-width: 900px) {
  .movie-layout-split { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; max-width: 760px; }
  .movie-layout-split :is(.movie, .review-panel, .movie-reviews, .movie-posts) { grid-column: auto; grid-row: auto; }
  .movie-layout-split .review-panel { position: static; }
}

@media (max-width: 700px) {
  .movie { flex-direction: column; gap: 20px; padding: 20px; }
  .poster-large { width: 120px; }
  /* Set by static/js/feed-more.js; without script the whole synopsis shows. */
  .movie-overview.is-clamped { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 4; }
  /* Signed in, the poster, title and credits head the page on its background, then the review
     panel, then the synopsis, links and seasons in their own panel, so rating needs no scrolling. */
  .movie-layout-split { row-gap: 20px; }
  .movie-layout-split .movie,
  .movie-layout-split .movie-info { display: contents; }
  .movie-layout-split .movie-head > :last-child { margin-bottom: 0; }
  .movie-layout-split .movie-about { order: 1; padding: 20px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
  .movie-layout-split .movie-reviews { order: 2; margin-top: 12px; }
  .movie-layout-split .movie-posts { order: 3; }
}

/* Reviews on the movie page */

/* Friends' reviews: rows in one panel, name and date on one line, text under them. */
.review-list { overflow: hidden; }
.review-row { padding: 16px 24px; }
.review-row + .review-row { border-top: 1px solid var(--border); }
.review-row-own { margin-bottom: 12px; }
.review-row .review-byline { flex-direction: row; flex-wrap: wrap; align-items: baseline; column-gap: 10px; }
.review-row .reading { margin: 10px 0 0 48px; overflow-wrap: anywhere; }
.review-row .review-gesture { margin: 6px 0 0 48px; }
/* Posts on a title's page, under its reviews: the composer, then a row per post. */
.movie-posts { margin-top: 8px; }
.post-row { padding: 16px 24px; }
.post-row + .post-row { border-top: 1px solid var(--border); }
.post-row .review-byline { flex-direction: row; flex-wrap: wrap; align-items: baseline; column-gap: 10px; }
.post-row > .reading, .post-row > .feed-spoiler { margin: 10px 0 0 48px; overflow-wrap: anywhere; }
.post-row .feed-spoiler .reading { margin: 6px 0 0; }
.posts-more { display: block; padding: 12px 24px; border-top: 1px solid var(--border); font-family: var(--mono); font-size: 12.5px; color: var(--text-secondary); }

/* Comments: a thread under each row on the movie page (DESIGN.md, "Comment"). */
.thread { display: flex; flex-direction: column; gap: 8px; margin: 14px 0 0 48px; }
.thread-more { align-self: flex-start; font-family: var(--mono); font-size: 12.5px; color: var(--text-secondary); }
.comment { display: flex; gap: 10px; padding: 12px 14px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; }
.comment-body { flex: 1 1 auto; min-width: 0; }
.comment-head { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 10px; margin: 0; }
.comment-name { font-size: 15px; font-weight: 700; }
.comment-delete { margin-left: auto; }
.comment-delete .text-button { font-family: var(--mono); font-size: 12.5px; color: var(--text-secondary); }
.comment-text { margin-top: 4px; font-size: 13.5px; line-height: 1.6; overflow-wrap: anywhere; }
.comment-box { display: flex; align-items: flex-end; gap: 8px; }
.comment-box textarea { flex: 1 1 auto; min-width: 0; min-height: 0; max-height: 200px; padding: 8px 12px; font: inherit; font-size: 13.5px; line-height: 1.6; field-sizing: content; resize: none; }
/* The button appears once there is something to send. */
.comment-box:not(:has(.comment-box-texts)):has(textarea:placeholder-shown) :is(button, .comment-private-toggle) { display: none; }
.comment-private-toggle { display: inline-flex; align-items: center; gap: 6px; align-self: center; margin: 0; font-family: var(--mono); font-size: 12.5px; font-weight: 400; letter-spacing: normal; text-transform: none; color: var(--text-secondary); white-space: nowrap; }
.comment-private-toggle input { margin: 0; accent-color: var(--accent); }
.comment-error { margin: 0; }

@media (max-width: 700px) {
  .review-row { padding: 14px 16px; }
  .review-row .review-header { flex-wrap: wrap; }
  .review-row .card-rating { flex-basis: 100%; margin-left: 48px; }
  .review-row .reading { margin-left: 0; }
  .review-row .review-gesture { margin-left: 0; }
  .review-row .thread { margin-left: 0; }
}

.review-header { display: flex; align-items: center; gap: 12px; }
.review-byline { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.review-name { font-size: 18px; font-weight: 700; line-height: 1.3; overflow-wrap: anywhere; }

.avatar-medium { width: 36px; height: 36px; font-size: 16px; }

/* Star ratings: highest star on the left. Each star is an empty star with a
   gold copy on top, clipped by a nested svg to the filled share. */

.stars { display: inline-flex; gap: 4px; }
.star { display: block; overflow: visible; }
.star path { stroke: var(--star-outline); stroke-width: 1px; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.star-empty { fill: var(--star-empty); }
.star-full { fill: var(--star); }
.stars-small .star { width: 18px; height: 18px; }
.stars-small { gap: 3px; }

.card-rating {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
}

/* Friends page */

/* Invite friends at the header's right, like New shelf on My Shelves. */
.friends-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }
.friends-header h1 { margin: 0; }

.section-label {
  margin: 0 0 8px;
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.section-label .count { margin-left: 6px; }

.person-list { margin: 0; padding: 0; list-style: none; }

.person-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 10px 16px;
}

.person-row + .person-row { border-top: 1px solid var(--border); }

.avatar {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--text-primary);
  color: var(--nav-text);
  font-family: var(--serif);
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
}

.person-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 15px;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.person-link { flex: 1 1 auto; min-width: 0; display: flex; color: var(--text-primary); text-decoration: none; }
.person-link:hover .person-name { text-decoration: underline; text-decoration-color: var(--border-strong); }

.row-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }

.friends-aside { display: grid; gap: 24px; }
.aside-panel { padding: 20px; }
.aside-panel form, .aside-panel form > div { margin: 0; }
.stacked-form { display: grid; gap: 12px; }

input.link-field { font-family: var(--mono); font-size: 12.5px; color: var(--text-secondary); }
.link-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.link-actions form { margin: 0; }

/* Friends page (friends/page.html): requests, a card per friend, then the addresses invited.
   Wide like My Shelves. */

.friends-header { margin-bottom: 24px; }

.friend-requests { display: grid; gap: 12px; margin-bottom: 12px; }

.request-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  padding: 14px 24px;
  background: var(--accent-tint);
  border: 1px solid var(--accent-line);
  border-radius: 12px;
}

.request-panel > .avatar { width: 40px; height: 40px; font-size: 18px; }
.request-who { flex: 1 1 240px; min-width: 0; }
.request-line { margin: 0; font-size: 15px; overflow-wrap: anywhere; }
.request-line .person-name { font-size: 18px; }
.request-meta { margin: 3px 0 0; }
.request-panel .row-actions form { margin: 0; }

.friend-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }

.friend-card { padding: 20px 24px 22px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }

.friend-card-head { display: flex; align-items: center; gap: 14px; }
.friend-card-head > .avatar { width: 44px; height: 44px; font-size: 20px; }
.friend-card-who { flex: 0 1 auto; min-width: 0; }
.friend-card-name { margin: 0; font-size: 22px; line-height: 1.2; letter-spacing: -0.01em; }
.friend-card-name .person-name { font-size: inherit; }
.friend-card-meta { display: flex; align-items: flex-start; gap: 6px; margin: 4px 0 0; }
.friend-card-meta .seal { flex: none; margin-top: 1px; }
.friend-card-none { margin: 14px 0 0 58px; }

/* Custom shelves: tabs to the friend's named shelves, right-aligned before the ⋯ button. */
.friend-shelves { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-left: auto; }
.friend-shelves-label {
  margin-right: 4px;
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.shelf-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 36px;
  padding: 0 12px 0 10px;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}
.shelf-tab:hover { background: var(--bg); }
.shelf-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.shelf-tab-glyph { flex: none; }
.shelf-tab-book { fill: none; stroke: var(--text-secondary); stroke-width: 1.2; }
.shelf-tab-plank { fill: var(--shelf-wood); }
.shelf-tab-count { color: var(--text-secondary); font-family: var(--mono); font-size: 12px; font-weight: 400; }

/* ⋯ and its menu (static/js/friend-menu.js). */
.friend-more { position: relative; flex: none; margin-left: auto; }
.friend-shelves + .friend-more { margin-left: 0; }
.friend-more-button, .friend-more-button:hover {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--text-secondary);
  background: none;
  border: 0;
  border-radius: 6px;
}
.friend-more-button:hover, .friend-more-button[aria-expanded="true"] { color: var(--text-primary); background: var(--bg); }
.friend-more-button svg { fill: currentColor; }
.friend-menu {
  position: absolute;
  z-index: 10;
  top: calc(100% + 4px);
  right: 0;
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
}
.friend-menu form { margin: 0; }
.friend-menu button { white-space: nowrap; }

/* The plank: what the friend recommends, new to the viewer first, standing on the My Shelves
   plank that runs the card's width under the name. Titles and marks sit below it. */
.friend-plank {
  --new-w: 84px;
  --rated-w: 56px;
  --stand: calc(var(--new-w) * 1.5);
  --label-h: 24px;
  --plank: 10px;
  margin: 20px 0 0 58px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
}
.friend-plank:not(.has-new) { --stand: calc(var(--rated-w) * 1.5); }
.friend-plank.is-fitted { overflow-x: hidden; }

.friend-plank-shelf {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 36px;
  box-sizing: border-box;
  width: max-content;
  min-width: 100%;
  padding: 0 8px 4px;
}
.friend-plank-shelf::before {
  content: "";
  position: absolute;
  top: calc(var(--label-h) + 10px + var(--stand));
  left: 0;
  right: 0;
  box-sizing: border-box;
  height: var(--plank);
  background: var(--shelf-wood);
  border-top: 3px solid var(--shelf-wood-top);
  box-shadow: 0 2px 0 rgb(26 25 21 / 0.16), 0 4px 0 rgb(26 25 21 / 0.07);
}

.plank-group[hidden] { display: none; }
.plank-label {
  box-sizing: border-box;
  height: var(--label-h);
  margin: 0 0 10px;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-strong);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.plank-new .plank-label { color: var(--accent); border-bottom: 2px solid var(--accent); }
/* The +N tile follows the last poster at the posters' gap, under no label. */
.plank-end { margin-left: -26px; padding-top: calc(var(--label-h) + 10px); }

.plank-posters { display: flex; gap: 14px; margin: 0; padding: 0; list-style: none; }
.plank-rated .plank-posters { gap: 10px; }
.plank-posters li { flex: none; display: flex; flex-direction: column; scroll-snap-align: start; }
.plank-posters li[hidden] { display: none; }
.plank-new li { width: var(--new-w); }
.plank-rated li, .plank-end li { width: var(--rated-w); }
.plank-posters a { display: flex; flex-direction: column; color: var(--text-primary); text-decoration: none; }
.plank-stand { display: flex; align-items: flex-end; height: var(--stand); }
.plank-stand .poster { width: 100%; box-shadow: 0 2px 6px rgb(26 25 21 / 0.18); }
.plank-stand .poster-fallback { box-sizing: border-box; aspect-ratio: 2 / 3; padding: 4px; font-size: 8px; }
.plank-new .poster-fallback { padding: 6px; font-size: 11px; }
.plank-posters a:hover .poster, .plank-posters a:focus-visible .poster { border-color: var(--accent); }
.plank-posters a:hover .plank-title { text-decoration: underline; }
.plank-title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  margin-top: calc(var(--plank) + 6px);
  font-size: 12.5px;
  line-height: 1.35;
  overflow-wrap: break-word;
  hyphens: auto;
}
.plank-year { margin-top: 2px; color: var(--text-secondary); font-family: var(--mono); font-size: 12px; }
.plank-mark {
  display: flex;
  align-items: center;
  gap: 3px;
  margin-top: calc(var(--plank) + 6px);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.plank-star { flex: none; fill: var(--star); stroke: var(--star-outline); stroke-width: 1.5; }
.plank-more { height: var(--stand); justify-content: flex-end; }
.plank-more a {
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: var(--rated-w);
  aspect-ratio: 2 / 3;
  padding: 4px;
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.3;
  text-align: center;
}
.plank-more a:hover, .plank-more a:focus-visible { color: var(--text-primary); border-color: var(--accent); }

/* Invited: one mono line per address, Cancel as underlined text. */
.friends-sent { margin-top: 28px; }
.friends-sent .person-row { display: block; padding: 2px 0; color: var(--text-secondary); font-family: var(--mono); font-size: 12.5px; }
.friends-sent .person-row + .person-row { border-top: 0; }
.friends-sent .person-name { font-size: inherit; font-weight: 400; }
.friends-sent form { display: inline; margin: 0; }
.text-button, .text-button:hover {
  min-height: 0;
  padding: 0;
  color: inherit;
  background: none;
  border: 0;
  font: inherit;
  letter-spacing: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.text-button:hover { color: var(--text-primary); }

/* No friends yet: a centred panel with the group link. */
.friends-empty { max-width: 440px; margin: 24px auto 0; padding: 28px 28px 24px; border-radius: 12px; }
.friends-empty-title { margin: 0 0 18px; font-size: 18px; }
.friends-empty .link-actions button { flex: 1 1 0; }
.friends-empty-more { display: inline-block; margin-top: 16px; color: var(--text-secondary); font-family: var(--mono); font-size: 13px; text-underline-offset: 3px; }
.friends-empty-more:hover { color: var(--text-primary); }

@media (max-width: 600px) {
  .request-panel { padding: 14px 16px; }
  .request-panel .row-actions { flex-basis: 100%; margin-left: 56px; }
  .friend-card { padding: 16px; }
  .friend-card-head { flex-wrap: wrap; row-gap: 12px; }
  .friend-card-who { flex: 1 1 0; }
  .friend-more { order: 2; margin-left: 0; }
  .friend-shelves { order: 3; flex-basis: 100%; justify-content: flex-start; margin-left: 58px; }
  .friend-plank { --new-w: 72px; --rated-w: 50px; margin-left: 0; }
  .friend-plank-shelf { padding: 0 0 4px; }
  .friend-card-none { margin-left: 0; }
}

/* Share prompt: Invite page, and the friendless Feed */

.share-prompt { max-width: 420px; margin: 0 0 24px; padding: 20px; }
.share-prompt-title { margin: 0 0 12px; font-size: 15px; }
.share-prompt .link-actions button { flex: 1 1 0; }
.share-page { max-width: 760px; }

/* My Shelves' Invite Friends? banner, until a first friend or the × */
.invite-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 24px;
  padding: 4px 4px 4px 20px;
  background: var(--accent-tint);
  border: 1px solid var(--accent-line);
  border-radius: 12px;
}
.invite-banner a { font-weight: 700; }
.invite-banner form { margin: 0; }
.invite-banner-close, .invite-banner-close:hover {
  width: 44px;
  min-height: 44px;
  padding: 0;
  color: var(--text-secondary);
  background: none;
  border: 0;
  font-size: 22px;
  line-height: 1;
}
.invite-banner-close:hover { color: var(--text-primary); }
.link-reset { margin: 10px 0 0; color: var(--text-secondary); font-family: var(--mono); font-size: 12.5px; }

/* Invite a group / individual friends: the graph (static/js/connected-group.js) beside the list it draws. */

.connected-group { margin-bottom: 16px; padding: 24px; }
/* The shape cards (DEBUG only for now): a small picture and a name, the picked one tinted. */
.invite-modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; margin: 0 0 24px; padding: 0; border: 0; }
.invite-mode { display: flex; align-items: center; gap: 14px; min-height: 44px; margin: 0; padding: 14px 16px; color: var(--text-primary); font-family: var(--serif); font-size: 15px; font-weight: 700; letter-spacing: 0; text-transform: none; background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius); cursor: pointer; }
.invite-mode:has(input:checked) { background: var(--accent-tint); border-color: var(--accent); }
.invite-mode:has(input:disabled) { color: var(--text-secondary); cursor: not-allowed; }
.invite-mode input { margin: 0; accent-color: var(--accent); }
.invite-mode-icon { flex: none; }
.invite-mode-lines { stroke: var(--text-primary); stroke-width: 1.5; }
.invite-mode-icon circle { fill: var(--text-primary); }
.invite-mode-icon .invite-mode-you { fill: var(--accent); }
.connected-group-body { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 32px; align-items: start; }
.group-graph svg, .group-graph img { display: block; width: 260px; max-width: 100%; height: auto; }
.group-builder[hidden] { display: none; }
.group-add { display: flex; align-items: flex-start; gap: 8px; margin: 0; }
/* Takes a pasted list: two lines to start, growing a little with what's typed. */
.group-add textarea { flex: 1 1 auto; min-width: 0; min-height: 72px; max-height: 160px; field-sizing: content; resize: none; }
.group-add button { flex: none; }
.group-error { min-height: 1.5em; margin: 6px 0 10px; font-family: var(--mono); font-size: 12.5px; color: var(--error); }
.group-list { display: grid; gap: 4px; margin: 0 0 8px; padding: 0; list-style: none; }
.group-member { display: flex; align-items: center; gap: 12px; min-height: 44px; font-family: var(--mono); font-size: 14px; overflow-wrap: anywhere; }
.group-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--text-primary); }
.group-you .group-dot { background: var(--accent); }
button.group-remove { flex: none; margin-left: auto; padding: 4px 10px; font-size: 12.5px; font-weight: 400; color: var(--text-secondary); background: var(--surface); border-color: var(--border); }
button.group-remove:hover { color: var(--text-primary); background: var(--bg); border-color: var(--border-strong); }
.group-count { margin: 0 0 16px; }
.connected-group-side .link-actions button { flex: 1 1 0; }
.connected-group-side button:disabled { color: var(--text-secondary); background: var(--bg); border-color: var(--border); cursor: not-allowed; }
.connected-group-side [data-link-help], .group-soon { margin: 10px 0 0; }
.circle-create { margin: 0; }
.circle-create .group-error { margin-bottom: 0; }

/* A live circle's panel on the invite page: a one-line header that opens to the rest. */
.circle-panel { margin-bottom: 16px; padding: 0; }
.circle-summary { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; min-height: 44px; padding: 16px 24px; cursor: pointer; list-style: none; }
.circle-summary::-webkit-details-marker { display: none; }
.circle-title { font-size: 18px; font-weight: 700; }
.circle-body { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 32px; align-items: start; padding: 0 24px 24px; }
.circle-graph svg { display: block; width: 260px; max-width: 100%; height: auto; }
.circle-slot { fill: none; stroke: var(--border-strong); stroke-width: 2; stroke-dasharray: 4 4; }
.circle-dot { fill: var(--text-primary); stroke: var(--text-primary); stroke-width: 2; }
.circle-dot-you { fill: var(--accent); stroke: var(--accent); }
.circle-dot-open { fill: var(--surface); }
.circle-side { min-width: 0; }
.circle-rename { margin: 0 0 16px; }
.circle-heading { margin: 20px 0 4px; }
.group-member .row-actions { display: flex; gap: 6px; margin-left: auto; }
.group-member form { margin: 0; }
.group-dot-open { background: var(--surface); border: 2px solid var(--text-primary); }
.circle-actions { margin-top: 16px; }

.group-email { margin-top: 24px; }
.group-email summary { min-height: 44px; display: flex; align-items: center; font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--accent); cursor: pointer; }
.group-email[open] summary { margin-bottom: 8px; }
.group-email form { margin: 0; }
.group-edge { stroke: var(--text-primary); stroke-linecap: round; }
.group-node { fill: var(--text-primary); }
.group-node-you { fill: var(--accent); }
.group-placeholder line { stroke: var(--border-strong); }
.group-placeholder circle { fill: var(--border-strong); }

@media (max-width: 700px) {
  .circle-summary { padding: 16px; }
  .circle-body { grid-template-columns: minmax(0, 1fr); gap: 20px; padding: 0 16px 20px; }
  .circle-graph { justify-self: center; }
  .connected-group { padding: 20px 16px; }
  .connected-group-body { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .group-graph { justify-self: center; }
}

/* Invite page */

.invite-panel {
  max-width: 420px;
  margin: 0 auto;
  padding: 32px;
  text-align: center;
}

.avatar-large { width: 56px; height: 56px; font-size: 25px; }

.invite-name {
  margin: 16px 0 20px;
  font-size: 32px;
  line-height: 1.1;
  overflow-wrap: anywhere;
}

.invite-recommended { margin: 0 -32px 24px; text-align: left; }
.invite-recommended .section-label { margin: 0 32px 8px; }

.invite-posters {
  display: flex;
  gap: 12px;
  margin: 0;
  padding: 0 32px 4px;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.invite-posters li { flex: none; width: 67px; }
.invite-posters .poster { width: 67px; }
.invite-posters .poster-fallback { padding: 6px; font-size: 9px; }
.invite-posters .shelf-title { padding: 0; }

.invite-panel form { margin: 0; }
.invite-actions { display: grid; gap: 8px; }
.invite-panel button, .invite-panel .button { width: 100%; text-align: center; }

/* Waiting on a request (friends/_waiting.html): You and the other person, a dashed line between. */

.waiting { text-align: center; }
.waiting-graph { display: block; width: 220px; max-width: 100%; height: auto; margin: 0 auto 16px; }
.waiting-edge { stroke: var(--border-strong); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 2 9; }
.waiting-node { fill: var(--text-primary); }
.waiting-node-you { fill: var(--accent); }
.waiting-initial { fill: var(--nav-text); font-family: var(--serif); font-size: 23px; font-weight: 700; }
.waiting-line { margin: 0; font-size: 18px; line-height: 1.4; overflow-wrap: anywhere; }

/* Welcome page: the request, then two places to start. */

.waiting-panel { margin-bottom: 16px; padding: 32px; border-radius: 12px; }
.welcome-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.welcome-tile {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 18px;
  min-height: 200px;
  padding: 28px 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--text-primary);
  text-align: center;
  text-decoration: none;
  transition: border-color 250ms;
}
.welcome-tile:hover, .welcome-tile:focus-visible { border-color: var(--accent); }
.welcome-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.welcome-tile-title { max-width: 16em; font-size: 19px; font-weight: 700; line-height: 1.35; }
.welcome-glyph { display: block; }
.welcome-glyph-line { stroke: var(--accent); stroke-width: 4; stroke-linecap: round; }
.welcome-glyph-poster { fill: var(--text-primary); }
.welcome-glyph-slot { fill: none; stroke: var(--border-strong); stroke-width: 1.5; stroke-dasharray: 3 2; }
.welcome-glyph-plank-top { fill: var(--shelf-wood-top); }
.welcome-glyph-plank { fill: var(--shelf-wood); }

@media (max-width: 700px) {
  .waiting-panel { padding: 24px 16px; }
  .welcome-tiles { grid-template-columns: 1fr; gap: 12px; }
  .welcome-tile { min-height: 0; padding: 24px 16px; grid-template-columns: auto 1fr; align-items: center; justify-items: start; text-align: left; }
  .welcome-tile-title { font-size: 17px; }
  .welcome-glyph { width: 48px; height: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  .welcome-tile { transition: none; }
}

/* Review form */


/* The number spans the stars and the slider beneath them. */
.rating-picker {
  display: inline-grid;
  grid-template-columns: auto auto;
  column-gap: 20px;
  row-gap: 12px;
  align-items: center;
  max-width: 100%;
}

.rating-number {
  grid-row: 1 / span 2;
  min-width: 2.4ch;
  font-family: var(--mono);
  font-size: 120px;
  font-weight: 700;
  line-height: 0.72;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}

.rating-picker .stars, .rating-picker input { grid-column: 2; }

/* --fill is set by rating-picker.js. The track's fill is one flat colour layer, not a gradient. */
.rating-picker input[type="range"] {
  --fill: 0%;
  width: 100%;
  height: 24px;
  margin: 0;
  background: transparent;
  appearance: none;
  cursor: pointer;
}

.rating-picker input[type="range"]::-webkit-slider-runnable-track {
  height: 10px;
  border: 1px solid var(--star-outline);
  border-radius: 6px;
  background: linear-gradient(var(--star), var(--star)) right / var(--fill) 100% no-repeat, var(--star-empty);
}

.rating-picker input[type="range"]::-moz-range-track {
  height: 8px;
  border: 1px solid var(--star-outline);
  border-radius: 6px;
  background: linear-gradient(var(--star), var(--star)) right / var(--fill) 100% no-repeat, var(--star-empty);
}

.rating-picker input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  width: 24px;
  height: 24px;
  margin-top: -8px;
  border: 1px solid var(--star-outline);
  border-radius: 50%;
  background: var(--star);
}

.rating-picker input[type="range"]::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border: 1px solid var(--star-outline);
  border-radius: 50%;
  background: var(--star);
}

.rating-picker input[type="range"]:focus { outline: none; }
.rating-picker input[type="range"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.form-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.form-actions-end { margin-left: auto; }

.confirm-panel { max-width: 420px; margin: 0 auto; padding: 28px 32px; }
.confirm-panel .meta { margin-bottom: 20px; }

@media (max-width: 700px) {
  .confirm-panel { padding: 20px; }
  .rating-picker { column-gap: 14px; }
  .rating-number { font-size: 64px; letter-spacing: -0.02em; }
}

/* Rating popup on posters (reviews/_rate_popup.html, static/js/rate-popup.js).
   Hover opens it where there is a mouse; a tap, click or Enter sets .is-open. */

.rate-poster { position: relative; flex: none; }

.rate-poster-button, .rate-poster-button:hover {
  display: block;
  min-height: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 4px;
}

.rate-poster-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.rate-popup {
  display: none;
  position: absolute;
  z-index: 10;
  top: -12px;
  left: calc(100% + 12px);
  width: 300px;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 14px;
  border-radius: 18px;
}

/* Fills the gap beside the poster so the pointer can cross into the popup. */
.rate-popup::before { content: ""; position: absolute; top: 0; bottom: 0; right: 100%; width: 14px; }

.rate-poster.is-open .rate-popup { display: flex; }

/* Typing in the popup keeps it open after the pointer leaves. */
.rate-popup:focus-within { display: flex; }

@media (hover: hover) {
  .rate-poster:hover .rate-popup { display: flex; }
}

/* A linked poster (director and actor grids) opens on focus, since Enter follows the link. */
.rate-poster-linked:focus-within .rate-popup { display: flex; }

/* In a row that scrolls sideways (friend planks, shelf rows) the popup is fixed to the viewport,
   placed by rate-popup.js under the poster, or over it with .is-above. */
.rate-poster-float .rate-popup { position: fixed; top: var(--float-top, 0); left: var(--float-left, 0); }
.rate-poster-float .rate-popup::before { top: auto; bottom: 100%; right: 0; left: 0; width: auto; height: 14px; }
.rate-poster-float.is-above .rate-popup::before { top: 100%; bottom: auto; }

.rate-popup > div { margin: 0; }
.rate-status { flex: 1; min-height: 1.4em; margin: 0; }

@media (max-width: 700px) {
  .rate-popup { top: calc(100% + 12px); left: 0; }
  .rate-popup::before { top: auto; bottom: 100%; right: 0; left: 0; width: auto; height: 14px; }
}

/* Director page: a grid of posters, title and year under each. Fixed column counts let the
   rating popup open below a poster and line up with whichever edge keeps it on the page. */

.poster-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 24px 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.poster-grid-item { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

.poster-grid a {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--text-primary);
  text-decoration: none;
}

.poster-grid .poster, .poster-grid .rate-poster-button { width: 100%; }
.poster-grid .poster-fallback { padding: 8px; font-size: 12px; }
.poster-grid a:hover .poster, .poster-grid a:focus-visible .poster { border-color: var(--accent); }
.poster-grid a:hover .poster-grid-title { text-decoration: underline; }

.poster-grid-title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 14px;
  line-height: 1.35;
}

/* Actor page: Newest · Best known, then a More button under the grid. */

.sort-toggle { display: flex; gap: 20px; margin: -8px 0 20px; font-family: var(--mono); font-size: 13px; }
.sort-toggle a { padding: 4px 0; color: var(--text-secondary); text-decoration: none; border-bottom: 2px solid transparent; }
.sort-toggle a:hover { color: var(--text-primary); }
.sort-toggle a[aria-current] { color: var(--text-primary); font-weight: 700; border-bottom-color: var(--accent); }

.poster-grid-more { grid-column: 1 / -1; display: flex; justify-content: center; }

.poster-grid .rate-popup { top: calc(100% + 12px); left: 0; }
.poster-grid .rate-popup::before { top: auto; bottom: 100%; right: 0; left: 0; width: auto; height: 14px; }
.poster-grid-item:nth-child(5n) .rate-popup,
.poster-grid-item:nth-child(5n + 4) .rate-popup { left: auto; right: 0; }

@media (max-width: 700px) {
  .poster-grid { grid-template-columns: repeat(3, 1fr); gap: 20px 12px; }
  .poster-grid-title { font-size: 13px; }
  .poster-grid-item:nth-child(n) .rate-popup { left: 0; right: auto; transform: none; }
  .poster-grid-item:nth-child(3n + 2) .rate-popup { left: 50%; transform: translateX(-50%); }
  .poster-grid-item:nth-child(3n) .rate-popup { left: auto; right: 0; }
}

/* Empty states and tables */

.empty-state { padding: 40px 32px; text-align: center; }
.empty-state p:first-child { font-size: 15px; }
.empty-state .button { margin-top: 8px; }

.data-table { border-collapse: separate; border-spacing: 0; overflow: hidden; }
.data-table th, .data-table td { padding: 10px 16px; text-align: left; vertical-align: top; }
.data-table tr + tr > * { border-top: 1px solid var(--border); }
.data-table th { color: var(--text-secondary); font-family: var(--mono); font-size: 12.5px; font-weight: 400; }
.data-table td { font-family: var(--mono); font-size: 13px; overflow-wrap: anywhere; }

/* Account pages (allauth) */

.auth-panel {
  max-width: 420px;
  margin: 0 auto;
  padding: 28px 32px;
}

.manage-panel { padding: 28px 32px; }

.auth-panel h1, .manage-panel h1 { margin-bottom: 12px; }
.auth-panel h2, .manage-panel h2 { font-size: 16px; margin: 24px 0 12px; }

.auth-panel form { margin-bottom: 20px; }
.auth-panel form:last-child, .auth-panel > :last-child { margin-bottom: 0; }
.auth-panel form button[type="submit"] { width: 100%; }

.auth-panel hr, .manage-panel hr { margin: 24px 0; border: 0; border-top: 1px solid var(--border); }

.auth-panel.home-panel { width: fit-content; padding: 32px; }
.home-brand { display: flex; align-items: center; justify-content: flex-start; gap: 16px; margin-bottom: 12px; }
.home-brand h1 { margin: 0; }
.home-logo { display: block; flex: none; }
.home-tagline { text-align: left; }
.home-actions { justify-content: flex-start; }
.auth-footer { margin: 16px 0 0; text-align: center; }
.auth-footer a { color: var(--text-secondary); }

.legal { padding: 28px 32px; }
.legal p { margin: 0 0 14px; }
.legal p:last-child { margin-bottom: 0; }
.legal h2 { font-size: 16px; margin: 24px 0 8px; }
.legal ul { margin: 0 0 14px; padding-left: 20px; }
.legal li { margin-bottom: 4px; }

.helptext { display: block; margin-top: 6px; }

.checkbox-field { display: flex; align-items: center; gap: 8px; }
.checkbox-field label { margin: 0; }
.checkbox-field input { width: 16px; height: 16px; margin: 0; }

.provider-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.provider-list .button { display: block; text-align: center; }
.auth-panel .provider-list form { margin: 0; }

.provider-button { gap: 10px; width: 100%; }
.provider-icon { flex: none; }
.provider-button:disabled { color: var(--text-secondary); border-color: var(--border); cursor: not-allowed; }
.provider-button:disabled .provider-icon-google { filter: grayscale(1); opacity: 0.5; }

/* Log in and Sign up links under the form. */
.entrance-links { margin: 12px 0 0; text-align: center; }

/* The eye sits inside the right end of a password input. */
.password-field { position: relative; display: block; }
.password-field input { padding-right: 48px; }
.password-toggle, .password-toggle:hover {
  position: absolute;
  top: 0;
  right: 0;
  width: 44px;
  height: 100%;
  min-height: 0;
  padding: 0;
  color: var(--text-secondary);
  background: none;
  border: 0;
}
.password-toggle[aria-pressed="true"] { color: var(--accent); }

/* "or" centred on a hairline between the form and the provider buttons. */
.social-login-or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 24px 0 16px;
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 12.5px;
}

.social-login-or::before, .social-login-or::after { content: ""; flex: 1; border-top: 1px solid var(--border); }

/* Auth card: regular-weight sans controls, pill buttons and borderless filled fields, placeholders
   in place of visible labels. The headings stay serif. */
.auth-panel :is(button, .button, input, a, .entrance-links, .social-login-or, .helptext, .errorlist) {
  font-family: var(--sans);
  font-weight: 400;
  letter-spacing: 0;
}
.auth-panel :is(button, .button) { font-size: 15px; border-radius: var(--pill); }
.auth-panel .button-secondary { background: var(--surface); border-color: var(--border-strong); }
.auth-panel .button-secondary:hover { background: var(--bg); }
.auth-panel .provider-button:disabled, .auth-panel .provider-button:disabled:hover { background: var(--surface); }

.auth-panel input:is([type="email"], [type="password"], [type="text"]) {
  min-height: 44px;
  padding: 10px 18px;
  font-size: 15px;
  background: var(--field-fill);
  border-color: var(--field-fill);
  border-radius: var(--pill);
}
.auth-panel input:is([type="email"], [type="password"], [type="text"]):focus { background: var(--surface); }
.auth-panel form p { margin-bottom: 12px; }
.auth-panel form p:has(+ button) { margin-bottom: 20px; }

/* Placeholders name the fields; the labels stay for screen readers. */
.auth-panel p:not(.checkbox-field) > label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 700px) {
  .auth-panel, .manage-panel, .legal { padding: 20px; }
}

/* Footer */


@media (max-width: 700px) {
  /* Phones: the wordmark and breadcrumb with the settings icon on the first row, the links centred below. */
  .site-header { grid-template-columns: minmax(0, 1fr); padding: 10px 16px; }
  .site-header-left { padding-right: 38px; }
  .site-links .nav-icon { top: 6px; right: 12px; translate: none; }
  .breadcrumbs > :not(:last-child) { display: none; }
  .container { padding: 24px 16px 0; }
}

/* Tab bar: on phones a signed-in user's nav links become four tabs fixed to the bottom of the screen. */
.tab-bar { display: none; }

@media (max-width: 700px) {
  /* The top row keeps the wordmark, the breadcrumb and the settings icon. */
  .has-tabs .site-header { row-gap: 0; }
  .has-tabs .site-links-main, .has-tabs .site-links-end > :not(.nav-icon) { display: none; }
  /* Room under the last thing on the page, so the bar never covers it. */
  .has-tabs { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }

  .tab-bar {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    /* Under the rating popup and its shelf panel (10, 11), which may open near the bottom. */
    z-index: 9;
    padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--border);
  }

  .tab-bar a {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 7px 2px 6px;
    border-radius: 12px;
    color: var(--text-secondary);
    font-family: var(--mono);
    font-size: 12px;
    line-height: 1.3;
    text-decoration: none;
    white-space: nowrap;
  }

  .tab-bar a:hover { color: var(--text-primary); }
  .tab-bar a[aria-current="page"] { color: var(--accent); background: var(--accent-tint); }

  .tab-icon { position: relative; display: block; height: 24px; }
  .tab-icon svg { display: block; }

  /* The Friends badge on the icon's upper-right corner, like a phone's app badge. */
  .tab-count {
    position: absolute;
    top: -5px;
    left: 15px;
    box-sizing: border-box;
    min-width: 20px;
    height: 20px;
    padding: 0 4px;
    border: 2px solid var(--surface);
    border-radius: var(--pill);
    background: var(--nav-badge);
    color: #ffffff;
    font-family: var(--sans);
    font-size: 11px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
  }
}

@media (max-width: 360px) {
  .tab-bar a { font-size: 11px; }
}

/* Page dock: the search page's bottom band, holding the TMDB credit. */

.page-dock {
  margin-top: 56px;
  background: var(--surface);
  border-top: 1px solid var(--border-strong);
}

/* TMDB recommendations on the Browse page, under the search box. */

.poster-dock { margin-top: 32px; }

.poster-dock-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  margin-bottom: 14px;
}

.poster-dock-header .section-label, .poster-dock-header .meta { margin: 0; }

.poster-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 22px 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.poster-strip a {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--text-primary);
  text-decoration: none;
}

.poster-strip-poster { position: relative; display: block; }
.poster-strip .poster { display: block; width: 100%; height: auto; aspect-ratio: 2 / 3; }
.poster-strip .poster-fallback { display: flex; font-size: 9px; }
.poster-strip a:hover .poster, .poster-strip a:focus-visible .poster { border-color: var(--accent); }

.poster-strip-title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 12.5px;
  line-height: 1.3;
}

.poster-strip-year { color: var(--text-secondary); font-family: var(--mono); font-size: 12px; }

/* Friends who reviewed the movie: monograms stacked in the poster's lower-left corner,
   newest first and on top. */
.poster-badges { position: absolute; left: 6px; bottom: 6px; display: flex; }
.poster-badge { position: relative; box-shadow: 0 0 0 2px var(--surface); }
.poster-badge + .poster-badge { margin-left: -7px; }
.poster-badge:nth-child(1) { z-index: 3; }
.poster-badge:nth-child(2) { z-index: 2; }
.poster-badge:nth-child(3) { z-index: 1; }

.poster-badge-more {
  background: var(--surface);
  box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 1px var(--border-strong);
  color: var(--text-primary);
  font-family: var(--mono);
  font-size: 11px;
}

@media (max-width: 600px) {
  .poster-strip {
    display: flex;
    flex-wrap: nowrap;
    gap: 12px;
    margin: 0 -16px;
    padding: 0 16px 4px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-padding-inline: 16px;
    scroll-snap-type: x proximity;
  }

  .poster-strip li { flex: none; width: 80px; scroll-snap-align: start; }
}

/* TMDB's required credit: logo first, notice beside it; wraps under the logo's right on phones. */

.tmdb-credit {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 24px 10px;
  background: var(--border);
  border-top: 1px solid var(--border-strong);
  color: var(--text-primary);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.4;
}

.tmdb-credit a { flex: none; }
.tmdb-credit img { display: block; flex: none; height: 14px; width: auto; }
.tmdb-credit p { margin: 0; }
.tmdb-credit .legal-links { flex: none; margin-left: auto; white-space: nowrap; }
.legal-links a { color: var(--text-primary); }

/* Home page: just the legal links, in the same bar as the TMDB credit. */
.home-footer {
  margin-top: 56px;
  padding: 8px 24px 10px;
  background: var(--border);
  border-top: 1px solid var(--border-strong);
  font-family: var(--mono);
  font-size: 12px;
  text-align: center;
}
.home-footer p { margin: 0; }

@media (max-width: 700px) {
  .tmdb-credit { flex-wrap: wrap; padding: 8px 16px 10px; }
  .tmdb-credit p { flex: 1 1 0; }
  .tmdb-credit .legal-links { flex-basis: 100%; text-align: right; }
}

/* Recommend seal (reviews/_seal.html, shared shapes in templates/_seal_defs.html).
   Off: a grey outline. On: gold, with dark gold lines. */

.seal-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.seal-stop-light { stop-color: var(--seal-light); }
.seal-stop-gold { stop-color: var(--seal-gold); }
.seal-stop-dark { stop-color: var(--seal-dark); }

.seal { display: block; flex: none; overflow: visible; }
.seal-edge, .seal-line { fill: none; stroke: var(--border-strong); stroke-width: 1px; vector-effect: non-scaling-stroke; }
.seal text { fill: var(--text-secondary); }
.seal-rim { font-weight: 700; }
.seal-rim-top { font-family: var(--serif); font-size: 8.5px; letter-spacing: 0.12em; }
.seal-rim-bottom { font-family: var(--mono); font-size: 7.5px; letter-spacing: 0.04em; }
.seal-initial { font-family: var(--serif); font-size: 30px; font-weight: 700; }
.seal-small .seal-initial { font-size: 50px; }

.seal.is-on .seal-edge, [aria-pressed="true"] > .seal .seal-edge { fill: url(#seal-gold); stroke: var(--seal-line); }
.seal.is-on .seal-line, [aria-pressed="true"] > .seal .seal-line { stroke: var(--seal-line); }
.seal.is-on text, [aria-pressed="true"] > .seal text { fill: var(--seal-line); }

/* Recommend toggle (reviews/_seal_toggle.html, static/js/seal-toggle.js): a seal button with
   its word beside it, muted when off. 96px in the review form; a 28px pill in the rating popup. */

.seal-button, .seal-button:hover {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  min-height: 44px;
  padding: 0;
  color: var(--text-secondary);
  background: none;
  border: 0;
  border-radius: var(--radius);
}

.seal-button[aria-pressed="true"] { color: var(--text-primary); }
.seal-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.seal-word { font-family: var(--mono); font-size: 16px; font-weight: 700; letter-spacing: 0.03em; }

/* Want to watch (reviews/_want_toggle.html): a bookmark outline, filled green when on. */
.want-toggle, .want-toggle:hover {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 400;
  color: var(--text-secondary);
  background: none;
  border: 0;
  border-radius: var(--radius);
}

.want-toggle svg { width: 20px; height: 25px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.want-toggle span { font-weight: 700; letter-spacing: 0.03em; }

/* The rating UI's top row: Recommend on the left, Want to watch on the right. */
.want-toggle:hover { color: var(--text-primary); }
.want-toggle[hidden] { display: none; }
.want-toggle[aria-pressed="true"] { color: var(--text-primary); }
.want-toggle[aria-pressed="true"] svg { fill: var(--accent); stroke: var(--accent); }
.want-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* A short stamp as the seal turns on. */
.seal-button.is-stamping .seal { animation: seal-stamp 320ms ease-out; }

@keyframes seal-stamp {
  0% { transform: scale(1.3) rotate(-14deg); opacity: 0.4; }
  60% { transform: scale(0.94) rotate(2deg); opacity: 1; }
  100% { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .seal-button.is-stamping .seal { animation: none; }
}

/* An empty picker hides the slider's thumb. */
.rating-picker[data-empty] input[type="range"]::-webkit-slider-thumb { opacity: 0; }
.rating-picker[data-empty] input[type="range"]::-moz-range-thumb { opacity: 0; }

/* The viewer's seal on a recommended poster's upper-right corner (reviews/_poster_seal.html). */
.rate-poster-button { position: relative; }
.poster-seal { position: absolute; top: -6px; right: -6px; z-index: 1; }
.poster-seal:empty { display: none; }

/* The rating popup's pills (.rate-pills, shared with the movie page's review panel): Recommend,
   Want to watch, Rate and Write a review, stacked white pills like the auth card's provider
   buttons (system sans, icon then a centred label). */

.rate-pills :is(.seal-toggle, .want-toggle, .rate-pill, .rate-review, .rate-shelve) { width: 100%; }

.rate-pills :is(.seal-button, .want-toggle, .rate-pill, .rate-review-button, .rate-shelve-button),
.rate-pills :is(.seal-button, .want-toggle, .rate-review-button, .rate-shelve-button):hover {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--pill);
}

.rate-pills :is(.seal-button, .want-toggle, .rate-review-button, .rate-shelve-button):hover { border-color: var(--text-secondary); }
.rate-pills :is(.seal-button, .want-toggle, .rate-review-button, .rate-shelve-button):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rate-pills :is(.seal-word, .want-toggle span) { font: inherit; letter-spacing: 0; }
.rate-pills .want-toggle svg { width: 18px; height: 22px; stroke-width: 1.5; }
/* The pills' display: flex would otherwise show Want to watch once it's seen. */
.rate-pills .want-toggle[hidden] { display: none; }

.rate-pills :is(.seal-button, .want-toggle)[aria-pressed="true"],
.rate-pills :is(.seal-button, .want-toggle)[aria-pressed="true"]:hover {
  color: var(--accent);
  background: var(--accent-tint);
  border-color: var(--accent);
}

/* Rate: the number (or "Rate"), the stars as the slider, and × once rated. */
.rate-pill { gap: 10px; cursor: default; }
.rate-pill:has(.rating-picker:not([data-empty])) { color: var(--accent); background: var(--accent-tint); border-color: var(--accent); }
.rate-pill:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.rating-picker-pill { display: flex; align-items: center; gap: 10px; }
.rating-picker-pill .rating-number {
  min-width: 2.6ch;
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0;
}
.rate-pill-stars { position: relative; display: flex; }
.stars-pill { gap: 0; }
.stars-pill .star { width: 28px; height: 28px; }

/* The slider lies over the stars, unseen: dragging left raises the rating. A thin thumb
   keeps the value under the pointer. */
.rate-pill-stars input[type="range"] { position: absolute; inset: -8px 0; width: 100%; height: auto; opacity: 0; }
.rate-pill-stars input[type="range"]::-webkit-slider-thumb { width: 2px; }
.rate-pill-stars input[type="range"]::-moz-range-thumb { width: 2px; }

.rate-pill-clear, .rate-pill-clear:hover {
  flex: none;
  width: 24px;
  height: 24px;
  min-height: 0;
  padding: 0;
  font-family: var(--sans);
  font-size: 18px;
  font-weight: 400;
  line-height: 1;
  color: var(--text-secondary);
  background: none;
  border: 0;
  border-radius: 50%;
}
.rate-pill-clear:hover { color: var(--text-primary); background: var(--bg); }
.rate-pill-clear[hidden] { display: none; }

/* Write a review: the pill grows into a serif text box with Done. */
.rate-review { overflow: hidden; border: 1px solid var(--border-strong); border-radius: 24px; }
.rate-review[open] { border-color: var(--accent); border-radius: 16px; }
.rate-review-button { list-style: none; cursor: pointer; }
.rate-review-button::-webkit-details-marker { display: none; }
.rate-pills .rate-review-button, .rate-pills .rate-review-button:hover { border: 0; border-radius: 0; }
.rate-pills .rate-review-button:hover { background: var(--bg); }
.rate-review-button svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }
.rate-review.has-text .rate-review-button span::after { content: " · written"; color: var(--text-secondary); }
.rate-review-body textarea {
  min-height: 120px;
  padding: 12px 20px;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.6;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
}
.rate-review-body textarea:focus { border-color: var(--border); outline: none; }
.rate-review-foot { display: flex; justify-content: flex-end; padding: 6px 12px 10px; }
.rate-review-done, .rate-review-done:hover {
  min-height: 36px;
  padding: 6px 16px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--pill);
}
.rate-review-done:hover { background: var(--bg); }

/* Shelve It (reviews/_shelve_it.html): a pill that opens a second panel beside the popup,
   listing the user's named shelves as toggles, then New shelf. */
.rate-shelve { position: relative; }
.rate-shelve-button { list-style: none; cursor: pointer; }
.rate-shelve-button::-webkit-details-marker { display: none; }
.rate-shelve-button svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.rate-pills .rate-shelve[open] .rate-shelve-button { color: var(--accent); background: var(--accent-tint); border-color: var(--accent); }

.shelve-panel {
  position: absolute;
  z-index: 11;
  top: -14px;
  left: calc(100% + 26px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 240px;
  padding: 14px;
  border-radius: 18px;
}

/* Fills the gap between the popup and the panel so the pointer can cross. */
.shelve-panel::before { content: ""; position: absolute; top: 0; bottom: 0; right: 100%; width: 28px; }

.shelve-toggle, .shelve-toggle:hover {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 0;
  text-align: left;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--pill);
}

.shelve-toggle:hover { border-color: var(--text-secondary); }
.shelve-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.shelve-toggle svg { flex: none; fill: none; stroke: currentColor; stroke-width: 2; visibility: hidden; }
.shelve-toggle[aria-pressed="true"], .shelve-toggle[aria-pressed="true"]:hover { color: var(--accent); background: var(--accent-tint); border-color: var(--accent); }
.shelve-toggle[aria-pressed="true"] svg { visibility: visible; }
.shelve-toggle span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.shelve-empty { margin: 0; text-align: center; }
.shelve-new { align-self: center; padding: 8px 0; font-family: var(--sans); font-size: 14px; }

/* Where the popup opens below its poster (grids, phones), the panel opens below Shelve It. */
.poster-grid .shelve-panel { top: calc(100% + 8px); left: 0; width: 100%; }
.poster-grid .shelve-panel::before { display: none; }

@media (max-width: 700px) {
  .shelve-panel { position: static; width: 100%; margin-top: 8px; padding: 0; border: 0; }
  .shelve-panel::before { display: none; }
}

.rate-pills .rate-status { font-family: var(--sans); font-size: 13px; text-align: center; }

/* The movie page's review panel (reviews/_review_form.html): the popup's panel and pills,
   with Write a review always open as the review box, and Shelve It's list opening inline. */
.review-panel { display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: 18px; }
.review-panel > div { margin: 0; }
.review-panel .shelve-panel { position: static; width: 100%; margin-top: 8px; padding: 0; border: 0; }
.review-panel .shelve-panel::before { display: none; }

.review-box { display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--accent); border-radius: 16px; }
.review-box:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.review-box textarea {
  min-height: 300px;
  padding: 14px 20px;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.7;
  border: 0;
  border-radius: 0;
  resize: vertical;
  field-sizing: content;
}
.review-box textarea:focus { outline: none; }
.review-box-foot { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 8px 12px 8px 20px; border-top: 1px solid var(--border); }
.review-panel .review-box-foot .rate-status { text-align: left; }
.review-delete-link { display: inline-flex; align-items: center; min-height: 36px; padding: 0 14px; font-family: var(--sans); font-size: 14px; color: var(--text-secondary); text-decoration: none; border-radius: var(--pill); }
.review-delete-link:hover { color: var(--text-primary); background: var(--bg); }

@media (max-width: 900px) {
  .review-box textarea { min-height: 180px; }
}

/* Movie page: the poster takes the recommender's seal; a card's seal sits after its rating. */
.movie-poster { position: relative; flex: none; }
.card-rating .seal { margin-left: 4px; }

/* Account page */

.account-panel { padding: 20px; }
.account-panel form, .account-panel form > div { margin: 0; }
.account-password { margin: 24px 0 0; }
.include-tv { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 24px 0 0; }
.include-tv .checkbox-field { margin: 0; }
.include-tv .include-tv-status { margin: 0; }
/* Clips the form while static/js/account-password.js grows or shrinks it. */
.account-password.is-resizing { overflow: hidden; }
.account-logout { margin: 24px 0 0; }
.account-delete-line { margin: 24px 0 0; font-family: var(--mono); font-size: 12.5px; }
.account-delete { color: var(--text-secondary); }

/* My Page */

/* Shelves run the full page width, so wider screens show more posters; the Friends page too. */
.my-page.page-narrow { max-width: none; }

/* Past phone widths it spans the window, not the 1240px page, less a margin each side. */
@media (min-width: 701px) {
  .my-page.page-narrow, .friends-page {
    --my-page-margin: 48px;
    width: calc(100vw - 2 * var(--my-page-margin));
    margin-left: calc(50% - 50vw + var(--my-page-margin));
  }
}
.my-name { color: var(--text-primary); text-decoration: none; }
.my-name:hover { text-decoration: underline; text-decoration-color: var(--border-strong); }
.my-name-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
.my-name-form > div { margin: 0; }
.my-name-form .form-actions { grid-column: 1 / -1; }

@media (max-width: 700px) {
  .my-name-form { grid-template-columns: 1fr; }
}

/* My Shelves: a header (grip, glyph, name and count, See all), then posters standing on a
   plank. Each poster carries its own piece of the plank (the items touch), and the row's
   ::after carries it to the edge. */

.my-page-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }
.my-page-header h1, .my-page-header .new-shelf { margin: 0; }

.shelf { --shelf-poster: 80px; --plank: 10px; --seasons: 12px; margin-top: 44px; }

.shelf-header { position: relative; display: flex; align-items: center; gap: 8px; min-height: 44px; }

.shelf-name {
  margin: 0;
  color: var(--text-primary);
  font-family: var(--serif);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.shelf-name .count {
  margin-left: 10px;
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
}

.shelf-glyph { display: flex; flex: none; }
.shelf-glyph-reviewed svg { fill: var(--star); stroke: var(--star-outline); stroke-width: 1.5; }
.shelf-glyph-want-to-watch svg { fill: none; stroke: var(--text-secondary); stroke-width: 1.5; }

.shelf-all {
  margin-left: auto;
  padding: 12px 0;
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 13px;
  text-align: right;
  text-decoration: none;
  white-space: nowrap;
}

.shelf-all:hover { color: var(--text-primary); text-decoration: underline; }

.shelf-row {
  /* Keeps the absolutely positioned hidden text under each rating inside the scroller. */
  position: relative;
  display: flex;
  margin: 0 -8px;
  padding: 8px 0 4px;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
}

/* static/js/shelf-fit.js hides the posters that don't fit whole. */
.shelf-row.is-fitted { overflow-x: hidden; }

.shelf-row li { flex: none; scroll-snap-align: start; }

.shelf-row a {
  display: flex;
  flex-direction: column;
  width: calc(var(--shelf-poster) + 16px);
  color: var(--text-primary);
  text-decoration: none;
}

.shelf-poster { position: relative; padding: 0 8px var(--plank); }

/* The plank: a lighter top face over the darker front, a soft shadow under it. */
.shelf-poster::after, .shelf-more::after, .shelf-empty::after, .shelf-row::after, .shelf-grid-poster::after {
  content: "";
  box-sizing: border-box;
  height: var(--plank);
  background: var(--shelf-wood);
  border-top: 3px solid var(--shelf-wood-top);
  /* Unblurred bands, so the pieces join without seams. */
  box-shadow: 0 2px 0 rgb(26 25 21 / 0.16), 0 4px 0 rgb(26 25 21 / 0.07);
}

.shelf-poster::after, .shelf-more::after, .shelf-empty::after { position: absolute; left: 0; right: 0; bottom: 0; }

.shelf-row::after { flex: 1 0 8px; align-self: flex-start; margin-top: calc(var(--seasons) + var(--shelf-poster) * 1.5); }

.shelf-row .poster { width: var(--shelf-poster); box-shadow: 0 2px 6px rgb(26 25 21 / 0.18); }
.shelf-row .poster-fallback { padding: 6px; font-size: 9px; }
.shelf-row a:hover .poster, .shelf-row a:focus-visible .poster { border-color: var(--accent); }
.shelf-row a:hover .shelf-title { text-decoration: underline; }

.shelf-title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  margin-top: 6px;
  padding: 0 8px;
  font-size: 12px;
  line-height: 1.3;
}

/* My Shelves titles keep to one line; the link's title attribute holds the whole. */
.shelf-row .shelf-title {
  display: block;
  color: var(--text-secondary);
  font-size: 12.5px;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.shelf-year { margin-top: 3px; padding: 0 8px; color: var(--text-secondary); font-family: var(--mono); font-size: 12px; white-space: nowrap; }

/* A show's seasons above its poster (G3): a row every poster keeps, so all stand level. */
.season-blocks { display: flex; gap: 2px; height: 6px; margin-bottom: 6px; padding: 0 8px; overflow: hidden; }
.season-block { flex: none; box-sizing: border-box; width: 8px; height: 6px; background: var(--text-secondary); border: 1px solid var(--text-secondary); border-radius: 1px; }
.season-block-open { background: none; }

.shelf-rating {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 3px;
  padding: 0 8px;
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 700;
}

.shelf-rating-star { flex: none; fill: var(--star); stroke: var(--star-outline); stroke-width: 1.5; }

/* The last slot when a shelf holds more than fit: a poster-sized tile to the shelf page. */
.shelf-more { position: relative; align-self: flex-start; margin-top: var(--seasons); padding: 0 8px var(--plank); }

.shelf-row .shelf-more a {
  align-items: center;
  justify-content: center;
  width: var(--shelf-poster);
  aspect-ratio: 2 / 3;
  padding: 4px;
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  font-family: var(--mono);
  font-size: 12.5px;
  text-align: center;
}

.shelf-row .shelf-more a:hover, .shelf-row .shelf-more a:focus-visible { color: var(--text-primary); border-color: var(--accent); }

/* An empty shelf: one dashed slot on the plank, to Browse. */
.shelf-empty { position: relative; display: flex; margin: 0 -8px; padding: 8px 8px calc(var(--plank) + 4px); }
.shelf-empty::after { bottom: 4px; }

.shelf-browse {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: var(--shelf-poster);
  aspect-ratio: 2 / 3;
  color: var(--text-secondary);
  border: 1px dashed var(--border-strong);
  border-radius: 4px;
  font-family: var(--mono);
  font-size: 12.5px;
  text-decoration: none;
}

.shelf-browse:hover, .shelf-browse:focus-visible { color: var(--text-primary); border-color: var(--accent); }
.shelf-browse-plus { font-size: 20px; line-height: 1; }

/* Shelf page: the director grid, the seal in the poster's corner and smaller stars under the title.
   Each row stands on the plank: every poster carries a piece widened by half the column gap. */
.shelf-grid-poster { --plank: 10px; --half-gap: 10px; position: relative; padding-bottom: var(--plank); }
.shelf-grid-poster::after { position: absolute; left: calc(var(--half-gap) * -1); right: calc(var(--half-gap) * -1); bottom: 0; }
.shelf-grid-poster .poster { box-shadow: 0 2px 6px rgb(26 25 21 / 0.18); }
@media (max-width: 700px) { .shelf-grid-poster { --half-gap: 6px; } }
.poster-grid .card-rating { gap: 6px; }
.poster-grid .stars-small { gap: 2px; }
.poster-grid .stars-small .star { width: 14px; height: 14px; }
/* Browse Movies Like These, under the grid and its More. */
.shelf-browse-like { display: flex; justify-content: center; margin: 32px 0 0; }
/* A stored shelf's thread, last on its page, and the header link down to it. */
.shelf-comments { margin-top: 40px; }
.shelf-comments .thread { margin: 0; }
.shelf-comments-link { margin: 8px 0 0; }
.shelf-comments-link a { color: var(--text-secondary); }
.shelf-comments-link a:hover { color: var(--text-primary); }
/* My Shelves: a stored shelf's thread size beside its name, down to the thread on its page. */
.shelf-comment-count { color: var(--text-secondary); text-decoration: none; white-space: nowrap; }
.shelf-comment-count:hover { color: var(--text-primary); text-decoration: underline; }
.shelf-header:has(form) .shelf-comment-count { display: none; }

/* Dragging a shelf poster (static/js/shelf-sort.js): it follows the pointer above the page
   and a dashed outline marks where it will land. */
[data-shelf-sort] a { -webkit-touch-callout: none; }
[data-shelf-sort] img { -webkit-user-drag: none; }
.is-shelf-dragging, .is-shelf-dragging * { cursor: grabbing; user-select: none; -webkit-user-select: none; }
.is-shelf-dragging .shelf-row { scroll-snap-type: none; }
.is-dragging { position: fixed; z-index: 20; pointer-events: none; opacity: 0.9; }
[data-movie].is-dragging .poster { border-color: var(--accent); }
.is-slot .poster, .is-slot .poster-seal, .is-slot .shelf-title, .is-slot .shelf-rating,
.is-slot .poster-grid-title, .is-slot .card-rating { visibility: hidden; }
.is-slot .shelf-poster::before, .is-slot .shelf-grid-poster::before {
  content: "";
  position: absolute;
  inset: 0 8px var(--plank);
  border: 1px dashed var(--border-strong);
  border-radius: 4px;
}
.is-slot .shelf-grid-poster::before { inset: 0 0 var(--plank); }

/* New shelf (accounts/_new_shelf_*.html): a button in the page header that becomes a name field. */
.new-shelf { margin-top: 32px; }
.new-shelf-form { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px; max-width: 520px; }
.new-shelf-form > div:first-of-type { flex: 1 1 220px; margin: 0; }
.new-shelf-form .form-actions { margin: 0; }
.shelf-actions { display: flex; gap: 20px; margin: 8px 0 0; font-family: var(--mono); font-size: 13px; }
.shelf-actions a { color: var(--text-secondary); }
.shelf-actions a:hover { color: var(--text-primary); }
/* Edit / Done beside Delete on a stored shelf's page; edit mode puts an × on each poster. */
.shelf-tools { display: flex; gap: 20px; margin: 8px 0 0; }
.shelf-tools .shelf-actions { margin: 0; }
.shelf-edit { margin: 0; font-family: var(--mono); font-size: 13px; }
.shelf-edit a { color: var(--text-secondary); }
.shelf-edit a:hover { color: var(--text-primary); }
.poster-grid-item:has(.shelf-remove, .shelf-undo) { position: relative; }
.shelf-remove { position: absolute; top: -8px; left: -8px; margin: 0; }  /* top left: the seal takes the top right */
.shelf-remove button {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-primary);
  cursor: pointer;
}
/* The visible 28px circle inside the 44px tap target. */
.shelf-remove button::before {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--surface);
}
.shelf-remove button:hover::before { border-color: var(--text-primary); }
.shelf-remove svg { position: relative; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; }
.is-removed .poster, .is-removed .poster-grid-title { opacity: 0.35; }
.shelf-undo { position: absolute; top: 6px; left: 6px; margin: 0; }
.shelf-undo button {
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--pill);
  background: var(--surface);
  color: var(--text-primary);
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.shelf-undo button:hover { border-color: var(--text-primary); }
.shelf-page-name { display: flex; align-items: center; gap: 4px; margin-bottom: 4px; }
.shelf-page-name h1 { margin: 0; }
.shelf-page-name:has(form) .shelf-pencil, .shelf-header:has(form) .shelf-pencil { display: none; }
.shelf-header .new-shelf-form { flex: 1 1 auto; }
/* Shelf notes: in full under the shelf page's name, one line under the name on My Shelves. */
.shelf-note { margin: 4px 0 0; max-width: 640px; color: var(--text-secondary); font-family: var(--serif); font-size: 15px; line-height: 1.7; overflow-wrap: anywhere; }
.shelf-byline { margin: 0; color: var(--text-secondary); font-family: var(--serif); font-size: 15px; }
.shelf-byline a { color: var(--text-primary); text-decoration: none; }
.shelf-byline a:hover { text-decoration: underline; text-decoration-color: var(--border-strong); }
.shelf-note-line { max-width: none; margin: 0 0 6px; overflow: hidden; font-size: 14px; white-space: nowrap; text-overflow: ellipsis; }
.shelf-note-add { font-family: var(--mono); font-size: 13px; }
.shelf-note-add a { color: var(--text-secondary); text-decoration: none; }
.shelf-note-add a:hover { color: var(--text-primary); text-decoration: underline; }
.shelf-page-name:has(form) ~ .shelf-note, .shelf-header:has(form) + .shelf-note { display: none; }
.new-shelf-form .shelf-note-field { flex: 1 1 100%; margin: 0; }
.shelf-note-field textarea { min-height: 0; max-height: 160px; field-sizing: content; resize: none; }
.shelf-pencil {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--text-secondary);
  border-radius: 6px;
}
.shelf-pencil:hover { color: var(--text-primary); }
.shelf-pencil svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }

/* One six-dot grip per shelf (accounts/_shelf_grip.html), in the gutter left of the name,
   drags the whole shelf. It shows on hover or focus, and always where there's no hover. */
.shelf-handle, .shelf-handle:hover {
  position: absolute;
  top: 50%;
  left: -30px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 44px;
  min-height: 0;
  padding: 0;
  color: var(--text-secondary);
  background: none;
  border: 0;
  border-radius: 4px;
  cursor: grab;
  touch-action: none;
  opacity: 0;
  transform: translateY(-50%);
}

.shelf-item:hover .shelf-handle, .shelf-item:focus-within .shelf-handle { opacity: 1; }
.shelf-handle:hover { color: var(--text-primary); }
.shelf-handle:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.shelf-handle svg { fill: currentColor; }

@media (hover: none) {
  .shelf-handle, .shelf-handle:hover { opacity: 1; }
}

/* Until the window leaves room outside the page, the rows sit flush with the page edge. */
@media (max-width: 1299px) {
  .shelf-row, .shelf-empty { margin: 0; }
}

/* A fixed element keeps its child's margin inside, so drop it to stay under the pointer. */
.shelf-item.is-dragging { background: var(--bg); }
.shelf-item.is-dragging .shelf { margin-top: 0; }
.shelf-item.is-slot { outline: 1px dashed var(--border-strong); outline-offset: 4px; border-radius: 6px; }
.shelf-item.is-slot > * { visibility: hidden; }

@media (max-width: 700px) {
  .shelf { --shelf-poster: 60px; }
  .shelf-handle, .shelf-handle:hover { left: -16px; width: 16px; }
}


/* Feed: one column of friends' activity, newest first. */

/* minmax(0, 1fr): a long poster row scrolls inside its item instead of widening the column. */
.feed { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }

.feed-item { padding: 24px; border-radius: calc(var(--radius) * 2); }
/* Pinned: the friend requests panel, waiting on the viewer in the accent's light green. */
.feed-item-pinned { display: block; padding: 0; border-color: var(--accent-line); background: var(--accent-tint); }
.feed-requests-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--accent-line);
}
.feed-requests-title { margin: 0; color: var(--text-secondary); font-family: var(--mono); font-size: 13px; font-weight: 700; letter-spacing: 0.02em; }
.feed-requests-count {
  min-width: 22px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--accent-line);
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  text-align: center;
}
.feed-requests { margin: 0; padding: 0; list-style: none; }
.feed-request { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding: 12px 20px; }
.feed-request + .feed-request { border-top: 1px solid var(--accent-line); }
/* An answered row slides out and fades while htmx waits to remove it (swap:250ms). */
.feed-request.htmx-swapping { opacity: 0; transform: translateX(24px); transition: opacity 250ms ease, transform 250ms ease; }
@media (prefers-reduced-motion: reduce) {
  .feed-request.htmx-swapping { transform: none; }
}
.feed-request-name { flex: 1 1 auto; min-width: 0; font-size: 14px; overflow-wrap: anywhere; }
.feed-request-actions { gap: 8px; }
.feed-request-actions form { margin: 0; }
/* A circle's requests as one row; Show opens the single rows inside it. */
.feed-request-more { flex-basis: 100%; }
.feed-request-more summary { min-height: 44px; display: inline-flex; align-items: center; font-family: var(--mono); font-size: 12.5px; color: var(--accent); cursor: pointer; }
.feed-request-more .feed-request { padding: 12px 0; }
/* A circle asking a new member to connect with everyone in it. */
.feed-item-pinned.feed-circle { margin-bottom: 12px; padding: 16px 20px; }
.feed-circle-members { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 12px 0 16px; padding: 0; list-style: none; font-size: 14px; }
.feed-circle-members li { display: flex; align-items: center; gap: 8px; }
.feed-circle .form-actions form { margin: 0; }
.feed-poster { flex: none; text-decoration: none; }
/* The one shadow on the site's posters (DESIGN.md, "Posters"): small and soft, feed only. */
.feed-poster .poster, .feed-posters .poster { box-shadow: 0 2px 6px rgb(26 25 21 / 0.18); }
.feed-poster .poster { width: 70px; }
.feed-poster .poster-fallback { font-size: 9px; }

/* The headline: avatar, then one sentence (the name bold, titles italic), the date at the right. */
.feed-headline { display: flex; align-items: baseline; gap: 12px; }
.feed-avatar { flex: none; align-self: flex-start; width: 32px; height: 32px; font-size: 14px; }
/* The top padding centres a one-line sentence on the avatar. */
.feed-title { flex: 1 1 auto; min-width: 0; margin: 0; padding-top: 4px; font-size: 18px; font-weight: 400; line-height: 1.4; overflow-wrap: anywhere; }
.feed-title a { color: var(--text-primary); text-decoration: none; }
.feed-title a:hover { text-decoration: underline; text-decoration-color: var(--border-strong); }
.feed-name { font-weight: 700; }
.feed-work { font-style: italic; }
.feed-date { flex: none; white-space: nowrap; }

/* Under the headline, indented to the sentence (avatar plus gap). */
.feed-body { margin: 16px 0 0 44px; }
.feed-single { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto 1fr; column-gap: 20px; align-items: start; }
.feed-single > .rate-poster { grid-row: 1 / span 2; }
.feed-single .feed-poster { display: block; }
.feed-single .feed-rating { margin: 0; }
.feed-single .feed-review { grid-column: 2; }

.feed-rating { display: flex; align-items: center; gap: 10px; margin: 8px 0 0; font-family: var(--mono); font-size: 13px; }
.stars-feed { gap: 4px; }
.stars-feed .star { width: 20px; height: 20px; }
.stars-feed .star path { stroke: none; }
.stars-feed .star-full { fill: var(--star-deep); }
.feed-rating-number { font-weight: 700; }
.feed-rating-scale { margin-left: -6px; color: var(--text-secondary); }

.feed-text { margin: 10px 0 0; font-size: 17px; line-height: 1.6; overflow-wrap: anywhere; }
/* Set by static/js/feed-more.js; without script the whole review shows. */
.feed-text.is-clamped { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 6; }
.feed-more { margin-top: 4px; font-family: var(--mono); font-size: 13px; }


.feed-posters {
  display: flex;
  gap: 12px;
  margin-top: 10px;
  /* Room above and right for the corner seal, which a scrolling row would clip. */
  padding: 6px 6px 4px 0;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.feed-poster-item { flex: none; width: 67px; }
/* "2 comments" under a movie in the feed, linking to its thread on the movie page. */
/* The composer at the top of the feed. Post shows once a title is picked and either box has text. */
.composer { --composer-pad: 20px; display: grid; align-content: start; gap: 10px; margin-bottom: 12px; padding: 18px var(--composer-pad); }
.composer > div { margin: 0; }
.composer-text { min-height: 0; max-height: 320px; padding: 10px 12px; font-size: 15px; line-height: 1.6; field-sizing: content; resize: none; }
.composer-spoiler { font-size: 14px; }
.composer-title { display: grid; gap: 8px; margin: 0; padding: 0; border: 0; }
.composer-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.composer-chips:empty { display: none; }
.composer-chip { display: inline-flex; align-items: baseline; gap: 6px; margin: 0; padding: 4px 12px; border: 1px solid var(--border-strong); border-radius: 999px; cursor: pointer; color: var(--text-primary); font-family: var(--serif); font-size: 13.5px; font-weight: 400; letter-spacing: normal; text-transform: none; }
.composer-chip input { position: absolute; opacity: 0; pointer-events: none; }
.composer-chip:has(input:checked) { border-color: var(--accent); background: var(--accent-tint); }
.composer-chip:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.composer-search { padding: 8px 12px; font-size: 14px; }
.composer-episode-fields { display: flex; gap: 8px; }
.composer-episode-fields { align-items: center; }
/* The episode stepper: − and + either side of the number, in one pill. */
.composer-stepper { display: inline-flex; align-items: stretch; overflow: hidden; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); }
.composer-step { min-height: 0; padding: 4px 11px; border: 0; border-radius: 0; background: none; color: var(--text-secondary); font-family: var(--mono); font-size: 15px; font-weight: 400; }
.composer-step:hover { background: var(--bg); color: var(--text-primary); }
.composer-stepper .composer-number { flex: none; width: 4.5em; padding: 5px 4px; border: 0; border-inline: 1px solid var(--border); border-radius: 0; font-family: var(--mono); font-size: 13px; text-align: center; appearance: textfield; }
.composer-stepper .composer-number::-webkit-inner-spin-button, .composer-stepper .composer-number::-webkit-outer-spin-button { appearance: none; margin: 0; }
.composer-stepper:focus-within { border-color: var(--accent); }
.composer-season { flex: none; padding: 5px 12px; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); color: var(--text-primary); font-family: var(--mono); font-size: 13px; }
.composer-season:focus { border-color: var(--accent); outline: none; }
.composer-head { display: flex; align-items: flex-start; gap: 12px; }
.composer-avatar { width: 32px; height: 32px; margin-top: 7px; font-size: 14px; }
.composer-box { position: relative; flex: 1 1 auto; min-width: 0; display: grid; }
.composer-box .composer-text { padding-right: 44px; }
/* The + attaches a title; its tip shows on hover and focus. */
.composer-add { position: absolute; top: 8px; right: 8px; display: grid; place-items: center; width: 28px; height: 28px; min-height: 0; padding: 0; border: 1px solid var(--border-strong); border-radius: 50%; background: var(--surface); color: var(--text-secondary); cursor: pointer; }
.composer-add:hover, .composer-add:focus-visible, .composer-add[aria-expanded="true"] { border-color: var(--accent); background: var(--surface); color: var(--accent); }
.composer-tip { position: absolute; top: 10px; right: 42px; padding: 3px 8px; border-radius: 4px; background: var(--text-primary); color: var(--nav-text); font-family: var(--mono); font-size: 12px; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity 150ms ease; }
.composer-add:is(:hover, :focus-visible) + .composer-tip { opacity: 1; }
/* Three ways in. Typing first folds them away (static/js/composer.js), which eases the panel's height. */
.composer-pills { display: grid; grid-template-rows: 1fr; transition: opacity 250ms ease; }
.composer-pills.is-folded { grid-template-rows: 0fr; opacity: 0; margin-top: -10px; visibility: hidden; }
.composer-pills-row { display: flex; flex-wrap: wrap; gap: 6px; min-height: 0; overflow: hidden; }
.composer-pill { display: inline-flex; align-items: center; gap: 6px; min-height: 0; padding: 6px 13px; font-weight: 400; line-height: 1.4; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); color: var(--text-primary); font-family: var(--serif); font-size: 13.5px; letter-spacing: normal; white-space: nowrap; cursor: pointer; }
.composer-pill:hover { border-color: var(--text-secondary); background: var(--surface); }
.composer-pill[aria-pressed="true"]:hover { background: var(--accent-tint); }
.composer-pill[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-tint); color: var(--accent); }
.composer-pill svg { flex: none; }
/* With script the picker opens from a pill or the +; without it, it always shows. */
.composer-ready .composer-title:not(.is-open) { display: none; }
/* The picker: a row of the viewer's latest posters, then Search, which opens the search field. */
.composer-ready .composer-title:not(.is-searching) :is(.composer-search, #composer-results) { display: none; }
.composer-strip { display: flex; align-items: flex-start; gap: 12px; overflow-x: auto; padding: 2px 2px 4px; overscroll-behavior-x: contain; }
.composer-strip:empty { display: none; }
/* The picker's posters scroll out to the panel's edges. */
.composer-title .composer-strip { margin-inline: calc(-1 * var(--composer-pad)); padding-inline: var(--composer-pad); scroll-padding-inline: var(--composer-pad); scrollbar-width: none; }
.composer-poster, .composer-search-tile { flex: none; display: flex; flex-direction: column; align-items: center; gap: 5px; width: 58px; margin: 0; cursor: pointer; text-align: center; font-family: var(--serif); font-weight: 400; letter-spacing: normal; text-transform: none; }
.composer-poster input { position: absolute; opacity: 0; pointer-events: none; }
.composer-poster-frame { position: relative; display: block; }
.composer-poster .poster { width: 56px; box-shadow: 0 1px 3px rgb(26 25 21 / 0.18); }
.composer-poster .poster-fallback { padding: 4px; font-size: 8px; }
.composer-poster:hover .poster, .composer-poster:has(input:focus-visible) .poster { border-color: var(--accent); }
.composer-poster:has(input:checked) .poster { outline: 2px solid var(--accent); outline-offset: 2px; }
.composer-poster-tag { position: absolute; top: 4px; left: 4px; padding: 0 3px; border-radius: 3px; background: var(--surface); color: var(--text-primary); font-family: var(--mono); font-size: 9.5px; font-weight: 700; }
.composer-poster-title { width: 100%; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; color: var(--text-primary); font-family: var(--serif); font-size: 11px; font-weight: 400; line-height: 1.25; letter-spacing: normal; }
.composer-poster .meta { font-size: 10.5px; letter-spacing: normal; }
.composer-search-tile { min-height: 0; padding: 0; border: 0; background: none; color: var(--text-secondary); }
.composer-search-tile:hover { background: none; }
.composer-search-tile-frame { display: grid; place-items: center; width: 56px; aspect-ratio: 2 / 3; border: 1.5px dashed var(--border-strong); border-radius: 4px; background: var(--surface); }
.composer-search-tile:hover .composer-search-tile-frame { border-color: var(--accent); color: var(--accent); }
.composer-search-tile .composer-poster-title { color: var(--text-secondary); font-family: var(--mono); }
/* The picked title: poster, name and run, the episode for a show, and ×. */
#composer-attached:empty { display: none; }
.composer-attached { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 14px; align-items: start; }
.composer-attached-poster .poster { width: 70px; box-shadow: 0 1px 3px rgb(26 25 21 / 0.18); }
.composer-attached-poster .poster-fallback { padding: 6px; font-size: 9px; }
.composer-attached-body { display: grid; gap: 7px; justify-items: start; min-width: 0; }
.composer-attached-name { font-size: 18px; line-height: 1.3; }
.composer-attached-when { color: var(--text-secondary); font-size: 14px; }
.composer-detach { display: grid; place-items: center; width: 28px; height: 28px; min-height: 0; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--text-secondary); }
.composer-detach:hover { background: var(--bg); color: var(--text-primary); }
/* The spoiler under a ticket stub's tear line: a dashed rule across the panel with a notch at each edge. */
.composer { overflow: hidden; }
.composer > .composer-fold { position: relative; display: grid; gap: 8px; margin: 2px calc(-1 * var(--composer-pad)) 0; padding: 12px var(--composer-pad) 0; border-top: 1.5px dashed var(--border-strong); }
.composer-fold::before, .composer-fold::after { content: ""; position: absolute; top: -9px; width: 16px; height: 16px; border: 1px solid var(--border); border-radius: 50%; background: var(--bg); }
.composer-fold::before { left: -9px; }
.composer-fold::after { right: -9px; }
.composer-fold-head { justify-content: flex-start; gap: 7px; min-height: 0; padding: 0; border: 0; background: none; color: var(--text-secondary); font-weight: 400; cursor: pointer; }
.composer-fold-head:hover { background: none; color: var(--text-primary); }
.composer-fold-tag { margin-left: auto; }
.composer-fold .composer-spoiler { border-style: dashed; background: var(--bg); }
.composer:has(#composer-text:placeholder-shown):has(#composer-spoiler:placeholder-shown) .composer-fold { display: none; }
/* With script the box opens from the tear line, or shows while it holds text. */
.composer-ready .composer-fold:not(.is-open):has(#composer-spoiler:placeholder-shown) .composer-spoiler { display: none; }
.composer:not(.composer-ready) .composer-fold-head { display: none; }
@media (prefers-reduced-motion: reduce) { .composer-pills, .composer-tip { transition: none; } }
.composer-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.composer-error { margin: 0 auto 0 0; color: var(--error); font-family: var(--mono); font-size: 12.5px; }
.composer:has(#composer-text:placeholder-shown):has(#composer-spoiler:placeholder-shown) :is(.composer-actions:not(:has(.composer-error)), .composer-actions .button) { display: none; }
.feed-replies .thread { margin-left: 0; }
.comment-spoiler { margin-top: 8px; padding-top: 8px; }
.comment-box-texts { display: grid; flex: 1 1 auto; gap: 6px; min-width: 0; margin: 0; }
.comment-box:has(.comment-box-texts textarea[name="text"]:placeholder-shown):has(.comment-box-spoiler:placeholder-shown) .comment-box-spoiler { display: none; }
.comment-box-texts textarea { width: 100%; min-height: 0; max-height: 200px; padding: 8px 12px; font: inherit; font-size: 13.5px; line-height: 1.6; field-sizing: content; resize: none; }
.comment-box:not(:has(input[name="title"]:checked)):has(.comment-box-texts textarea[name="text"]:placeholder-shown):has(.comment-box-spoiler:placeholder-shown) :is(button[type="submit"], .comment-private-toggle) { display: none; }
/* A reply's + names a title: it opens a search whose posters are radio buttons. */
.comment-box-reply { position: relative; display: grid; }
.comment-box-reply textarea { padding-right: 40px; }
.comment-add { position: absolute; top: 6px; right: 6px; display: grid; place-items: center; width: 26px; height: 26px; min-height: 0; padding: 0; border: 1px solid var(--border-strong); border-radius: 50%; background: var(--surface); color: var(--text-secondary); }
.comment-add:hover, .comment-add[aria-expanded="true"] { border-color: var(--accent); background: var(--surface); color: var(--accent); }
.comment-titles { display: none; gap: 8px; }
.comment-titles.is-open { display: grid; }
.comment-title-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.comment-title-row .want-toggle { margin-top: 6px; }
.post-delete { margin-top: 8px; text-align: right; }
.post-delete .text-button { font-family: var(--mono); font-size: 12.5px; color: var(--text-secondary); }

/* Posts: the episode tag beside the title, and spoiler text behind a disclosure. */
/* A titled post's friends' marks on its title, and the composer's picked title's. */
.post-marks { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: 8px 0 0; font-size: 14px; }
.post-mark { display: inline-flex; align-items: center; gap: 4px; }
.post-mark-name { font-weight: 700; }
.post-mark-star { fill: var(--star-deep); }
.composer-attached .post-marks { margin: 0; font-size: 13px; }
.feed-tag { font-weight: 400; white-space: nowrap; }
/* A titled post shows its poster beside the text. */
.feed-post-media { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 20px; align-items: start; }
.feed-post-media > .feed-review:only-child { grid-column: 1 / -1; }
/* A spoiler is a ticket stub: below a tear line, its summary with the eye-off glyph and Show. */
.feed-spoiler, .comment-spoiler { border-top: 1.5px dashed var(--border-strong); }
.feed-spoiler { margin-top: 12px; padding-top: 10px; }
.feed-spoiler-summary, .comment-spoiler summary { display: flex; align-items: center; gap: 7px; width: auto; list-style: none; cursor: pointer; }
.feed-spoiler-summary::-webkit-details-marker, .comment-spoiler summary::-webkit-details-marker { display: none; }
.feed-spoiler-summary::before, .comment-spoiler summary::before { content: ""; flex: none; width: 16px; height: 16px; background: currentColor; mask: url("../img/eye-off.1d3df85e0f7d.svg") center / contain no-repeat; }
.feed-spoiler-summary::after, .comment-spoiler summary::after { content: "Show"; margin-left: auto; color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
:is(.feed-spoiler, .comment-spoiler)[open] > summary::after { content: "Hide"; }
.feed-spoiler-summary:hover, .comment-spoiler summary:hover { color: var(--text-primary); }
.feed-spoiler[open] .feed-text { margin-top: 6px; }
.feed-comments { display: inline-block; margin-top: 8px; font-family: var(--mono); font-size: 12.5px; color: var(--text-secondary); }
.feed-comments:hover { color: var(--text-primary); }
.feed-poster-item .feed-comments { display: block; margin-top: 4px; font-size: 11.5px; }
/* A shelf or want item's count, for the shelf's thread on its page. */
.feed-shelf-comments { margin-top: 10px; }
.feed-shelf-comments .feed-comments { margin-top: 0; }
.feed-poster-item a { display: flex; flex-direction: column; color: var(--text-primary); text-decoration: none; }
.feed-poster-frame { position: relative; }
.feed-posters .poster { width: 67px; }
.feed-posters .poster-fallback { padding: 6px; font-size: 9px; }
.feed-posters .shelf-title { padding: 0; }
.feed-posters a:hover .poster, .feed-posters a:focus-visible .poster { border-color: var(--accent); }
.feed-posters a:hover .shelf-title { text-decoration: underline; }
.feed-posters .card-rating { flex-wrap: wrap; gap: 2px 4px; margin-top: 4px; font-size: 12px; }
.feed-posters .stars-small { gap: 2px; }
.feed-posters .stars-small .star { width: 11px; height: 11px; }
/* Phones only: the "+N" tile after three posters opens the rest in place (static/js/feed-posters.js). */
.feed-poster-more-item { display: none; }
button.feed-poster-more {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 67px;
  aspect-ratio: 2 / 3;
  box-sizing: border-box;
  border: 1px dashed var(--border-strong);
  border-radius: 4px;
  padding: 0;
  background: var(--surface);
  color: var(--text-secondary);
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
}
button.feed-poster-more:hover { border-color: var(--accent); background: var(--surface); color: var(--text-primary); }

/* Heads the unpinned items, under any friend requests. */

.feed-older { display: flex; justify-content: center; margin-top: 8px; }

@media (max-width: 700px) {
  .composer { --composer-pad: 16px; }
  /* The pills stay one row on phones, scrolling sideways to the panel's edges. */
  .composer-pills-row { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; margin-inline: calc(-1 * var(--composer-pad)); padding-inline: var(--composer-pad); scrollbar-width: none; }
  .feed-item { gap: 14px; padding: 18px 16px; }
  .feed-item-pinned { padding: 0; }
  .feed-requests-head, .feed-request { padding-left: 16px; padding-right: 16px; }
  .feed-item-pinned.feed-circle { padding: 16px; }
  /* The buttons drop under the name, lined up with it. */
  .feed-request-actions { flex-basis: 100%; padding-left: 44px; }
  .feed-poster .poster { width: 56px; }
  .feed-headline { gap: 10px; }
  .feed-avatar { width: 28px; height: 28px; font-size: 13px; }
  .feed-title { padding-top: 2px; font-size: 16px; line-height: 1.45; }
  .feed-date { font-size: 12px; }
  /* Full width on phones; review text runs under the poster. */
  .feed-body { margin-left: 0; margin-top: 14px; }
  .feed-single, .feed-post-media { column-gap: 14px; }
  .feed-single > .rate-poster { grid-row: 1; }
  .feed-single .feed-review { grid-column: 1 / -1; margin-top: 4px; }
  .feed-posters.is-folded .feed-poster-item:nth-child(n + 4):not(.feed-poster-more-item) { display: none; }
  .feed-posters.is-folded .feed-poster-more-item:not([hidden]) { display: block; }
  /* Folded, the four always fit: they shrink below 67px on narrow phones rather than scroll. */
  .feed-posters.is-folded { overflow-x: hidden; }
  .feed-posters.is-folded .feed-poster-item { flex: 0 1 67px; min-width: 0; }
  .feed-posters.is-folded .poster, .feed-posters.is-folded .feed-poster-more { width: 100%; }
  .feed-text { font-size: 15px; }
}

/* iOS Safari zooms into any field under 16px when it takes focus, so touch screens get 16px.
   Last in the file so it outranks the smaller sizes above. */
@media (pointer: coarse) {
  input:is([type="email"], [type="password"], [type="text"], [type="search"], [type="number"]),
  textarea,
  .auth-panel input:is([type="email"], [type="password"], [type="text"]),
  .rate-review-body textarea,
  .review-box textarea,
  .comment-box textarea,
  .comment-box-texts textarea,
  .composer-text,
  .composer-search,
  input.link-field { font-size: 16px; }
}

/* A reply's title (reviews/_comment_title.html): a small poster beside the name and year. */
.comment-title { display: inline-flex; align-items: center; gap: 10px; margin-top: 6px; color: var(--text-primary); text-decoration: none; }
.comment-title:hover .comment-title-name { text-decoration: underline; }
.comment-title-poster { flex: none; width: 32px; height: 48px; border-radius: 2px; }
.comment-title-name { font-family: var(--serif); font-size: 14px; font-weight: 700; }
