/* Type faces: css/fonts.css (Newsreader for titles, Schibsted Grotesk for the rest). */
:root {
  /* Colour (docs/design-language.md §1.12): warm paper-black, ink, one accent per meaning. --new only
     means new for you (and Senin için's reasons), --live only live, the cream --focus-c only focus. */
  --bg: #12100e; --panel-1: #1b1815; --panel-2: #26221d; --panel-3: #332d26; --end-card-2: #3a332b;
  --ink: #f4efe6; --ink-2: #cfc6b8; --ink-3: #a59a8b; --ink-inv: #15120f;
  --new: #f2b84b; --live: #e5484d; --focus-c: #fffaf0; --rule: rgba(244, 239, 230, .16);
  --cat-ulusal: #2a2019; --cat-spor: #16281e; --cat-haber: #18202c; --cat-cocuk: #1d2a1f;
  /* The names the rules were written with, on that palette (hex: scripts/library-tiles.py and
     notice-clip.py read --bg, --bg2, --ink, --red and --muted from this block). Muted is ink-2: it
     carries sentences, and ink-3 (6.6:1) is for labels only. */
  --bg2: #1b1815; --panel: #26221d; --line: rgba(244, 239, 230, .16);
  /* --red stays the brand red: white text on it (the TV badge, TR, CANLI) reads 4.51:1, on --live 3.91:1. */
  --muted: #cfc6b8; --red: #e52634; --red-2: #ff4453; --good: #3ccf8e; --warn: #f5b841;
  /* Secondary text on imagery or a translucent layer (docs/design-language.md, colour). */
  --on-art: #cfc6b8;
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --sans: "Schibsted Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Side gutters clear a landscape iPhone's notch (viewport-fit=cover). */
  --gutter: max(clamp(16px, 4vw, 56px), env(safe-area-inset-left), env(safe-area-inset-right)); --card: clamp(118px, 13vw, 200px);
  /* Sizes per device class (§1.12 type, space, size, radius, focus): desktop here, html.tv and the
     phone block below. Surfaces move onto them as their slice redraws them (round 4 S1-S7). */
  --fs-cover: 88px; --fs-title: 68px; --fs-row: 32px; --fs-deck: 25px; --fs-reason: 19px;
  --fs-body: 19px; --fs-detail: 17px; --fs-button: 18px;
  --m: 64px; --card-gap: 24px; --row-gap: 56px; --w-wide: 310px; --w-poster: 198px; --h-btn: 52px;
  --r1: 6px; --r2: 10px; --r3: 14px; --radius: var(--r2);
  /* Focus is cream everywhere (a dark gap, then a cream ring): red only means live or an error.
     Artwork lifts 1.05 and takes the same ring, with a shadow under it off the TV. */
  --ring: 4px; --ring-gap: 4px;
  /* How far a ring reaches out of its box: a strip that scrolls (and so clips) pads by it and takes it
     back with a negative margin, so nothing moves and no ring is cut. */
  --ring-out: calc(var(--ring) + var(--ring-gap));
  --focus: 0 0 0 var(--ring-gap) var(--bg), 0 0 0 calc(var(--ring-gap) + var(--ring)) var(--focus-c);
  --focus-art: var(--focus), 0 14px 32px rgba(0, 0, 0, .6);
  /* Type steps (docs/design-language.md, type): size, leading, tracking, weight. Longhands, never the
     font shorthand (it resets font-variant-numeric). Leading, measured on "Çağlayan / İğneci Şişli"
     (§1.6): text that wraps needs 1.15 in Newsreader 500 (Ğ rises .901em, ğ ş ç descend .247em) and
     1.2 in Schibsted Grotesk 700 (İ .958em, ğ .203em); clamped text with overflow: hidden keeps 1.4
     (Newsreader's first-line marks need 1.34). */
  --t-display-size: var(--fs-title); --t-display-lh: 1.15; --t-display-ls: -.02em; --t-display-w: 500;
  --t-title1-lh: 1.15; --t-title2-size: 1.4rem; --t-title2-lh: 1.2; --t-title2-ls: -.015em; --t-title2-w: 700;
  --t-title3-size: 1.25rem; --t-title3-lh: 1.25; --t-title3-ls: -.01em; --t-title3-w: 700;
  --t-headline-size: 1.05rem; --t-headline-lh: 1.3; --t-headline-w: 700;
  --t-body-size: 1.05rem; --t-body-lh: 1.55; --t-body-w: 400;
  --t-callout-size: .92rem; --t-callout-lh: 1.4; --t-callout-w: 600;
  --t-caption-size: .85rem; --t-caption-lh: 1.4; --t-caption-ls: .005em; --t-caption-w: 600;
  --t-caption2-size: .75rem; --t-caption2-lh: 1.3; --t-caption2-ls: .01em; --t-caption2-w: 600;
  /* Motion (docs/motion.md): strong curves; the built-in ones are too weak. Press 60 ms in, 200 ms
     out (O7); controls 100 in, 250 out. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --t-press-in: 60ms; --t-press-out: 200ms; --t-controls-in: 100ms; --t-controls-out: 250ms;
  color-scheme: dark;
}
/* TV (1920 x 1080, read from 3 m): the §1.12 TV column. 26 px is the smallest text a new TV surface uses. */
html.tv {
  --fs-cover: 96px; --fs-title: 88px; --fs-row: 44px; --fs-deck: 34px; --fs-reason: 30px;
  --fs-body: 30px; --fs-detail: 28px; --fs-button: 30px; --fs-tv-min: 26px;
  --m: 96px; --card-gap: 40px; --row-gap: 60px; --w-wide: 402px; --w-poster: 254px; --h-btn: 76px;
  --r1: 8px; --r2: 14px; --r3: 20px;
  --ring: 5px; --ring-gap: 5px;
  /* No shadow under a lifted card on a TV: a blurred shadow was the costliest repaint per key. */
  --focus-art: var(--focus);
}
@media (max-width: 720px) {
  html:not(.tv) {
    --fs-cover: 40px; --fs-title: 36px; --fs-row: 23px; --fs-deck: 18px; --fs-reason: 15px;
    --fs-body: 16px; --fs-detail: 14px; --fs-button: 16px;
    --m: 20px; --card-gap: 12px; --row-gap: 36px; --w-wide: 264px; --w-poster: 136px; --h-btn: 48px;
  }
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
body { min-height: 100vh; overflow-x: hidden; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
/* 10-foot step (docs/design.md): TV browsers at 1600px+ scale every rem by 1.25 (16 -> 20px base).
   html.tv comes from the user agent (ui.js) for TV browsers that report a fine pointer. */
@media (min-width: 1600px) and (pointer: none), (min-width: 1600px) and (pointer: coarse) { html { font-size: 125%; } }
@media (min-width: 1600px) { html.tv { font-size: 125%; } }
/* A big screen with no hover (Android TV and Fire TV browsers, casting sticks) is a couch screen too;
   desktops always hover, so their type stays put. */
@media (min-width: 1800px) and (hover: none) { html { font-size: 125%; } }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.muted { color: var(--muted); }
:focus { outline: none; }
:focus-visible, .episode:focus { box-shadow: var(--focus); border-radius: var(--radius); }

/* ---------- icons (js/icons.js: 24px grid, 1.5px stroke, currentColor) ---------- */
.icon { width: 1.25em; height: 1.25em; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; vertical-align: -.25em; }
.icon.solid { fill: currentColor; }

/* ---------- buttons & fields ---------- */
.btn { display: inline-flex; align-items: center; gap: .5em; min-height: 44px; padding: .7em 1.4em; border-radius: 8px; background: rgba(244, 239, 230, .16); font-weight: 700; font-size: 1rem; transition: background .15s, transform 200ms var(--ease-out); }
.btn:focus-visible { background: rgba(244, 239, 230, .28); }
.btn.primary { background: var(--ink); color: var(--ink-inv); }
.btn.primary:focus-visible { background: var(--focus-c); }
.btn .icon { margin-left: -.2em; }
.row-btns { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 18px; }
/* A TV's ring reaches 10 px out of a button: 24 px between them keeps it off the next one. */
html.tv .row-btns { gap: 24px; }
.field { width: 100%; padding: 14px 16px; border-radius: 8px; border: 1px solid var(--line); background: var(--bg2); color: var(--ink); font: inherit; font-size: 1.05rem; }
.field:focus { border-color: var(--ink); }
.field:focus-visible { box-shadow: none; }   /* its white border already says so */
.field.pin { text-align: center; letter-spacing: .5em; font-size: 1.6rem; }
.field-label { font-weight: 700; font-size: .9rem; color: var(--ink); text-align: left; justify-self: start; }
.msg { min-height: 1.2em; color: var(--red-2); margin: 10px 0 0; }

/* ---------- gate / profiles ---------- */
.center-screen { min-height: 100vh; min-height: 100dvh; display: grid; place-content: center; justify-items: center; gap: 28px; padding: var(--gutter); text-align: center;
  background: radial-gradient(1200px 600px at 50% 110%, rgba(120, 18, 28, .45), transparent 60%), var(--bg); }
/* Text logo: randımanlı + red TV badge (brand kit colours; set in the text face, so the gate loads one font). */
.brand-mark { display: inline-flex; align-items: center; gap: .18em; font-weight: 800; font-size: clamp(1.9rem, 5vw, 2.6rem); letter-spacing: -.035em; color: var(--ink); line-height: 1; }
.brand-mark .tv { font-size: .42em; letter-spacing: .02em; background: var(--red); color: #fff; border-radius: .28em; padding: .22em .38em .2em; transform: translateY(-.55em); }
.brand-mark.big { font-size: clamp(2.6rem, 9vw, 4.2rem); }
.brand-mark.small { font-size: 1.45rem; }
@media (max-width: 720px) { .brand-mark.small { font-size: 1.15rem; } }
.center-screen h1 { font-family: var(--serif); font-size: clamp(1.8rem, 4vw, 3rem); margin: 0; font-weight: 500; line-height: var(--t-title1-lh); letter-spacing: -.01em; }

/* ---------- top bar ---------- */
/* Readable over bright art at the top of a page: a longer, stronger scrim. Scrolled, the bar is
   opaque and a 24 px edge fades the page into it (no line over moving content). A TV swaps at once. */
.topbar { position: fixed; top: 0; left: 0; right: 0; z-index: 20; display: flex; align-items: center; gap: clamp(12px, 2.5vw, 36px); padding: max(10px, env(safe-area-inset-top)) var(--gutter) 22px;
  background: linear-gradient(180deg, rgba(18, 16, 14, .94), rgba(18, 16, 14, .78) 55%, rgba(18, 16, 14, 0)); transition: background-color .2s; }
.topbar::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 24px; pointer-events: none; opacity: 0; transition: opacity .2s;
  background: linear-gradient(180deg, var(--bg), rgba(18, 16, 14, 0)); }
.topbar.scrolled { background-color: var(--bg); }
.topbar.scrolled::after { opacity: 1; }
html.tv .topbar, html.tv .topbar::after { transition: none; }
/* A TV draws the bar inside the overscan-safe box (x 96..1824, y 54..1026) with its 10 px ring: the
   controls start at x 106 and y 64, end at x 1814, and are 36 px tall, so a focused one's ring ends
   at y 110, where the guide's header starts (live.css); pages that started higher start at 120. */
html.tv .topbar { padding: 64px 106px 18px; }
html.tv .topbar nav a { padding-top: 5px; padding-bottom: 5px; }
html.tv .icon-link, html.tv .me { width: 36px; height: 36px; }
html.tv .page-title, html.tv .list-head { margin-top: 120px; }
html.tv .list-head .page-title, html.tv .set-head .page-title, html.tv .bagla .page-title, html.tv .admin > .page-title { margin-top: 0; }
html.tv .settings, html.tv .bagla { padding-top: 120px; }
.brand { display: inline-flex; }
.topbar nav { display: flex; gap: clamp(10px, 2vw, 26px); overflow-x: auto; scrollbar-width: none; padding: var(--ring-out); margin: calc(-1 * var(--ring-out)); }
.topbar nav a { color: rgba(244, 239, 230, .78); font-weight: 600; white-space: nowrap; padding: 10px 2px; }
.topbar nav a.active { color: var(--ink); }
/* Where you are, by more than colour (inactive links are ink at .78): a 2 px bar under the label,
   out of the flow. Wider screens only; the phone's tab bar marks it with its icon and colour. */
@media (min-width: 721px) {
  .topbar nav a { position: relative; }
  .topbar nav a.active::after { content: ""; position: absolute; left: 2px; right: 2px; bottom: 4px; height: 2px; border-radius: 1px; background: currentColor; }
}
/* Tablets (iPad portrait, small laptops): all seven sections fit on one line, none cut off. */
@media (min-width: 721px) and (max-width: 1100px) {
  .topbar nav { gap: 10px; }
  .topbar nav a { font-size: .9rem; }
  .brand-mark.small { font-size: 1.25rem; }
}
@media (min-width: 721px) and (max-width: 820px) {
  .topbar { gap: 10px; }
  .topbar nav { gap: 5px; }
  .topbar nav a { font-size: .85rem; }
}
.nav-icon { display: none; }
.spacer { flex: 1; }
.icon-link { position: relative; display: grid; place-items: center; width: 44px; height: 44px; font-size: 1.2rem; color: var(--ink); }
.icon-link.active::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 2px; height: 2px; border-radius: 1px; background: currentColor; }
.back-link { margin-left: -10px; color: var(--ink); }
.me { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; }
.me img { width: 34px; height: 34px; border-radius: 50%; display: block; }

/* ---------- hero & detail ---------- */
.page { padding-bottom: 64px; }
.hero, .detail { position: relative; min-height: min(78vh, 760px); display: flex; align-items: flex-end; padding: calc(120px + env(safe-area-inset-top)) var(--gutter) 48px; }
.hero-bg { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background-size: cover; background-position: center 20%; background-color: var(--bg2);
  mask-image: linear-gradient(180deg, #000 55%, transparent 100%); -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 100%); }
.hero-bg::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  background: linear-gradient(90deg, rgba(18, 16, 14, .92) 0%, rgba(18, 16, 14, .8) 35%, rgba(18, 16, 14, .45) 60%, rgba(18, 16, 14, 0) 80%); }
/* No backdrop at TMDB: the poster itself, whole, on the right (app.js backdrop). */
.hero-bg.poster-bg { background-size: contain; background-repeat: no-repeat; background-position: right var(--gutter) top calc(80px + env(safe-area-inset-top)); }
.hero-body, .detail-body { position: relative; max-width: 640px; }
/* 1.15: at 1.05 a two-line Turkish title's ğ and y sit on the next line's İ dot. */
.hero h1, .detail h1 { font-family: var(--serif); font-size: var(--t-display-size); margin: 0 0 10px; line-height: var(--t-display-lh); font-weight: var(--t-display-w); letter-spacing: var(--t-display-ls); }
.meta { color: var(--muted); font-weight: 600; margin: 6px 0; white-space: pre-wrap; }
.meta-strip { color: var(--on-art); }
/* Title art: a fixed box, so a logo that loads with the page moves nothing. Wide logos fill the
   width, tall ones the height; bottom-left keeps them on the text's edge. */
.title.has-logo { margin-bottom: 18px; line-height: 0; }
.title .logo { display: block; width: min(100%, 480px); height: clamp(72px, 15vh, 150px); object-fit: contain; object-position: left bottom;
  filter: drop-shadow(0 2px 14px rgba(0, 0, 0, .55)); }
.title.fade .logo { animation: logo-in 300ms var(--ease-out); }
@keyframes logo-in { from { opacity: 0; } }
.ep-line { font-weight: 700; margin: 0 0 4px; font-size: 1.05rem; }
.meta-strip, .ends { text-shadow: 0 1px 8px rgba(0, 0, 0, .7); }
.meta-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 1em; font-size: 1.05rem; white-space: normal; }
.cert { padding: 1px 7px; border: 1.5px solid currentColor; border-radius: 5px; font-size: .8rem; font-weight: 800; letter-spacing: .02em; line-height: 1.4; }
.stars { position: relative; display: inline-flex; color: rgba(244, 239, 230, .22); }
.stars-row { display: inline-flex; }
.stars .icon { width: 1.15em; height: 1.15em; stroke: none; vertical-align: 0; }
.stars-fill { position: absolute; top: 0; right: auto; bottom: 0; left: 0; overflow: hidden; color: var(--ink); }
.ends { display: flex; align-items: center; gap: 8px; color: var(--on-art); font-weight: 600; margin: 12px 0 0; font-variant-numeric: tabular-nums; }
.ends .icon { width: 1.2em; height: 1.2em; }
.overview { font-size: 1.05rem; line-height: 1.55; color: #e9e2d6; }

/* ---------- rows & cards ---------- */
.row { margin: 26px 0 0; }
/* Row headings in the title face (§1.12 rowHeading): one line, so 1.15 is room enough. */
.row h2 { font-family: var(--serif); font-size: var(--fs-row); line-height: 1.15; margin: 0 var(--gutter) 10px; font-weight: 500; letter-spacing: -.01em; }
.row-link { display: inline-flex; align-items: center; gap: 2px; }
.row-link .icon { width: 1em; height: 1em; }
/* A row's swipe ends at its end: it never chains into the page or the browser's back gesture. */
.track { display: flex; gap: 10px; overflow-x: auto; overscroll-behavior-x: contain; padding: calc(8px + var(--ring-out)) var(--gutter) calc(14px + var(--ring-out)); margin: calc(-1 * var(--ring-out)) 0; scroll-padding: 0 var(--gutter); scrollbar-width: none; scroll-snap-type: x proximity; }
.track::-webkit-scrollbar { display: none; }
/* A mouse without a sideways wheel: a page back or on (ui.js scrollable). Hovering fine pointers
   only; remotes and touch screens never see them. */
.track-wrap { position: relative; }
.row-arrow { display: none; }
@media (hover: hover) and (pointer: fine) {
  .row-arrow:not([hidden]) { display: grid; place-items: center; position: absolute; top: calc(8px + var(--ring-out)); bottom: calc(14px + var(--ring-out)); z-index: 3; width: max(44px, var(--gutter));
    color: var(--ink); opacity: 0; transition: opacity .18s; cursor: pointer; }
  .row-arrow.prev { left: 0; background: linear-gradient(90deg, rgba(18, 16, 14, .85), transparent); }
  .row-arrow.next { right: 0; background: linear-gradient(270deg, rgba(18, 16, 14, .85), transparent); }
  .row-arrow.prev .icon { transform: rotate(180deg); }
  .row-arrow .icon { width: 32px; height: 32px; }
  .track-wrap:hover .row-arrow { opacity: 1; }
}
.card { position: relative; flex: 0 0 var(--card); display: flex; flex-direction: column; gap: 6px; border-radius: var(--radius); scroll-snap-align: start; transition: transform 200ms var(--ease-out); }
.card.wide { flex-basis: calc(var(--card) * 1.9); }
.poster { position: relative; display: block; aspect-ratio: 2/3; border-radius: var(--radius); overflow: hidden; background: var(--panel); }
.card.wide .poster { aspect-ratio: 16/9; }
.poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card.broken .poster img { visibility: hidden; }
.card:focus-visible { box-shadow: none; transform: scale(1.05); z-index: 2; }
.card:focus-visible .poster { box-shadow: var(--focus-art); }
/* Titles: over the poster on hover/focus with a pointer; always shown under it on touch screens. */
.card-title { position: absolute; top: auto; right: 0; bottom: 0; left: 0; padding: 26px 10px 10px; border-radius: 0 0 var(--radius) var(--radius); font-size: .85rem; font-weight: 700;
  background: linear-gradient(0deg, rgba(0, 0, 0, .85), transparent); opacity: 0; transition: opacity .18s; pointer-events: none; }
.card.wide .card-title, .card:focus-visible .card-title { opacity: 1; }
.card.wide .card-title { padding-bottom: 16px; }
.card.broken .card-title { opacity: 1; top: 0; right: 0; bottom: 0; left: 0; display: grid; place-items: center; padding: 12px; text-align: center; background: none; border-radius: var(--radius); }
/* Turkish-dub mark: a small brand-red tag, top left, legible over any poster. */
.dub-mark { position: absolute; top: 8px; left: 8px; padding: 3px 6px 2px; border-radius: 5px; background: var(--red); color: #fff; font-size: .68rem; font-weight: 800; letter-spacing: .06em; line-height: 1; box-shadow: 0 1px 6px rgba(0, 0, 0, .35); }
.bar { position: absolute; left: 8px; right: 8px; bottom: 6px; height: 4px; border-radius: 2px; background: rgba(255, 255, 255, .25); overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--red); }
/* Placeholders while a row or search answer loads: the poster's shape, no motion. */
.card.skel { pointer-events: none; }
.card.skel .poster { background: var(--panel); }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--card), 1fr)); gap: 14px; padding: 8px var(--gutter); }
.grid .card { flex: none; }
.grid .empty { grid-column: 1 / -1; padding: 12px 0; }
/* Fixed offsets clear the top bar, which grows by the status bar in the home-screen app (black-translucent). */
.page-title { margin: calc(96px + env(safe-area-inset-top)) var(--gutter) 10px; font-family: var(--serif); font-weight: 500; font-size: var(--fs-title); line-height: 1.15; letter-spacing: -.02em; }
.empty { color: var(--muted); padding: 20px var(--gutter); }
.empty p { margin: 0 0 6px; }
.empty > p:first-child { color: var(--ink); font-weight: 700; }
.page-error { padding-top: calc(120px + env(safe-area-inset-top)); }
.sub-head { font-size: 1.05rem; font-weight: 700; color: var(--muted); margin: 18px var(--gutter) 2px; }

@media (hover: hover) {
  .btn:hover { background: rgba(244, 239, 230, .28); }
  .btn.primary:hover { background: #fff; }
  .topbar nav a:hover, .icon-link:hover { color: var(--ink); }
  .card:hover { transform: scale(1.05); z-index: 2; }
  .card:hover .card-title { opacity: 1; }
  .icon-btn:hover, .menu-item:hover { background: rgba(255, 255, 255, .12); }
}
@media (hover: none) {
  .card-title { position: static; padding: 0 2px; opacity: 1; background: none; font-weight: 600; font-size: .8rem; line-height: var(--t-caption-lh); color: #e9e2d6;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .card.wide .card-title { padding: 0 2px; }
}

/* ---------- calm TV mode (html.tv, ui.js) ---------- */
/* A TV's chip repaints slowly, and a remote press must answer at once (docs/motion.md): nothing
   eases, blurs or masks there. The focused card still lifts, with a plain white edge instead of
   the glow; the hero fades into the page under a gradient instead of a mask; the logo has no shadow. */
html.tv .card, html.tv .poster, html.tv .card-title, html.tv .profile { transition: none; }
html.tv .hero-bg { mask-image: none; -webkit-mask-image: none; }
html.tv .hero-bg::before { content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: linear-gradient(180deg, rgba(18, 16, 14, 0) 55%, var(--bg) 100%); }
html.tv .title .logo { filter: none; }

/* ---------- the browser floor: Chromium 85 (Tizen 6.5) ---------- */
/* inset is Chromium 87: written out as top, right, bottom and left everywhere but the player's rules. */
@supports not (inset: 0) {
  .player, .player-overlay, .player-controls, .menu-scrim { top: 0; right: 0; bottom: 0; left: 0; }
}
/* aspect-ratio is Chromium 88. A box as wide as its parent takes its height from padding (a share of
   that width); a box of known width gets the height that width gives. */
@supports not (aspect-ratio: 1) {
  .poster { height: 0; padding-top: 150%; }
  .card.wide .poster { padding-top: 56.25%; }
  .poster img { position: absolute; top: 0; left: 0; }
  .card.service .poster { height: calc(var(--card) * 1.3 * .5625); padding-top: 0; }
  .card.service .poster img { position: static; }
  /* A grid that centres its label needs a real height: its row would start below the padding. */
  .card.more-tile .poster { height: calc(var(--card) * 1.5); padding-top: 0; }
  .dl-poster { height: 84px; }
}

/* ---------- İndirilenler (RealDebrid gathering) ---------- */
.btn.small { min-height: 36px; padding: .45em 1em; font-size: .9rem; }
.btn.danger { background: var(--red); color: #fff; }
.spinner.small { width: 16px; height: 16px; border-width: 2px; }
.gather { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; margin-top: 12px; }
.gather-meta { color: var(--muted); font-size: .88rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.gather-status { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font-weight: 700; font-variant-numeric: tabular-nums; }
.gather-status.failed { color: #ffd98a; }
.ring { width: 24px; height: 24px; transform: rotate(-90deg); fill: none; stroke-width: 2.5; }
.ring-track { stroke: rgba(244, 239, 230, .18); }
.ring-fill { stroke: var(--red); stroke-linecap: round; transition: stroke-dasharray .4s; }
.season-tools .gather { margin: 0; }
/* The answer arrives 0.2–4 s after paint: on detail pages and seasons the slot keeps its height
   (invisible while empty) so the bottom-anchored title and Play button never jump. */
.detail-body > .gather, .season-tools .gather { min-height: 44px; }
.detail-body > .gather[hidden], .season-tools .gather[hidden] { display: flex !important; visibility: hidden; }
/* That slot already spaces a movie's detail from the row below: no bottom padding on top of it. */
.detail.movie { padding-bottom: 0; }
.player-error .gather { justify-content: center; margin: 4px 0 16px; }
/* Nothing plays in this browser: İndir leads, one plain line under it says why. */
.gather-why { flex-basis: 100%; margin: 0; color: var(--muted); font-size: .92rem; }
.no-copy { margin: 12px 0 4px; color: var(--muted); font-weight: 600; }
.dl-list { display: grid; gap: 8px; padding: 8px var(--gutter); max-width: 900px; }
.dl-row { display: flex; align-items: center; gap: 8px; border-radius: var(--radius); background: rgba(244, 239, 230, .04); padding-right: 8px; }
.dl-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; padding: 8px; text-align: left; border-radius: var(--radius); }
.dl-main:focus-visible { background: rgba(244, 239, 230, .08); }
.dl-poster { flex: none; width: 56px; aspect-ratio: 2/3; border-radius: 6px; overflow: hidden; background: var(--panel); }
.dl-poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dl-poster img.broken { visibility: hidden; }
.dl-text { flex: 1; min-width: 0; display: grid; gap: 3px; }
.dl-title { font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dl-sub { color: var(--muted); font-size: .85rem; }
.dl-bar { display: block; height: 3px; border-radius: 2px; background: rgba(244, 239, 230, .14); overflow: hidden; margin-top: 4px; }
.dl-bar > span { display: block; height: 100%; background: var(--red); transition: width .4s; }
.dl-row.ready .dl-bar > span { background: var(--good); }
.dl-status { display: flex; justify-content: space-between; gap: 12px; font-size: .82rem; font-weight: 700; color: var(--muted); }
.dl-row.ready .dl-state { color: #9ff0c9; }
.dl-row.failed .dl-state { color: #ffd98a; }
.dl-pct { font-variant-numeric: tabular-nums; }
.dl-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.dl-ask { font-size: .88rem; color: var(--muted); }
.dl-empty { padding-left: 0; padding-right: 0; }
@media (hover: hover) { .dl-main:hover { background: rgba(244, 239, 230, .08); } }
@media (max-width: 720px) {
  .dl-row { flex-wrap: wrap; padding-right: 0; }
  .dl-actions { margin-left: auto; padding: 0 8px 8px; }
  .dl-row .dl-actions:has(.icon-btn:only-child) { margin: 0 4px 0 0; padding: 0; }
}

/* ---------- live tv ---------- */

/* ---------- player ---------- */
.player { position: fixed; inset: 0; z-index: 100; background: #000; cursor: none; }
/* The page under an open player keeps no scrollbar, and the wheel or PageDown can't scroll it
   (claim adds the class; the full-screen element is the page itself, so its own overflow counts).
   :has() is its own rule: Chromium 80 drops a selector list it can't read. */
html.player-open { overflow: hidden; }
html:has(> body > .player) { overflow: hidden; }
.player.show-ui { cursor: default; }
/* Subtitles are the browser's own, laid out in the <video> box, not the picture. The film player
   (fitPicture) makes that box the picture plus a band of the black bar under it when the bar holds
   two lines, so a letterboxed film's subtitles sit just under the picture (on it when the bar is
   thinner), and it lifts them over the control bar while it shows. Unset (live TV, before the size
   is known) the video fills the player. */
.player { --cue-font: clamp(18px, 2.6vw, 34px); }
.player.sub-s { --cue-font: clamp(15px, 2vw, 26px); }
.player.sub-l { --cue-font: clamp(24px, 3.5vw, 46px); }
/* A TV is read from across the room: the browser's 2.6vw cap (34 px at 1080p) read small to parents at
   three metres. Apple TV and Netflix default near 4-5% of the height; Orta is 46 px (4.3%). */
html.tv .player { --cue-font: 46px; }
html.tv .player.sub-s { --cue-font: 38px; }
html.tv .player.sub-l { --cue-font: 58px; }
.player-video { position: absolute; left: 0; top: var(--pic-top, 0px); width: 100%; height: var(--pic-h, 100%); object-fit: contain;
  object-position: 50% var(--pic-y, 50%); font-size: var(--cue-font); background: #000; }
.player-video::cue { font-family: var(--sans); font-size: var(--cue-font); background: rgba(0, 0, 0, .55); }
/* The last frame held over the video while it goes over to another path (player.js holdFrame): taps reach the video. */
.frame-hold { pointer-events: none; }
/* Two rules: one unknown pseudo-element in a selector list drops the whole rule. WebKit (as its own
   controls do) shortens the cue container; Chromium ignores that height but moves each cue. Native
   full screen and PiP size the container inline, so neither applies there. Chromium's cues move
   with the control bar, in and out at its pace. */
.player.show-ui .player-video::-webkit-media-text-track-container { height: calc(100% - var(--cue-lift, 0px)); }
.player .player-video::-webkit-media-text-track-display { transition: transform .25s ease; }
.player.show-ui .player-video::-webkit-media-text-track-display { transform: translateY(calc(-1 * var(--cue-lift, 0px)));
  transition-duration: .1s; transition-timing-function: var(--ease-out); }
/* Subtitle looks (prefs.subStyle; the box above is "box"). iPhone's own full-screen player and a
   system caption style the viewer set win over these. */
.player.cue-shadow .player-video::cue { background: transparent; text-shadow: 0 0 2px #000, 0 0 4px #000, 0 2px 6px rgba(0, 0, 0, .9); }
.player.cue-yellow .player-video::cue { color: #ffd60a; background: rgba(0, 0, 0, .85); }
/* The subtitles the page draws (player.js drawCues, cues.js): over the video's box (fitPicture), rising
   with the bar like the browser's own. The ::cue rules above are for where the browser draws them. */
.cue-layer { position: absolute; left: 0; top: var(--pic-top, 0px); width: 100%; height: var(--pic-h, 100%); pointer-events: none;
  font: 500 var(--cue-font)/1.3 var(--sans); color: #fff; transition: transform .25s ease; }
.player.show-ui .cue-layer { transform: translateY(calc(-1 * var(--cue-lift, 0px))); }
/* A TV's lowest 54 px may be cut off (overscan): the bottom line stays above them. */
html.tv .cue-band.bottom { bottom: max(.4em, 54px); }
.cue-band { position: absolute; left: 4%; right: 4%; display: flex; flex-direction: column; gap: .08em; }
.cue-band.top { top: .4em; }
.cue-band.middle { top: 50%; transform: translateY(-50%); }
.cue-band.bottom { bottom: .4em; }
.cue-line { text-align: center; }
.cue-line.start { text-align: start; }
.cue-line.end { text-align: end; }
.cue-text { white-space: pre-line; background: rgba(0, 0, 0, .55); padding: 0 .25em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.player.cue-shadow .cue-text { background: transparent; text-shadow: 0 0 2px #000, 0 0 4px #000, 0 2px 6px rgba(0, 0, 0, .9); }
.player.cue-yellow .cue-text { color: #ffd60a; background: rgba(0, 0, 0, .85); }
/* Above the controls layer (both inset: 0): tap-to-play and the error card stay tappable while the
   controls show; the overlay itself lets taps through to them. */
.player-overlay { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; z-index: 1; }
.player-overlay > * { pointer-events: auto; grid-area: 1 / 1; }
.player-status { font-size: 1.2rem; color: var(--muted); padding: 12px 20px; border-radius: 10px; background: rgba(0, 0, 0, .5); pointer-events: none; }
.player-error { text-align: center; max-width: 520px; padding: 24px; }
.player-error p { color: var(--muted); }
.spinner { width: 48px; height: 48px; border-radius: 50%; border: 3px solid rgba(255, 255, 255, .2); border-top-color: var(--ink); animation: spin .9s linear infinite; pointer-events: none; }
@keyframes spin { to { transform: rotate(360deg); } }
/* The top scrim holds .55 where the title's second line sits (12%), so it reads on bright art. */
.player-controls { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: space-between; opacity: 0; transition: opacity .25s; pointer-events: none;
  background: linear-gradient(180deg, rgba(0, 0, 0, .78), rgba(0, 0, 0, .55) 12%, transparent 26%, transparent 70%, rgba(0, 0, 0, .8)); }
.player.show-ui .player-controls { opacity: 1; pointer-events: auto; }
.player-controls .top { display: flex; align-items: center; gap: 16px; padding: max(16px, env(safe-area-inset-top)) var(--gutter) 16px; }
.player-controls .bottom { padding: 0 var(--gutter) max(20px, env(safe-area-inset-bottom)); }
.player-title .pt-main, .live-label .pt-main { font-size: 1.3rem; font-weight: 800; }
/* Secondary text over the picture: --on-art (#cfc6b8), not muted, which is for solid surfaces. */
.player-title .pt-sub, .live-label .pt-sub { color: var(--on-art); }
.seekrow { position: relative; display: flex; align-items: center; gap: 12px; }
.seek-wrap { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; }
/* Touch drags through a 44 px layer over the bar (player.js bindScrub); mouse, keys and TV use the range.
   It reaches up from the bar, never down: on a phone the times sit right under it (a tap on the length
   shows the time left), in landscape the buttons. */
.seek-hit { display: none; }
@media (pointer: coarse) { .seek-hit { display: block; position: absolute; left: 0; right: 0; top: -20px; bottom: 0; touch-action: none; } }
html.tv .seek-hit { display: none; }
/* Above the thumb while it is dragged, or where a press sends the film: the time there, how far
   ("+30 sn") and the segment it falls in. The rail spans the thumb's travel (the bar less 12 px);
   player.js (paintBubble) moves it by a share of its own width, so placing the bubble reads no layout. */
.seek-rail { position: absolute; left: 6px; right: 6px; bottom: calc(100% + 6px); pointer-events: none; }
.seek-bubble { position: absolute; bottom: 0; left: 0; display: grid; justify-items: center; gap: 2px; padding: 6px 10px; border-radius: 8px;
  background: var(--panel); box-shadow: 0 6px 20px rgba(0, 0, 0, .5); white-space: nowrap; pointer-events: none; transform: translateX(-50%);
  opacity: 0; transition: opacity 250ms ease; }
.seek-bubble.show { opacity: 1; transition-duration: 100ms; }
.sb-time { font-weight: 800; font-variant-numeric: tabular-nums; }
.sb-seg, .sb-note { color: var(--muted); font-size: .82rem; font-weight: 700; }
.sb-note { font-variant-numeric: tabular-nums; }
/* The seek bar, drawn by hand so it reads calm: a 4 px track (6 px focused or dragged), the played
   part ink up to --p (player.js paintSeek) over the track at .40, a small ink thumb. Not red: red is
   live and errors only, and red on light grey told the two parts apart by hue alone (1.10:1). Each engine's pseudo-elements get
   rules of their own: one unknown pseudo-element voids a whole selector list. */
.seek { --track: 4px; flex: 1; min-width: 0; height: 24px; margin: 0; background: transparent; -webkit-appearance: none; appearance: none; }
.seek:focus-visible { --track: 6px; }
.seek:active, .seek.dragging { --track: 6px; }
.seek::-webkit-slider-runnable-track { height: var(--track); border-radius: 3px;
  background: linear-gradient(90deg, var(--ink) var(--p, 0%), rgba(244, 239, 230, .4) var(--p, 0%)); }
.seek::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; margin-top: calc((var(--track) - 12px) / 2); border: 0; border-radius: 50%; background: var(--ink); }
.seek::-moz-range-track { height: var(--track); border-radius: 3px; background: rgba(244, 239, 230, .4); }
.seek::-moz-range-progress { height: var(--track); border-radius: 3px; background: var(--ink); }
.seek::-moz-range-thumb { width: 12px; height: 12px; border: 0; border-radius: 50%; background: var(--ink); }
/* Phones: the bar spans the full width, the times under it at either end. */
@media (max-width: 720px) {
  .seekrow { flex-wrap: wrap; justify-content: space-between; row-gap: 0; }
  .seekrow .seek-wrap { order: -1; flex-basis: 100%; }
  .seekrow .time { min-width: 0; font-size: .85rem; }
}
.time { font-variant-numeric: tabular-nums; color: #ddd; min-width: 60px; text-align: center; }
.player .dur { cursor: pointer; }   /* a tap shows the time left (player.js toggleLeft) */
/* Paused a while with no input (player.js settle): the controls fade as when idle (250 ms) and the paused
   frame dims from the left (black .8 to .25, no blur) under "Duraklatıldı" at the top and, bottom left, the
   logo, the episode in big type, its synopsis and where the viewer is, until the next key or tap. */
.pause-card { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(90deg, rgba(0, 0, 0, .8), rgba(0, 0, 0, .5) 50%, rgba(0, 0, 0, .25)), linear-gradient(0deg, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0) 40%);
  opacity: 0; visibility: hidden; transition: opacity 250ms ease, visibility 0s 250ms; }
.player.settled .pause-card { opacity: 1; visibility: visible; transition: opacity 250ms ease, visibility 0s; }
.pause-card p { margin: 0; }
.pc-mark { position: absolute; top: max(24px, env(safe-area-inset-top)); left: var(--pm); display: flex; align-items: center; gap: .5em; font-size: var(--fs-detail); font-weight: 600; color: var(--on-art); }
.pc-mark .icon { color: var(--ink); stroke-width: 3; }
.pc-body { position: absolute; left: var(--pm); bottom: max(48px, env(safe-area-inset-bottom)); width: min(1100px, calc(100% - 2 * var(--pm))); }
.pc-logo { display: block; max-width: min(460px, 60%); max-height: 128px; margin-bottom: 18px; object-fit: contain; object-position: left bottom; }
.pc-kicker { font-size: var(--fs-detail); font-weight: 600; color: var(--on-art); margin-bottom: 6px !important; }
.pc-title { font-family: var(--serif); font-weight: 500; font-size: var(--fs-cover); line-height: 1.15; letter-spacing: -.02em; }
.pc-sub { margin-top: 4px !important; font-size: var(--fs-body); font-weight: 600; }
.pc-deck { margin-top: 14px !important; max-width: 24em; font-family: var(--serif); font-style: italic; font-size: var(--fs-deck); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pc-time { margin-top: 18px !important; font-size: var(--fs-detail); color: var(--on-art); white-space: pre-wrap; font-variant-numeric: tabular-nums; }
/* OK Devam et: a TV's remote only (the play pill says Oynat elsewhere, never Devam et beside Duraklat). */
.pc-ok { display: none; }
html.tv .pc-ok { display: flex; align-items: center; gap: 14px; margin-top: 26px !important; font-size: var(--fs-button); font-weight: 700; }
kbd { display: inline-block; padding: 0 .35em; border: 2px solid currentColor; border-radius: 6px; font: 800 .75em/1.4 var(--sans); }
.buttons { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.icon-btn { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 10px; font-size: 1.4rem; }
.icon-btn:focus-visible { background: rgba(255, 255, 255, .15); }
.buttons > .icon-btn { flex: none; }
/* Settings menu: opaque (no video bleeding through), the picture dimmed behind it. A panel above
   the control bar on wide screens, a bottom sheet on phones, a side sheet on phones held sideways. */
.player { touch-action: manipulation; }   /* no double-tap zoom: a double tap skips 10 s */
.menu-scrim { position: absolute; inset: 0; z-index: 2; background: rgba(0, 0, 0, .6); }
.player-menu { position: absolute; right: var(--gutter); bottom: calc(110px + env(safe-area-inset-bottom)); z-index: 3; width: min(380px, 90vw); max-height: min(70vh, 560px);
  display: flex; flex-direction: column; background: var(--panel); border-radius: 14px; box-shadow: 0 12px 40px rgba(0, 0, 0, .5); }
.menu-grab { display: none; }
.menu-head { display: flex; align-items: center; gap: 8px; min-height: 56px; padding: 4px 4px 4px 16px; border-bottom: 1px solid var(--line); }
.menu-head h2 { flex: 1; margin: 0; font-size: 1.05rem; }
.menu-back { flex: 1; display: flex; align-items: center; gap: 10px; min-height: 48px; margin-left: -8px; padding: 0 8px; border-radius: 8px; font-weight: 800; font-size: 1.05rem; text-align: left; }
.menu-close { flex: none; color: var(--muted); }
.menu-body { overflow-y: auto; overscroll-behavior: contain; padding: 8px; }
/* More below: the last rows fade out instead of ending at a hard edge. */
.menu-body.more { -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(180deg, #000 calc(100% - 40px), transparent); }
/* Nothing masks on a TV (docs/motion.md): the mask made each remote scroll of a long list 2.4x the raster. */
html.tv .menu-body.more { -webkit-mask-image: none; mask-image: none; }
.menu-body h3 { font-size: .85rem; color: var(--muted); margin: 14px 12px 6px; }
.menu-body h3 .h3-value { float: right; color: var(--ink); font-weight: 700; }   /* Altyazı zamanlaması: "0,5 sn erken" */
.menu-sizes[data-group="timing"] .menu-item { justify-content: center; }
.menu-row, .menu-item { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; text-align: left; padding: 10px 12px; border-radius: 8px; }
.menu-row-label { font-weight: 700; flex: none; }
.menu-row-value { flex: 1; min-width: 0; text-align: right; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-row .icon { color: var(--muted); }
.menu-item .icon { visibility: hidden; }
.menu-item[aria-checked="true"] { font-weight: 800; }
.menu-item[aria-checked="true"] .icon { visibility: visible; }
.menu-sizes { display: flex; gap: 4px; }
.menu-sizes .menu-item { flex: 1; gap: 6px; }
/* "Koyu kutu" in a third of a 390 px sheet wrapped onto two lines: each look as wide as its words, on one
   line (tighter under 340 px, where the three in Manrope need 330 px at 12 px padding). */
.menu-sizes[data-group="style"] .menu-item { flex: 1 1 auto; white-space: nowrap; }
@media (max-width: 340px) { .menu-sizes[data-group="style"] .menu-item { gap: 4px; padding-left: 6px; padding-right: 6px; } }
/* Solid, so the focused item reads from the couch and never looks like the selected (bold, checked) one. */
.menu-row:focus-visible, .menu-item:focus-visible, .menu-back:focus-visible { background: var(--ink); color: var(--ink-inv); box-shadow: none; }
.menu-row:focus-visible .icon, .menu-row:focus-visible .menu-row-value { color: var(--ink-inv); }
@media (max-width: 720px), (pointer: coarse) and (max-height: 500px) {
  .player-menu { left: 0; right: 0; bottom: 0; width: auto; max-height: 50vh; max-height: 50dvh; border-radius: 16px 16px 0 0; padding-bottom: env(safe-area-inset-bottom); }
  /* The phone's sheet going down on its spring (player.js sheetGo): closed (hidden) for everything else,
     drawn and untouchable until it is down. */
  .player-menu.closing[hidden] { display: flex !important; pointer-events: none; }
  .menu-scrim.closing[hidden] { display: block !important; pointer-events: none; }
  .menu-grab { display: block; width: 40px; height: 4px; margin: 8px auto 0; border-radius: 2px; background: rgba(244, 239, 230, .3); }
  .menu-head { min-height: 52px; }
}
/* Reduced motion: the spring jumps (spring.js), so the sheet fades in instead (150 ms). */
@media (max-width: 720px) and (prefers-reduced-motion: reduce) { .player-menu, .menu-scrim { animation: fade-in 150ms var(--ease-out); } }
@media (pointer: coarse) and (max-height: 500px) and (min-width: 721px) {
  .player-menu { left: auto; top: 0; width: min(380px, 50vw); max-height: none; border-radius: 16px 0 0 16px; padding-right: env(safe-area-inset-right); }
  .menu-grab { display: none; }
}
/* Error: a solid card on a dark scrim; the controls behind it go away. */
.player.failed .player-controls { display: none; }
.player.failed .player-overlay { background: rgba(0, 0, 0, .82); }
.player-error { background: var(--panel); border-radius: 16px; margin: 16px; }
.player-error h2 { margin: 0 0 8px; font-size: 1.3rem; }
.player-error .row-btns { justify-content: center; }
/* Up next: bottom right, above the controls, until picked, cancelled or counted down. */
.next-card { position: absolute; right: var(--gutter); bottom: calc(120px + env(safe-area-inset-bottom)); z-index: 2; width: min(360px, calc(100vw - 32px));
  padding: 16px 18px; border-radius: 14px; background: var(--panel); box-shadow: 0 12px 40px rgba(0, 0, 0, .5); }
.next-card p { margin: 0; }
.nc-kicker { color: var(--muted); font-size: .85rem; font-weight: 700; }
.nc-title { font-weight: 800; margin-top: 2px !important; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nc-count { color: var(--muted); font-size: .9rem; margin-top: 6px !important; font-variant-numeric: tabular-nums; }
.next-card .row-btns { margin-top: 12px; }
@media (max-width: 720px) { .next-card { left: 16px; right: 16px; width: auto; bottom: calc(130px + env(safe-area-inset-bottom)); } }
/* "Nasıldı?" (player.js askRating): the up-next card's look at the bottom left, clear of the skip pill
   a film's mid-credits scene brings; as wide as its three verdicts. */
.rate-card { left: var(--gutter); right: auto; width: auto; max-width: calc(100vw - 2 * var(--gutter)); }
.rate-card .row-btns { flex-wrap: wrap; }
@media (max-width: 720px) { .rate-card { left: 16px; right: 16px; bottom: calc(190px + env(safe-area-inset-bottom)); } }   /* over the pill */
/* Skip intro, recap or credits: bottom right above the control bar, seen with or without it. In
   200 ms (fade and scale from .96), out 250 ms; hidden, it is out of the focus order and unread. */
.skip-wrap { position: absolute; right: var(--gutter); bottom: calc(120px + env(safe-area-inset-bottom)); z-index: 2; }
.skip-pill { background: rgba(27, 24, 21, .92); color: var(--ink); border: 1px solid rgba(244, 239, 230, .5); box-shadow: 0 8px 28px rgba(0, 0, 0, .5);
  opacity: 0; visibility: hidden; transform: scale(.96); transition: opacity 250ms ease, transform 250ms ease, visibility 0s 250ms; }
.skip-pill.show { opacity: 1; visibility: visible; transform: none; transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out), visibility 0s; }
.skip-pill:focus-visible { background: var(--ink); color: var(--ink-inv); }
.player.failed .skip-wrap { display: none; }
/* The soft dip around a skip (player.js dip): to black in 200 ms while the sound ramps down, back in
   300 ms once the new frame is in. Over the picture, under the controls and the pill. Ease-in going
   dark: the picture leaves gently and is black before the cut. Reduced motion keeps it: it is a fade. */
.skip-dip { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: #000; opacity: 0; pointer-events: none; transition: opacity 300ms var(--ease-out); }
.skip-dip.on { opacity: 1; transition: opacity 200ms ease-in; }
/* "Kaldığın yer 23:14": the place kept while the transcode runs from the beginning, under the title;
   with the controls, and alone for a moment when it first shows (.peek). */
.place-line { position: absolute; left: var(--gutter); top: calc(88px + env(safe-area-inset-top)); z-index: 2; display: flex; align-items: center; gap: 12px;
  max-width: calc(100vw - 2 * var(--gutter)); padding: 8px 14px; border-radius: 10px; background: rgba(27, 24, 21, .82); font-weight: 700; font-variant-numeric: tabular-nums;
  opacity: 0; visibility: hidden; transition: opacity 200ms var(--ease-out), visibility 0s 200ms; }
.player.show-ui .place-line, .place-line.peek { opacity: 1; visibility: visible; transition: opacity 200ms var(--ease-out), visibility 0s; }
.place-line { flex-wrap: wrap; row-gap: 8px; }
.place-line > * { white-space: nowrap; }
.place-line .btn { margin-right: -6px; }
.place-line[hidden], .player.failed .place-line { display: none; }
/* Remuxed in the page there is nothing AirPlay could send. */
.player.remuxing .airplay-btn { display: none; }
@media (hover: hover) { .skip-pill:hover { background: var(--ink); color: var(--ink-inv); } }
/* Double-tap skip: a mark on that side counting the run ("+30 sn", player.js ripple). Mounted once; in
   100 ms with a scale from .92 over 120 ms, out 250 ms. A further tap changes its number, never
   restarts it. Reduced motion: the scale goes (only opacity transitions there). */
.seek-ripple { position: absolute; top: 50%; z-index: 1; display: grid; place-items: center; width: 96px; height: 96px; margin-top: -48px; border-radius: 50%;
  background: rgba(255, 255, 255, .18); pointer-events: none; font-size: 1.1rem; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap;
  opacity: 0; transform: scale(.92); transition: opacity 250ms ease, transform 120ms var(--ease-out); }
.seek-ripple.on { opacity: 1; transform: none; transition-duration: 100ms, 120ms; }
@media (prefers-reduced-motion: reduce) { .seek-ripple { transform: none; } }
.seek-ripple.left { left: 12%; }
.seek-ripple.right { right: 12%; }

/* ---------- the film player's chrome and end cards (round 4 S3; live TV keeps the rules above) ----------
   Nothing on screen while it plays. With the controls: the clock top right, and over a scrim at the
   bottom the title in the title face, the episode, the bar, "42 dk izlendi" and "1 sa 37 dk kaldı, bitiş
   22:41", and one row of pills named in words. In 100 ms, out 250 ms. --pm: the side margin (a TV's keeps
   the 10 px focus ring inside x 96..1824). */
.player.vod { --pm: max(var(--m), env(safe-area-inset-left), env(safe-area-inset-right)); --chrome-h: 230px; }
html.tv .player.vod { --pm: calc(var(--m) + var(--ring-out)); --chrome-h: 300px; }
.player.vod .player-controls { transition: opacity 250ms ease;
  background: linear-gradient(0deg, rgba(0, 0, 0, .86), rgba(0, 0, 0, .7) 22%, rgba(0, 0, 0, .35) 40%, rgba(0, 0, 0, 0) 58%),
    linear-gradient(180deg, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0) 18%); }
.player.vod.show-ui .player-controls { transition: opacity 100ms var(--ease-out); }
.player.vod .player-controls .top { gap: 8px; padding: max(20px, env(safe-area-inset-top)) var(--pm) 0; }
.player.vod .top .spacer { flex: 1; }
.player.vod .clock { margin-left: 8px; font-size: var(--fs-detail); color: var(--on-art); font-variant-numeric: tabular-nums; }
.player.vod .player-controls .bottom { padding: 0 var(--pm) max(36px, env(safe-area-inset-bottom)); }
.player.vod .player-title .pt-main { font-family: var(--serif); font-weight: 500; font-size: calc(var(--fs-row) * 1.08); line-height: 1.15; letter-spacing: -.01em; }
.player.vod .player-title .pt-sub { margin-top: 4px; font-size: var(--fs-detail); }
.player.vod .seekrow { margin-top: 18px; }
.player.vod .seek-wrap { margin: 0 -6px; }   /* the thumb's travel starts and ends on the margin */
.player.vod .times { display: flex; justify-content: space-between; gap: 16px; margin-top: 8px; font-size: var(--fs-detail); color: var(--on-art);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.player.vod .time { min-width: 0; color: var(--on-art); text-align: left; }
.player.vod .time b { color: var(--ink); font-weight: 700; }
.player.vod .dur { cursor: default; text-align: right; }
.player.vod .buttons { flex-wrap: wrap; gap: 12px; margin-top: 22px; }   /* a seventh pill wraps, never past the margin */
.pill { display: inline-flex; align-items: center; gap: .5em; flex: none; min-height: var(--h-btn); max-width: 22em; padding: 0 1.1em; border-radius: 999px;
  background: rgba(28, 25, 22, .92); color: var(--ink); font-size: var(--fs-button); font-weight: 600; white-space: nowrap;
  transition: background-color .15s, transform var(--t-press-out) var(--ease-out); }
.pill .icon { width: 1.15em; height: 1.15em; }
.pill-label { overflow: hidden; text-overflow: ellipsis; }
.pill:focus-visible { background: var(--focus-c); color: var(--ink-inv); box-shadow: var(--focus); }
@media (hover: hover) { .pill:hover { background: rgba(58, 51, 43, .96); } .pill:focus-visible:hover { background: var(--focus-c); } }
.player.vod .buttons > .pill { padding: 0 1.1em; font-size: var(--fs-button); font-weight: 600; }
.player.vod .icon-btn { width: 44px; height: 44px; border-radius: 50%; font-size: 1.25rem; }
.player.vod .back { background: rgba(28, 25, 22, .7); }
html.tv .player.vod .back { display: none; }   /* the remote's Back closes the player */
html.tv .player.vod .player-controls .top { padding-top: 54px; }
html.tv .player.vod .player-controls .bottom { padding-bottom: 64px; }   /* the ring's 10 px end at 1026 */
html.tv .player.vod .buttons { gap: 24px; margin-top: 30px; }
html.tv .player.vod .seekrow { margin-top: 26px; }
html.tv .player.vod .times { margin-top: 12px; }
html.tv .player.vod .seek { --track: 6px; height: 30px; }
html.tv .player.vod .seek:focus-visible { --track: 8px; }
html.tv .player.vod .seek::-webkit-slider-thumb { width: 24px; height: 24px; margin-top: calc((var(--track) - 24px) / 2); }
/* The remote's thumb on the focused bar: a cream ring like every focus. */
html.tv .player.vod .seek:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--bg), 0 0 0 9px var(--focus-c); }
html.tv .pill { transition: none; }
/* The paused frame's words sit where the chrome's do. */
html.tv .player.vod .pc-mark { top: 54px; }
html.tv .player.vod .pc-body { bottom: 88px; }
html.tv .player.vod .pc-logo { max-height: 170px; max-width: 560px; }
/* The settings menu above the pills, inside the safe area, in TV type. */
.player.vod .player-menu { right: var(--pm); }
html.tv .player.vod .player-menu { bottom: calc(64px + var(--h-btn) + 24px); width: 560px; font-size: 26px; }
html.tv .player.vod .menu-body h3 { font-size: .8em; }

/* Skip: the pill bottom right, under it what it skips and how long ("Önceki bölümlerde, 3 dk 10 sn") with
   how far in the film is, on a shade that keeps both readable over a bright frame (no blur). Above the
   chrome while it shows. A TV's pill says OK. */
.player.vod .skip-wrap { right: var(--pm); bottom: max(48px, env(safe-area-inset-bottom)); display: flex; flex-direction: column; align-items: flex-end;
  transition: transform 200ms var(--ease-out); }
.player.vod.show-ui .skip-wrap { transform: translateY(calc(-1 * var(--chrome-h))); }
.player.vod .skip-wrap::before { content: ""; position: absolute; top: -60px; right: calc(-1 * var(--pm)); bottom: -60px; left: -120px; z-index: -1; pointer-events: none;
  background: radial-gradient(farthest-side at 100% 75%, rgba(0, 0, 0, .7), rgba(0, 0, 0, .45) 50%, rgba(0, 0, 0, 0)); opacity: 0; transition: opacity 250ms ease; }
.player.vod .skip-wrap.show.named::before { opacity: 1; transition-duration: 200ms; }
.player.vod .skip-pill { min-height: var(--h-btn); padding: 0 1.2em; border-radius: 999px; font-size: var(--fs-button); }
.skip-cap, .skip-prog { opacity: 0; visibility: hidden; transition: opacity 250ms ease, visibility 0s 250ms; }
.player.vod .skip-wrap.show.named .skip-cap, .player.vod .skip-wrap.show.named .skip-prog { opacity: 1; visibility: visible; transition: opacity 200ms var(--ease-out), visibility 0s; }
.skip-cap { margin: 12px 0 0; font-size: var(--fs-detail); font-weight: 500; color: var(--ink); text-shadow: 0 1px 3px rgba(0, 0, 0, .9), 0 0 14px rgba(0, 0, 0, .6); white-space: nowrap; }
.skip-prog { align-self: stretch; height: 4px; margin-top: 10px; border-radius: 2px; background: rgba(244, 239, 230, .3); overflow: hidden; }
.skip-prog i { display: block; height: 100%; background: var(--ink); transform-origin: 0 50%; transform: scaleX(0); }
html.tv .player.vod .skip-wrap { bottom: 88px; transition: none; }
html.tv .player.vod .skip-pill::after { content: "OK"; margin-left: .6em; padding: 0 .35em; border: 2px solid currentColor; border-radius: 6px; font: 800 .75em/1.4 var(--sans); }
/* The place kept while the transcode runs from the start: under the top row. */
.player.vod .place-line { left: var(--pm); }
html.tv .player.vod .place-line { top: 54px; }
.player.vod .next-card { right: var(--pm); bottom: max(48px, env(safe-area-inset-bottom)); }
.player.vod .rate-card { left: var(--pm); right: auto; }
html.tv .player.vod .next-card { bottom: 88px; }

/* End cards (player.js endCard): the room goes flat, the film plays on in a frame on the left (one
   transform, fitEnd: over 300 ms on phones and computers, in one step on a TV, as AVPlay's display rect
   would move), "Jenerik oynuyor. Biten: …" under it, the decision on the right. */
.player.vod .player-video { transform-origin: 0 0; transition: transform 300ms var(--ease-out); }
html.tv .player.vod .player-video { transition: none; }
.player.vod.ending { background: var(--bg); }
.player.vod.ending .player-video { background: transparent; }
.player.vod.ending .player-controls, .player.vod.ending .skip-wrap, .player.vod.ending .place-line, .player.vod.ending .cue-layer, .player.vod.ending .pause-card { visibility: hidden; opacity: 0; }
.end-card { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 2; display: grid; grid-template-columns: minmax(0, 47fr) minmax(0, 53fr); column-gap: 72px;
  align-items: center; padding: 54px var(--pm); }
.end-slot { width: 100%; padding-top: 56.25%; }
.end-from { margin: 20px 0 0; font-size: var(--fs-detail); color: var(--on-art); }
.end-side { min-width: 0; }
.end-side p { margin: 0; }
.end-still { position: relative; width: 440px; max-width: 100%; height: 248px; margin-bottom: 26px; border-radius: var(--r2); overflow: hidden; background: var(--panel-1); }
.end-still img { display: block; width: 100%; height: 100%; object-fit: cover; }
.end-len { position: absolute; left: 12px; bottom: 12px; padding: 4px 10px; border-radius: var(--r1); background: rgba(18, 16, 14, .86); font-size: var(--fs-detail); font-weight: 600; }
.end-kicker { font-size: var(--fs-detail); font-weight: 600; color: var(--on-art); }
.end-title { margin: 8px 0 14px; font-family: var(--serif); font-weight: 500; font-size: var(--fs-title); line-height: 1.15; letter-spacing: -.02em; }
.end-next .end-title, .end-still .end-title { font-size: calc(var(--fs-title) * .8); }
.end-deck { max-width: 24em; font-family: var(--serif); font-style: italic; font-size: var(--fs-deck); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.end-facts { margin-top: 14px !important; font-size: var(--fs-detail); color: var(--on-art); font-variant-numeric: tabular-nums; }
.end-card .row-btns { margin-top: 30px; gap: 16px; }   /* wraps rather than past the margin */
.end-card .btn { flex: none; min-height: var(--h-btn); padding: 0 1.3em; border-radius: 999px; font-size: var(--fs-button); white-space: nowrap; background: var(--end-card-2); }
.end-card .btn.primary { background: var(--ink); color: var(--ink-inv); }
/* One focus language for every control that isn't art: the cream fill and the ring. */
.end-card .btn:focus-visible, .player.vod .next-card .btn:focus-visible { background: var(--focus-c); color: var(--ink-inv); box-shadow: var(--focus); }
.btn-two { display: grid; text-align: left; line-height: 1.2; }
.btn-two small { font-size: .72em; font-weight: 500; opacity: .85; font-variant-numeric: tabular-nums; }
.end-card .btn.primary .btn-two { padding: 8px 0; }
html.tv .end-card { padding: 54px var(--pm); column-gap: 80px; }
html.tv .end-card .row-btns { gap: 24px; }

@media (max-width: 720px) {
  html:not(.tv) .player.vod { --chrome-h: 260px; }
  .player.vod .player-controls .bottom { padding-bottom: max(24px, env(safe-area-inset-bottom)); }
  .player.vod .player-title .pt-main { font-size: 24px; }
  .player.vod .seekrow { margin-top: 12px; }
  .player.vod .times { font-size: 13px; }
  .player.vod .buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
  .player.vod .buttons > .pill { justify-content: center; min-width: 0; max-width: none; padding: 0 12px; font-size: 15px; }
  .player.vod .pc-logo { max-height: 72px; }
  .player.vod .pc-body { bottom: max(28px, env(safe-area-inset-bottom)); }
  .player.vod .skip-wrap { bottom: calc(var(--chrome-h) * .25); }
  .player.vod .skip-cap { font-size: 13px; }
  /* Upright: the credits along the top, the card under them; no still (the frame is the picture). */
  .end-card { grid-template-columns: minmax(0, 1fr); align-content: start; row-gap: 18px; overflow: hidden;
    padding: max(16px, env(safe-area-inset-top)) var(--pm) max(20px, env(safe-area-inset-bottom)); }
  .end-still { display: none; }
  .end-title { font-size: 30px; margin: 4px 0 10px; }
  .end-next .end-title { font-size: 26px; }
  .end-deck { font-size: 16px; -webkit-line-clamp: 2; }
  .end-late .end-deck { -webkit-line-clamp: 4; }   /* why it didn't start is the point */
  .end-card .row-btns { flex-direction: column; align-items: stretch; gap: 10px; margin-top: 20px; }
  .end-card .btn { justify-content: center; font-size: 16px; }
}
/* A phone held sideways (844 x 390): one row of pills; the end card side by side, without the still, so
   "Şimdi oynat" and its countdown fit the height. */
@media (pointer: coarse) and (max-height: 500px) and (min-width: 721px) {
  .player.vod { --chrome-h: 150px; }
  .player.vod .player-controls .top { padding-top: max(12px, env(safe-area-inset-top)); }
  .player.vod .player-controls .bottom { padding-bottom: max(14px, env(safe-area-inset-bottom)); }
  .player.vod .player-title .pt-main { font-size: 20px; }
  .player.vod .player-title .pt-sub, .player.vod .times { font-size: 13px; }
  .player.vod .seekrow { margin-top: 6px; }
  .player.vod .buttons { gap: 8px; margin-top: 10px; }
  .player.vod .buttons > .pill { min-height: 40px; font-size: 14px; padding: 0 14px; }
  .player.vod .pc-body { bottom: 18px; }
  .player.vod .pc-title { font-size: 34px; }
  .player.vod .pc-deck { font-size: 15px; }
  .player.vod .pc-logo { max-height: 56px; margin-bottom: 8px; }
  .player.vod .pc-mark { top: max(12px, env(safe-area-inset-top)); }
  .player.vod .skip-wrap { bottom: 16px; }
  .end-card { column-gap: 28px; padding: 16px var(--pm); }
  .end-still { display: none; }
  .end-from { margin-top: 10px; font-size: 13px; }
  .end-kicker, .end-facts { font-size: 13px; }
  .end-title { font-size: 26px; margin: 2px 0 8px; }
  .end-next .end-title { font-size: 22px; }
  .end-deck { font-size: 15px; -webkit-line-clamp: 2; }
  .end-card .row-btns { margin-top: 14px; gap: 10px; }
  .end-card .btn { min-height: 44px; font-size: 15px; padding: 0 16px; }
}

.toast { position: fixed; left: 50%; bottom: calc(32px + env(safe-area-inset-bottom)); z-index: 200; display: flex; align-items: center; gap: 12px; width: max-content; max-width: min(560px, calc(100vw - 32px));
  transform: translate(-50%, 20px); opacity: 0; background: var(--panel); padding: 12px 18px; border-radius: 10px; box-shadow: 0 8px 30px rgba(0, 0, 0, .45);
  transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out); }
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.error { border-left: 3px solid var(--red); padding-right: 8px; }
.toast.sticky { padding-right: 8px; }
.toast-close { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 8px; flex: none; color: var(--muted); }
.toast-close:focus-visible { color: var(--ink); }

/* ---------- phones ---------- */
@media (max-width: 720px) {
  .topbar { gap: 10px; padding-top: max(8px, env(safe-area-inset-top)); padding-bottom: 8px; }
  /* Phones: the sections become a bottom tab bar (thumb reach, nothing cut off). */
  /* Opaque, with no blur and no line: a 20 px edge fades the page into it instead. Visible overflow,
     or the edge above it would be clipped (the labels fit: their size is capped below). */
  .topbar nav { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; justify-content: space-around; gap: 0; overflow: visible; margin: 0;
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom)); background: var(--bg); }
  .topbar nav::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 20px; pointer-events: none;
    background: linear-gradient(0deg, var(--bg), rgba(18, 16, 14, 0)); }
  /* Five sections (Filmler and Diziler live in Keşfet on a phone): each as wide as its label needs
     (İndirilenler more than Listem), the rest shared. */
  /* Inactive labels on the opaque bar: muted (8:1). The size is capped: at 200% text every label
     overflowed ("İndirilenler" needs 122 px of 96), and tab bars don't scale their labels. */
  .topbar nav a { color: var(--muted); display: grid; justify-items: center; gap: 3px; font-size: min(.75rem, 14px); padding: 4px 1px; text-align: center; flex: 1 1 auto; min-width: 0; min-height: 48px; }
  .topbar nav a.nav-wide { display: none; }
  .nav-icon { display: block; width: 22px; height: 22px; }
  .page { padding-bottom: calc(84px + env(safe-area-inset-bottom)); }
  .hero, .detail { min-height: 62vh; padding-top: calc(96px + env(safe-area-inset-top)); padding-bottom: 32px; }
  .title .logo { height: 80px; width: min(100%, 320px); }
  /* Text spans the full width here: shade from the bottom as well, so it reads on bright art. */
  .hero-bg::after { background: linear-gradient(0deg, rgba(18, 16, 14, .95) 0%, rgba(18, 16, 14, .75) 55%, rgba(18, 16, 14, 0) 90%),
    linear-gradient(90deg, rgba(18, 16, 14, .6), rgba(18, 16, 14, 0) 80%); }
  .toast { bottom: calc(84px + env(safe-area-inset-bottom)); }
  .icon-btn { width: 44px; height: 44px; }
  /* Thumb-sized targets (44px). */
  .toast-close { width: 44px; height: 44px; }
  .btn.small { min-height: 44px; }
  .dl-actions { gap: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  /* Fewer and gentler, not none: fades and colour changes stay (they explain what changed);
     movement goes (transforms apply at once). */
  /* visibility too: the pause card and the place line fade out instead of cutting. */
  * { transition-property: opacity, visibility, background-color, color, border-color !important; scroll-behavior: auto !important; }
  .card:hover, .card:focus-visible { transform: none; }
  .spinner { animation-duration: 3s; }
  .seek-ripple { animation-name: fade-in-out; }
  .skip-pill, .skip-pill.show { transform: none; transition-property: opacity, visibility !important; }
}
/* Reduced transparency and increased contrast (docs/design-language.md, accessibility): the top
   bar and the marks over posters go opaque. More contrast also lifts muted text and lines and darkens
   the hero's scrim by .2 (a colour under its gradient, so the phone's own gradient gets it too).
   Chromium 85 on the TV knows none of these queries and keeps the base. */
@media (prefers-reduced-transparency: reduce) {
  .topbar, .topbar.scrolled { background: var(--bg); }
  .remove-mark { background: var(--bg); }
}
@media (prefers-contrast: more) {
  :root { --muted: #f4efe6; --on-art: #f4efe6; --line: rgba(244, 239, 230, .28); }
  .topbar, .topbar.scrolled { background: var(--bg); }
  .remove-mark { background: var(--bg); }
  .hero-bg::after { background-color: rgba(18, 16, 14, .2); }
}
/* Forced colours drop every box-shadow, and the focus ring is one: an outline takes its place. */
@media (forced-colors: active) {
  :focus-visible, .episode:focus, .card:focus-visible, .profile:focus-visible, .field:focus-visible { outline: 3px solid CanvasText; outline-offset: 2px; }
}
/* Its own rule (* matches no pseudo-element; an unknown one voids a list): the lift applies at once. */
@media (prefers-reduced-motion: reduce) { .player .player-video::-webkit-media-text-track-display, .cue-layer { transition: none; } }

/* Tap-to-play: shown only when a browser refuses to autoplay (iOS after async loading). */
.tap-play { display: grid; place-items: center; width: 132px; height: 132px; border-radius: 50%; background: rgba(229, 38, 52, .92); color: #fff; box-shadow: 0 10px 40px rgba(0, 0, 0, .5); }
.tap-play .icon { width: 56px; height: 56px; transform: translateX(3px); }
.tap-play small { position: absolute; margin-top: 190px; font-size: 1rem; color: var(--ink); white-space: nowrap; }
.tap-play:focus-visible { box-shadow: var(--focus); }

/* ---------- profile settings (js/settings.js) ---------- */
.settings { max-width: 760px; margin: 0 auto; padding: calc(96px + env(safe-area-inset-top)) var(--gutter) 48px; display: grid; gap: 28px; }
.set-head { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 20px; }
.set-head .page-title { margin: 0 0 4px; }
.set-head p { margin: 0; }
.set-avatar { width: 84px; height: 84px; border-radius: 16px; }
.set-saved { position: fixed; top: calc(76px + env(safe-area-inset-top)); left: 50%; z-index: 25; margin: 0; padding: 8px 16px; border-radius: 999px; background: var(--panel); color: var(--good);
  font-weight: 700; font-size: .9rem; opacity: 0; transform: translate(-50%, -6px); transition: opacity .2s, transform .2s; pointer-events: none; }
.set-saved.show { opacity: 1; transform: translate(-50%, 0); }
.set-group h2 { margin: 0 0 4px; font-size: 1.15rem; }
.set-hint { margin: 0 0 12px; color: var(--muted); }
.set-group h2 + .set-opts { margin-top: 12px; }
.set-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
.set-opt, .set-switch { display: grid; gap: 4px; text-align: left; padding: 14px 16px; border-radius: 12px; background: var(--bg2); border: 1px solid var(--line);
  color: var(--ink); transition: border-color .15s, background .15s; }
/* Chosen: filled, with a check. The check's room is kept when unchosen, so nothing reflows. */
.set-opt[aria-checked="true"] { border-color: var(--ink); background: var(--ink); color: var(--ink-inv); }
.set-opt[aria-checked="true"] .set-opt-sub { color: #5b5247; }
.set-opt-label { display: flex; align-items: center; gap: 8px; font-weight: 700; }
.set-opt-label .icon { stroke-width: 2.5; visibility: hidden; }
.set-opt[aria-checked="true"] .set-opt-label .icon { visibility: visible; }
.set-group > .btn { margin-top: 12px; }
/* Televizyonu bağla: the code field and its button on one line, wrapping on narrow phones. */
.tv-link-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: stretch; }
.tv-link-form .tv-code { width: min(240px, 100%); flex: 0 1 240px; letter-spacing: .25em; }
.tv-msg { margin: 10px 0 0; min-height: 1.35em; }
.tv-msg.bad { color: var(--red-2); }
/* Genres: wide enough for "Bilim kurgu" on one line with its check. */
.set-opts.chips, .set-opts.compact.chips { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.set-opt-sub { color: var(--muted); font-size: .88rem; line-height: 1.35; }
.set-switch { width: 100%; grid-template-columns: 1fr auto; align-items: center; gap: 16px; }
.set-switch-text { display: grid; gap: 4px; }
.set-knob { position: relative; width: 48px; height: 28px; border-radius: 999px; background: rgba(244, 239, 230, .2); transition: background .2s; }
.set-knob::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: var(--ink); transition: transform .2s; }
.set-switch[aria-checked="true"] .set-knob { background: var(--good); }
.set-switch[aria-checked="true"] .set-knob::after { transform: translateX(20px); }
/* Full width, fixed height (an aspect-ratio with a max-height would narrow it). */
.set-sample { margin-top: 12px; display: grid; place-items: end center; width: 100%; height: clamp(110px, 22vw, 160px); border-radius: 12px; padding: 16px;
  background: linear-gradient(180deg, #2c2721, #0f0d0b); }
.set-sample span { background: rgba(0, 0, 0, .55); padding: 2px 8px; border-radius: 4px; }
.set-sample.sub-s span { font-size: 15px; }
.set-sample.sub-m span { font-size: 20px; }
.set-sample.sub-l span { font-size: 27px; }
.set-sample.cue-shadow span { background: transparent; text-shadow: 0 0 2px #000, 0 0 4px #000, 0 2px 6px rgba(0, 0, 0, .9); }
.set-sample.cue-yellow span { color: #ffd60a; background: rgba(0, 0, 0, .85); }
.set-note { margin: 0; font-size: .9rem; }
.me.active img { box-shadow: 0 0 0 2px var(--ink); }
@media (max-width: 720px) {
  .set-head { grid-template-columns: auto 1fr; }
  .set-head .btn { grid-column: 1 / -1; justify-self: start; }
  .set-avatar { width: 64px; height: 64px; }
  .set-opts { grid-template-columns: 1fr; gap: 8px; }
  .set-opts.compact { grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); }
}

/* ---------- Listem tools ---------- */
.list-head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 12px; margin: calc(96px + env(safe-area-inset-top)) var(--gutter) 10px; }
.list-head .page-title { margin: 0; }
.list-bar { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { min-height: 40px; padding: 8px 16px; border-radius: 999px; background: rgba(244, 239, 230, .1); color: var(--muted); font: inherit; font-weight: 700; font-size: .92rem; border: 0; }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--ink-inv); }
.chip.select { appearance: none; -webkit-appearance: none; padding-right: 32px; color: var(--ink);
  background: rgba(244, 239, 230, .1) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23cfc6b8' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat right 12px center; }
.chip.select option { background: var(--panel); color: var(--ink); }
/* Phones: 44px chips, and 16px text so iOS does not zoom into the sort select. After the base rule, or it loses. */
@media (max-width: 720px) { .chip { min-height: 44px; font-size: 1rem; } }
.remove-mark { position: absolute; top: 8px; right: 8px; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: rgba(18, 16, 14, .82); color: var(--ink); }
.remove-mark .icon { width: 18px; height: 18px; }
.grid.editing .card .poster img { opacity: .7; }
.card.removable { text-align: left; color: var(--ink); }
.card.removable:focus-visible .remove-mark, .card.removable:hover .remove-mark { background: var(--red); }

/* İndirilenler summary line */
.dl-summary { margin: -4px var(--gutter) 14px; min-height: 1.2em; font-weight: 600; }

/* İndirilenler ready notice: toast action and the count on the nav link */
.toast { width: max-content; }   /* left: 50% alone shrinks it to half the screen on phones */
.toast-action { flex: none; min-height: 44px; padding: 8px 18px; border-radius: 8px; background: var(--ink); color: var(--ink-inv); font-weight: 800; }
.toast-action:focus-visible { background: #fff; }
.nav-dot { display: inline-grid; place-items: center; min-width: 18px; height: 18px; margin-left: 6px; padding: 0 5px; border-radius: 9px; background: var(--red); color: #fff;
  font-size: .7rem; font-weight: 800; line-height: 1; vertical-align: 1px; font-variant-numeric: tabular-nums; }
@media (max-width: 720px) {
  .topbar nav a { position: relative; }
  .nav-dot-box { position: absolute; top: 0; left: calc(50% + 6px); }
  .nav-dot { margin-left: 0; }
}

/* ---------- watching state: row edit (Continue Watching, Next Up), İzlendi, season tools ---------- */
.row-head { display: flex; align-items: center; gap: 12px; margin: 0 var(--gutter) 10px; }
.row-head h2 { margin: 0; }
.track.editing .card .poster img { opacity: .7; }
.track .remove-mark { width: 40px; height: 40px; }

/* ---------- motion (docs/motion.md) ---------- */
/* Remote focus answers the key at once: the focused card and profile scale up without a
   transition (a D-pad hop is the most frequent action in the app), and the one left behind
   eases back. Pointer hover keeps the 200 ms ease-out from the base rules. */
.card:focus-visible, .card:focus-visible .card-title, .profile:focus-visible { transition: none; }
/* Press feedback for taps and clicks: the interface heard it. In fast (60 ms: an 80 ms tap releases
   before a 160 ms press-in ends), out slower (200 ms). */
.icon-btn, .chip, .tab, .toast-action { transition: transform 200ms var(--ease-out); }
.btn:active, .icon-btn:active, .chip:active, .tab:active, .toast-action:active { transform: scale(0.97); transition-duration: 60ms; }
.poster { transition: transform 200ms var(--ease-out); }
.card:active .poster { transform: scale(0.97); transition-duration: 60ms; }
/* Player controls appear with the key press that asks for them; the idle hide fades (.25s). */
.player.show-ui .player-controls { transition: opacity 100ms var(--ease-out); }
/* PIN and trailer dialogs: enter instead of teleporting over the page. Centred, so they scale from the centre. */
.pin-dialog[open], .trailer-dialog[open] { animation: pop-in 200ms var(--ease-out); }
@keyframes pop-in { from { opacity: 0; transform: scale(0.96); } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-in-out { 20% { opacity: 1; } from, to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .pin-dialog[open], .trailer-dialog[open] { animation-name: fade-in; } }

/* ---------- pixel pets (js/pets.js): rare moments only ---------- */
.pets { position: fixed; left: 0; right: 0; bottom: var(--pet-ground, calc(14px + env(safe-area-inset-bottom))); height: 0; z-index: 40; pointer-events: none; }
.pet { position: absolute; left: 0; bottom: 0; transform-origin: 22% 100%; will-change: transform; }
.pet-nap { left: auto; right: max(24px, var(--gutter)); pointer-events: auto; cursor: pointer; }
.pet-sprite { background-repeat: no-repeat; image-rendering: pixelated; animation: pet-frames var(--fps, 360ms) steps(2) infinite; }
.pet-sprite.flip { transform: scaleX(-1); }
@keyframes pet-frames { to { background-position-x: var(--sheet); } }
.pet-bubble { position: absolute; bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%); padding: 5px 10px; white-space: nowrap;
  font: 700 .8rem/1.2 var(--sans); color: #12100e; background: #f4efe6;
  box-shadow: 0 -3px 0 #2a1a12, 0 3px 0 #2a1a12, -3px 0 0 #2a1a12, 3px 0 0 #2a1a12; }
.pet-spark { position: absolute; bottom: 18px; width: 6px; height: 6px; }
.pet-heart { position: absolute; left: 62%; bottom: 70%; transform: translate(-50%, 0); }
.pet-z { position: absolute; right: 12px; bottom: 90%; font: 700 1rem var(--sans); color: #f4efe6;
  animation: pet-z 2.4s ease-out infinite; }
@keyframes pet-z { from { transform: translate(0, 6px); opacity: 0; } 30% { opacity: .9; } to { transform: translate(10px, -26px); opacity: 0; } }
.pet-loading { display: inline-block; vertical-align: middle; margin-right: 12px; }
.player-status:has(.pet-loading) { display: flex; align-items: center; }
@media (max-width: 720px) { .pets { --pet-ground: calc(72px + env(safe-area-inset-bottom)); } }
@media (prefers-reduced-motion: reduce) { .pet-sprite, .pet-z { animation: none; } }

/* ---------- sign-in with Clerk: TV QR code, #/bagla, Profil ayarları > Hesap, #/admin (js/account.js) ---------- */
/* The QR code: white quiet zone drawn in, a fixed size that a phone reads from the sofa. */
.bagla { max-width: 760px; margin: 0 auto; padding: calc(96px + env(safe-area-inset-top)) var(--gutter) 48px; display: grid; gap: 16px; }
.bagla .page-title { margin: 0; }
.bagla p { margin: 0; }
.bagla-choices { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(16px, 3vw, 32px); }
.ask-dialog { width: min(420px, 92vw); margin: auto; border: 0; color: var(--ink); background: var(--panel); border-radius: 16px; padding: 28px; }
.ask-dialog::backdrop { background: rgba(0, 0, 0, .7); }
.ask-dialog h2 { margin: 0 0 8px; font-size: 1.2rem; }
.ask-dialog p { margin: 0; }
.account-body { display: grid; gap: 16px; }
.account h3 { margin: 0 0 4px; font-size: 1rem; }
.link-card { display: grid; gap: 10px; padding: 18px; border-radius: 12px; background: var(--panel); }
.link-card .set-hint { margin: 0; }
.link-card .btn { justify-self: start; }
.devices { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.devices li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.devices li:last-child { border-bottom: 0; }
.devices .dev-name { font-weight: 700; }
.devices .btn { margin-left: auto; min-height: 40px; padding: .5em 1.1em; }
/* #/admin: the title sits in the column (.settings pads the page), not a page width further in. */
.admin > .page-title { margin: 0; }
/* #/admin email sign-in steps (account.js readinessBlock): name over its one-line what, the link at the end */
.rd-step { flex-wrap: nowrap; }
.rd-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.rd-step.done .dev-name { font-weight: 500; color: var(--muted); }
.rd-step.done > .muted { margin-left: auto; }
.admin-person { align-items: flex-start; }
.admin-add { display: flex; gap: 10px; flex: 1 1 100%; }
.admin-add .field { flex: 1; min-width: 0; padding: 10px 14px; }
.admin-person .msg { flex: 1 1 100%; margin: 0; }
.admin-person .msg:empty { display: none; }
