/* =============================================================================
   IzeChat — Reels experience (isolated, additive)
   -----------------------------------------------------------------------------
   Loaded AFTER stylesheet/style.css and dark.css, so the few rules here that
   deliberately correct the stock reels styling win on equal specificity without
   any !important and without editing the base theme.

   Four jobs:
     1. Make the reel-to-reel slide read as a vertical pager (the stock rules
        parked EVERY hidden reel below the viewport, so swiping back looked like
        swiping forward), and stop the whole off-screen stack from being laid out.
     2. The double-tap heart and its burst.
     3. The shared-element surface that carries a reel between the feed card and
        the full-screen player.
     4. Press feedback on a carousel card, so the double-tap hold is never felt
        as an unresponsive tap.

   Everything decorative sits behind prefers-reduced-motion.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. THE PAGER
   -------------------------------------------------------------------------- */

/* `transition: all` on a full-screen fixed layer animates every property that
   ever changes on it — including ones that cost layout. Name the two that
   actually move. `visibility` is stepped, not eased: delayed on the way out so
   the exiting reel stays on screen for its whole slide, immediate on the way in. */
.reels_list {
	transition: transform .34s cubic-bezier(.2, .8, .2, 1),
	            opacity .2s linear,
	            visibility 0s linear 0s;
	backface-visibility: hidden;
}

.reels_list.hidden {
	transition: transform .34s cubic-bezier(.2, .8, .2, 1),
	            opacity .2s linear,
	            visibility 0s linear .34s;
}

/* A reel BEHIND the active one exits upward. Without this every hidden reel sat
   below the viewport, so "previous" slid in from the same edge as "next". */
.reels_list.hidden.ize-reel-above {
	transform: translateY(-100%);
}

/* Only the active reel and its immediate neighbours are rendered at all. The
   rest keep their DOM (and their buffered video) but cost no layout, no paint
   and no compositing — which is what stops a long session from getting heavier
   with every swipe. `ize-reel-near` is maintained by ize-reels.js. */
.reels_list.hidden:not(.ize-reel-near) {
	content-visibility: hidden;
	contain: strict;
}

/* Compositor lease — held for the slide, dropped after. A permanent will-change
   on these layers would pin a texture per reel in GPU memory. */
.reels_list.ize-reel-anim {
	will-change: transform, opacity;
}

/* The player's own backdrop. A reel that is still buffering shows black, never
   the page behind it and never white. */
.hidden_reels {
	background: #000;
}

/* Portrait video in a portrait box. object-fit is also set from JS for reels
   that arrive later; this covers the server-rendered first paint so there is no
   letterboxed first frame that then corrects itself. */
.wo_reels_cont .tag_vid_plyr video,
.reels_list video {
	object-fit: cover;
	background: #000;
}

/* -----------------------------------------------------------------------------
   2. DOUBLE-TAP HEART + BURST
   One node, one animation, removed on animationend by the engine.
   -------------------------------------------------------------------------- */

.ize-reel-anchor { position: relative; }

.ize-reel-heart {
	position: absolute;
	z-index: 30;
	width: 0;
	height: 0;
	pointer-events: none;
	color: #ff3363;
	will-change: transform, opacity;
}

.ize-reel-heart svg {
	position: absolute;
	left: -56px;
	top: -56px;
	width: 112px;
	height: 112px;
	filter: drop-shadow(0 6px 18px rgba(0, 0, 0, .45));
	animation: ize-reel-heart-pop .78s cubic-bezier(.2, .9, .25, 1) forwards;
}

@keyframes ize-reel-heart-pop {
	0%   { opacity: 0; transform: scale(.2)  rotate(-14deg); }
	18%  { opacity: 1; transform: scale(1.18) rotate(6deg); }
	34%  { opacity: 1; transform: scale(.94) rotate(-3deg); }
	48%  { opacity: 1; transform: scale(1)   rotate(0deg); }
	100% { opacity: 0; transform: scale(1.5) translateY(-26px) rotate(0deg); }
}

/* Particles: eight, each with its own angle, distance and delay written as
   custom properties by the engine so one keyframe covers all of them. */
.ize-reel-spark {
	position: absolute;
	left: -3px;
	top: -3px;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
	opacity: 0;
	transform: rotate(var(--a)) translateX(0);
	animation: ize-reel-spark-out .62s cubic-bezier(.15, .8, .3, 1) var(--t, 0ms) forwards;
}

@keyframes ize-reel-spark-out {
	0%   { opacity: 0;  transform: rotate(var(--a)) translateX(6px)  scale(.4); }
	22%  { opacity: .95; }
	100% { opacity: 0;  transform: rotate(var(--a)) translateX(var(--d, 56px)) scale(.15); }
}

/* The like button acknowledging the gesture. IzeMotion.bump() drives the scale;
   this only carries the colour, so the two never fight over `transform`. */
.reels_like_btn { transition: color .18s ease; }
.reels_like_btn.active-like { color: #ff3363; }
.reels_like_btn.active-like svg { color: #ff3363; }

/* -----------------------------------------------------------------------------
   3. SHARED-ELEMENT SURFACE
   A single drawn frame flying between the feed card and the player. It sits
   above the page and below the app's modals (1200) so nothing it covers can be
   interacted with mid-flight, and nothing above it is hidden by it.
   -------------------------------------------------------------------------- */

.ize-reel-hero {
	position: fixed;
	inset: 0;
	z-index: 1100;
	display: none;
	pointer-events: none;
}

.ize-reel-hero.is-open { display: block; }

.ize-reel-hero-scrim {
	position: absolute;
	inset: 0;
	background: #000;
	opacity: 0;
	will-change: opacity;
	transition: opacity .26s cubic-bezier(.2, .8, .2, 1);
}

.ize-reel-hero.is-running .ize-reel-hero-scrim { opacity: 1; }
.ize-reel-hero.is-closing .ize-reel-hero-scrim { opacity: 0; }

/* The frame is laid out ONCE at its destination box (left/top/width/height are
   written by JS, never transitioned) and flown with transform alone. That is the
   whole difference between a transition the compositor can run on its own and
   one that forces layout + paint on every frame — which is what this did first,
   and what made it feel laggy. transform-origin must be the top-left corner the
   FLIP arithmetic is expressed from. */
.ize-reel-hero-frame {
	position: absolute;
	left: 0;
	top: 0;
	overflow: hidden;
	border-radius: 14px;
	background: #000;
	transform-origin: 0 0;
	will-change: transform;
	backface-visibility: hidden;
	transition: transform .3s cubic-bezier(.22, .74, .2, 1),
	            border-radius .18s linear;
}

/* Corner rounding is the one paint-bound property here, so it is given a short
   duration of its own and is done well before the flight ends. */
.ize-reel-hero.is-running .ize-reel-hero-frame { border-radius: 0; }
.ize-reel-hero.is-closing.is-running .ize-reel-hero-frame { border-radius: 14px; }

/* cover, so the aspect ratio is preserved through the whole flight: the frame
   is cropped exactly as the card cropped it and exactly as the player will. */
.ize-reel-hero-frame > canvas {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.ize-reel-hero.is-leaving { transition: opacity .2s linear; opacity: 0; }

/* -----------------------------------------------------------------------------
   4. CARD PRESS FEEDBACK
   The carousel holds a tap open for one double-tap window (180ms). This is what
   makes that window invisible: the card responds on the touch itself.
   -------------------------------------------------------------------------- */

.tag_feed_reel_card {
	transition: transform .16s cubic-bezier(.2, .8, .2, 1);
}

.tag_feed_reel_card.ize-reel-card-press {
	transform: scale(.955);
}

/* Liked state on a feed card, so a double tap there has somewhere to land. */
.tag_feed_reel_card[data-liked="1"] .tag_feed_reel_likes_row svg {
	color: #ff3363;
	filter: drop-shadow(0 0 4px rgba(255, 51, 99, .55));
}

/* -----------------------------------------------------------------------------
   5. MOTION POLICY
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.reels_list,
	.tag_feed_reel_card,
	.ize-reel-hero-frame,
	.ize-reel-hero-scrim {
		transition-duration: .01ms !important;
	}
	.ize-reel-heart svg { animation-duration: .4s; }
	.ize-reel-spark { display: none; }
}

/* The motion runtime's global off switch (battery saver, lean device, user
   preference) reaches these the same way it reaches every other component. */
html.ize-mo-off .reels_list,
html.ize-mo-off .ize-reel-hero-frame,
html.ize-mo-off .ize-reel-hero-scrim {
	transition-duration: .01ms !important;
}
html.ize-mo-off .ize-reel-spark { display: none; }
