/*
 * Scroll to top.
 *
 * The third control in the bottom corners, and the one with the least claim on
 * a visitor's attention: the chat launcher is an invitation and the reading
 * preferences are a promise, while this is only a shortcut back to something
 * the visitor can already reach. So it goes in the start corner above the
 * reading preferences rather than in the corner the chat panel opens out of —
 * anything stacked over the bot is covered the moment the bot is used — and it
 * is drawn as an outlined circle rather than a filled one, so the three read as
 * a set without a passive shortcut looking as loud as the two affordances.
 *
 * Geometry comes from stack.css. Nothing here states an offset from a viewport
 * edge; the corner and the position in it are the two lines below plus the
 * `data-jmns-stack` attribute in the markup.
 */

.jmns-top {
	/* Second slot up in the bottom-inline-start corner — see the roster in
	   stack.css, which is the only place the whole arrangement is written
	   down. */
	--jmns-stack-order: 1;

	display: inline-flex;
	align-items: center;
	justify-content: center;

	/*
	 * 48px square, matching the reading-preferences launcher it sits above
	 * rather than the 44px floor, so the column reads as one column.
	 *
	 * All four properties, deliberately. The theme's base control rule is
	 * `:where(button, input[type="submit"]), .button` — the `:where()` half
	 * carries no specificity (ADR-052) but the declarations inside it still
	 * apply, and it sets `min-block-size: 48px` *and* `padding: 0.75rem 1.5rem`.
	 * A size alone leaves the padding, a height alone leaves the floor, and the
	 * result is a 96px-wide oval where a 48px circle was asked for. That pair
	 * has caught components in this codebase before; it needs all of them.
	 */
	inline-size: 48px;
	block-size: 48px;
	min-block-size: 48px;
	min-inline-size: 48px;
	padding: 0;

	border: 1px solid var(--wp--preset--color--interactive, #245746);
	border-radius: 50%;
	/* Opaque, not transparent: it passes over body copy, cards and the ink
	   footer, and a see-through disc over any of them is unreadable. */
	background-color: var(--wp--preset--color--surface, #fff);
	color: var(--wp--preset--color--interactive, #245746);
	cursor: pointer;
	box-shadow: 0 1px 3px rgb(var(--jmns-shade-rgb, 38 51 42) / 0.25);

	/* See the note above the keyframes at the foot of this file. */
	animation: jmns-top-in 120ms ease-out;
}

/*
 * Hidden means hidden.
 *
 * top.js sets the `hidden` attribute, and that has to actually remove the
 * control rather than fade it: a transparent button in the corner of a page
 * nobody has scrolled is still in the tab order, still a 48px target under a
 * thumb, and still announced — a control that does nothing, which is worse than
 * no control.
 *
 * Stated rather than left to the UA stylesheet, because the rule above sets
 * `display` and would beat it. Class plus attribute is 0-2-0 against that
 * rule's 0-1-0, so the order the two are written in does not decide it; that is
 * the same failure the print rule in stack.css had to be doubled to avoid.
 */
.jmns-top[hidden] {
	display: none;
}

.jmns-top:hover {
	background-color: var(--wp--preset--color--interactive, #245746);
	color: var(--wp--preset--color--surface, #fff);
}

.jmns-top:focus-visible {
	/* The ring the rest of the portal uses; 2px at `interactive`, which clears
	   the 3:1 SC 1.4.11 asks of a focus indicator on this ground. */
	outline: 2px solid var(--wp--preset--color--interactive, #245746);
	outline-offset: 2px;
}

.jmns-top__icon {
	display: inline-flex;
}

/*
 * Shipped rather than borrowed, exactly as bot.css and the plugin's other
 * front-end components do: the accessible name of this button is a visually
 * hidden span, and a theme that does not define `screen-reader-text` would put
 * "Kembali ke atas" on screen beside the arrow.
 */
.jmns-top .screen-reader-text {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * It arrives rather than appearing, which is 120ms of fade and nothing that
 * moves the page.
 *
 * An animation and not a transition, because the resting state is
 * `display: none` — there is no state to transition from. Both switches that
 * turn motion off reach it: the media query below, and the site's own
 * preference, whose rule in access.css flattens every animation on the page to
 * 0.01ms with `!important`. Neither is checked in JavaScript, because both are
 * expressible here and a declared rule is re-evaluated the instant the visitor
 * changes their mind — which they can do from the panel one slot below this
 * button. That is why the first-entry loader answers the site's switch in
 * main.css rather than in its script, and why the announcement strip answers
 * the media query in ticker.css rather than in ticker.js. The one part of this
 * button that cannot be declared is the scroll itself; top.js says why.
 */
@keyframes jmns-top-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
	.jmns-top {
		animation: none;
	}
}
