/* ---------------------------------------------------------------------------
 * Remote-control navigation for uzkino.mn.
 *
 * Everything here is scoped to html.tv-mode, which tv-nav.js only sets on a
 * television. A phone or a desktop never sees a single rule from this file.
 *
 * The site's own stylesheet carries 21 `outline: none` declarations, so on a TV
 * you could move the selection with the remote and never see where it was.
 * These rules have to win against those, hence the specificity and !important -
 * used deliberately, not out of laziness.
 * ------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
 * The canvas.
 *
 * master.blade.php pins the viewport to a fixed 1280px logical canvas before
 * the first layout, the way a television interface is actually built: lay out
 * once, at one width, and let the panel scale it. Every length below is
 * therefore a length on that canvas and not a device pixel - one canvas pixel
 * is 1.5 device pixels on a 1080p set, 1.0 on a 720p set, 3.0 on a 4K one.
 * ------------------------------------------------------------------------- */

html.tv-mode {
  /* A television is watched from three metres away.

     18 canvas px is 27 device px on a 1080p panel - a fortieth of the screen
     height, which is the ordinary ten-foot body size. The same 18px on the
     960px viewport the WebView hands us by default was 36 device px: that, not
     this number, is what made the site enormous.

     Stated as vw as well, so the canvas and the type cannot multiply again. On
     the intended canvas 1.40625vw IS 18px, so this changes nothing while the
     pin works; if it ever fails - an old WebView, a Tizen or webOS browser we
     have no settings for - the type tracks the real viewport instead of
     compounding with it. The plain px line above is for engines without
     clamp(), which ignore the line below. */
  font-size: 18px;
  font-size: clamp(15px, 1.40625vw, 28px);

  /* or the WebView decides our columns are narrow and inflates the text again,
     on top of everything else */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;

  /* Every scroll on a television is one tv-nav.js performs itself, and a smooth
     scroll is animated with requestAnimationFrame - which a set pauses whenever
     the page is not the visible surface. Measured in a throttled context:
     window.scrollTo did nothing at all, twice over, and the same call landed
     immediately once scroll-behavior was auto. The theme sets
     scroll-behavior:smooth on :root inside a prefers-reduced-motion query;
     html.tv-mode outranks :root, and the !important closes the argument. */
  scroll-behavior: auto !important;

  /* Overscan: some sets still crop every edge, and Google's television
     guidance allows up to 5% - 64px across and 36px down on this canvas.
     Horizontally the theme already insets its content 60-68px, which is inside
     that, so only the vertical edges need help: the header sits over the top of
     the hero and the footer ends flush with the bottom. 27px is 3.75%, Google's
     own margin. Raise to 36px on a set that crops hard, drop to 0 on one that
     shows a full frame. This is the only place to change it. */
  --tv-safe-y: 27px;
}

/* The header is position:absolute over the hero, but its used `top` cannot be
   moved (it stays 0 even with !important). Padding on the bar inside it does
   the same job and is what actually works. */
html.tv-mode .navbar-inner { padding-top: var(--tv-safe-y); }
html.tv-mode footer        { padding-bottom: var(--tv-safe-y); }

/* the hint strip is read from the same three metres as everything else */
html.tv-mode .tv-hint { font-size: 1rem; }

/* the ring itself ------------------------------------------------------- */
html.tv-mode .tv-focus,
html.tv-mode .tv-focus:focus,
html.tv-mode a.tv-focus,
html.tv-mode button.tv-focus {
  outline: 4px solid #ff2d2d !important;
  outline-offset: 3px !important;
  border-radius: 6px;
  box-shadow: 0 0 0 8px rgba(255, 45, 45, .28), 0 12px 34px rgba(0, 0, 0, .65) !important;
  position: relative;
  z-index: 30;
}

/* The poster's ring is drawn on the card, not on the anchor that holds focus:
   the anchor's parent box clips at its own edge. */
html.tv-mode .tv-focus-card {
  outline: 4px solid #ff2d2d !important;
  outline-offset: 3px !important;
  border-radius: 8px;
  box-shadow: 0 0 0 8px rgba(255, 45, 45, .28), 0 14px 38px rgba(0, 0, 0, .7) !important;
  position: relative;
  z-index: 30;
}

/* ...and then the anchor must not draw a second one inside it */
html.tv-mode .tv-focus-card .tv-focus {
  outline: none !important;
  box-shadow: none !important;
}

/* A poster is the thing people aim at, so it earns a little lift - but the lift
   goes on the artwork and never on the box whose rectangle decides where the
   page scrolls to. Scaling the focused anchor by 1.06 moved its top and bottom
   by about 3% of its height, which is enough to ask for a few pixels of scroll
   every single time the ring lands on it.

   The artwork is not inside that anchor: on an .iq-card the focusable anchor is
   an empty box stretched over the card and .image-box is its sibling, so the
   lift is hung off .tv-focus-card, the card the script marks alongside it. The
   top-10 shelf is the other way round - the <img> really is inside the focused
   a.overly-images - hence the third selector. A transform on a descendant does
   not move the ancestor's border box, so the card the band rule measures stays
   exactly where it was. */
html.tv-mode .tv-focus-card .image-box,
html.tv-mode .tv-focus-card img,
html.tv-mode .tv-focus img {
  transform: scale(1.06);
  transition: transform .14s ease-out;
}

@media (prefers-reduced-motion: reduce) {
  html.tv-mode .tv-focus-card .image-box,
  html.tv-mode .tv-focus-card img,
  html.tv-mode .tv-focus img { transform: none; }
}

/* text controls read better with a filled selection than a hairline ring */
html.tv-mode a.nav-link.tv-focus,
html.tv-mode .navbar .tv-focus,
html.tv-mode .btn.tv-focus {
  background: #ff2d2d !important;
  color: #fff !important;
}

/* the dialog: keep the focused control clear of the artwork behind it */
html.tv-mode .uzm-btn.tv-focus {
  outline: 4px solid #fff !important;
  box-shadow: 0 0 0 8px rgba(255, 255, 255, .3) !important;
}

/* nothing on a TV is reached by pointer, so hover states only confuse */
html.tv-mode *:hover { transition: none; }

/* a hint strip, shown for a few seconds on the first screen ------------- */
.tv-hint {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  z-index: 9999;
  display: flex;
  gap: 22px;
  align-items: center;
  padding: 12px 26px;
  border-radius: 999px;
  background: rgba(12, 12, 14, .92);
  color: #f2f2f4;
  font-size: 15px;
  letter-spacing: .01em;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .6);
  opacity: 0;
  transition: opacity .4s ease;
  pointer-events: none;
}
.tv-hint.show { opacity: 1; }
.tv-hint b {
  display: inline-block;
  min-width: 26px;
  padding: 2px 7px;
  margin-right: 7px;
  border-radius: 5px;
  background: #2a2a30;
  color: #fff;
  font-weight: 600;
  text-align: center;
}

/* ---------------------------------------------------------------------------
 * The film dialog, while a film is running.
 *
 * play-modal.js hides the text half of the card when playback starts but
 * leaves its own close button drawn, absolutely positioned at the top right of
 * what is now a full-screen card. On a television that X sits over the picture
 * - and worse, being the first focusable thing left inside the dialog, the
 * remote layer paints its red ring around it and then cannot move off, because
 * while a film plays the arrows seek and OK plays and pauses. Visible, ringed
 * and dead. Back is how you leave a film on a remote; the X is a mouse's idea.
 *
 * display:none rather than visibility or opacity, so that visible() drops it
 * from the candidate list too and the ring never lands there in the first
 * place. Not comma-joined with :fullscreen - an engine that does not know that
 * selector would discard the whole rule, and this one has to hold everywhere.
 * ------------------------------------------------------------------------- */
html.tv-mode .uzm.playing .uzm-x { display: none; }

/* The overlay lies over the screen because of `inset: 0`, which Chromium below
   87 does not know - and a television is exactly where a stale WebView turns
   up. Without this the film would play in a box at the page's static position,
   which is precisely what "cannot be watched fullscreen" looks like. Costs
   nothing wherever inset already works. */
html.tv-mode .uzm {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

html.tv-mode .uzm.playing { overflow: hidden; }

/* The focus ring sets `position: relative` on whatever it lands on, so that its
   z-index means something. On a control that was already positioned, that
   relocates it: the dialog's big play button is
   `position:absolute; left:50%; top:50%; transform:translate(-50%,-50%)`, and
   turning it relative moves `top: 50%` from "half the artwork" to "half the
   artwork below where it already sat" - measured, the button dropped from
   194-264 to 700-770 in a 720px viewport, four fifths of it off the screen, at
   the moment the remote was pointing at it. The dialog is already scrolled to
   its end there, so nothing can pull it back.

   Keep its own positioning. The ring still draws; only the relocation goes. */
html.tv-mode .uzm-play.tv-focus { position: absolute !important; }
