/* ══════════════════════════════════════════════════════════════════════════
   CARD CRAFT.

   The shell's cards were solid fills with a 1px border and a 12px radius —
   correct, legible, and indistinguishable from every other product built this
   decade. This layer gives them a material.

   THE MATERIAL IS PAPER, and specifically the paper this company already lives
   on: a receipt, a ledger page, a ticket stub, a rubber stamp. Fanikiwa counts
   a month down to the matchbox and the salt; QQ Soko publishes what a thing
   costs elsewhere. Those are receipt gestures. So the cards are receipts.

   It is not decoration for its own sake — each move carries meaning:

     ledger rule      a list of costs reads as a ledger, because it is one
     ticket notch     anything with a price is a stub you could tear off
     stamp            a verdict was made by somebody, and it shows
     corner fold      this card was placed here by a seller who paid
     perforation      a gate is a page torn out, not a wall

   On QipQop the same grammar runs at night: the paper is dark card stock, the
   rules are brass, the stamp is oxblood. Same craft, different hour.

   NOTHING HERE CHANGES MARKUP. Every rule attaches to classes that already
   exist, so no JS, no PHP and no test has to know this file arrived.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the reset the shell never had ──────────────────────────────────────
   `.qqs-row` is width:100% with padding and a border. Without border-box that
   is 100% PLUS the padding, and every ledger row ran past the right edge. The
   shell stylesheet never set this and the production page happened to inherit
   it from elsewhere — which is exactly the kind of luck that stops being lucky
   the first time a component is used somewhere new. */

.qqs-body, .qqs-body *, .qqs-screen, .qqs-screen *,
.rvp, .rvp *, .qqsh, .qqsh *, .qqb, .qqb * { box-sizing: border-box; }

/* ── the stock ────────────────────────────────────────────────────────────
   Paper is never one flat colour. Two almost-invisible gradients give it a
   tooth you feel rather than see — at 2–3% opacity it reads as texture, and
   above about 6% it reads as dirt. */

:root {
	--paper-tooth:
		repeating-linear-gradient(
			90deg,
			rgba(0,0,0,.014) 0 1px,
			transparent 1px 3px
		),
		repeating-linear-gradient(
			0deg,
			rgba(0,0,0,.010) 0 1px,
			transparent 1px 4px
		);
	--card-lift:
		0 1px 0 rgba(255,255,255,.55) inset,
		0 1px 2px rgba(32,64,47,.06),
		0 6px 14px -8px rgba(32,64,47,.28);
	--card-lift-hi:
		0 1px 0 rgba(255,255,255,.6) inset,
		0 2px 4px rgba(32,64,47,.08),
		0 14px 26px -12px rgba(32,64,47,.34);
}

[data-house="qipqop"] {
	--paper-tooth:
		repeating-linear-gradient(90deg, rgba(255,255,255,.016) 0 1px, transparent 1px 3px),
		repeating-linear-gradient(0deg, rgba(255,255,255,.010) 0 1px, transparent 1px 4px);
	--card-lift:
		0 1px 0 rgba(255,255,255,.05) inset,
		0 1px 2px rgba(0,0,0,.5),
		0 6px 16px -8px rgba(0,0,0,.7);
	--card-lift-hi:
		0 1px 0 rgba(255,255,255,.07) inset,
		0 2px 5px rgba(0,0,0,.55),
		0 16px 30px -12px rgba(0,0,0,.8);
}

/* ── the base card: paper on paper ───────────────────────────────────────
   A hairline border AND a lift, because paper laid on paper has both an edge
   and a shadow. One without the other is a rectangle. */

.qqs-w,
.qqs-row,
.qqs-tl,
.qqs-empty,
.qqs-gatecard,
.qqs-promise,
.qqs-stat2 div,
.qqsh__trust,
.qqsh__stats div,
.qqb__ch,
.qqs-ours,
.qqs-nopromo {
	position: relative;
	background-image: var(--paper-tooth);
	background-blend-mode: multiply;
	box-shadow: var(--card-lift);
	border-radius: 14px;
	transition: box-shadow .18s ease, transform .18s ease;
}
[data-house="qipqop"] :is(.qqs-w,.qqs-row,.qqs-tl,.qqs-empty,.qqs-gatecard,
	.qqs-promise,.qqs-stat2 div,.qqsh__trust,.qqsh__stats div,.qqb__ch,.qqs-ours) {
	background-blend-mode: screen;
}

button.qqs-w:hover, button.qqs-row:hover, .qqs-tl:hover {
	box-shadow: var(--card-lift-hi);
	transform: translateY(-1px);
}
button.qqs-w:active, button.qqs-row:active, .qqs-tl:active {
	transform: translateY(0);
	box-shadow: var(--card-lift);
}

/* ── the spine ───────────────────────────────────────────────────────────
   A world card carries its world's colour as a printed spine down the left
   edge — the way a file does. It replaces the uniform border that made every
   card look like every other card. */

.qqs-w::before {
	content: "";
	position: absolute;
	left: 0; top: 9px; bottom: 9px;
	width: 3px;
	border-radius: 0 3px 3px 0;
	background: var(--sh-accent);
	opacity: .5;
}
.qqs-w:hover::before { opacity: 1; }

/* Each world tints its own spine from the chip colour already on the icon. */
.qqs-w .ic {
	box-shadow: inset 0 0 0 1px rgba(0,0,0,.05);
	border-radius: 10px;
}

/* ── the ledger rule ─────────────────────────────────────────────────────
   A list of costs should read as a ledger. Dotted leaders run from the label
   to the figure, the way a printed account does, so the eye tracks across
   instead of guessing which number belongs to which line. */

.qqs-row .tx { position: relative; }

.qqs-row .mt {
	font-variant-numeric: tabular-nums;
	letter-spacing: -.01em;
}

.qqs-row:has(.mt) .tx b::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: .34em;
	border-bottom: 1px dotted var(--sh-edge);
	z-index: 0;
	opacity: .8;
}
.qqs-row:has(.mt) .tx b {
	position: relative;
	display: inline-block;
	max-width: 100%;
}
.qqs-row:has(.mt) .tx b::before {
	content: "";
	position: absolute;
	inset: 0 -3px;
	background: var(--sh-card);
	z-index: -1;
}

/* ── the ticket stub ─────────────────────────────────────────────────────
   Anything carrying a price gets two notches punched out of its sides. It is
   the oldest signal in retail: this part tears off, this part is yours. */

.qqs-stat2 div,
.qqb__tot,
.qqs-reelstage .cap {
	position: relative;
}

.qqs-stat2 div::before,
.qqs-stat2 div::after {
	content: "";
	position: absolute;
	top: 50%;
	width: 11px; height: 11px;
	margin-top: -5.5px;
	border-radius: 50%;
	background: var(--sh-screen);
	box-shadow: inset 0 0 0 1px var(--sh-edge);
}
.qqs-stat2 div::before { left: -6px; }
.qqs-stat2 div::after  { right: -6px; }

/* the big figure is the point of a stub, so it is set like one */
.qqs-stat2 b,
.qqb__tot b {
	font-variant-numeric: tabular-nums;
	letter-spacing: -.02em;
}

/* ── perforation ─────────────────────────────────────────────────────────
   A gate is a page torn out of the pad, not a wall put across the corridor.
   The top edge is perforated; the accent spine stays, because the reason is
   the important part. */

.qqs-gatecard {
	border-top: 0;
	padding-top: 15px;
}
.qqs-gatecard::before {
	content: "";
	position: absolute;
	left: 10px; right: 10px; top: 5px;
	height: 2px;
	background-image: radial-gradient( circle at 2px 1px,
		var(--sh-edge) 0 1.3px, transparent 1.5px );
	background-size: 7px 2px;
	background-repeat: repeat-x;
	opacity: .9;
}

/* ── the stamp ───────────────────────────────────────────────────────────
   A verdict was reached by somebody. `LIVE`, `SOON`, `LICENCE` stop being
   pills and become inked marks — set slightly askew, because a stamp never
   lands square. */

.qqs-st {
	transform: rotate(-1.6deg);
	border: 1.5px solid currentColor;
	background: transparent !important;
	letter-spacing: .09em;
	padding: 2px 7px;
	border-radius: 4px;
	opacity: .92;
	box-shadow: 0 0 0 2px var(--sh-card) inset;
}
.qqs-st.live { color: #2C6046; }
.qqs-st.soon { color: #6B6357; }
.qqs-st.lic  { color: #7A2E35; }
[data-house="qipqop"] .qqs-st.live { color: #BFE0CC; }
[data-house="qipqop"] .qqs-st.soon { color: #C0AB98; }
[data-house="qipqop"] .qqs-st.lic  { color: #E8A0A6; }

/* ── the corner fold ─────────────────────────────────────────────────────
   A card in a paid slot has a folded corner. It is quieter than a badge and
   impossible to mistake for editorial once you have seen it twice — and it
   sits alongside the label rather than replacing it, because the label is the
   disclosure and this is only the texture. */

.qqs-tile:has(.qqs-badge)::after {
	content: "";
	position: absolute;
	top: 0; right: 0;
	width: 22px; height: 22px;
	background: linear-gradient(225deg,
		rgba(245,234,216,.92) 0 50%, transparent 50%);
	z-index: 4;
	border-bottom-left-radius: 3px;
}

/* ── the reel tile: a photograph, not a swatch ───────────────────────────
   A vignette and a warm top light stop the gradient reading as a flat colour
   chip. Cheap, and it is the difference between a placeholder and an image. */

.qqs-tile .bg::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		radial-gradient( 120% 70% at 50% -10%, rgba(255,255,255,.20), transparent 60% ),
		radial-gradient( 100% 100% at 50% 55%, transparent 45%, rgba(0,0,0,.30) 100% );
}
.qqs-tile { box-shadow: var(--card-lift); }
.qqs-tile:hover { box-shadow: var(--card-lift-hi); }

/* ── the shop's own paper ────────────────────────────────────────────────
   The trust line is the most important sentence on a shop page, so it is set
   as a typed note rather than a grey box — ruled, indented, unmistakably
   somebody's assessment. */

.qqsh__trust {
	background-image:
		repeating-linear-gradient( 0deg,
			transparent 0 21px,
			color-mix(in srgb, var(--sh-edge) 55%, transparent) 21px 22px ),
		var(--paper-tooth);
	line-height: 22px;
	padding-top: 11px;
	padding-bottom: 11px;
}

/* ── numerals ────────────────────────────────────────────────────────────
   Money lines up or it is not money. */

.qqs-stat2 b, .qqb__tot b, .qqb__amt, .qqsh__stats b, .qqs-row .mt,
.qqs-tile .tx u, .rvp__big {
	font-variant-numeric: tabular-nums lining-nums;
}

/* ── the world grid gets air ─────────────────────────────────────────────
   Cards this dense read as a wall. A little more gap and a little less radius
   on the icon makes each one a separate object. */

.qqs-worlds { gap: 9px; }
.qqs-w { padding: 10px 10px 10px 12px; }

/* ── reduced motion keeps the material, loses the movement ─────────────── */

@media (prefers-reduced-motion: reduce) {
	.qqs-w, .qqs-row, .qqs-tl, .qqs-tile { transition: none; }
	button.qqs-w:hover, button.qqs-row:hover, .qqs-tl:hover { transform: none; }
}

/* ── where the craft must NOT go ─────────────────────────────────────────
   Sacred ground gets no stamp, no fold, no stub. A memorial is not a ticket,
   and a refusal to sell is not a design flourish. Flat, quiet, deliberate. */

.qqs-nopromo {
	box-shadow: none;
	background-image: none;
	border-radius: 12px;
}
.qqs-nopromo::before, .qqs-nopromo::after { display: none !important; }

/* ── containment ─────────────────────────────────────────────────────────
   The reel rail scrolls sideways, which gives the body a scroll width wider
   than its box. Any full-width child then stretches to THAT width and runs off
   the right edge — the ledger rows did exactly this. The rail is allowed to
   overflow; nothing else is. */

.qqs-body { overflow-x: hidden; }
.qqs-railwrap { max-width: 100%; }
.qqs-list, .qqs-worlds, .qqs-stat2, .qqs-gatecard, .qqs-nopromo, .qqs-tiles {
	max-width: 100%;
}
.qqs-row { min-width: 0; }
.qqs-row .tx { min-width: 0; overflow: hidden; }
.qqs-row .tx b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The rail arrows sat 6px outside the wrapper on each side, which is what was
   widening the body. They belong inside the rail they steer. */
.qqs-railarrow.prev { left: 2px; }
.qqs-railarrow.next { right: 2px; }
.qqs-rail { max-width: 100%; min-width: 0; }
