/*
 * Video shopping (reels) page -- structural styles only.
 * Everything cosmetic lives in the Tailwind classes on ~/Views/Home/Web/Partial/Video/*.cshtml.
 *
 * Layout contract (Figma 1944-3 / 1949-60, 1440x964 frame):
 *   header 72  ->  stage top pad 16  ->  video column 852  ->  stage bottom pad 24
 *   rail sits 24px right of the video column, bottom-aligned with it
 *   arrows sit 24px from the viewport right edge, centred on the stage
 */

html.video-shopping,
html.video-shopping body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

.video-shell {
  --video-stage-pad-top: 16px;
  --video-stage-pad-bottom: 24px;
  position: relative;
  height: calc(100dvh - var(--video-header-h, 88px));
  min-height: 420px;
  overflow: hidden;
  background: #171717;
}

/*
 * The stage gutters live on the slide, not here: `overflow: hidden` clips at the padding box,
 * so padding on the viewport would let the next slide show through the bottom gutter.
 */
.video-viewport {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

/* One slide per screen; the track slides vertically by whole viewport heights. */
.video-track {
  height: 100%;
  transition: transform 0.42s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}

.video-track.is-dragging {
  transition: none;
}

.video-slide {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 24px;
  height: 100%;
  padding: var(--video-stage-pad-top) 24px var(--video-stage-pad-bottom);
}

/*
 * The video box is sized in JS from the clip's real aspect ratio (see sizeStage() in
 * video-page.js) so portrait, square and landscape clips all hug their frame exactly
 * as designed, instead of being letterboxed inside a fixed box.
 */
.video-stage {
  position: relative;
  flex: 0 0 auto;
  height: 100%;
  aspect-ratio: 9 / 16;
  max-width: 100%;
  overflow: hidden;
  border-radius: 16px;
  background: #000;
}

/*
 * End-of-feed card: no panel, just the page showing through. Declared after .video-stage so it
 * wins the background without depending on where the Tailwind CDN injects its own rules.
 */
.video-stage--plain {
  background: transparent;
}

.video-stage video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}

/*
 * Product card morph.
 *
 * One element does both states instead of swapping two, so the thumbnail grows into the card and
 * back with nothing popping in or out: the <img> is the same node throughout.
 *
 * Collapsed  46x46 -- just the image, wrapped in the design's two hairline rings. The rings are
 *            ::before / ::after so no extra DOM is needed and they can simply fade out on expand.
 *            Ring geometry is Figma 3070:2513 scaled from 64 to 46 (x0.71875): outer ring on the
 *            border box, inner ring inset 3.28, image inset 6.57 -> 32.86.
 * Expanded   240 wide, white, the compact product card from Figma 3070:2629.
 *
 * Height cannot be transitioned from `auto`, and the expanded height depends on how many lines the
 * product name wraps to, so video-page.js measures it, animates to that px value and then hands the
 * height back to `auto` -- otherwise a late reflow (font swap, image load) would clip the buttons.
 */
.product-morph {
  --morph-media: 32.86px;
  position: relative;
  width: 46px;
  height: 46px;
  padding: 6.57px;
  overflow: hidden;
  border-radius: 14.78px;
  background: transparent;
  transition:
    width 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
    height 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
    padding 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
    border-radius 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
    background-color 0.34s ease;
  will-change: width, height;
}

/* The two hairline rings -- collapsed only. */
.product-morph::before,
.product-morph::after {
  content: "";
  position: absolute;
  z-index: 1;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.product-morph::before {
  inset: 0;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 14.78px;
}

.product-morph::after {
  inset: 3.28px;
  border: 1px solid #fff;
  border-radius: 11.5px;
}

.product-morph[data-expanded="true"] {
  --morph-media: 64px;
  width: 240px;
  padding: 10px;
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}

.product-morph[data-expanded="true"]::before,
.product-morph[data-expanded="true"]::after {
  opacity: 0;
}

.product-morph__media {
  display: block;
  flex: 0 0 auto;
  width: var(--morph-media);
  height: var(--morph-media);
  overflow: hidden;
  border-radius: 8.21px;
  background: #f4f5f7;
  transition:
    width 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
    height 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
    border-radius 0.34s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.product-morph[data-expanded="true"] .product-morph__media {
  border-radius: 10px;
}

/*
 * Measuring the expanded height (setExpanded in video-page.js) means flipping to the expanded state
 * for one synchronous read. Transitions have to be off for the WHOLE subtree while that happens, not
 * just on the card: .product-morph__media animates its own width, so with only the card frozen the
 * read lands on a half-grown 33px thumbnail -- which also lets the name wrap at the wrong width and
 * returns a height several px short of the real one, clipping the buttons until the 380ms handoff.
 */
.product-morph.is-measuring,
.product-morph.is-measuring::before,
.product-morph.is-measuring::after,
.product-morph.is-measuring * {
  transition: none !important;
}

.product-morph__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * Everything except the image is clipped away by overflow:hidden while collapsed; fading it keeps
 * the text from flashing through during the grow, and pointer-events keeps it untappable.
 */
.product-morph__reveal {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.16s ease;
}

.product-morph[data-expanded="true"] .product-morph__reveal {
  opacity: 1;
  pointer-events: auto;
  transition: opacity 0.22s ease 0.14s;
}

@media (prefers-reduced-motion: reduce) {
  .product-morph,
  .product-morph::before,
  .product-morph::after,
  .product-morph__media,
  .product-morph__reveal {
    transition-duration: 0.01ms;
  }
}

/*
 * Like burst -- Figma 3070:2795, the 96px heart at node 3070:2844.
 *
 * Pops in past full size, settles back a little, holds, then fades away: the shape of the gesture
 * TikTok-style feeds use to confirm a like. Fired by playLikeBurst() in video-page.js, which
 * restarts it by removing the class, forcing a reflow and re-adding it, so rapid repeat likes each
 * get their own pop instead of the first one swallowing the rest.
 *
 * The centring translate is part of every keyframe: animating `transform` replaces the whole
 * property, so a separate -translate-x/y utility would be dropped for the animation's duration.
 */
.video-like-burst {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.2);
}

.video-like-burst.is-bursting {
  animation: video-like-burst 900ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@keyframes video-like-burst {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.2);
  }
  /* Overshoot -- the "grow". */
  16% {
    opacity: 0.95;
    transform: translate(-50%, -50%) scale(1.25);
  }
  /* Settle back down a touch, which is what gives the pop its weight. */
  36% {
    opacity: 0.95;
    transform: translate(-50%, -50%) scale(0.92);
  }
  52% {
    opacity: 0.95;
    transform: translate(-50%, -50%) scale(1.02);
  }
  /* Hold at full size before leaving. */
  64% {
    opacity: 0.95;
    transform: translate(-50%, -50%) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1.16);
  }
}

@media (prefers-reduced-motion: reduce) {
  .video-like-burst.is-bursting {
    animation: video-like-burst-reduced 320ms ease both;
  }

  @keyframes video-like-burst-reduced {
    0%,
    60% {
      opacity: 0.95;
      transform: translate(-50%, -50%) scale(1);
    }
    100% {
      opacity: 0;
      transform: translate(-50%, -50%) scale(1);
    }
  }
}

/* Bottom scrim -- Figma paints it over the lower 458 of 852 (~54%). */
.video-scrim {
  position: absolute;
  inset: 46% 0 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.72) 100%);
}

.video-rail {
  flex: 0 0 auto;
}

/*
 * Rail buttons. Sizes and the tinted circle live here rather than as md: utilities because the
 * Tailwind CDN does not emit some responsive + arbitrary-opacity combinations (md:bg-white/[0.12]
 * silently never got generated), which left the desktop rail untinted.
 *
 * Phone (Figma 3070:2517): bare 28px icons over the video, 44px hit area, no background.
 * Desktop (Figma 2478-11582): 48px circles on rgba(255,255,255,0.12) with 24px icons.
 */
.video-rail__btn {
  width: 44px;
  height: 44px;
  background: transparent;
}

.video-rail__btn svg {
  width: 28px;
  height: 28px;
}

@media (min-width: 768px) {
  .video-rail__btn {
    width: 48px;
    height: 48px;
    background: rgba(255, 255, 255, 0.12);
  }

  .video-rail__btn:hover {
    background: rgba(255, 255, 255, 0.2);
  }

  .video-rail__btn svg {
    width: 24px;
    height: 24px;
  }
}

/*
 * ---------------------------------------------------------------------------------------------
 * Action sheets (phones only)
 * ---------------------------------------------------------------------------------------------
 *
 * The "..." menu and the report flow are ONE set of markup for both breakpoints: desktop keeps the
 * anchored popover / centred modal it has always had (Figma 1950-22, 1950-551), and phones present
 * the very same nodes as bottom action sheets (Figma 3070-2898 "Sheet — video menu", 3071-1919
 * "Sheet — report reasons", 3071-2044 "Sheet — other reason input", 3071-2384 "Sheet — report
 * sent"). Nothing here leaks onto the web layout: every phone rule is inside the max-width block.
 *
 * Widths, radii and shadows live here rather than as md:/utility pairs because they have to differ
 * per breakpoint, and a utility class would tie the override to wherever the Tailwind CDN happens
 * to inject its own rules (the same reason .video-rail__btn owns the rail sizing).
 */

/* Report flow scrim + centring -- the desktop values. */
.video-sheet-host {
  align-items: center;
  justify-content: center;
  padding-left: 16px;
  padding-right: 16px;
  background: rgba(10, 10, 10, 0.72);
  backdrop-filter: blur(2px);
}

/*
 * Wrapper around the report steps. `display: contents` makes it vanish from desktop layout, so the
 * steps stay direct flex children of the host exactly as before; on a phone it becomes the single
 * element that slides up, which keeps the animation tied to opening the sheet rather than replaying
 * on every step change.
 */
.video-sheet-wrap {
  display: contents;
}

/* Panel chrome -- desktop card. */
.video-sheet {
  width: 393px;
  max-width: 100%;
  border-radius: 16px;
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4);
}

/* Drag handle is sheet-only furniture: absent on desktop, no Tailwind `hidden` involved so the
 * media query below is guaranteed to win. */
.video-sheet__handle {
  display: none;
}

/* "..." menu -- desktop popover. */
.video-more-menu {
  width: 260px;
  border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.4);
}

/*
 * Row metrics and the report controls below are owned here for BOTH breakpoints, with the matching
 * utilities kept out of the markup on purpose. A class-vs-class tie is decided by source order, and
 * the Tailwind CDN injects its <style> after this file -- so `padding: 18px 20px` in the phone block
 * would silently lose to a `py-[13px]` utility. (Same reason .video-rail__btn owns the rail sizing.)
 */
.video-more-menu__row,
.video-more-menu__cancel {
  padding: 13px 16px;
  font-size: 15px;
  text-align: left;
}

.video-more-menu__row-icon,
.video-more-menu__row-icon svg {
  width: 18px;
  height: 18px;
}

/* Report step 2/3 controls -- desktop sizes (Figma 1950-622 / 1950-737). */
.video-sheet-field {
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 14px;
  line-height: 19px;
}

.video-sheet-cta {
  border-radius: 10px;
  padding-top: 12px;
  padding-bottom: 12px;
  font-size: 14px;
}

.video-sheet-done-icon svg {
  width: 34px;
  height: 34px;
}

.video-sheet-done-title {
  font-size: 17px;
}

@media (max-width: 767px) {
  .video-sheet-host {
    align-items: flex-end;
    padding: 0;
    background: rgba(0, 0, 0, 0.4);
    backdrop-filter: none;
  }

  .video-sheet-wrap {
    display: block;
    width: 100%;
    animation: video-sheet-in 260ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  .video-sheet,
  .video-more-menu {
    width: 100%;
    max-width: none;
    border-radius: 20px 20px 0 0;
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.28);
  }

  /* Pinned to the bottom edge. video-page.js skips its inline left/top on phones, so there is
   * nothing here to out-specify. */
  .video-more-menu {
    left: 0;
    right: 0;
    top: auto;
    bottom: 0;
    animation: video-sheet-in 260ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  .video-sheet__handle {
    display: block;
  }

  /* Menu rows -- Figma 3070:2954 / 3070:2958: roomier taps, 16px label, centred cancel. */
  .video-more-menu__row,
  .video-more-menu__cancel {
    padding: 18px 20px;
    font-size: 16px;
  }

  .video-more-menu__cancel {
    text-align: center;
  }

  /* Figma 3070:2955 sizes the flag at 20 on the sheet (18 in the desktop popover). */
  .video-more-menu__row-icon,
  .video-more-menu__row-icon svg {
    width: 20px;
    height: 20px;
  }

  /* Free-text field -- Figma 3071:2102: 120 tall, 16/14 padding, 15/21 text. */
  .video-sheet-field {
    height: 120px;
    padding: 14px 16px;
    font-size: 15px;
    line-height: 21px;
  }

  /* Sheet buttons -- Figma 3071:2104 / 3071:2391. */
  .video-sheet-cta {
    border-radius: 12px;
    padding-top: 14px;
    padding-bottom: 14px;
    font-size: 15px;
  }

  /* Figma 3071:2387 / 3071:2388. */
  .video-sheet-done-icon svg {
    width: 48px;
    height: 48px;
  }

  .video-sheet-done-title {
    font-size: 18px;
  }
}

@keyframes video-sheet-in {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .video-sheet-wrap,
  .video-more-menu {
    animation-duration: 0.01ms;
  }
}

/*
 * Feed toast. Desktop (Figma 1952-62) pins it bottom-right; the phone block near the end of this
 * file moves it into the above-the-caption slot per Figma 3071-2436. Owned here rather than as
 * inset utilities so the phone override wins regardless of where the Tailwind CDN injects its own
 * rules.
 */
.video-toast {
  right: 24px;
  bottom: 24px;
  max-width: calc(100vw - 48px);
}

/* Range slider (filter panel) -- two native inputs stacked over one shared track. */
.video-range {
  position: relative;
  height: 16px;
}

.video-range input[type="range"] {
  position: absolute;
  inset: 0;
  width: 100%;
  margin: 0;
  height: 16px;
  background: none;
  pointer-events: none;
  -webkit-appearance: none;
  appearance: none;
}

.video-range input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  pointer-events: auto;
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: #fff;
  border: 0;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
  cursor: pointer;
}

.video-range input[type="range"]::-moz-range-thumb {
  pointer-events: auto;
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: #fff;
  border: 0;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
  cursor: pointer;
}

.no-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.no-scrollbar::-webkit-scrollbar {
  display: none;
}

/* Tablet: keep the rail outside the video but tighten the gutters. */
@media (min-width: 768px) and (max-width: 900px) {
  .video-slide {
    gap: 12px;
    padding: var(--video-stage-pad-top) 12px var(--video-stage-pad-bottom);
  }
}

/*
 * Phones: the reel goes full-bleed. No gutters, no rounding, and the rail floats over the
 * video's right edge instead of sitting beside it -- there is no room for an outside column.
 * The prev/next arrows are dropped entirely (NavArrows.cshtml hides them below md); swiping
 * and the wheel/keyboard handlers already cover navigation.
 *
 * sizeStage() detects the same breakpoint and stops writing inline width/height/margin, so
 * nothing here needs !important to win.
 */
@media (max-width: 767px) {
  .video-slide {
    position: relative;
    gap: 0;
    padding: 0;
  }

  .video-stage {
    width: 100%;
    height: 100%;
    max-width: none;
    aspect-ratio: auto;
    border-radius: 0;
  }

  /*
   * Engagement rail -- Figma 3070:2517. On a phone it is bare 28px icons over the video with their
   * counts underneath, not the desktop's tinted circles; 20px between items, 8px off the right edge.
   */
  .video-rail {
    position: absolute;
    right: 8px;
    bottom: 12px;
    z-index: 5;
    gap: 20px;
    height: auto;
    /* justify-between collapses at auto height, so the gap above does the spacing. */
    justify-content: flex-end;
  }

  /*
   * Toast -- Figma 3071-2436: a full-width bar sitting in the same above-the-caption slot as the
   * product card, so it clears both the caption and the tabbar. The 95px matches
   * [data-product-slot]'s bottom-[95px]; on a phone the stage bottom is the tabbar top, so a fixed
   * element needs the bar's height added on top of it.
   */
  .video-toast {
    left: 16px;
    right: 16px;
    bottom: calc(var(--reel-tabbar-h, 64px) + 95px);
    max-width: none;
  }

  /* Sit the caption clear of the floating rail. */
  .video-stage [data-caption-title],
  .video-stage [data-caption-handle] {
    max-width: calc(100vw - 96px);
  }

  /*
   * Phone chrome -- Figma 3070-2480. The web header is dropped entirely: the new design has no
   * logo, search or cart up top (the cart moved to the bottom tabbar), so MobileTopBar.cshtml
   * supplies the only top chrome -- sound on the left, feed switcher in the middle. Navigation back
   * to the store is the tabbar's "Басты" tab.
   */
  html.video-shopping {
    --reel-tabbar-h: 64px; /* Mobile/Partial/Tabbar.cshtml is h-16 */
  }

  html.video-shopping header {
    display: none;
  }

  /* Runs to the very top; stops short of the tabbar pinned to the bottom. */
  html.video-shopping .video-shell {
    height: calc(100dvh - var(--reel-tabbar-h));
  }
}
