/* ===========================================================================
   Round 6 · R1 — persistent support control
   ---------------------------------------------------------------------------
   Companion to inc/round6-support.php and assets/js/round6-support.js.

   THE ONE MEASUREMENT THIS WHOLE SHEET RESTS ON
   The docked tab's visible width is 16px, set once in --r6s-tab and used only in
   the docking transform. Against that, here is every inline-padding floor this
   theme ships, audited across all of style.css and assets/css/*.css:

       .wrap                    padding-inline: clamp(20px, 5vw, 56px)     -> 20
       .pharma-rail-viewport    padding-inline: clamp(18px, 3.4vw, 44px)   -> 18
       phone gutter             --mobile-gutter: clamp(20px, 5.5vw, 24px)  -> 20

   The tightest is 18px, so no content box on this site can come closer than 18px
   to the viewport's right edge, at any width. 16 < 18. The docked control
   therefore cannot overlap content at ANY viewport width — not because a
   screenshot looked fine, but because the two numbers cannot cross. Round 5's
   failure was a 164x52 pill at the bottom-right corner covering 86% of a
   wishlist button; the equivalent number here, in the resting state, is zero by
   construction. If a future edit lowers any of those floors below 16px, THIS is
   the guarantee that breaks, which is why the audit lives here and not in a
   report someone has to go and find.

   The only chrome that is allowed nearer than 16px — the mix-box tray
   (round4-box.css, right: clamp(12px, 2.4vw, 26px)) and the lightbox close
   button (round4-media.css, right: clamp(12px, 3vw, 28px)) — both sit at a
   HIGHER z-index than this control (220 and 260 against 170), so they paint over
   the tab and take its clicks rather than the other way round. The script docks
   for both as well; the layering is the second, independent line.

   WHY IT IS EDGE-ATTACHED AND NOT A FLOATING CIRCLE
   Round 5's B8 finding: a floating circular widget pinned to a corner is the
   universal signifier of an OPEN live chat, and this channel is not open. A tab
   welded to the viewport edge (square right corners, no drop shadow when
   docked) reads as chrome. (Round 7 added a QR card that this tab minimises
   to; it lives in round7-support.css and is opened only by the script.)

   WHY IT SITS IN THE LOWER-RIGHT AND NOT IN THE CORNER ITSELF
   The bottom-right corner is already occupied on this site: the compare tray
   (mobile.css, min-height 72px), the mix-box tray (round4-box.css, --p3box-h),
   the toast, and on a handset the browser's own chrome and home indicator. So
   the control is lifted clear of all of them and the lift is derived from the
   trays' own measured heights rather than guessed — see --r6s-floor below.

   MOTION
   Transform and opacity only, --ease, no bounce. Nothing here animates a layout
   property: the two states are one `translateX` apart, which is why the control
   can cross-fade between them without ever reflowing the page.
   ========================================================================= */

.r6s {
	/* --- the contract ------------------------------------------------- */
	--r6s-tab: 16px;                          /* docked visible width, < 18px */
	--r6s-panel: 236px;                       /* labelled body width (R7: + the "+" button) */
	/* Resting height above the viewport bottom. clamp() so a short phone
	   viewport does not push the control into the middle of the page and a tall
	   desktop one does not strand it halfway up. */
	--r6s-lift: clamp(96px, 17vh, 180px);
	/* Raised only while another piece of bottom chrome is on screen. 0 by
	   default so nothing moves on a page that has no tray. */
	--r6s-floor: 0px;

	position: fixed;
	/* 170 sits above .grain (150) and all page content, and below every overlay
	   that is allowed to own the screen: compare tray 180, backdrop 190, cart
	   drawer 200, filter sheet 205, search 210, box tray 220, toast 220,
	   lightbox 260, skip link 500. The script docks for those anyway; this
	   ordering is the belt to that braces. Round 6 Lane C's ambient field is a
	   fixed canvas at z-index 0, so this control is unambiguously above it. */
	z-index: 170;
	right: env(safe-area-inset-right, 0px);
	bottom: calc(max(var(--r6s-lift), var(--r6s-floor)) + env(safe-area-inset-bottom, 0px));

	display: flex;
	align-items: stretch;
	width: max-content;
	max-width: calc(100vw - 12px);
	min-height: 76px;

	/* #59677C, not --line-strong. --line-strong (#2b3a50) measures 1.79:1
	   against the page and fails WCAG 1.4.11's 3:1 for a control boundary;
	   #59677C measures 3.58:1 and is the same boundary Round 5 already adopted
	   for the checkout and lab-report controls, so this introduces no new value. */
	border: 1px solid #59677C;
	border-right: 0;
	border-radius: var(--r-md) 0 0 var(--r-md);

	/* OPAQUE on purpose. Round 5's lesson: an engine can declare
	   backdrop-filter and never composite it, and Round 6 puts a moving 3D field
	   behind every route. Legibility here does not depend on either. */
	background: var(--panel);
	color: var(--text);
	text-decoration: none;
	-webkit-tap-highlight-color: transparent;

	/* Docked is the resting state, the no-JS state and the state PHP prints. */
	transform: translateX(calc(100% - var(--r6s-tab)));
	transition: transform 260ms var(--ease), border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}

/* Round 7: the root used to be the link itself, and a blanket
   `.r6s * { pointer-events: none }` made it one target. The root is now a plain
   wrapper holding a link (or a label) AND a real <button>, so its children have
   to take their own clicks. The tab sliver needs no rule: a click on it bubbles
   to the wrapper, which is where the script listens. */

/* --- the docked sliver ---------------------------------------------------- */

.r6s-tab {
	flex: 0 0 var(--r6s-tab);
	width: var(--r6s-tab);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 7px;
	/* A whisper of accent so the sliver reads as this brand's chrome and not as
	   a rendering artefact. 8% over --panel stays opaque and stays dark. */
	background: color-mix(in srgb, var(--accent) 8%, var(--panel));
	border-radius: var(--r-md) 0 0 var(--r-md);
}

/* A solid dot. Round 6 drew a hollow ring here while no handle existed — this
   theme's "pending" mark — and NAEM-SPEC #3 (Round 7) retired "not open yet" as
   a visual state on every support surface, this one included. */
.r6s-mark {
	width: 7px;
	height: 7px;
	border: 1px solid var(--accent);
	border-radius: 50%;
	background: var(--accent);
}

.r6s-chevron {
	width: 6px;
	height: 6px;
	border-left: 1.5px solid var(--quiet);
	border-bottom: 1.5px solid var(--quiet);
	transform: rotate(45deg);
	transition: transform 220ms var(--ease);
}

/* --- the expanded body ---------------------------------------------------- */

.r6s-panel {
	width: var(--r6s-panel);
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 12px 18px 12px 13px;
	border-left: 1px solid var(--line);
}
.r6s-icon { display: block; flex: 0 0 auto; color: var(--accent-text); }
.r6s-icon svg { display: block; width: 22px; height: 22px; }

.r6s-text { display: grid; gap: 2px; min-width: 0; }
.r6s-text b {
	color: var(--text);
	font: 600 15px/1.25 "Inter Tight", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	letter-spacing: -.005em;
}
/* #a7b0bc on #0a0f1c measures 8.6:1 — comfortably past 4.5:1, and it is measured
   on the OPAQUE panel, which is the worst pixel that can exist here because the
   panel never lets the background through. */
.r6s-note {
	color: var(--muted);
	font: 500 11px/1.35 "Inter Tight", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	letter-spacing: .05em;
	text-transform: uppercase;
}

/* --- states --------------------------------------------------------------- */

/* (0,2,0) so it beats the base rule without !important. */
.r6s[data-r6-state="docked"] {
	transform: translateX(calc(100% - var(--r6s-tab)));
	box-shadow: none;
}
.r6s[data-r6-state="expanded"] {
	transform: translateX(0);
	/* The shadow exists only when the panel is out, so the docked sliver never
	   paints anything at all over page content. */
	box-shadow: -14px 0 36px rgba(0, 0, 0, .46);
}
.r6s[data-r6-state="expanded"] .r6s-chevron { transform: rotate(-135deg); }

/* No script: the control still opens, on hover and on keyboard focus, so the
   honest sentence is reachable without JS. `html.r6s-js` is added by
   round6-support.js on its first line, so exactly one of these paths is ever
   live. (0,3,1) beats the [data-r6-state] rules above, which is deliberate:
   with no script those attributes are frozen at "docked". */
html:not(.r6s-js) .r6s:hover,
html:not(.r6s-js) .r6s:focus-within { transform: translateX(0); }
html:not(.r6s-js) .r6s:hover .r6s-chevron,
html:not(.r6s-js) .r6s:focus-within .r6s-chevron { transform: rotate(-135deg); }

/* Only something that can act gets a pointer cursor. With the script running the
   whole tab answers a press (it opens); without it only the link does, and the
   browser already gives a link its cursor. */
html.r6s-js .r6s { cursor: pointer; }

.r6s:hover { border-color: var(--accent); }
/* Focus now lands on the link or the button INSIDE the wrapper (Round 7), and
   each draws its own ring in round7-support.css. The control is flush to the
   viewport edge, so part of any ring is off screen; the wrapper's border doubles
   as the indicator so the focused state is unmistakable on all four sides. */
.r6s:focus-within { border-color: var(--accent-bright); }

/* --- getting out of the way ---------------------------------------------- */

/* Bottom chrome. --p3box-h is the mix-box tray's MEASURED height (mix-box.js
   writes it to the root element), not a guessed constant, and 84px is the
   fallback round4-box.css itself uses. */
body.p3box-on .r6s { --r6s-floor: calc(var(--p3box-h, 84px) + 34px); }
body.compare-active .r6s { --r6s-lift: clamp(128px, 20vh, 200px); }

/* Overlays own the screen. The script docks for these already; these rules are
   the failure path — if the script errors after promoting the control, the
   markup still cannot sit on top of an open drawer, sheet, search or nav.
   (0,3,0) beats [data-r6-state="expanded"]'s (0,2,0). */
body.overlay-open .r6s[data-r6-state],
html.overlay-open .r6s[data-r6-state],
body.p3box-active .r6s[data-r6-state] {
	transform: translateX(calc(100% - var(--r6s-tab)));
	box-shadow: none;
}
body.p3box-active .r6s[data-r6-state] .r6s-chevron,
body.overlay-open .r6s[data-r6-state] .r6s-chevron { transform: rotate(45deg); }

@media print { .r6s { display: none; } }

/* Narrow phones: the body narrows, the 16px sliver does not. The sliver is the
   part that carries the collision guarantee, so it is the one number that must
   never respond to a breakpoint. */
@media (max-width: 420px) {
	.r6s { --r6s-panel: 212px; }
	.r6s-panel { padding: 12px 14px 12px 11px; gap: 10px; }
}

/* Honour reduced motion by NOT STARTING, not by going faster: both states are
   reached instantly and the two consecutive frames are identical. Last block in
   the sheet, so ordering alone carries it and no !important is used. */
@media (prefers-reduced-motion: reduce) {
	.r6s, .r6s-chevron { transition: none; }
}
