/* ══════════════════════════════════════════════════════════════════════════
   QQ SHELL — the front door, both houses.

   One stylesheet, two skins. Which one applies is decided by the data-house
   attribute PHP writes onto <html>, so nothing here is duplicated per build:

     [data-house="africa"]  — daylight. Cream, forest, terracotta.
     [data-house="qipqop"]  — warm night. Brass on oxblood, felt green.

   The structure below is identical in both. Only the tokens change, which is
   the whole point of running one codebase across two companies.
   ══════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────── tokens ───────────────────────── */

:root,
[data-house="africa"] {
	--forest: #0E3F28;
	--deep:   #05271A;
	--green:  #2E7D52;
	--amber:  #E0972F;
	--terra:  #C67139;
	--cream:  #F5EAD8;
	--ink:    #20402F;
	--line:   #E4D7C0;
	--muted:  #8A7D68;
	--paper:  #FBF7EE;

	/* roles the shell actually paints with */
	--sh-page:    #E7DCC8;
	--sh-screen:  var(--paper);
	--sh-bar:     var(--cream);
	--sh-card:    #fff;
	--sh-edge:    var(--line);
	--sh-text:    var(--ink);
	--sh-dim:     var(--muted);
	--sh-accent:  var(--terra);
	--sh-brand:   var(--forest);
	--sh-hover:   #F2EDE0;
	--sh-on:      #E9F2EC;
	--sh-on-bar:  var(--green);
	--sh-frame:   #111;
	--sh-glow:    rgba(5, 39, 26, .30);
	--sh-tile-sh: rgba(14, 63, 40, .14);
	--sh-scrim:   linear-gradient(to top, rgba(5,39,26,.95), rgba(5,39,26,.72) 40%, transparent);
	--sh-av:      rgba(245, 234, 216, .95);
	--sh-tile-b:  #CFE0D4;
	--sh-dots:    #D3C7AE;
}

[data-house="qipqop"] {
	--night:   #120C09;
	--room:    #1C1310;
	--card:    #241813;
	--edge:    #3A2A22;
	--brass:   #D99A3C;
	--oxblood: #7A2E35;
	--felt:    #2A5240;
	--cream:   #EDE2D2;
	--dim:     #A08D7C;

	--sh-page:    #0C0806;
	--sh-screen:  var(--night);
	--sh-bar:     var(--room);
	--sh-card:    var(--card);
	--sh-edge:    var(--edge);
	--sh-text:    var(--cream);
	--sh-dim:     var(--dim);
	--sh-accent:  var(--brass);
	--sh-brand:   var(--brass);
	--sh-hover:   #2B1D17;
	--sh-on:      #2B1D17;
	--sh-on-bar:  var(--brass);
	--sh-frame:   #000;
	--sh-glow:    rgba(217, 154, 60, .16);
	--sh-tile-sh: rgba(0, 0, 0, .5);
	--sh-scrim:   linear-gradient(to top, rgba(12,8,6,.96), rgba(12,8,6,.74) 42%, transparent);
	--sh-av:      rgba(237, 226, 210, .12);
	--sh-tile-b:  #C0AB98;
	--sh-dots:    #4A3629;
}

/* ───────────────────────── the stage ───────────────────────── */

html.qq-shell-html,
body.qq-shell-body {
	margin: 0;
	padding: 0;
	height: 100%;
	background: var(--sh-page);
}

body.qq-shell-body {
	font-family: Figtree, system-ui, -apple-system, "Segoe UI", sans-serif;
	color: var(--sh-text);
	-webkit-font-smoothing: antialiased;
	overscroll-behavior: none;
}

.qqs-stage {
	position: fixed;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

body.admin-bar .qqs-stage { top: 32px; }
@media (max-width: 782px) { body.admin-bar .qqs-stage { top: 46px; } }

/* Phone on the desktop, full bleed on the phone — same markup either way. */
.qqs-phone {
	width: 100%;
	height: 100%;
	background: var(--sh-frame);
	display: flex;
}

@media (min-width: 820px) {
	.qqs-stage { padding: 22px; }
	.qqs-phone {
		width: 394px;
		height: min(94vh, 940px);
		flex: 0 0 394px;
		border-radius: 38px;
		padding: 9px;
		box-shadow: 0 18px 46px var(--sh-glow);
	}
}

.qqs-screen {
	flex: 1;
	min-width: 0;
	background: var(--sh-screen);
	overflow: hidden;
	display: flex;
	flex-direction: column;
	position: relative;
}

@media (min-width: 820px) { .qqs-screen { border-radius: 30px; } }

/* The lamp over the QipQop table. Nothing but atmosphere, so it never
   intercepts a tap. */
[data-house="qipqop"] .qqs-screen::before {
	content: "";
	position: absolute;
	top: -90px; right: -70px;
	width: 280px; height: 280px;
	border-radius: 50%;
	background: radial-gradient(circle, rgba(217,154,60,.16), transparent 68%);
	pointer-events: none;
	z-index: 1;
}

/* ───────────────────────── top bar ───────────────────────── */

.qqs-tb {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 11px 13px;
	padding-top: max(11px, env(safe-area-inset-top));
	background: var(--sh-bar);
	border-bottom: 1px solid var(--sh-edge);
	flex: none;
	position: relative;
	z-index: 3;
}

.qqs-burger {
	width: 34px; height: 34px;
	border-radius: 10px;
	border: 1px solid var(--sh-edge);
	background: var(--sh-card);
	display: grid;
	place-items: center;
	cursor: pointer;
	flex: none;
	padding: 0;
}
.qqs-burger span {
	display: block;
	width: 15px; height: 2px;
	background: var(--sh-brand);
	border-radius: 2px;
	box-shadow: 0 5px 0 var(--sh-brand), 0 -5px 0 var(--sh-brand);
}

.qqs-id { min-width: 0; flex: 1; }
.qqs-id b {
	display: block;
	font-size: 14px;
	font-weight: 900;
	line-height: 1.1;
	color: var(--sh-brand);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
[data-house="qipqop"] .qqs-id b {
	font-family: Caprasimo, Georgia, serif;
	font-weight: 400;
	font-size: 16px;
	color: var(--cream);
}
.qqs-id small {
	display: block;
	font-size: 10px;
	color: var(--sh-dim);
	margin-top: 1px;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.qqs-pill {
	font-size: 10px;
	font-weight: 800;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 99px;
	padding: 5px 9px;
	flex: none;
	color: inherit;
	text-decoration: none;
}
[data-house="qipqop"] .qqs-pill { color: var(--brass); }

.qqs-pill--age {
	background: var(--oxblood, #7A2E35);
	border-color: transparent;
	color: #F6E5DE;
	font-size: 9px;
	font-weight: 900;
	letter-spacing: .04em;
}

/* ───────────────────── the world banner ─────────────────────
   You always know which world you are in, because it is written across the
   top of it in that world's own colour. */

.qqs-wb {
	display: flex;
	align-items: center;
	gap: 9px;
	padding: 9px 13px;
	color: #fff;
	flex: none;
	position: relative;
	z-index: 3;
	transition: background .25s ease;
}
[data-house="qipqop"] .qqs-wb { border-bottom: 1px solid var(--sh-edge); }

.qqs-wb .qqs-wb-ic { font-size: 19px; }
.qqs-wb b { font-size: 13.5px; font-weight: 900; display: block; }
.qqs-wb small { display: block; font-size: 10px; opacity: .82; font-weight: 600; }

.qqs-switch {
	margin-left: auto;
	font-size: 9.5px;
	font-weight: 800;
	letter-spacing: .05em;
	text-transform: uppercase;
	background: rgba(255,255,255,.2);
	border: 1px solid rgba(255,255,255,.32);
	color: #fff;
	border-radius: 99px;
	padding: 4px 9px;
	cursor: pointer;
	flex: none;
	font-family: inherit;
}

/* ───────────────────────── the body ───────────────────────── */

.qqs-body {
	flex: 1;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	padding: 12px 13px 14px;
	position: relative;
	z-index: 2;
}


.qqs-eyebrow {
	font-size: 9.5px;
	font-weight: 900;
	letter-spacing: .11em;
	text-transform: uppercase;
	color: var(--sh-brand);
	margin: 2px 0 8px;
	display: flex;
	align-items: center;
	gap: 6px;
}
.qqs-eyebrow i {
	width: 5px; height: 5px;
	border-radius: 50%;
	background: var(--sh-accent);
	font-style: normal;
	flex: none;
}

/* ─────────────── the reel rail: small, uniform, auto-sliding ───────────────
   112×158 instead of 266×420. Three fit on a screen instead of one and a
   fifth, which is the entire reason this redesign exists. */

.qqs-rail {
	display: flex;
	gap: 8px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	padding-bottom: 6px;
	margin-bottom: 4px;
	-webkit-overflow-scrolling: touch;
}
.qqs-rail::-webkit-scrollbar { height: 5px; }   /* themed below */

.qqs-tile {
	position: relative;
	flex: 0 0 auto;
	scroll-snap-align: start;
	width: 112px; height: 158px;
	border-radius: 14px;
	overflow: hidden;
	border: 0;
	padding: 0;
	cursor: pointer;
	font-family: inherit;
	text-align: left;
	display: block;
	color: inherit;
	text-decoration: none;
	box-shadow: 0 2px 8px var(--sh-tile-sh);
}
.qqs-tile .bg { position: absolute; inset: 0; }
.qqs-tile .scr {
	position: absolute; left: 0; right: 0; bottom: 0;
	height: 64%;
	background: var(--sh-scrim);
}
.qqs-tile .av {
	position: absolute;
	top: 9px; left: 50%;
	transform: translateX(-50%);
	width: 38px; height: 38px;
	border-radius: 50%;
	background: var(--sh-av);
	display: grid;
	place-items: center;
	font-size: 19px;
	background-size: cover;
	background-position: center;
}
.qqs-tile .pl {
	position: absolute;
	top: 7px; left: 7px;
	width: 16px; height: 16px;
	border-radius: 50%;
	background: rgba(245,234,216,.94);
	display: grid;
	place-items: center;
	font-size: 7px;
	color: var(--deep, #05271A);
}
.qqs-tile .tx { position: absolute; left: 8px; right: 8px; bottom: 7px; z-index: 2; }
.qqs-tile .tx b {
	display: block;
	font-size: 9.5px;
	font-weight: 900;
	color: #fff;
	line-height: 1.15;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qqs-tile .tx s {
	display: block;
	text-decoration: none;
	font-size: 8px;
	color: var(--sh-tile-b);
	margin-top: 1px;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qqs-tile .tx u {
	display: inline-block;
	text-decoration: none;
	font-size: 8.5px;
	font-weight: 900;
	color: var(--amber, #E0972F);
	margin-top: 3px;
}
[data-house="qipqop"] .qqs-tile .tx u { color: var(--brass); }

.qqs-dots { display: flex; gap: 4px; justify-content: center; margin: 2px 0 12px; }
.qqs-dots i {
	width: 4px; height: 4px;
	border-radius: 50%;
	background: var(--sh-dots);
	transition: width .2s ease, background .2s ease;
}
.qqs-dots i.on { width: 14px; border-radius: 99px; background: var(--sh-accent); }

/* ───────────────── hero: the page finally explains itself ───────────────── */

.qqs-hero {
	border-radius: 16px;
	padding: 15px;
	color: var(--cream);
	margin-bottom: 12px;
	background: linear-gradient(150deg, #2F7A54, #0E3F28 55%, #05271A);
}
[data-house="qipqop"] .qqs-hero { background: linear-gradient(150deg, #3A2118, #1A100C); }

.qqs-hero h3 {
	font-family: Caprasimo, Georgia, serif;
	font-weight: 400;
	font-size: 19px;
	margin: 0 0 6px;
	line-height: 1.2;
	color: #fff;
}
.qqs-hero p { margin: 0; font-size: 11.5px; line-height: 1.6; color: #DCC9AB; }
.qqs-hero .three { display: flex; gap: 6px; margin-top: 11px; }
.qqs-hero .three div {
	flex: 1;
	background: rgba(245,234,216,.12);
	border-radius: 9px;
	padding: 7px 8px;
}
.qqs-hero .three b { display: block; font-size: 10px; font-weight: 900; color: #fff; }
.qqs-hero .three small {
	font-size: 8.5px;
	color: #A7C4B0;
	line-height: 1.35;
	display: block;
	margin-top: 1px;
}
[data-house="qipqop"] .qqs-hero .three small { color: #C0AB98; }

/* ───────────────────── the worlds grid — the explanation ─────────────────── */

.qqs-worlds { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }

.qqs-w {
	display: flex;
	gap: 8px;
	align-items: center;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 12px;
	padding: 9px;
	cursor: pointer;
	font-family: inherit;
	text-align: left;
	color: inherit;
	text-decoration: none;
	transition: border-color .15s ease;
}
.qqs-w:hover, .qqs-w:focus-visible { border-color: var(--sh-accent); }
.qqs-w .ic {
	width: 32px; height: 32px;
	border-radius: 9px;
	display: grid;
	place-items: center;
	font-size: 17px;
	flex: none;
}
.qqs-w b { display: block; font-size: 11.5px; font-weight: 900; line-height: 1.15; }
.qqs-w small { display: block; font-size: 9px; color: var(--sh-dim); margin-top: 1px; line-height: 1.3; }

/* A world that is not open yet says so rather than opening an empty room. */
.qqs-w[data-status="planned"] { opacity: .74; }
.qqs-w[data-status="planned"] small::after { content: " · not open yet"; color: var(--sh-dim); }

/* ───────────────────── bottom nav — reframes per world ─────────────────────
   The same five positions everywhere. Inside Pets they mean pet things;
   inside Soko they mean market things. You are never lost because you are
   always somewhere. */

.qqs-bn {
	display: flex;
	background: var(--sh-bar);
	border-top: 1px solid var(--sh-edge);
	flex: none;
	padding: 5px 3px 7px;
	/* ── clearing the floating buttons ──────────────────────────────────
	   A WhatsApp bubble (and every other chat widget) parks itself bottom-right
	   at around 60px square with a 20px inset, directly on top of the fifth
	   door. The button was still there and still tappable by the browser — it
	   was simply invisible and unreachable by a thumb, which is worse than
	   missing, because nobody reports a button they cannot see.

	   The bar sits above that zone. `--qq-fab-clear` is one number to change if
	   a widget ever moves. */
	/* ── DO NOT LOWER THIS WITHOUT LOOKING AT A REAL PHONE ──────────────────
	   74px, because a THIRD-PARTY WhatsApp plugin parks a ~60px disc in the
	   bottom-right corner. It is not ours and never was.

	   I lowered this to 30px in v8.41.1 on the reasoning that our own help
	   button had moved into the top bar, so we were "no longer clearing our own
	   furniture". That reasoning was wrong: THE CLEARANCE WAS NEVER FOR OUR
	   FURNITURE. It was always for the plugin. The fifth door went straight
	   back under the bubble and he saw it on his phone within the hour.

	   Moving our button did not move the plugin's. */
	/* Default lives at the bottom of this file now: FLUSH, with the clearance
	   added back only when a floater is actually found. See "THE BAR SITS ON
	   THE FLOOR". */
	--qq-fab-clear: 10px;
	padding-bottom: max( var(--qq-fab-clear), calc( env(safe-area-inset-bottom) + var(--qq-fab-clear) ) );
	position: relative;
	z-index: 3;
}

/* Nothing floats over the last door. If a widget insists, it sits above the
   bar rather than on it. */
.qqs-screen [class*="whatsapp"],
.qqs-screen .wa-widget,
.qqs-screen .floating-wpp {
	bottom: calc( var(--qq-fab-clear, 74px) + 8px ) !important;
}

/* ── THE DOCK ──────────────────────────────────────────────────────────────
   The rule above lifts OTHER people's bubbles off the fifth door. It never
   applied to three of our own, because it matches on their class names and
   ours are not called whatsapp-anything: `.qqa-wa`, `.qqa-watip` and
   `.qqr-bubble` all sat at bottom:18px right:18px. We built a sweep to stop
   other people doing exactly this and then did it ourselves — and two of the
   three were at the SAME coordinates, so they also covered each other.

   Two slots, declared once. A third floater gets slot 3 here rather than a
   number picked in whichever file it lives in, which is how the first two
   ended up on top of one another. */
:root {
	--qq-dock-1: 66px;    /* first floater: clears the bar */
	--qq-dock-2: 132px;   /* second: clears the bar AND the first */
}

/* A desk has no thumb reach problem and no chat bubble in the way. */
@media (min-width: 820px) and (hover: hover) {
	.qqs-bn { padding-bottom: max(7px, env(safe-area-inset-bottom)); }
}
.qqs-bn button, .qqs-bn a {
	flex: 1;
	min-width: 0;
	border: 0;
	background: none;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	cursor: pointer;
	font-family: inherit;
	padding: 4px 1px;
	color: var(--sh-dim);
	text-decoration: none;
}
.qqs-bn .on { color: var(--sh-brand); }
.qqs-bn .i { font-size: 16px; line-height: 1; }
.qqs-bn .l {
	font-size: 8.5px;
	font-weight: 800;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 100%;
}
.qqs-bn .on .l { color: var(--sh-brand); }

/* A door that is present in every world but means something different in
   each one carries a quiet amber mark. */
.qqs-stick { position: relative; }
.qqs-stick::after {
	content: "";
	position: absolute;
	top: -2px; right: 8px;
	width: 4px; height: 4px;
	border-radius: 50%;
	background: var(--sh-accent);
}

/* ───────────────────────── the rail menu ─────────────────────────
   Every door in the house, grouped, collapsible, and honest about what is
   open. This is the map. */

.qqs-sheet {
	position: absolute;
	inset: 0;
	background: rgba(5, 39, 26, .5);
	z-index: 20;
	display: none;
}
[data-house="qipqop"] .qqs-sheet { background: rgba(0, 0, 0, .62); }
.qqs-sheet.open { display: block; }

.qqs-menu {
	position: absolute;
	left: 0; top: 0; bottom: 0;
	width: min(270px, 82%);
	background: var(--sh-screen);
	display: flex;
	flex-direction: column;
	animation: qqs-slide .18s ease-out;
}
@keyframes qqs-slide { from { transform: translateX(-16px); opacity: .4; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .qqs-menu { animation: none; } }

.qqs-mh { padding: 13px; border-bottom: 1px solid var(--sh-edge); background: var(--sh-bar); }
.qqs-mh b {
	display: block;
	font-family: Caprasimo, Georgia, serif;
	font-weight: 400;
	font-size: 17px;
	color: var(--sh-brand);
}
.qqs-mh small { font-size: 9.5px; color: var(--sh-dim); }

.qqs-ml { flex: 1; overflow-y: auto; padding: 8px 0; }


.qqs-grp {
	padding: 7px 13px 3px;
	font-size: 9px;
	font-weight: 900;
	letter-spacing: .11em;
	text-transform: uppercase;
	color: var(--sh-dim);
}

.qqs-mi {
	display: flex;
	align-items: center;
	gap: 9px;
	width: 100%;
	border: 0;
	background: none;
	padding: 8px 13px;
	cursor: pointer;
	font-family: inherit;
	text-align: left;
	color: var(--sh-text);
	text-decoration: none;
}
.qqs-mi:hover, .qqs-mi:focus-visible { background: var(--sh-hover); }
.qqs-mi.on { background: var(--sh-on); box-shadow: inset 3px 0 0 var(--sh-on-bar); }
.qqs-mi .ic { width: 24px; text-align: center; font-size: 15px; flex: none; }
.qqs-mi b { font-size: 12px; font-weight: 800; display: block; line-height: 1.2; }
.qqs-mi small { font-size: 9px; color: var(--sh-dim); display: block; }

.qqs-st {
	margin-left: auto;
	font-size: 7.5px;
	font-weight: 900;
	letter-spacing: .05em;
	text-transform: uppercase;
	border-radius: 99px;
	padding: 2px 6px;
	flex: none;
}
.qqs-st.live { background: #E8F4EC; color: #2C6046; }
.qqs-st.soon { background: #F0ECE2; color: #6B6357; }
.qqs-st.lic  { background: #F6E5DE; color: #7A2E35; }
[data-house="qipqop"] .qqs-st.live { background: rgba(42,82,64,.42); color: #BFE0CC; }
[data-house="qipqop"] .qqs-st.soon { background: rgba(160,141,124,.22); color: #C0AB98; }
[data-house="qipqop"] .qqs-st.lic  { background: rgba(122,46,53,.5); color: #F6E5DE; }

.qqs-sub { padding-left: 34px; }
.qqs-chev { margin-left: auto; font-size: 10px; color: var(--sh-dim); transition: transform .2s ease; flex: none; }
.qqs-mi.exp .qqs-chev { transform: rotate(90deg); }
.qqs-kids { display: none; }
.qqs-mi.exp + .qqs-kids { display: block; }

/* ─────────────────── cross-house promo, and its refusals ───────────────────
   The card is rendered by PHP (qq_promo_render / qq_way_out_render) so the
   rules live in one place. These are only its clothes. */

.qqs-slot { margin: 4px 0 12px; }
.qqs-slot .qq-xpromo, .qqs-slot .qq-wayout { margin: 0; }

.qqs-nopromo {
	background: #F2F7F3;
	border: 1px solid #CFE0D4;
	border-radius: 12px;
	padding: 11px 13px;
	margin: 4px 0 12px;
	font-size: 11.5px;
	color: #2C6046;
	line-height: 1.55;
}
[data-house="qipqop"] .qqs-nopromo {
	background: rgba(42,82,64,.22);
	border-color: rgba(42,82,64,.5);
	color: #BFE0CC;
}

/* ─────────────────── QipQop: the gates and the safer-play strip ───────────── */

.qqs-gate label {
	display: flex;
	gap: 9px;
	align-items: flex-start;
	margin: 12px 0 0;
	background: rgba(237,226,210,.07);
	border: 1px solid rgba(237,226,210,.18);
	border-radius: 11px;
	padding: 11px;
	cursor: pointer;
	font-size: 11.5px;
	line-height: 1.55;
	color: #C0AB98;
}
.qqs-gate label b { color: #EDE2D2; }
.qqs-gate input { margin-top: 2px; flex: none; }

.qqs-rg { display: flex; gap: 6px; margin-bottom: 12px; }
.qqs-rg button {
	flex: 1;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 11px;
	padding: 9px 5px;
	cursor: pointer;
	font-family: inherit;
	color: var(--sh-text);
}
.qqs-rg b { display: block; font-size: 10px; font-weight: 800; }
.qqs-rg small {
	display: block;
	font-size: 8px;
	font-weight: 900;
	letter-spacing: .06em;
	color: var(--sh-accent);
	margin-top: 2px;
}

.qqs-legal {
	font-size: 10px;
	line-height: 1.6;
	color: var(--sh-dim);
	border-top: 1px solid var(--sh-edge);
	margin-top: 14px;
	padding-top: 11px;
}

/* ───────────────────────── odds and ends ───────────────────────── */

.qqs-empty {
	background: var(--sh-card);
	border: 1px dashed var(--sh-edge);
	border-radius: 12px;
	padding: 14px;
	font-size: 11.5px;
	line-height: 1.6;
	color: var(--sh-dim);
	margin-bottom: 12px;
}

.qqs-skip {
	position: absolute;
	left: -9999px;
	top: 0;
	background: var(--sh-card);
	color: var(--sh-text);
	padding: 10px 14px;
	z-index: 40;
	border-radius: 0 0 10px 0;
}
.qqs-skip:focus { left: 0; }

:where(.qqs-screen) :focus-visible {
	outline: 2px solid var(--sh-accent);
	outline-offset: 2px;
}

/* Crawlable, not visible. The SEO copy the old front page carried is kept. */
.qqs-seo {
	position: absolute;
	width: 1px; height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
	padding: 0;
	margin: -1px;
}

@media (prefers-reduced-motion: reduce) {
	.qqs-rail { scroll-behavior: auto; }
	.qqs-wb { transition: none; }
}

/* ══════════════════════════ the screens ══════════════════════════════════
   Everything below dresses what qq-shell-screens.php renders. The furniture is
   deliberately plain: a screen's job is to show what the engine knows, and an
   engine that knows nothing yet should look like it, not like a loading state
   that never finishes. */

.qqs-sh { margin: 2px 0 12px; }
.qqs-sh h2 {
	font-family: Caprasimo, Georgia, serif;
	font-weight: 400;
	font-size: 20px;
	margin: 0 0 4px;
	color: var(--sh-brand);
	line-height: 1.2;
}
.qqs-sh p { margin: 0; font-size: 12px; line-height: 1.55; color: var(--sh-dim); }

.qqs-p    { font-size: 12.5px; line-height: 1.6; color: var(--sh-text); margin: 0 0 12px; }
.qqs-note {
	font-size: 11px;
	line-height: 1.6;
	color: var(--sh-dim);
	margin: 10px 0 12px;
	padding-left: 10px;
	border-left: 2px solid var(--sh-edge);
}

/* rows */
.qqs-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.qqs-row {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 12px;
	padding: 10px 11px;
	font-family: inherit;
	text-align: left;
	color: inherit;
}
button.qqs-row { cursor: pointer; }
button.qqs-row:hover, button.qqs-row:focus-visible { border-color: var(--sh-accent); }
.qqs-row .ic { font-size: 18px; flex: none; width: 22px; text-align: center; }
.qqs-row .tx { min-width: 0; flex: 1; }
.qqs-row .tx b { display: block; font-size: 12px; font-weight: 800; line-height: 1.25; }
.qqs-row .tx small { display: block; font-size: 10px; color: var(--sh-dim); line-height: 1.4; margin-top: 1px; }
.qqs-row .mt {
	margin-left: auto;
	flex: none;
	font-size: 10.5px;
	font-weight: 900;
	color: var(--sh-accent);
	white-space: nowrap;
}

/* tiles */
.qqs-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
.qqs-tl {
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 12px;
	padding: 11px 10px;
	cursor: pointer;
	font-family: inherit;
	text-align: left;
	color: inherit;
}
.qqs-tl:hover, .qqs-tl:focus-visible { border-color: var(--sh-accent); }
.qqs-tl .ic { font-size: 19px; display: block; margin-bottom: 5px; }
.qqs-tl b { display: block; font-size: 11.5px; font-weight: 900; line-height: 1.2; }
.qqs-tl small { display: block; font-size: 9.5px; color: var(--sh-dim); line-height: 1.35; margin-top: 2px; }

/* the honest empty state */
.qqs-empty b { display: block; font-size: 13px; font-weight: 800; color: var(--sh-text); margin-bottom: 4px; }
.qqs-empty p { margin: 0; font-size: 11.5px; line-height: 1.6; color: var(--sh-dim); }

/* a gate: shown INSTEAD of the goods, and it always gives the reason */
.qqs-gatecard {
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-left: 4px solid var(--sh-accent);
	border-radius: 12px;
	padding: 13px 14px;
	margin-bottom: 12px;
}
.qqs-gatecard .lk {
	display: inline-block;
	font-size: 8.5px;
	font-weight: 900;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--sh-dim);
	margin-bottom: 6px;
}
.qqs-gatecard b { display: block; font-size: 13px; font-weight: 800; margin-bottom: 4px; }
.qqs-gatecard p { margin: 0; font-size: 11.5px; line-height: 1.6; color: var(--sh-dim); }
.qqs-gatecard small {
	display: block;
	font-size: 10px;
	color: var(--sh-dim);
	margin-top: 7px;
	opacity: .85;
}

/* the discretion promise on the QipQop Soko */
.qqs-promise {
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 12px;
	padding: 12px 13px;
	margin-bottom: 12px;
}
.qqs-promise b { display: block; font-size: 12px; font-weight: 900; margin-bottom: 4px; }
.qqs-promise p { margin: 0; font-size: 11.5px; line-height: 1.6; }
.qqs-promise small { display: block; font-size: 10px; color: var(--sh-dim); margin-top: 6px; line-height: 1.5; }

/* two numbers side by side — the wallet */
.qqs-stat2 { display: flex; gap: 8px; margin-bottom: 12px; }
.qqs-stat2 div {
	flex: 1;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 12px;
	padding: 11px;
	text-align: center;
}
.qqs-stat2 b { display: block; font-size: 20px; font-weight: 900; color: var(--sh-brand); line-height: 1.1; }
.qqs-stat2 small { display: block; font-size: 9.5px; color: var(--sh-dim); margin-top: 3px; }

.qqs-cta {
	display: inline-block;
	background: var(--sh-brand);
	color: var(--sh-screen);
	border: 0;
	border-radius: 11px;
	padding: 10px 16px;
	font-family: inherit;
	font-size: 12.5px;
	font-weight: 800;
	cursor: pointer;
	margin-top: 10px;
}
.qqs-cta.ghost {
	background: transparent;
	color: var(--sh-brand);
	border: 1px solid var(--sh-edge);
}
[data-house="qipqop"] .qqs-cta { color: #120C09; }

.qqs-loading {
	font-size: 12px;
	color: var(--sh-dim);
	padding: 26px 0;
	text-align: center;
}

/* ═══════════════ the showcase row, and the reel it lands in ═══════════════
   A bought slot is labelled. Always, everywhere, without exception — a member
   has to be able to tell at a glance which cards were paid for, or the row
   stops being worth watching and the whole engine loses its value. */

.qqs-badge {
	position: absolute;
	top: 7px; right: 7px;
	z-index: 3;
	font-size: 7px;
	font-weight: 900;
	letter-spacing: .06em;
	text-transform: uppercase;
	background: rgba(245, 234, 216, .93);
	color: var(--deep, #05271A);
	border-radius: 99px;
	padding: 2px 6px;
	max-width: 74%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
[data-house="qipqop"] .qqs-badge { background: rgba(237, 226, 210, .9); color: #120C09; }

/* our own product, advertised by us, inside our own house */
.qqs-ours {
	display: block;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-left: 4px solid var(--sh-brand);
	border-radius: 12px;
	padding: 13px 14px;
	margin: 4px 0 12px;
}
.qqs-ours .k {
	font-size: 9px;
	font-weight: 900;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--sh-dim);
}
.qqs-ours b { display: block; font-size: 13.5px; margin: 5px 0 3px; color: var(--sh-text); }
.qqs-ours p { margin: 0; font-size: 11.5px; color: var(--sh-dim); line-height: 1.55; }
.qqs-ours .qqs-cta { margin-top: 9px; }

/* the reel stage — one card, full width, the thing to buy attached to it */
.qqs-reelstage {
	position: relative;
	border-radius: 16px;
	overflow: hidden;
	aspect-ratio: 4 / 5;
	margin-bottom: 12px;
	display: flex;
	align-items: flex-end;
}
.qqs-reelstage img {
	position: absolute;
	inset: 0;
	width: 100%; height: 100%;
	object-fit: cover;
}
.qqs-reelstage .cap {
	position: relative;
	z-index: 2;
	width: 100%;
	padding: 14px;
	background: var(--sh-scrim);
}
.qqs-reelstage .cap b {
	display: block;
	font-size: 16px;
	font-weight: 900;
	color: #fff;
	line-height: 1.2;
}
.qqs-reelstage .cap u {
	display: block;
	text-decoration: none;
	font-size: 13px;
	font-weight: 900;
	color: var(--amber, #E0972F);
	margin-top: 4px;
}
[data-house="qipqop"] .qqs-reelstage .cap u { color: var(--brass); }

/* the engine's own doors, at the top of the menu, when it is finished */
.qqs-grp--engine {
	color: var(--sh-brand);
	background: var(--sh-on);
	margin-bottom: 2px;
	padding-top: 9px;
	padding-bottom: 5px;
}

/* the centre of the bar is the engine: raised, and unmistakable */
.qqs-bn .qqs-navi:nth-child(3) { position: relative; }
.qqs-bn .qqs-navi:nth-child(3) .i {
	font-size: 20px;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 50%;
	width: 42px; height: 42px;
	display: grid;
	place-items: center;
	margin-top: -14px;
	box-shadow: 0 3px 10px var(--sh-tile-sh);
}
.qqs-bn .qqs-navi:nth-child(3).on .i {
	background: var(--sh-brand);
	border-color: var(--sh-brand);
}

/* ═══════════════════════════ the scrollbar ════════════════════════════════
   The rail menu holds thirty-one doors and the body holds a whole screen, and
   until now both scrolled with the bar hidden. That is fine under a thumb,
   which tells you there is more, and actively disorienting with a mouse, where
   nothing does. Somebody who cannot see that a list continues assumes it has
   ended — and half our doors were below the fold.

   So: a real bar, in the house's own colours, wide enough to grab and distinct
   enough to read against the paper behind it. Always visible rather than fading
   in on hover, because an affordance that only appears once you have already
   guessed it is there is not an affordance. */

[data-house="africa"] {
	--sh-track: #EFE6D4;
	--sh-thumb: #B9A886;
	--sh-thumb-hover: var(--terra);
}
[data-house="qipqop"] {
	--sh-track: #1A120E;
	--sh-thumb: #4E3A2C;
	--sh-thumb-hover: var(--brass);
}

/* Modern engines: the standard properties. Chrome 121+ and Firefox both honour
   these, and when they are set Chrome IGNORES ::-webkit-scrollbar entirely — so
   the legacy block below is fenced behind @supports rather than sitting
   alongside them, which is what silently produced a zero-width bar the first
   time round.

   `auto`, not `thin`: this bar is meant to be seen and grabbed. */
.qqs-body,
.qqs-ml {
	scrollbar-width: auto;
	scrollbar-color: var(--sh-thumb) var(--sh-track);
}
.qqs-rail {
	scrollbar-width: thin;
	scrollbar-color: var(--sh-thumb) transparent;
}

/* Older WebKit (Safari, and Chrome before 121) has no standard property, so it
   gets the pseudo-elements instead. */
@supports not (scrollbar-color: auto) {
	.qqs-body::-webkit-scrollbar,
	.qqs-ml::-webkit-scrollbar {
		width: 11px;
	}
	.qqs-body::-webkit-scrollbar-track,
	.qqs-ml::-webkit-scrollbar-track {
		background: var(--sh-track);
		border-radius: 99px;
		margin: 4px 0;
	}
	.qqs-body::-webkit-scrollbar-thumb,
	.qqs-ml::-webkit-scrollbar-thumb {
		background: var(--sh-thumb);
		border-radius: 99px;
		border: 2px solid var(--sh-track);
		min-height: 34px;                 /* never a dot you cannot grab */
	}
	.qqs-body::-webkit-scrollbar-thumb:hover,
	.qqs-body::-webkit-scrollbar-thumb:active,
	.qqs-ml::-webkit-scrollbar-thumb:hover,
	.qqs-ml::-webkit-scrollbar-thumb:active {
		background: var(--sh-thumb-hover);
	}
	.qqs-rail::-webkit-scrollbar { height: 5px; }
	.qqs-rail::-webkit-scrollbar-track { background: transparent; }
	.qqs-rail::-webkit-scrollbar-thumb { background: var(--sh-thumb); border-radius: 99px; }
}

/* Under a thumb there is no bar to draw, so the menu says so instead: a soft
   fade at the bottom edge while there is further to go. */
.qqs-menu { position: absolute; }
.qqs-ml::after {
	content: "";
	position: sticky;
	bottom: 0;
	display: block;
	height: 26px;
	margin-top: -26px;
	pointer-events: none;
	background: linear-gradient(to top, var(--sh-screen), transparent);
}

/* ═══════════════════════ show me around · before you leave ════════════════ */

.qqs-tour { position: absolute; inset: 0; }
/* The scrim sits under the spotlit element; the card sits over it. Getting
   this order wrong put the lit element on top of the whole tour — which is
   exactly what happened when a step spotlit the body itself. */
.qqs-tour-scrim { position: absolute; inset: 0; z-index: 60; background: rgba(5, 39, 26, .55); }
[data-house="qipqop"] .qqs-tour-scrim { background: rgba(0, 0, 0, .66); }

/* The thing being described stays lit above the scrim — the tour points at the
   interface, it does not draw a picture of it. */
.qqs-lit {
	position: relative;
	z-index: 61;
	border-radius: 12px;
	box-shadow: 0 0 0 3px var(--sh-accent), 0 0 0 12px rgba(224, 151, 47, .22);
}

.qqs-tour-card {
	position: absolute;
	left: 13px; right: 13px;
	z-index: 62;
	background: var(--sh-screen);
	border: 1px solid var(--sh-edge);
	border-radius: 14px;
	padding: 14px 15px;
	box-shadow: 0 14px 34px rgba(0, 0, 0, .3);
}
.qqs-tour-n {
	font-size: 9px;
	font-weight: 900;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--sh-dim);
	margin-bottom: 5px;
}
.qqs-tour-card b {
	display: block;
	font-family: Caprasimo, Georgia, serif;
	font-weight: 400;
	font-size: 17px;
	color: var(--sh-brand);
	line-height: 1.2;
	margin-bottom: 5px;
}
.qqs-tour-card p { margin: 0; font-size: 12px; line-height: 1.6; color: var(--sh-dim); }
.qqs-tour-act { display: flex; gap: 8px; margin-top: 12px; }
.qqs-tour-act .qqs-cta { margin-top: 0; flex: 1; }

.qqs-leave { position: absolute; inset: 0; z-index: 70; display: flex; align-items: flex-end; }
.qqs-leave-scrim { position: absolute; inset: 0; background: rgba(5, 39, 26, .55); }
[data-house="qipqop"] .qqs-leave-scrim { background: rgba(0, 0, 0, .7); }

.qqs-leave-card {
	position: relative;
	z-index: 71;
	width: 100%;
	background: var(--sh-screen);
	border-top: 3px solid var(--sh-brand);
	border-radius: 18px 18px 0 0;
	padding: 18px 16px 16px;
	animation: qqs-rise .2s ease-out;
}
@keyframes qqs-rise { from { transform: translateY(22px); opacity: .5; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .qqs-leave-card { animation: none; } }

.qqs-leave-x {
	position: absolute;
	top: 9px; right: 11px;
	background: none;
	border: 0;
	font-size: 22px;
	line-height: 1;
	color: var(--sh-dim);
	cursor: pointer;
	padding: 4px 8px;
}
.qqs-leave-card .k {
	font-size: 9px;
	font-weight: 900;
	letter-spacing: .09em;
	text-transform: uppercase;
	color: var(--sh-dim);
}
.qqs-leave-card b {
	display: block;
	font-family: Caprasimo, Georgia, serif;
	font-weight: 400;
	font-size: 19px;
	color: var(--sh-brand);
	line-height: 1.2;
	margin: 6px 0 6px;
}
.qqs-leave-card p { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--sh-dim); }
.qqs-leave-act { display: flex; gap: 8px; margin-top: 13px; }
.qqs-leave-act .qqs-cta { margin-top: 0; flex: 1; }

/* Saying no is a plain, full-width, obvious control — not grey text hidden in a
   corner. If the refusal is harder to find than the acceptance, the card is a
   trick, and neither house is running tricks. */
.qqs-leave-no {
	display: block;
	width: 100%;
	margin-top: 9px;
	background: none;
	border: 0;
	padding: 9px;
	font-family: inherit;
	font-size: 12.5px;
	font-weight: 700;
	color: var(--sh-dim);
	cursor: pointer;
	text-decoration: underline;
}
.qqs-leave-card .q {
	font-size: 10.5px;
	color: var(--sh-dim);
	margin-top: 6px;
	text-align: center;
	line-height: 1.5;
}

/* ── the drawn scrollbar ──────────────────────────────────────────────────
   Native bars are hidden on phones, faded on macOS and ignored by Chrome when
   scrollbar-color is set, so the shell draws its own and this is what a member
   actually sees. Wide enough for a thumb, in the house's own colours, and it
   disappears only when there is genuinely nothing below. */

.qqs-sb {
	position: absolute;
	top: 6px; right: 3px; bottom: 6px;
	width: 8px;
	border-radius: 99px;
	background: var(--sh-track);
	opacity: 0;
	pointer-events: none;
	transition: opacity .15s ease;
	z-index: 5;
}
.qqs-sb.on { opacity: 1; pointer-events: auto; }

.qqs-sb-thumb {
	position: absolute;
	left: 0; top: 0;
	width: 100%;
	border-radius: 99px;
	background: var(--sh-thumb);
	cursor: grab;
	touch-action: none;
	transition: background .15s ease;
}
.qqs-sb-thumb:hover,
.qqs-sb.drag .qqs-sb-thumb { background: var(--sh-thumb-hover); }
.qqs-sb.drag .qqs-sb-thumb { cursor: grabbing; }

/* Inside the rail menu it sits against the menu's own paper. */
.qqs-menu .qqs-sb { right: 2px; }

@media (prefers-reduced-motion: reduce) {
	.qqs-sb, .qqs-sb-thumb { transition: none; }
}

/* ── forms: safer play, and anything else that writes ── */
.qqs-form { margin-bottom: 12px; }
.qqs-field {
	display: flex;
	align-items: center;
	gap: 10px;
	background: var(--sh-card);
	border: 1px solid var(--sh-edge);
	border-radius: 12px;
	padding: 9px 11px;
	margin-bottom: 7px;
}
.qqs-field span { font-size: 12px; font-weight: 800; flex: 1; }
.qqs-field input {
	width: 118px;
	background: var(--sh-screen);
	border: 1px solid var(--sh-edge);
	border-radius: 8px;
	padding: 7px 9px;
	font-family: inherit;
	font-size: 13px;
	color: var(--sh-text);
	text-align: right;
}
.qqs-tl.on { border-color: var(--sh-accent); box-shadow: inset 0 0 0 1px var(--sh-accent); }
.qqs-note.ok  { color: var(--sh-brand); border-left-color: var(--sh-brand); }
.qqs-note.bad { color: #b32d2e; border-left-color: #b32d2e; }

/* the player */
.qqs-player { position: relative; border-radius: 16px; overflow: hidden; margin-bottom: 12px; background: #000; }
.qqs-player .qqr-media, .qqs-player video, .qqs-player iframe {
	display: block; width: 100%; aspect-ratio: 9 / 16; border: 0; object-fit: cover;
}
.qqs-player-cap {
	position: absolute; left: 0; right: 0; bottom: 0;
	padding: 14px; background: var(--sh-scrim);
}
.qqs-player-cap b { display: block; font-size: 15px; font-weight: 900; color: #fff; }
.qqs-player-cap small { display: block; font-size: 10.5px; color: #CFE0D4; margin-top: 3px; }
.qqs-row--buy .qqs-cta { margin-top: 0; padding: 7px 13px; font-size: 11.5px; }

/* ── the world picker scrolls too ──────────────────────────────────────────
   Eight worlds fit. Twelve do not, and the count only goes up — a new world is
   a line in the taxonomy, so this grid has to survive growth without pushing
   the reels off the bottom of the screen.

   So it caps its own height and scrolls, with the same drawn bar as the menu.
   The cap is generous enough that a short list never scrolls at all: nothing
   here clips a grid that already fits. */

.qqs-worlds {
	/* Capped low enough that the reel rail above it is never pushed off screen.
	   The picker scrolls; the reels do not get buried. */
	max-height: 34vh;
	overflow-y: auto;
	position: relative;
	padding-right: 12px;      /* room for the bar, so it never sits on a card */
	scrollbar-width: none;    /* the drawn bar replaces the native one */
}
.qqs-worlds::-webkit-scrollbar { width: 0; }

/* The picker's bar sits inside the grid rather than beside the body's. */
.qqs-worlds + .qqs-sb,
.qqs-worlds ~ .qqs-sb { right: 1px; }

@media (min-height: 780px) {
	.qqs-worlds { max-height: 42vh; }
}

/* listing photos — a horizontal strip, same rail as everything else */
.qqs-rail--photos { gap: 6px; margin-bottom: 10px; }
.qqs-photo {
	flex: 0 0 auto;
	width: 148px; height: 108px;
	border-radius: 12px;
	background-size: cover;
	background-position: center;
	scroll-snap-align: start;
	border: 1px solid var(--sh-edge);
}

/* ══════════════════════════ the rail, as a component ══════════════════════
   Swipe on touch (native scroll — smoother than anything hand written, and it
   already respects the platform), drag with a mouse, arrows, dots, keyboard.
   The same component whichever engine filled it. */

.qqs-railwrap { position: relative; }

.qqs-rail { cursor: grab; scroll-behavior: smooth; }
.qqs-rail.dragging { cursor: grabbing; scroll-behavior: auto; scroll-snap-type: none; }
.qqs-rail.dragging .qqs-tile { pointer-events: none; }
.qqs-rail:focus-visible { outline: 2px solid var(--sh-accent); outline-offset: 3px; border-radius: 14px; }

/* Arrows are for pointers. A thumb has the whole rail to swipe, so they only
   appear where there is a cursor to use them. */
.qqs-railarrow {
	position: absolute;
	top: 62px;
	z-index: 4;
	width: 28px; height: 28px;
	border-radius: 50%;
	border: 1px solid var(--sh-edge);
	background: var(--sh-card);
	color: var(--sh-brand);
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
	display: none;
	place-items: center;
	box-shadow: 0 2px 8px var(--sh-tile-sh);
	padding: 0;
}
.qqs-railarrow.prev { left: -6px; }
.qqs-railarrow.next { right: -6px; }
.qqs-railarrow:hover { border-color: var(--sh-accent); }

@media (hover: hover) and (pointer: fine) {
	.qqs-railwrap:hover .qqs-railarrow { display: grid; }
}

/* Dots are controls now, not decoration — each one goes to its card, so each
   one has to be big enough to hit. */
.qqs-dots button {
	width: 6px; height: 6px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--sh-dots);
	cursor: pointer;
	transition: width .2s ease, background .2s ease;
	position: relative;
}
/* A 6px dot is not a tap target; this gives it 24px without moving anything. */
.qqs-dots button::after {
	content: "";
	position: absolute;
	inset: -9px;
}
.qqs-dots button.on { width: 16px; border-radius: 99px; background: var(--sh-accent); }
.qqs-dots button:focus-visible { outline: 2px solid var(--sh-accent); outline-offset: 3px; }

/* A representative card says so, quietly. It is not a member's real reel and it
   should never be mistaken for one. */
.qqs-rep {
	position: absolute;
	top: 8px; right: 8px;
	z-index: 3;
	width: 5px; height: 5px;
	border-radius: 50%;
	background: rgba(245, 234, 216, .5);
	font-size: 0;
	overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
	.qqs-rail { scroll-behavior: auto; }
	.qqs-dots button { transition: none; }
}


/* ── help, in the bar ─────────────────────────────────────────────────────
   Option A. Green among cream, so it reads as the one different thing in the
   row without needing to float over anything. */
.qqs-pill--wa{
	background:#25D366;
	border-color:#1FAE53;
	color:#fff;
	font-size:13px;
	line-height:1;
	padding:6px 10px;
	text-decoration:none;
	display:inline-flex;
	align-items:center;
	/* A 44px target without a 44px pill. */
	position:relative;
}
.qqs-pill--wa::after{content:"";position:absolute;inset:-7px}
.qqs-pill--wa:hover{background:#1FAE53}
[data-house="qipqop"] .qqs-pill--wa{background:#1FAE53;border-color:#188C42}

/* ── the help pill before a number is set ─────────────────────────────────
   Only an admin ever sees this state. A member with no number configured gets
   no button at all, because a button that opens a chat with nobody is worse
   than no button. */
.qqs-pill--unset{background:#8A7D68;border-color:#6F6552;opacity:.85}

/* ── the basket, in the bar ───────────────────────────────────────────────
   Count AND total. A cart showing only a count makes somebody open it just to
   find out what they have spent. */
.qqs-pill--cart{cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;gap:5px}
.qqs-pill--cart .n{font-variant-numeric:tabular-nums}
.qqs-pill--cart .t{
	font-variant-numeric:tabular-nums;
	padding-left:5px;margin-left:1px;
	border-left:1px solid var(--sh-edge);
	opacity:.9;
}
.qqs-pill--cart.has{background:var(--sh-brand);border-color:var(--sh-brand);color:var(--sh-bar)}
.qqs-pill--cart.has .t{border-left-color:rgba(255,255,255,.3)}
.qqs-pill--cart:active{transform:scale(.96)}

/* it just changed — say so without a bounce that fights reduced motion */
.qqs-pill--cart.bump{animation:qqsBump .32s ease}
@keyframes qqsBump{0%{transform:scale(1)}40%{transform:scale(1.14)}100%{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.qqs-pill--cart.bump{animation:none}}

/* ── HIDING SOMEBODY ELSE'S FLOATING BUBBLE ───────────────────────────────
   Opt-in, via QQ Setup. Off by default, because hiding another plugin's UI
   without being asked is rude and hard to debug — somebody would spend an
   afternoon wondering why their plugin "stopped working".

   Two WhatsApp buttons on one screen is worse than either alone: the member
   cannot tell which one reaches a human, and one of them may go somewhere we
   do not control. Ours sits in the top bar where it cannot cover a door.

   The selectors are the common WhatsApp-plugin roots. Anything not on this
   list keeps working exactly as before — this hides, it never disables. */
body.qq-hide-fab .ht-ctc-chat,
body.qq-hide-fab .joinchat,
body.qq-hide-fab .wa__floating_button,
body.qq-hide-fab .wa-chat-box,
body.qq-hide-fab #whatsapp-chat-widget,
body.qq-hide-fab .whatsapp-chat-widget,
body.qq-hide-fab .qlwapp,
body.qq-hide-fab .ws-float-button {
	display: none !important;
}


/* ── THE ROW SITS FLUSH ───────────────────────────────────────────────────
   Approved 5 Aug 2026: help beside KES, bottom row flush.

   These were never two changes. The 74px gap exists for exactly one reason —
   to keep the fifth door out from under a third-party WhatsApp disc. Hide the
   disc and the reason is gone with it, so the row can sit where it belongs.

   Tying them to ONE class rather than two settings means they cannot disagree:
   there is no state where the bubble is showing AND the door is buried, and
   none where the bubble is gone AND 74px of every screen is still being spent
   on it. Turn the switch off in QQ Setup and BOTH revert together.

   10px, not 0 — the home indicator on a modern phone needs somewhere to be,
   and `env(safe-area-inset-bottom)` is added on top of this by the rule above. */
body.qq-hide-fab {
	--qq-fab-clear: 10px;
}

/* Hidden by the sweep (assets/js/qq-fab-sweep.js). A class, not an inline
   style, so turning the setting off restores the element untouched. */
.qq-fab-hidden { display: none !important; }

/* ── THE LIVE-LOCATION PULSE ──────────────────────────────────────────────
   Borrowed from the floating disc we just stopped rendering. That button was
   wrong in every other way — it sat on the fifth door — but the pulse was
   right: a ring that says somebody is actually at the other end, the way a
   live-location pin does.

   THREE PULSES, THEN IT RESTS. The original ran forever. On a disc you meet
   once that is fine; in a top bar that is on EVERY page it becomes wallpaper —
   people stop seeing it, which is the opposite of what it is for — and a thing
   that moves forever in the corner of your eye is tiring on a long scroll.
   Three says hello; infinity nags. */
.qqs-pill--wa{ position:relative; overflow:visible; }

.qqs-ping{
	position:absolute;
	inset:0;
	border-radius:99px;
	border:2px solid #25D366;
	animation:qqsping 2.6s ease-out 3;
	opacity:0;
	pointer-events:none;   /* it must never eat the tap it is advertising */
}

@keyframes qqsping{
	0%   { transform:scale(1);    opacity:.75 }
	70%  { transform:scale(1.55); opacity:0 }
	100% { opacity:0 }
}

/* An animation nobody asked for is one some people cannot tolerate. */
@media (prefers-reduced-motion: reduce){
	.qqs-ping{ animation:none; opacity:0 }
}

/* An unset button is a note to the admin, not a live line. Nothing pulses. */
.qqs-pill--unset .qqs-ping{ display:none }


/* ── OPTION B: the word ───────────────────────────────────────────────────
   "?" alone is a symbol; "? Help" is an instruction. The tagline beside the
   brand truncates to pay for it, which is the right trade — a tagline is
   decoration, a help button is not. */
.qqs-pill--wa{ gap:4px; font-weight:900 }
.qqs-pill--wa .qqs-pill-t{ font-size:10px; letter-spacing:.01em }

/* On the narrowest phones the word still wins; the tagline disappears first. */
@media (max-width:340px){
	.qqs-tb .qqs-brand small{ display:none }
}

/* ── THE BAR SITS ON THE FLOOR ────────────────────────────────────────────
   The gap under the five doors was PADDING INSIDE THE BAR, reserved for a
   floating disc. We no longer render one, and the sweep hides other people's,
   so reserving that space by default meant paying 74px on every screen for a
   button that is usually not there.

   INVERTED: flush is the default, and the clearance is added back ONLY when
   the sweep actually finds a floater it could not hide. The page no longer
   assumes a problem it cannot see. */
:root{ --qq-fab-clear: 10px; }

body.qq-fab-present{ --qq-fab-clear: 74px; }

/* ── THE BELL ─────────────────────────────────────────────────────────────
   A count, not a dot. "3" tells you whether to look now; a dot makes you open
   it to find out, which is a tax on every glance. */
.qqs-pill--bell{ cursor:pointer; font-family:inherit; font-size:13px; padding:5px 9px; position:relative }
.qqs-pill--bell .n{
	position:absolute; top:-5px; right:-5px;
	min-width:16px; height:16px; padding:0 4px;
	border-radius:99px; background:#C0392B; color:#fff;
	font-size:9.5px; font-weight:900; line-height:16px; text-align:center;
	border:2px solid var(--qqs-card, #FDFBF6);
	font-variant-numeric:tabular-nums;
}
.qqs-pill--bell.has{ border-color:#C0392B }

/* the panel */
.qqn-list{ display:flex; flex-direction:column; gap:8px }
.qqn{
	display:block; text-decoration:none; color:inherit;
	background:var(--qqs-card,#FDFBF6); border:1px solid var(--qqs-edge,#E4D7C0);
	border-radius:13px; padding:11px 13px;
}
.qqn--new{ border-left:3px solid var(--qqs-accent,#C67139) }
.qqn-k{ display:block; font-size:9px; font-weight:900; letter-spacing:.1em;
	text-transform:uppercase; color:var(--qqs-dim,#8A7D68) }
.qqn b{ display:block; font-size:14px; margin-top:2px }
.qqn-l{ display:block; font-size:12.5px; color:var(--qqs-dim,#8A7D68); margin-top:2px; line-height:1.45 }
.qqn-w{ display:block; font-size:10.5px; color:var(--qqs-dim,#8A7D68); margin-top:5px }

/* ── the 18+ declaration ─────────────────────────────────────────────
   Both answers get the same weight. If one is easier to press than the
   other, the number collected is a funnel, not a declaration. */
.qqs-agebtns { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.qqs-agebtns .qqs-cta { flex: 1 1 auto; min-width: 44%; min-height: 44px; text-align: center; }
.qqs-ageblocked { text-align: left; }
.qqs-ageblocked b { display: block; margin-bottom: 6px; }
