/* Movie catalogue additions. The colour/type variables and base controls come
   directly from GameDB's scripts.gallery._CSS, injected by movie_catalog.py. */
.skip{position:fixed;left:12px;top:-60px;z-index:200;padding:9px 13px;border-radius:6px;background:var(--ink);color:var(--bg);text-decoration:none}.skip:focus{top:12px}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* `hidden` has to actually hide. The browser's own [hidden]{display:none} is a
   user-agent rule, so ANY author rule that sets `display` on the same element
   beats it and the element stays on screen with its markup still saying hidden.
   That is how .quiet-button{display:inline-flex} kept For you, Your taste and
   Friends' picks on the page for signed-out visitors, and .filter-line label
   kept the My shelf filter there. One guard instead of a per-class [hidden]
   each time someone adds a rule. */
[hidden]{display:none!important}
.movie-header{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;padding:24px 28px 18px;border-bottom:1px solid var(--line);background:color-mix(in srgb,var(--surface) 84%,transparent)}
.movie-heading{min-width:0}.brand{display:block;color:var(--ink);font:600 30px/1.15 var(--serif);letter-spacing:-.01em;text-decoration:none}.movie-heading .tag{margin-top:2px}.movie-heading .sub{margin:3px 0 0}
.header-actions{display:flex;align-items:center;justify-content:flex-end;gap:9px;flex-wrap:wrap}.catalog-switch{display:flex;padding:3px;border:1px solid var(--line);border-radius:9px;background:var(--bg)}.catalog-switch a{padding:7px 13px;border-radius:6px;color:var(--muted);font-size:13px;font-weight:650;text-decoration:none}.catalog-switch a.active{background:var(--terra);color:#fff8ef;box-shadow:var(--shadow)}
/* Header chrome: home, light/dark, "?", chats. One shape, and it is the SAME
   shape /browse draws (.helpb in serve.py) so a visitor who learns one
   catalogue's header finds the other one wearing the same buttons. Change one,
   change the other. It was a text "Theme" button here and 30px circles there
   until 2026-07-25. */
.chromeb{display:inline-flex;align-items:center;justify-content:center;min-width:35px;height:35px;padding:0 10px;border:1px solid var(--line);border-radius:7px;background:var(--surface);color:var(--muted);font:600 15px var(--sans);line-height:1;text-decoration:none;cursor:pointer}
.chromeb:hover{border-color:var(--terra);color:var(--ink)}
.chromeb svg{display:block}
/* the light/dark switch wears the moon by day and the sun by night: the icon
   offers the OTHER mode, swapped in CSS so no JS runs at paint time */
#themebtn .tsun{display:none}
html[data-theme=dark] #themebtn .tsun{display:block}
html[data-theme=dark] #themebtn .tmoon{display:none}
/* the unread count sits on the chat button's shoulder, inline it would stretch
   the button out of line with the rest of the row */
#msgbtn{position:relative}#msgbtn .nbadge{position:absolute;top:-7px;right:-8px;margin-left:0}
button,.quiet-button,select,input,textarea{font:inherit}.quiet-button{display:inline-flex;align-items:center;justify-content:center;padding:8px 11px;border:1px solid var(--line);border-radius:7px;background:var(--surface);color:var(--muted);font-size:12.5px;text-decoration:none;cursor:pointer}.quiet-button:hover{border-color:var(--terra);color:var(--terra-deep)}
main{min-height:70vh}.movie-search{padding:18px 28px 14px;border-bottom:1px solid var(--line-soft);background:var(--bg)}.search-line{display:flex;gap:9px;align-items:stretch}.search-box{flex:1;max-width:720px}.search-box input{width:100%;height:44px;padding:10px 13px;border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--ink);outline:none}.search-box input:focus,.filter-line input:focus,.filter-line select:focus,.note-box:focus{border-color:var(--terra);box-shadow:0 0 0 3px color-mix(in srgb,var(--terra) 18%,transparent)}
.primary-button{min-height:42px;padding:8px 15px;border:0;border-radius:8px;color:#fff8ef;font-weight:700;cursor:pointer}.primary-button{background:var(--terra)}.primary-button:hover{filter:brightness(1.07)}button:disabled{opacity:.55;cursor:wait}.search-hint{margin:7px 0 12px;color:var(--faint);font-size:12px}.filter-line{display:flex;align-items:flex-end;gap:9px;flex-wrap:wrap}.filter-line label{display:flex;flex-direction:column;gap:3px;color:var(--faint);font-size:10px;font-weight:750;letter-spacing:.07em;text-transform:uppercase}.filter-line select,.filter-line input{height:36px;max-width:190px;padding:6px 9px;border:1px solid var(--line);border-radius:7px;background:var(--surface);color:var(--ink);font-size:12.5px;letter-spacing:0;text-transform:none;outline:none}.filter-line .year-input{width:86px}.filter-line .quiet-button{height:36px}
.results-head{display:flex;justify-content:space-between;gap:16px;padding:15px 28px 0;color:var(--muted);font-size:13px}.results-head p{margin:0}
.friend-line{margin:7px 0 0;color:var(--plum);font-size:10.5px;font-weight:700}.friend-line span{display:inline-block;margin:2px 4px 0 0;padding:2px 6px;border-radius:999px;background:color-mix(in srgb,var(--plum) 12%,transparent)}
.movie-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:16px;padding:16px 24px 24px}.movie-card{min-height:270px;display:grid;grid-template-columns:120px 1fr;overflow:hidden;border:1px solid var(--line);border-radius:13px;background:var(--surface);box-shadow:var(--shadow);transition:transform .15s,box-shadow .15s}.movie-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-lift)}
.poster-button{position:relative;min-height:100%;padding:0;border:0;border-right:1px solid var(--line-soft);background:linear-gradient(145deg,var(--cover-ph1),var(--cover-ph2));color:var(--faint);cursor:pointer;overflow:hidden}.poster-button img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.poster-button .poster-fallback{display:grid;height:100%;place-items:center;padding:10px;font:italic 13px var(--serif);text-align:center}.type-badge{position:absolute;top:8px;left:7px;z-index:2;padding:3px 7px;border-radius:4px;background:rgba(34,25,21,.82);color:#fff6e9;font-size:9px;font-weight:800;letter-spacing:.09em;text-transform:uppercase}
.movie-card-body{min-width:0;display:flex;flex-direction:column;padding:13px 13px 11px}.movie-title-button{padding:0;border:0;background:none;color:var(--ink);font:600 17px/1.25 var(--serif);text-align:left;cursor:pointer}.movie-title-button:hover{color:var(--terra-deep)}.movie-original{margin:3px 0 0;color:var(--faint);font-size:11px}.movie-meta{margin:6px 0 0;color:var(--muted);font-size:12px}.movie-rating{color:var(--amber);font-weight:750}.movie-chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}.movie-chip{padding:2px 7px;border:1px solid var(--line);border-radius:4px;background:var(--bg);color:var(--muted);font-size:10.5px}.movie-feel{display:-webkit-box;margin:9px 0 0;overflow:hidden;color:var(--feel-ink);font:italic 12.5px/1.45 var(--serif);-webkit-line-clamp:3;-webkit-box-orient:vertical}
.movie-marks{display:flex;gap:5px;flex-wrap:wrap;margin-top:auto;padding-top:10px}.mark-button{min-height:29px;padding:4px 7px;border:1px solid var(--line);border-radius:6px;background:var(--bg);color:var(--muted);font-size:10.5px;cursor:pointer}.mark-button:hover{border-color:var(--sage)}.mark-button.active{border-color:var(--sage);background:var(--sage-bg);color:var(--sage-deep);font-weight:750}.mark-button[data-status=favorite].active{border-color:var(--terra);background:var(--terra-soft);color:var(--terra-deep)}
.empty-state{grid-column:1/-1;padding:60px 20px;border:1px dashed var(--line);border-radius:13px;color:var(--muted);text-align:center}.empty-state strong{display:block;margin-bottom:5px;color:var(--ink);font:600 20px var(--serif)}.more-wrap{display:flex;justify-content:center;padding:0 24px 35px}
.movie-modal{position:fixed;z-index:150;inset:0;overflow-y:auto;padding:38px max(18px,calc((100vw - 1050px)/2));background:rgba(25,18,15,.76);backdrop-filter:blur(5px)}.movie-modal[hidden]{display:none}.modal-close{position:fixed;z-index:152;top:16px;right:20px;width:42px;height:42px;border:1px solid rgba(255,255,255,.3);border-radius:50%;background:#2a211dcc;color:#fff;font-size:28px;line-height:1;cursor:pointer}.movie-detail{position:relative;min-height:520px;overflow:hidden;border:1px solid var(--line);border-radius:18px;background:var(--surface);box-shadow:0 25px 80px rgba(0,0,0,.4)}.detail-hero{position:relative;min-height:280px;display:grid;grid-template-columns:190px 1fr;gap:24px;padding:28px;background:linear-gradient(100deg,var(--surface) 25%,color-mix(in srgb,var(--surface) 82%,transparent)),var(--detail-bg,none) center/cover}.detail-poster{width:190px;aspect-ratio:2/3;border-radius:10px;object-fit:cover;background:var(--cover-bg);box-shadow:0 12px 35px rgba(0,0,0,.28)}.detail-copy{align-self:end;min-width:0}.detail-copy h2{margin:0;font:600 clamp(29px,4vw,48px)/1.02 var(--serif)}.detail-copy .movie-meta{font-size:14px}.detail-copy .movie-feel{max-width:720px;-webkit-line-clamp:4;font-size:14px}.detail-actions{display:flex;gap:7px;flex-wrap:wrap;margin-top:14px}.detail-content{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:28px;padding:25px 28px 30px}.detail-section h3{margin:0 0 8px;font:600 19px var(--serif)}.detail-section p{white-space:pre-line}.credit-list{display:flex;gap:7px;overflow-x:auto;padding:3px 0 10px}.credit{flex:0 0 104px;color:var(--ink);font-size:10.5px}.credit img,.credit-photo{display:block;width:72px;height:72px;margin-bottom:5px;border-radius:50%;object-fit:cover;background:var(--cover-bg)}.credit b{display:block;font-size:11.5px}.credit span{color:var(--faint)}.note-box{width:100%;min-height:100px;padding:9px 10px;border:1px solid var(--line);border-radius:7px;background:var(--bg);color:var(--ink);outline:none;resize:vertical}.detail-links{display:flex;gap:12px;flex-wrap:wrap;margin-top:12px}.detail-links a{color:var(--terra-deep)}.movie-share-panel{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-top:10px;padding:10px;border:1px solid var(--line);border-radius:8px;background:var(--bg)}.movie-share-panel[hidden]{display:none}.movie-share-panel strong{width:100%;font-size:12px}.related-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}.related-button{padding:8px;border:1px solid var(--line);border-radius:7px;background:var(--bg);color:var(--ink);font-size:11px;text-align:left;cursor:pointer}.related-button:hover{border-color:var(--terra)}
.movie-toast{position:fixed;z-index:220;left:50%;bottom:24px;max-width:min(90vw,520px);padding:10px 14px;border-radius:8px;background:var(--ink);color:var(--bg);box-shadow:var(--shadow-lift);opacity:0;pointer-events:none;transform:translate(-50%,12px);transition:.2s}.movie-toast.show{opacity:1;transform:translate(-50%,0)}.movie-footer{display:flex;justify-content:space-between;gap:20px;padding:18px 28px;border-top:1px solid var(--line);color:var(--faint);font-size:11px}.movie-footer nav{display:flex;gap:14px}.movie-footer a{color:var(--muted);text-decoration:none}
.loading-card{height:270px;border-radius:13px;background:linear-gradient(100deg,var(--surface) 30%,var(--line-soft) 45%,var(--surface) 60%);background-size:220% 100%;animation:movie-shimmer 1.4s infinite}@keyframes movie-shimmer{to{background-position:-220% 0}}
/* The tour, the "?" in the header. Same overlay /browse draws (.tback/.tspot/
   .tcard in serve.py, TOURB) with this page's own steps: a step frames the
   control it is talking about instead of flying a camera at it. The spotlight
   is a hole punched with a huge outset shadow, so the framed control keeps its
   real colours rather than being tinted through an overlay. */
.tback{position:fixed;inset:0;z-index:120;display:none;background:rgba(30,24,18,.62)}
.tback.open{display:block}
.tspot{position:absolute;border-radius:8px;box-shadow:0 0 0 9999px rgba(30,24,18,.62),0 0 0 2px var(--terra);transition:all .22s ease;pointer-events:none}
.tback.drag .tspot,.tback.drag .tcard{transition:none}
.tcard{position:absolute;max-width:330px;padding:14px 16px;border:1px solid var(--line);border-radius:10px;background:var(--surface);box-shadow:var(--shadow-lift);transition:all .22s ease}
.tcard h3{margin:0 0 6px;font:600 17px/1.25 var(--serif)}
.tcard p{margin:0;color:var(--muted);line-height:1.5}
.trow{display:flex;align-items:center;gap:8px;margin-top:12px}
.trow button{padding:5px 12px;border:1px solid var(--line);border-radius:6px;background:var(--bg);color:var(--ink);font:inherit;cursor:pointer}
.trow button:hover:not(:disabled){border-color:var(--terra)}
.trow button:disabled{opacity:.4;cursor:default}
.trow .tprim{border-color:var(--terra);background:var(--terra);color:#fff3df}
.trow .tskip{margin-left:auto}
.tn{color:var(--faint);font:600 12px var(--sans)}
@media(max-width:700px){.tcard{left:12px!important;right:12px;width:auto;max-width:none}}

@media(max-width:760px){.movie-header{padding:16px;flex-direction:column}.header-actions{width:100%;justify-content:space-between}.movie-search{padding:14px 16px}.search-line{display:grid;grid-template-columns:1fr 1fr}.search-box{grid-column:1/-1}.filter-line{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.filter-line label,.filter-line select,.filter-line input{width:100%;max-width:none}.results-head{padding:13px 16px 0}.movie-grid{grid-template-columns:1fr;padding:13px 14px 20px}.movie-card{grid-template-columns:105px 1fr;min-height:245px}.detail-hero{grid-template-columns:110px 1fr;gap:15px;padding:18px}.detail-poster{width:110px}.detail-content{grid-template-columns:1fr;padding:20px}.movie-modal{padding:55px 8px 15px}.movie-footer{padding:16px;flex-direction:column}.movie-footer nav{flex-wrap:wrap}}
@media(max-width:420px){.movie-card{grid-template-columns:92px 1fr}.search-line{grid-template-columns:1fr}.search-box{grid-column:auto}.detail-hero{grid-template-columns:1fr}.detail-poster{width:120px}.detail-copy{align-self:start}.catalog-switch a{padding:7px 10px}}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{scroll-behavior:auto!important;animation-duration:.01ms!important;transition-duration:.01ms!important}}

/* ---- Discover ---------------------------------------------------------- */
.disc-back{position:fixed;inset:0;z-index:90;display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;padding:44px 16px;background:rgba(42,36,32,.45)}
.disc-back[hidden]{display:none}
.disc-card{position:relative;width:100%;max-width:760px;padding:22px 24px 18px;border:1px solid var(--line);border-radius:12px;background:var(--surface);box-shadow:var(--shadow-lift)}
.disc-card h2{margin:0 36px 4px 0;font:600 22px/1.2 var(--serif)}
.disc-sub{margin:0 0 14px;color:var(--muted);font-size:13px}
.disc-ask{display:flex;gap:9px;margin-bottom:12px}
.disc-ask input{flex:1;height:42px;padding:8px 12px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--ink);font-size:14px;outline:none}
.disc-ask input:focus{border-color:var(--terra)}
.disc-pills{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px}
.disc-pill{padding:5px 11px;border:1px solid var(--line);border-radius:999px;background:var(--bg);color:var(--muted);font-size:12px;cursor:pointer}
.disc-pill:hover{border-color:var(--terra);color:var(--ink)}
.disc-pill.on{background:var(--terra);border-color:var(--terra);color:#fff8ef;font-weight:700}
.disc-results{display:flex;flex-direction:column;gap:12px}
.disc-note{margin:6px 0;color:var(--faint);font-size:13px}
.disc-item{display:flex;gap:14px;padding:12px;border:1px solid var(--line-soft);border-radius:10px;background:var(--bg)}
.disc-art{flex:0 0 78px;height:117px;border-radius:6px;background:var(--cover-bg) center/cover no-repeat;border:1px solid var(--line-soft)}
.disc-art.ph{display:flex;align-items:center;justify-content:center;padding:6px;text-align:center;color:var(--faint);font:italic 11px var(--serif);background:linear-gradient(160deg,var(--cover-ph1),var(--cover-ph2))}
.disc-body{flex:1;min-width:0}
.disc-body h3{margin:0 0 3px;font:600 16.5px/1.25 var(--serif)}
.disc-body h3 a{color:inherit;text-decoration:none}
.disc-body h3 a:hover{text-decoration:underline;text-underline-offset:3px}
.disc-meta{margin:0 0 5px;color:var(--muted);font-size:12px}
.disc-acts{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.disc-foot{display:flex;gap:9px;margin-top:14px}
@media(max-width:760px){.disc-card{padding:18px 15px}.disc-ask{flex-direction:column}.disc-item{gap:10px}.disc-art{flex-basis:62px;height:93px}}

/* ---- taste sheet ------------------------------------------------------- */
.taste-wrap{display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start}
.taste-radar{flex:0 0 300px;max-width:100%;padding:14px 34px;overflow:visible}
/* radar.js ships defaults but every host so far restyles it (serve.py:798,
   shelf.py:1150). Without these the polygon paints solid black on this page.
   The label padding above is not decoration: the spoke labels sit OUTSIDE the
   viewBox, so a tight container clips "Heartfelt" to "tfelt". */
.taste-radar svg{width:100%;height:auto;overflow:visible}
.taste-radar .rdr-ring,.taste-radar .rdr-spoke{fill:none;stroke:var(--line);stroke-width:1}
.taste-radar .rdr-fill{fill:rgba(95,140,55,.30);stroke:#5f8f2e;stroke-width:2;stroke-linejoin:round}
.taste-radar .rdr-dot{fill:#5f8f2e}
.taste-radar .rdr-lbl{fill:var(--muted);font:600 12px var(--sans)}
.taste-facts{flex:1;min-width:200px}
.taste-class{margin:0 0 8px;font:600 21px/1.2 var(--serif);color:var(--terra-deep)}
.taste-facts .disc-meta{margin:0 0 5px}
@media(max-width:700px){.taste-radar{flex-basis:100%}}

/* the curated-list spine, same idea as /browse's strip: without an on-site
   link the list pages are orphans no crawler ever reaches */
.lists-strip { margin: 4px 0 10px; font-size: .9rem; line-height: 1.9; }
.lists-strip b { color: var(--faint, #8A7B6C); font-weight: 600; margin-right: 4px; }
.lists-strip a { color: var(--terra-deep, #96431F); text-decoration: none; }
.lists-strip a:hover { text-decoration: underline; }

/* "What's new": the notice board, drawn into this page's own panel (openNotes
   in movie-catalog.js). Twins: serve.py's .nlist popup on /browse, shelf.py's
   taped paper sheet in the shop. Only the list of dated cards needs styling
   here; the entry body borrows the panel's own prose. */
.nlist { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.nlist button { position: relative; text-align: left; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px;
  cursor: pointer; color: var(--ink); font: inherit; }
.nlist button:hover, .nlist button.on { border-color: var(--terra); }
.nlist .nv { display: block; font: 600 11px var(--sans); color: var(--faint);
  letter-spacing: .06em; }
.nlist .nt { display: block; font: 600 14px var(--sans); }
.nlist .nnew { position: absolute; top: -6px; right: -6px; background: var(--terra);
  color: #FFF3DF; font: 700 9px var(--sans); letter-spacing: .08em;
  border-radius: 6px; padding: 2px 5px; }
.nbody h3 { margin: 14px 0 4px; font: 600 17px/1.3 var(--serif); }
.nbody .nsec { margin-top: 10px; font: 600 11px var(--sans); letter-spacing: .08em;
  text-transform: uppercase; color: var(--faint); }
.nbody ul { margin: 4px 0 0; padding-left: 18px; }
.nbody li { margin: 3px 0; line-height: 1.5; }

/* Friends panel (openFriends in movie-catalog.js). Rows in the page's shared
   panel rather than a fourth modal; twin: #frback in serve.py. */
.fr-h { margin: 16px 0 6px; font: 600 15px var(--serif); color: var(--ink); }
.fr-h:first-child { margin-top: 2px; }
.fr-row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 8px 2px; border-bottom: 1px solid var(--line-soft); }
.fr-row b { flex: 1; min-width: 0; overflow: hidden; font-weight: 650;
  text-overflow: ellipsis; white-space: nowrap; }
.fr-row .disc-meta { margin: 0; flex: none; }
.fr-acts { display: flex; gap: 5px; flex: none; flex-wrap: wrap; }
.fr-find { margin: 4px 0 8px; }
.fr-find input { width: 100%; max-width: 320px; height: 36px; padding: 6px 10px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--surface);
  color: var(--ink); outline: none; }
.fr-find input:focus { border-color: var(--terra); }
/* A notification toast you can act on (toastGo): reads as tappable and lasts
   longer, because there is something to do. Plain toasts stay inert. */
.movie-toast.go { cursor: pointer; border: 1px solid var(--terra); }
.movie-toast.go::after { content: ' \2192'; opacity: .8; }
