/* Soap2Day 2026 - the lite (flat) backgrounds.
 * S2D26_FLAT_BACKGROUNDS_20260919
 *
 * One flat colour plus one static gradient per scheme. No canvas, no blur, no
 * blend mode, no animation, no image: the browser paints it once and never
 * touches it again. Every rule is scoped to body.s2d26-flat-bg, so the ordinary
 * site is untouched until the rollout.
 *
 * The colours are the ones already on screen: #eef2f6 / #000305 with the two
 * aqua washes (#7fe3e0 at 25%, #3bc8c4 at 18%) taken from the animated
 * .s2d26-grid-base, minus its movement.
 */

/* --- the site, light scheme --------------------------------------------- */

/* S2D26_FLAT_BG_LAYERING_20260920
 * The base colour and its two washes live on HTML, which the root stacking
 * context paints FIRST. The animated layers sit on body::before/::after with
 * z-index:-1, i.e. immediately after html and before every in-flow background -
 * so with the base on body (as it was) the animation was painted underneath it
 * and never seen. Body is transparent now, exactly as the original
 * :has(.s2d26-prompt-bg) arrangement had it. */

html:has(body.s2d26-flat-bg) {
	color-scheme: light;
	background-color: #eef2f6 !important;
	background-image:
		radial-gradient(circle at 12% 18%, rgba(127, 227, 224, .25), transparent 31%),
		radial-gradient(circle at 84% 74%, rgba(59, 200, 196, .18), transparent 36%) !important;
	background-repeat: no-repeat !important;
	background-position: 0 0, 0 0 !important;
	background-size: 100% 100%, 100% 100% !important;
	background-attachment: scroll !important;
}

/* S2D26_FLAT_BG_DARK_ORDER_20260920
 * Body must be transparent in BOTH schemes, and that has to be said at a
 * specificity the theme cannot outrank: css/theme-mode.css opens with
 * `html.night-mode body { background:#1a1a1a !important }`, which is (0,1,2).
 * A bare `body.s2d26-flat-bg` (0,1,1) loses to it, and the dark scheme paints
 * an opaque fill over the layers that sit behind the page. With the html in
 * front of the selector this is (0,3,3) and there is nothing to argue about. */

html:has(body.s2d26-flat-bg) body.s2d26-flat-bg,
html.dark:has(body.s2d26-flat-bg) body.s2d26-flat-bg,
html.night-mode:has(body.s2d26-flat-bg) body.s2d26-flat-bg,
html[data-theme="dark"]:has(body.s2d26-flat-bg) body.s2d26-flat-bg,
html body.s2d26-flat-bg.night-mode,
html body.s2d26-flat-bg.dark-mode,
html body.s2d26-flat-bg.dark {
	background: transparent !important;
}

/* --- the site, dark scheme ---------------------------------------------- */

html.dark:has(body.s2d26-flat-bg),
html.night-mode:has(body.s2d26-flat-bg),
html[data-theme="dark"]:has(body.s2d26-flat-bg) {
	color-scheme: dark;
	background-color: #000305 !important;
	background-image:
		radial-gradient(circle at 12% 18%, rgba(59, 200, 196, .20), transparent 34%),
		radial-gradient(circle at 84% 74%, rgba(127, 227, 224, .12), transparent 38%) !important;
	background-repeat: no-repeat !important;
	background-position: 0 0, 0 0 !important;
	background-size: 100% 100%, 100% 100% !important;
	background-attachment: scroll !important;
}

/* --- the page containers ------------------------------------------------ */
/* Copied from the original arrangement (site-backgrounds.css): while a full
 * screen background is behind the page, the page's own blocks must not paint
 * over it. Same selector list, scoped to the lite body class instead of
 * :has(.s2d26-prompt-bg). */

html body.s2d26-flat-bg:not(.s2d26-movie-page) :is(#main, #main > .container, #main .main-content, .page-category, .page-detail, .movies-list-wrap, .psyplay-api-popular-block),
html.dark body.s2d26-flat-bg:not(.s2d26-movie-page) :is(#main, #main > .container, #main .main-content, .page-category, .page-detail, .movies-list-wrap, .psyplay-api-popular-block),
html.night-mode body.s2d26-flat-bg:not(.s2d26-movie-page) :is(#main, #main > .container, #main .main-content, .page-category, .page-detail, .movies-list-wrap, .psyplay-api-popular-block),
html[data-theme="dark"] body.s2d26-flat-bg:not(.s2d26-movie-page) :is(#main, #main > .container, #main .main-content, .page-category, .page-detail, .movies-list-wrap, .psyplay-api-popular-block) {
	background-color: transparent !important;
}

/* --- the account cabinet ------------------------------------------------ */
/* The cabinet keeps the scene colour it has today (the variable it already
 * uses), but the aurora ribbons - the two blurred layers that drift on a 31s
 * and 34s loop - are gone. The static wash in .s2d26-account-scene::before
 * stays, so the corners keep their tint. */

html body.s2d26-flat-bg.ofa-account-page {
	background-color: transparent !important;
	background-image: none !important;
}

/* The scene colour moves up to html for the same reason as on the site: the
 * rotating layers are painted after html and before the in-flow content, so the
 * base has to be underneath them, not on top. The cabinet's own backdrop loses
 * its opaque fill (its veil keeps the gradients that give it depth). */
html:has(body.s2d26-flat-bg.ofa-account-page) {
	background-color: #02090c !important;
}

html:not(.dark):not(.night-mode):not([data-theme="dark"]):has(body.s2d26-flat-bg.ofa-account-page) {
	background-color: #edf9f9 !important;
}

html body.s2d26-flat-bg.ofa-account-page .s2d26-account-backdrop {
	background-color: transparent !important;
	background-image: none !important;
}

html body.s2d26-flat-bg.ofa-account-page .s2d26-account-scene {
	inset: 0 !important;
	animation: none !important;
}

html body.s2d26-flat-bg.ofa-account-page .s2d26-account-scene .s2d26-account-aurora,
html body.s2d26-flat-bg.ofa-account-page .s2d26-account-scene [class*="s2d26-aurora-ribbon"],
html body.s2d26-flat-bg.ofa-account-page .s2d26-account-scene [class*="s2d26-aurora-core"],
html body.s2d26-flat-bg.ofa-account-page .s2d26-account-scene [class*="s2d26-aurora-glow"] {
	display: none !important;
}

html body.s2d26-flat-bg.ofa-account-page .s2d26-account-backdrop,
html body.s2d26-flat-bg.ofa-account-page .s2d26-account-backdrop::after,
html body.s2d26-flat-bg.ofa-account-page .s2d26-account-scene::before {
	filter: none !important;
	-webkit-backdrop-filter: none !important;
	backdrop-filter: none !important;
}

/* ---------------------------------------------------------------------------
 * S2D26_FLAT_EFFECTS_20260919
 *
 * The lite version also drops the three costliest things drawn on a card:
 * the blur, the glass and the movement. Same scope as everything above -
 * body.s2d26-flat-bg - so the ordinary site is untouched.
 *
 * Not in this block on purpose: the shimmer, the always-on decoration
 * animations and the particles. Those are the next decision, not this one.
 * ------------------------------------------------------------------------- */

/* (1) no filter on a card, its artwork, or the poster surfaces ------------- */

/* S2D26_FLAT_EFFECTS_SCROOT_20260919
 * The artwork only. Anything with a "*" in it is gone from this file: a
 * descendant's own filter is that element's business, and a rule that reached
 * inside the card is what broke the play button's entrance. */
body.s2d26-flat-bg .mli-thumb,
body.s2d26-flat-bg .movies-list img,
body.s2d26-flat-bg .ml-mask img,
body.s2d26-flat-bg .s2d26-info-poster img,
body.s2d26-flat-bg .mvic-thumb img,
body.s2d26-flat-bg .ofa-media-card img,
body.s2d26-flat-bg .ofa-media-card__poster {
	filter: none !important;
	-webkit-filter: none !important;
}

/* (2) no glass. backdrop-filter only ever means "blur what is behind me", so
 *     switching it off cannot shift a thing. Compensating the few surfaces
 *     that used it as their only backdrop is a separate pass, once we have
 *     looked at how they read without it. -------------------------------- */

body.s2d26-flat-bg,
body.s2d26-flat-bg * {
	-webkit-backdrop-filter: none !important;
	backdrop-filter: none !important;
}

/* (6) the card holds still: no transition, and the hover state does not lift
 *     it, brighten it or add a shadow. The resting shadow and every layout
 *     transform (the play button's centring, for one) are left alone. ----- */

body.s2d26-flat-bg .ml-item,
body.s2d26-flat-bg .ofa-media-card {
	transition: none !important;
}

@media (hover: hover) and (pointer: fine) {
	/* The card itself may not lift, brighten or throw a shadow - and that is
	 * where it stops. The play button inside keeps its own
	 * translate(-50%,-50%) centring and its scale entrance. */
	body.s2d26-flat-bg .ml-item:hover,
	body.s2d26-flat-bg .psyplay-api-popular-grid > .ml-item:hover,
	body.s2d26-flat-bg .ofa-media-card:hover {
		transform: none !important;
		filter: none !important;
		box-shadow: none !important;
	}
}

/* ---------------------------------------------------------------------------
 * S2D26_LITE_BG_MOTION_20260920
 *
 * The site's motion, back at compositor prices: two surfaces, and every frame
 * costs a texture move or an alpha change. Nothing here repaints.
 *
 *   ::after  - the baked stage. Its softness is drawn into the artwork (an
 *              inline SVG with gradients), never by a filter, and it breathes on
 *              opacity while it sways on transform.
 *   ::before - the drifting blob. A radial gradient - soft by construction -
 *              translated across the stage.
 *
 * Both sit under the content (z-index:-1, above the body's own flat colour) and
 * are one screen each, so the texture memory is a couple of megabytes.
 * ------------------------------------------------------------------------- */

body.s2d26-flat-bg::before,
body.s2d26-flat-bg::after {
	content: "";
	position: fixed;
	z-index: -1;
	inset: -6%;
	pointer-events: none;
	background-repeat: no-repeat;
	background-position: 50% 50%;
	background-size: 112% 112%;
}

/* variant 3 - the baked artwork: softness is in the drawing, not in a filter */
body.s2d26-flat-bg::after {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='90' viewBox='0 0 160 90' preserveAspectRatio='none'%3E%3Cdefs%3E%3CradialGradient id='a' cx='26%25' cy='24%25' r='52%25'%3E%3Cstop offset='0' stop-color='%233bc8c4' stop-opacity='.34'/%3E%3Cstop offset='1' stop-color='%233bc8c4' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='b' cx='78%25' cy='70%25' r='46%25'%3E%3Cstop offset='0' stop-color='%237fe3e0' stop-opacity='.26'/%3E%3Cstop offset='1' stop-color='%237fe3e0' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='52%25' cy='92%25' r='44%25'%3E%3Cstop offset='0' stop-color='%239bebe4' stop-opacity='.20'/%3E%3Cstop offset='1' stop-color='%239bebe4' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect width='160' height='90' fill='url(%23a)'/%3E%3Crect width='160' height='90' fill='url(%23b)'/%3E%3Crect width='160' height='90' fill='url(%23c)'/%3E%3C/svg%3E");
	opacity: .9;
	will-change: opacity, transform;
	animation:
		s2d26-lite-breathe 22s ease-in-out infinite alternate,
		s2d26-lite-sway 74s ease-in-out infinite alternate;
}

/* variant 2 - the drift: one texture, moved by the compositor */
body.s2d26-flat-bg::before {
	background-image:
		radial-gradient(circle at 36% 40%, rgba(59, 200, 196, .26), transparent 44%),
		radial-gradient(circle at 68% 64%, rgba(127, 227, 224, .18), transparent 40%);
	will-change: transform;
	animation: s2d26-lite-drift 58s linear infinite alternate;
}

/* variant 1 - the breathing, on the stage */
@keyframes s2d26-lite-breathe {
	from { opacity: .56; }
	to   { opacity: .96; }
}

@keyframes s2d26-lite-sway {
	from { transform: translate3d(-1.2%, -0.6%, 0); }
	to   { transform: translate3d(1.2%, 0.6%, 0); }
}

@keyframes s2d26-lite-drift {
	from { transform: translate3d(-2.6%, -1.8%, 0) scale(1.02); }
	to   { transform: translate3d(2.6%, 1.8%, 0) scale(1.06); }
}

/* The dark scheme needs its own strength: the same alphas read weaker on
 * #000305 than on #eef2f6. */
html.dark body.s2d26-flat-bg::before,
html.night-mode body.s2d26-flat-bg::before,
html[data-theme="dark"] body.s2d26-flat-bg::before {
	background-image:
		radial-gradient(circle at 36% 40%, rgba(59, 200, 196, .34), transparent 46%),
		radial-gradient(circle at 68% 64%, rgba(127, 227, 224, .22), transparent 42%);
}

/* ---------------------------------------------------------------------------
 * S2D26_LITE_CABINET_MOTION_20260920
 *
 * The cabinet's motion. The ribbons are not coming back; instead two viewport
 * layers counter-rotate, the second with an opacity pulse, so the light visibly
 * travels without anything repainting.
 *
 * They are inset by 12%, which is what a rotation needs to keep every corner
 * covered: at 1080p that is roughly 130px of slack for a rotation that never
 * exceeds its sine. Each layer is about one screen of texture.
 * ------------------------------------------------------------------------- */

body.s2d26-flat-bg.ofa-account-page::before,
body.s2d26-flat-bg.ofa-account-page::after {
	content: "";
	position: fixed;
	z-index: -1;
	inset: -12%;
	pointer-events: none;
	background-repeat: no-repeat;
	background-position: 50% 50%;
	background-size: 130% 130%;
	transform-origin: 50% 50%;
	will-change: transform, opacity;
}

body.s2d26-flat-bg.ofa-account-page::before {
	background-image:
		radial-gradient(circle at 30% 30%, rgba(34, 231, 236, .20), transparent 38%),
		radial-gradient(circle at 72% 42%, rgba(19, 215, 224, .15), transparent 36%),
		radial-gradient(circle at 48% 76%, rgba(92, 251, 255, .12), transparent 40%);
	animation: s2d26-lite-scene-a 9s ease-in-out infinite alternate;
}

body.s2d26-flat-bg.ofa-account-page::after {
	background-image:
		radial-gradient(circle at 62% 34%, rgba(103, 221, 215, .16), transparent 34%),
		radial-gradient(circle at 40% 70%, rgba(59, 200, 196, .13), transparent 38%);
	opacity: .85;
	animation:
		s2d26-lite-scene-b 6s ease-in-out infinite alternate,
		s2d26-lite-scene-pulse 7s ease-in-out infinite alternate;
}

@keyframes s2d26-lite-scene-a {
	from { transform: rotate(-10deg) scale(1.02); }
	to   { transform: rotate(10deg) scale(1.08); }
}

@keyframes s2d26-lite-scene-b {
	from { transform: rotate(9deg) scale(1.06); }
	to   { transform: rotate(-9deg) scale(1.01); }
}

@keyframes s2d26-lite-scene-pulse {
	from { opacity: .45; }
	to   { opacity: .92; }
}

html.dark body.s2d26-flat-bg.ofa-account-page::before,
html.night-mode body.s2d26-flat-bg.ofa-account-page::before,
html[data-theme="dark"] body.s2d26-flat-bg.ofa-account-page::before {
	background-image:
		radial-gradient(circle at 30% 30%, rgba(34, 231, 236, .26), transparent 40%),
		radial-gradient(circle at 72% 42%, rgba(19, 215, 224, .20), transparent 38%),
		radial-gradient(circle at 48% 76%, rgba(92, 251, 255, .16), transparent 42%);
}

/* Motion off means exactly the static lite look: no layer, no animation. */
@media (prefers-reduced-motion: reduce) {
	body.s2d26-flat-bg::before,
	body.s2d26-flat-bg::after {
		animation: none;
		will-change: auto;
	}

	body.s2d26-flat-bg.ofa-account-page::before,
	body.s2d26-flat-bg.ofa-account-page::after {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
 * S2D26_LITE_BG_SWITCHES_20260920
 *
 * The switches the URL parameters set. Every rule here only ever removes a
 * layer or stops an animation, so the default (m4 / cab2) is exactly what r46
 * shipped and nothing has to be repeated.
 * ------------------------------------------------------------------------- */

/* m0 - nothing moves at all: the static lite look */
body.s2d26-flat-bg.s2d26-lite-m0::before,
body.s2d26-flat-bg.s2d26-lite-m0::after {
	animation: none;
}

/* m1 - the breathing only: no blob, no sway */
body.s2d26-flat-bg.s2d26-lite-m0::before,
body.s2d26-flat-bg.s2d26-lite-m1::before,
body.s2d26-flat-bg.s2d26-lite-m3::before {
	display: none;
}

body.s2d26-flat-bg.s2d26-lite-m1::after {
	animation: s2d26-lite-breathe 22s ease-in-out infinite alternate;
}

/* m2 - the drift only: the stage holds still behind it */
body.s2d26-flat-bg.s2d26-lite-m2::after,
body.s2d26-flat-bg.s2d26-lite-m3::after {
	animation: none;
}

/* m3 - the baked artwork on its own, nothing animated */

/* cabinet: cab0 hides both layers, cab1 keeps the first one only */
body.s2d26-flat-bg.ofa-account-page.s2d26-lite-cab0::before,
body.s2d26-flat-bg.ofa-account-page.s2d26-lite-cab0::after {
	display: none;
}

body.s2d26-flat-bg.ofa-account-page.s2d26-lite-cab1::after {
	display: none;
}

/* ---------------------------------------------------------------------------
 * S2D26_LITE_BG_FAST_TEST_20260920
 *
 * The RELEASE pace (frozen 20 Sep 2026, S2D26_LITE_RELEASE_CONFIG_20260920): the three
 * stacked layers run five times faster than the timings r46 shipped, which is
 * the look the owner approved. It hangs off the m4 body class - the class a page
 * carries whenever the parameter is absent or 4 - so `?s2d26_lite=5` still
 * reaches the calm timings above for comparison. Nothing else changes: the same
 * three animations, the same properties, still no filter and no repaint.
 * ------------------------------------------------------------------------- */

body.s2d26-flat-bg.s2d26-lite-m4::after {
	animation:
		s2d26-lite-breathe 4.4s ease-in-out infinite alternate,
		s2d26-lite-sway 14.8s ease-in-out infinite alternate;
}

body.s2d26-flat-bg.s2d26-lite-m4::before {
	animation: s2d26-lite-drift 11.6s linear infinite alternate;
}

/* ---------------------------------------------------------------------------
 * S2D26_LITE_DARK_DEPTH_20260920
 *
 * The dark scheme only, and the light scheme is untouched.
 *
 * Measured from the owner's screenshot: the background strips sat at luminance
 * 41-53 (rgb(15,54,54) to rgb(33,63,63)) against the theme's own dark surface of
 * #1a1a1a = 26 and a #000305 base of 1.7 - roughly twice as light as the theme
 * it replaced. The layers were dimmed by giving the stage a second, quieter
 * artwork instead of a static opacity: that opacity is animated (the breathing),
 * so a static value would either be overridden or need !important and kill the
 * animation. Same geometry, about a third of the light.
 * ------------------------------------------------------------------------- */

html.dark body.s2d26-flat-bg::after,
html.night-mode body.s2d26-flat-bg::after,
html[data-theme="dark"] body.s2d26-flat-bg::after {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='90' viewBox='0 0 160 90' preserveAspectRatio='none'%3E%3Cdefs%3E%3CradialGradient id='a' cx='26%25' cy='24%25' r='52%25'%3E%3Cstop offset='0' stop-color='%233bc8c4' stop-opacity='.12'/%3E%3Cstop offset='1' stop-color='%233bc8c4' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='b' cx='78%25' cy='70%25' r='46%25'%3E%3Cstop offset='0' stop-color='%237fe3e0' stop-opacity='.09'/%3E%3Cstop offset='1' stop-color='%237fe3e0' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='52%25' cy='92%25' r='44%25'%3E%3Cstop offset='0' stop-color='%239bebe4' stop-opacity='.07'/%3E%3Cstop offset='1' stop-color='%239bebe4' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect width='160' height='90' fill='url(%23a)'/%3E%3Crect width='160' height='90' fill='url(%23b)'/%3E%3Crect width='160' height='90' fill='url(%23c)'/%3E%3C/svg%3E") !important;
}

html.dark body.s2d26-flat-bg::before,
html.night-mode body.s2d26-flat-bg::before,
html[data-theme="dark"] body.s2d26-flat-bg::before {
	background-image:
		radial-gradient(circle at 36% 40%, rgba(59, 200, 196, .13), transparent 46%),
		radial-gradient(circle at 68% 64%, rgba(127, 227, 224, .085), transparent 42%) !important;
}

html.dark:has(body.s2d26-flat-bg),
html.night-mode:has(body.s2d26-flat-bg),
html[data-theme="dark"]:has(body.s2d26-flat-bg) {
	background-image:
		radial-gradient(circle at 12% 18%, rgba(59, 200, 196, .09), transparent 34%),
		radial-gradient(circle at 84% 74%, rgba(127, 227, 224, .05), transparent 38%) !important;
}

/* The cabinet moves faster and carries three layers, so it takes a smaller cut -
 * enough to stop lighting the room, not enough to lose the motion. */
html.dark body.s2d26-flat-bg.ofa-account-page::before,
html.night-mode body.s2d26-flat-bg.ofa-account-page::before,
html[data-theme="dark"] body.s2d26-flat-bg.ofa-account-page::before {
	background-image:
		radial-gradient(circle at 30% 30%, rgba(34, 231, 236, .16), transparent 40%),
		radial-gradient(circle at 72% 42%, rgba(19, 215, 224, .12), transparent 38%),
		radial-gradient(circle at 48% 76%, rgba(92, 251, 255, .10), transparent 42%) !important;
}
