/* Back to Top widget — ported from Tiger Elements' tiger-back-to-top.php
   inline base style (tiger-b2t → ractro-b2t). Colors/border/shadow come from
   per-instance style controls (higher specificity than these plain-class
   defaults); layout/position/animation are structural and live here. */

.ractro-b2t {
	position: fixed;
	bottom: var(--ractro-b2t-offset, 24px);
	--ractro-b2t-size: 46px;
	--ractro-b2t-scale: 1;
	font-size: 20px;
	width: var(--ractro-b2t-size);
	height: var(--ractro-b2t-size);
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	z-index: 9990;
	background: #185fa5;
	color: #ffffff;
	box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
	opacity: 0;
	visibility: hidden;
	transform: translateY(10px) scale(var(--ractro-b2t-scale));
	transition: opacity .25s, visibility .25s, transform .25s, background .2s, color .2s, box-shadow .2s;
}

.ractro-b2t.is-visible {
	opacity: 1;
	visibility: visible;
	transform: translateY(0) scale(var(--ractro-b2t-scale));
}

/* Font <i> icons follow font-size natively; inline <svg> ignores font-size,
   so bind its box to 1em and inherit color — the single Icon Size control
   drives both icon representations. */
.ractro-b2t i { font-size: 1em; line-height: 1; }
.ractro-b2t svg { width: 1em; height: 1em; stroke: currentColor; }

.ractro-b2t--left { left: var(--ractro-b2t-offset, 24px); right: auto; }
.ractro-b2t--right { right: var(--ractro-b2t-offset, 24px); left: auto; }

/* EDITOR CANVAS ONLY, by construction: back-to-top.php emits this attribute
   from the preview render and nowhere else, so this rule cannot match on the
   front end however specific it is. Widget JS does run in the canvas now, but
   the canvas never scrolls the WINDOW, so the handler above correctly leaves
   the button at opacity:0 and the author would see nothing.

   It mirrors .is-visible rather than forcing `transform: none`, so the Icon
   Size / scale control still previews. It also comes AFTER .is-visible on
   purpose: the two have identical specificity, and the revealed state is the
   one the canvas is asserting.

   BOTH SELECTORS ARE LOAD-BEARING, and the `:has()` one is the whole reason
   this was ever broken. An atomic widget's root class lands on TWO nodes in the
   canvas — React's identity wrapper and this PHP <button> one level below it
   (dev/canvas-dom-parity-check.mjs asserts exactly that, RULE 3) — so the
   wrapper is a `.ractro-b2t` too and inherits the opacity:0 above. `opacity` on
   an ancestor cannot be undone by a descendant: revealing only the button left
   it inside a fully transparent parent and the canvas still showed nothing.
   Measured that way, not reasoned about. The `:has()` rule reveals the wrapper
   from the button's own marker, so the trigger is still one widget-owned
   attribute and nothing here has to know the editor's DOM or class names.

   This used to be a bare `data-ractro-anim` plus a global reveal rule in the
   editor shell — the engine's own attribute, which collided with the Advanced
   tab's entrance animation on this widget's single tag. See back-to-top.php.

   ONE THING THIS DELIBERATELY DOES NOT OVERRIDE: if the author also set an
   entrance animation, the identity wrapper carries `data-ractro-anim` and
   ractro-anim.css holds it at opacity 0 until the driver reveals it. Same
   specificity as the `:has()` rule, and ractro-anim.css wins on order — left
   that way ON PURPOSE. That opacity is the animation's initial state, not this
   widget's baked one, and a widget stylesheet has no business outranking the
   animation engine. Measured in the canvas: such an element does get
   `.ractro-anim-in`, but its animation sits at currentTime 0 forever, so it
   never reaches the `to` keyframe and stays invisible. That is a canvas-wide
   entrance-animation defect (every animated widget, not this one) and it is
   what to fix — not this rule's specificity. */
.ractro-b2t[data-ractro-b2t-revealed],
.ractro-b2t:has([data-ractro-b2t-revealed]) {
	opacity: 1;
	visibility: visible;
	transform: translateY(0) scale(var(--ractro-b2t-scale));
}

/* …and the wrapper must not PAINT the button as well as reveal it. It wears the
   root class, so it also inherits the circle: background, radius and shadow. For
   most widgets that is invisible, because the wrapper and the widget's own root
   occupy the same box. This button is position:fixed and escapes the wrapper, so
   the two separate — revealing both drew a second, offset blue disc next to the
   real one (seen in the canvas, not deduced). Only the wrapper is stripped; the
   button keeps every one of its style controls. */
.ractro-b2t:has([data-ractro-b2t-revealed]) {
	background: none;
	box-shadow: none;
}

/* THE CANVAS IS NOT A VIEWPORT, so `position: fixed` does not mean there what it
   means on the page. dnd-kit puts a transform on the identity wrapper, and a
   transformed ancestor becomes the containing block for a fixed descendant — so
   `right: 24px` resolved against the 46px wrapper instead of the window and the
   revealed button landed half-under the editor's left rail, clipped. Measured;
   the fix is not to fight it. In preview the button flows in its own block
   instead, which is where its wrapper (the node the editor selects, outlines and
   measures) already is. The front end is untouched and stays fixed. */
.ractro-b2t[data-ractro-b2t-revealed] {
	position: static;
}
