/*
 * Shared TV stylesheet. See docs/TV-VERSION-DESIGN.md §5.5.
 *
 * WRITTEN TO THE CHROMIUM 38 FLOOR. Banned here and enforced by bin/lint_tv.php:
 * CSS Grid (57), custom properties (49), flex `gap` (84), clamp()/min()/max() (79),
 * aspect-ratio (88), position:sticky (56), :focus-visible (86), :focus-within (60),
 * logical properties (89), overflow:clip (90), backdrop-filter (76), unprefixed
 * filter (53), :is()/:where() (88), scroll-behavior (61).
 *
 * Flexbox IS available (Chromium 21) — only `gap` is missing, so children carry
 * margins. rem and vw/vh are available too, which is what makes the fluid canvas
 * below cost one line.
 *
 * CANVAS. LG and Samsung both document two graphics-plane resolutions: FHD panels
 * report 1280x720 CSS px, UHD panels report 1920x1080. A fixed design is coarse on
 * one and blurs Persian text on the other, so the whole scale hangs off one
 * vw-based root size and every dimension below is in rem.
 *   1rem = 19.2px @1280   ->   28.8px @1920
 */

/*
 * 1.5vw = 19.2px on a 1280 canvas and 28.8px on a 1920 one — the two graphics
 * resolutions LG and Samsung document, which is the whole range this scale is
 * meant to span.
 *
 * BOTH ENDS ARE CLAMPED. Left to itself, vw tracks width forever: a desktop
 * browser window wider than 1920 (and any set reporting its true panel width)
 * rendered every card, key and button proportionally oversized, because the scale
 * was following the viewport instead of the canvas. clamp() would express this in
 * one line but is Chromium 79 — media queries are the floor-safe form, and they
 * meet the vw curve exactly at each breakpoint, so the scale stays continuous.
 */
html {
    font-size: 1.5vw;
    background: #0d0f12;
    /* Weak net only. Any real horizontal leak must be killed at its source —
       see the modern layer's history with this exact class of bug. */
    overflow-x: hidden;
}

body {
    margin: 0;
    padding: 0;
    background: #0d0f12;
    /* Never #FFF on large areas: TV panels exaggerate contrast at both ends. */
    color: #e8e8e8;
    /* System Persian fallback. A subsetted WOFF2 is layered on top in Phase 2;
       WOFF2 is Chromium 36, so it is safe at the floor. Light weights are
       forbidden on TV, so the family only ever ships 500 and 700. */
    font-family: Tahoma, Arial, sans-serif;
    font-size: 1rem;
    line-height: 1.5;
    direction: rtl;
}

/* 1.5vw would be 16.5px here — hold it, so a small window stays legible. */
@media (max-width: 1100px) { html { font-size: 16.5px; } }
/* 1.5vw would be 28.8px here — hold it, so nothing grows past the 1920 canvas. */
@media (min-width: 1920px) { html { font-size: 28.8px; } }

img { border: 0; display: block; }
a { color: #e8e8e8; text-decoration: none; }
h1, h2 { margin: 0; font-weight: bold; }

/*
 * Kill the engine's own focus ring on everything focusable.
 *
 * Focus here is drawn by the .is-focused class, so the browser's default outline
 * is a SECOND indicator painted on top — it reads as a stray white/blue box
 * hugging the brand-red border, and on a card it lands between the border and the
 * poster. This is not an accessibility regression: the replacement indicator is a
 * 0.25rem border plus a surface swap, far stronger than the default ring.
 *
 * -webkit-tap-highlight-color kills the same artefact on pointer-driven sets
 * (the LG Magic Remote is a pointer).
 */
a, button, [data-nav-item],
a:focus, button:focus, [data-nav-item]:focus {
    outline: 0;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
/* The inner pseudo-element only. Zeroing `border` on the ELEMENTS above would
   strip the very border that draws focus. */
a::-moz-focus-inner, button::-moz-focus-inner {
    border: 0 none;
    padding: 0;
}

/* ---------------------------------------------------------------- safe area */
/* 5% on every edge. Four vendors specify this independently; many sets still
   crop the outer edge. vw/vh express it exactly and both work at the floor.
   (The old page used 28px, which is 2.2% — its end cards were croppable.) */
.tv-page { padding: 5vh 5vw; }

/* Long-form readable text sits inside a further inset — Roku requires 10% for
   text specifically, and it reads better at 3 metres regardless. */
.tv-prose { padding-right: 2.5vw; padding-left: 2.5vw; }

/* -------------------------------------------------------------------- head */
.tv-head {
    display: flex;
    align-items: center;
    height: 3.2rem;
    margin-bottom: 1rem;
    border-bottom: 0.1rem solid #232a38;
}
.tv-head__logo { color: #ff3b46; font-size: 1.4rem; font-weight: bold; }
.tv-head__spacer { flex: 1 1 auto; }
.tv-head__note { color: #8b93a3; font-size: 0.8rem; }

/* -------------------------------------------------------------------- rows */
.tv-row { margin-bottom: 1.3rem; }

.tv-row__title {
    font-size: 1.55rem;
    color: #ffffff;
    margin-bottom: 0.45rem;
}

/*
 * The rail viewport. The TRACK inside it is what moves, via transform, never
 * scrollLeft: RTL scrollLeft semantics flipped in Blink around Chromium 85, so
 * identical JS returns opposite signs on a webOS 3 set and a webOS 23 set.
 * transform is a coordinate system we own, and it is the GPU-cheap option.
 */
/* font-size:0 on the clip box kills the line-box gap under the inline-block
   track; cards set their own size back. */
.tv-rail { position: relative; overflow: hidden; font-size: 0; }
.tv-rail__track {
    /*
     * inline-block, NOT block. A block-level track is exactly as wide as the rail
     * no matter how much content overflows it, so its measured width can never
     * exceed the viewport width and every "is this rail scrollable" test answers
     * no — the rails silently stop translating and the browser scrolls the
     * overflow:hidden box instead, which is the failure this whole design avoids.
     * inline-block shrink-wraps to the real content width under white-space:nowrap.
     * In RTL it anchors to the right edge and overflows leftward, which is the
     * coordinate system tv.js's slide() maths assumes.
     */
    display: inline-block;
    vertical-align: top;
    position: relative;
    white-space: nowrap;
    /* Kills the ~5px text node the newline between two inline-block cards
       renders as. Children set their own size back. Without this the real pitch
       drifts from the measured one. */
    font-size: 0;
    /*
     * NO transition on the transform, deliberately. Rails jump rather than glide.
     * Three reasons: the existing modern layer already kills every transition for
     * TV after the renderer-crash work; the previous TV homepage moved its strip
     * with no animation at all; and a transition that fails to advance leaves the
     * rail visually frozen while the engine believes it moved — which is exactly
     * what happened in a non-compositing test environment here, and there is no
     * way to rule it out on a 2016 set without the device. Motion polish is worth
     * less than a rail that is always where the engine says it is. Revisit only
     * after the on-device diagnostic confirms this set composites normally.
     */
}

/*
 * Dimming is applied at ROW level, not per card. The research recommends dimming
 * unfocused siblings so the focused item wins by subtraction, but doing it per
 * card would put ~96 elements on their own compositing layers on a 2016 SoC.
 * One layer per row gets the same read for 8 layers instead of 96 — a deliberate
 * concession to the renderer-crash history.
 */
.tv-row { opacity: 0.55; }
.tv-row.is-current { opacity: 1; }

/* ------------------------------------------------------------------- cards */
.tv-card {
    display: inline-block;
    vertical-align: top;
    width: 9rem;
    margin-left: 0.85rem;   /* flex gap is Ch84; margins are the substitute */
    white-space: normal;
    font-size: 0.8rem;
}

.tv-card__img {
    width: 9rem;
    height: 13.5rem;        /* fixed 2:3 — aspect-ratio is Ch88 */
    background: #171c26;
    border: 0.25rem solid #171c26;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

.tv-card__label {
    display: block;
    height: 2.4rem;
    overflow: hidden;
    margin-top: 0.3rem;
    font-size: 0.78rem;
    line-height: 1.2rem;
    color: #c3cbd9;
}

/*
 * Focus. Driven by a JS-set class, never :focus — :focus-visible is Ch86 and
 * :focus-within is Ch60, and a class also keeps pointer and 5-way on one model.
 * 0.25rem is ~4.8px @1280 and ~7.2px @1920, inside the 4-6 / 6-8 vendor band.
 */
.tv-card.is-focused .tv-card__img { border-color: #ff3b46; background: #2a1216; }
.tv-card.is-focused .tv-card__label { color: #ffffff; }

/* "See all" tile — the last card of a rail. Same footprint as a poster so the
   lattice stays uniform (a ragged rail makes geometric focus feel arbitrary).
   line-height centres the single line vertically without flex or table games. */
.tv-card__more {
    display: block;
    width: 9rem;
    height: 13.5rem;
    background: #171c26;
    border: 0.25rem solid #2c313c;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    line-height: 13rem;
    text-align: center;
    font-size: 1rem;
    font-weight: bold;
    color: #c3cbd9;
}
.tv-card--more.is-focused .tv-card__more {
    border-color: #ff3b46;
    background: #2a1216;
    color: #ffffff;
}

/* Fact strip under a poster: scores + language badges. Solid colours rather than
   rgba, matching the layer's flattening rule; the greens/blues are the site's
   established دوبله / زیرنویس colours over the TV background. */
.tv-card__meta { display: block; margin-top: 0.25rem; font-size: 0; white-space: nowrap; overflow: hidden; }
.tv-m {
    display: inline-block;
    margin-left: 0.25rem;
    padding: 0 0.3rem;
    font-size: 0.68rem;
    font-style: normal;
    font-weight: bold;
    line-height: 1.15rem;
    border: 0.05rem solid #2c313c;
}
.tv-m--imdb { color: #f5c518; border-color: #4a3d12; }   /* IMDb's own colour */
.tv-m--mv   { color: #ff8f96; border-color: #5c1e22; }   /* MyMoviz score */
.tv-m--dub  { color: #5fd497; background: #10271e; border-color: #154a2f; font-weight: normal; }
.tv-m--sub  { color: #8fc0ff; background: #182536; border-color: #27476b; font-weight: normal; }

/* Resume progress. A plain two-div bar — no gradient (TV panels band them) and
   no transition, matching the rail rule that nothing depends on animation. */
.tv-card__bar { height: 0.3rem; background: #2a3040; margin-top: 0.25rem; }
.tv-card__bar span { display: block; height: 0.3rem; background: #e50914; }
.tv-card__next { display: block; font-size: 0.72rem; color: #6fd39b; margin-top: 0.2rem; }

/* ----------------------------------------------------------------- buttons */
.tv-btn {
    display: inline-block;
    /* Minimum focusable target: 3rem is ~58px @1280, ~86px @1920. A drifting
       Magic Remote pointer must not land between two targets. */
    min-height: 3rem;
    line-height: 2rem;
    padding: 0.5rem 1.1rem;
    margin-left: 0.8rem;
    background: #1b1f27;
    border: 0.25rem solid #2c313c;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    color: #e8e8e8;
    font-size: 0.95rem;
    font-weight: bold;
    font-family: inherit;
}
.tv-btn.is-focused { border-color: #ff3b46; background: #2a1216; color: #ffffff; }
.tv-btn--main { background: #e50914; border-color: #e50914; }

/* ------------------------------------------------------------ title page */
/* Flex, not grid (Ch57), and margins rather than gap (Ch84). */
.tv-detail { display: flex; margin-bottom: 1.4rem; }
.tv-detail__poster { width: 13rem; margin-left: 1.4rem; }
.tv-detail__poster img { width: 13rem; height: 19.5rem; background: #171c26; }
.tv-detail__info { flex: 1 1 auto; min-width: 0; }

.tv-title { font-size: 1.9rem; color: #ffffff; margin-bottom: 0.2rem; }
/* An original title is Latin inside an RTL page, so it carries its own
   direction. This is exactly the case that forbids arrow-key inversion in the
   focus engine — direction is a text property here, not a navigation one. */
.tv-title__en { display: block; font-size: 1rem; color: #9aa3b2; direction: ltr; text-align: right; margin-bottom: 0.5rem; }

.tv-facts { margin-bottom: 0.6rem; font-size: 0.95rem; color: #c3cbd9; }
.tv-fact { display: inline-block; margin-left: 1rem; }
.tv-fact b { color: #ffffff; }
.tv-fact--imdb b { color: #f5c518; }
.tv-fact--mv b { color: #ff3b46; }

.tv-plot {
    margin: 0 0 0.9rem;
    font-size: 0.95rem;
    line-height: 1.65rem;
    color: #c3cbd9;
    /* No line-clamp (-webkit-line-clamp needs -webkit-box, which is fragile on
       old engines); a fixed height with hidden overflow is predictable. */
    max-height: 6.6rem;
    overflow: hidden;
}

.tv-actions { margin-top: 0.4rem; }

/* --------------------------------------------------------- vertical lists */
/* Seasons, episodes and comments are all the same shape: a column of full-width
   focusable rows. Nothing expands in place — a row is a link to another page. */
.tv-list { margin-bottom: 1.2rem; }
.tv-listrow {
    display: block;
    min-height: 3rem;
    padding: 0.6rem 1rem;
    margin-bottom: 0.5rem;
    background: #141821;
    border: 0.25rem solid #232a38;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    font-size: 1rem;
    color: #e8e8e8;
}
.tv-listrow.is-focused { border-color: #ff3b46; background: #2a1216; color: #ffffff; }
.tv-listrow__main { font-weight: bold; }
.tv-listrow__sub { color: #9aa3b2; font-size: 0.85rem; margin-right: 0.8rem; }
.tv-listrow.is-focused .tv-listrow__sub { color: #c3cbd9; }
.tv-tag {
    display: inline-block;
    margin-right: 0.5rem;
    padding: 0 0.5rem;
    font-size: 0.75rem;
    border: 0.1rem solid #3b4658;
    color: #9aa3b2;
}
.tv-tag--dub { border-color: #2f6b46; color: #6fd39b; }

/* ------------------------------------------------------------- comments */
.tv-comment {
    padding: 0.7rem 1rem;
    margin-bottom: 0.5rem;
    background: #141821;
    border: 0.1rem solid #232a38;
}
.tv-comment__who { font-size: 0.9rem; color: #ff3b46; font-weight: bold; }
.tv-comment__re { font-size: 0.8rem; color: #7b8394; }
.tv-comment__score { font-size: 0.8rem; color: #7b8394; margin-right: 0.6rem; }
.tv-comment__text { margin-top: 0.35rem; font-size: 0.95rem; line-height: 1.6rem; color: #c3cbd9; }
.tv-comment__spoiler { margin-top: 0.35rem; font-size: 0.9rem; color: #d99a3c; }

/* ------------------------------------------------------------------- QR */
.tv-qr { display: flex; align-items: center; margin: 1.2rem 0; padding: 1rem;
         background: #141821; border: 0.1rem solid #232a38; }
.tv-qr img { width: 9rem; height: 9rem; margin-left: 1.2rem; background: #ffffff; }
.tv-qr__text { flex: 1 1 auto; font-size: 0.95rem; line-height: 1.6rem; color: #c3cbd9; }

/* ----------------------------------------------------------------- player */
.tv-video {
    display: block;
    width: 100%;
    /* Leaves room for the control row and the first quality entries without
       scrolling, on both the 720 and 1080 canvases. */
    height: 60vh;
    background: #000000;
    margin-bottom: 0.8rem;
}
.tv-controls { margin-bottom: 1rem; }
.tv-controls .tv-btn { min-width: 7rem; text-align: center; }
.tv-err {
    padding: 1rem;
    margin-bottom: 1rem;
    background: #2a1416;
    border: 0.25rem solid #5c2a2e;
    font-size: 1rem;
    color: #f2c9c5;
}
.tv-now { font-size: 0.9rem; color: #9aa3b2; margin-bottom: 0.6rem; }
.tv-now b { color: #e8e8e8; }

/* --------------------------------------------------------------- rating row */
.tv-rate { margin: 0.6rem 0 0.2rem; }
.tv-rate__lbl { display: block; font-size: 0.85rem; color: #9aa3b2; margin-bottom: 0.35rem; }
.tv-score {
    display: inline-block;
    width: 2.6rem;
    height: 3rem;
    line-height: 2.4rem;
    margin: 0 0 0.35rem 0.35rem;
    padding: 0;
    background: #1b1f27;
    border: 0.25rem solid #2c313c;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    color: #e8e8e8;
    font-size: 1.05rem;
    font-family: inherit;
    font-weight: bold;
    text-align: center;
}
.tv-score.is-focused { border-color: #ff3b46; background: #2a1216; color: #ffffff; }
/* The score this viewer already gave. Filled, so it reads at a glance without
   needing the focus ring to be on it. */
.tv-score--mine { background: #e50914; border-color: #e50914; color: #ffffff; }

/* -------------------------------------------------------------- browse grid */
/* Wrapping inline-block cards, not CSS Grid (Ch57). The focus engine resolves a
   wrapped grid geometrically, so rows and columns need no markup of their own —
   but the cards must stay a strict lattice (uniform size, no ragged offsets) or
   4-way navigation becomes ambiguous. */
.tv-grid { font-size: 0; margin-bottom: 1.2rem; }
.tv-grid .tv-card { margin-bottom: 1rem; }

/* ------------------------------------------------------------- keyboard */
.tv-kb { margin-bottom: 1rem; }
.tv-kb__row { font-size: 0; margin-bottom: 0.5rem; }

/*
 * Latin and numeric layouts must lay out LEFT-TO-RIGHT.
 * The page is dir="rtl", so a row of inline-block keys flows right-to-left and a
 * QWERTY row renders reversed — "q w e r t y" appears as "y t r e w q". The keys
 * are a picture of a keyboard, not language content, so the row carries its own
 * direction. The Persian layout keeps the inherited RTL, which is correct for it.
 *
 * This does NOT need a matching change in the focus engine: resolution is
 * geometric, so ArrowLeft still means "whatever is physically left" in both.
 */
.tv-kb__row--ltr { direction: ltr; }
.tv-query--ltr { direction: ltr; text-align: left; }

.tv-key {
    display: inline-block;
    vertical-align: top;
    /* Minimum focusable target from §5.5: ~58px at a 1280 canvas, ~86px at 1920.
       A drifting Magic Remote pointer landing between two keys is the most likely
       usability failure in the whole product, and this is its densest grid. */
    width: 3.2rem;
    height: 3rem;
    line-height: 2.4rem;
    margin: 0 0 0.4rem 0.4rem;
    background: #1b1f27;
    border: 0.25rem solid #2c313c;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    color: #e8e8e8;
    font-size: 1.15rem;
    font-family: inherit;
    text-align: center;
}
.tv-key.is-focused { border-color: #ff3b46; background: #2a1216; color: #ffffff; }
.tv-key--wide  { width: 6.8rem; font-size: 0.9rem; }
.tv-key--go    { width: 9rem; background: #e50914; border-color: #e50914; font-size: 0.95rem; }
.tv-key--go.is-focused { border-color: #ff3b46; }

/* The typed query. Large enough to read from a sofa, and it must never collapse
   to zero height when empty or the layout jumps on the first keypress. */
.tv-query {
    min-height: 3.4rem;
    line-height: 3.4rem;
    padding: 0 1rem;
    margin-bottom: 0.8rem;
    background: #14181f;
    border: 0.25rem solid #2c313c;
    font-size: 1.6rem;
    color: #ffffff;
    overflow: hidden;
    white-space: nowrap;
}
.tv-query--empty { color: #6c7484; font-size: 1.1rem; }

.tv-recents { margin-bottom: 0.9rem; }

/* No-JS fallback: a real input, so a set whose tv.js never ran can still search
   using the TV's own on-screen keyboard. Hidden as soon as JS takes over. */
.tv-kbfallback input {
    width: 22rem; height: 3rem; padding: 0 0.8rem;
    background: #14181f; border: 0.25rem solid #2c313c; color: #fff;
    font-size: 1.1rem; font-family: inherit;
}

/* -------------------------------------------------------------------- misc */
.tv-empty { color: #9aa3b2; font-size: 1rem; }
.tv-sub { color: #9aa3b2; font-size: 0.9rem; margin-bottom: 0.7rem; }

/* The device-login code. Read from a sofa and typed on a phone, so it is the
   largest text in the product; letter-spacing keeps similar glyphs apart. */
.tv-code {
    font-size: 3.4rem;
    font-weight: bold;
    color: #ff3b46;
    letter-spacing: 0.6rem;
    direction: ltr;
    text-align: right;
    margin: 0 0 0.8rem;
}
.tv-pager { margin-bottom: 1rem; }

.tv-foot {
    margin-top: 1.2rem;
    padding-top: 0.8rem;
    border-top: 0.1rem solid #232a38;
    color: #7b8394;
    font-size: 0.8rem;
    line-height: 1.7;
}
.tv-foot a { color: #ff3b46; text-decoration: underline; }
.tv-key { color: #e8e8e8; font-weight: bold; }

/*
 * Pointer mode. LG's Magic Remote is a free-space pointer and LG states it is the
 * primary input, so hover must select — but once the user picks up the D-pad,
 * hover styling has to stop fighting the focus class. tv.js sets the mode class
 * on <html> from whichever input was used last.
 */
.tv-keys .tv-card:hover .tv-card__img { border-color: #171c26; }
.tv-keys .tv-card.is-focused:hover .tv-card__img { border-color: #ff3b46; }

/*
 * No JS: the focus engine never ran, so rails cannot be moved by remote. Let the
 * browser's own scrolling reach the rest of each row rather than clipping it
 * away, and undo the row dimming so nothing looks broken.
 */
.tv-nojs .tv-rail { overflow-x: auto; }
.tv-nojs .tv-row { opacity: 1; }
