/* Ported verbatim from app/qq-africa-home.html — do not restyle.
   The two variables the original relied on, supplied locally. */
.rvp{--amber:#E0972F;--red:#C0392B}
/* ── the reel player: swipe up/down for people, left/right for scenes ── */
.rvp{position:absolute;inset:0;z-index:90;display:flex;flex-direction:column;color:#fff;overflow:hidden;
  touch-action:none;user-select:none;animation:fade .2s}
.rvp__bg{position:absolute;inset:0;transition:background .35s}
.rvp__bg::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.45),rgba(0,0,0,.15) 34%,rgba(0,0,0,.65))}
.rvp__bars{position:relative;z-index:3;display:flex;gap:3px;padding:11px 12px 0}
.rvp__bars i{flex:1;height:2.5px;border-radius:2px;background:rgba(255,255,255,.32);overflow:hidden}
.rvp__bars i span{display:block;height:100%;width:0;background:#fff;border-radius:2px}
.rvp__top{position:relative;z-index:3;display:flex;align-items:center;gap:9px;padding:11px 12px}
.rvp__av{width:34px;height:34px;border-radius:50%;background:rgba(255,255,255,.16);display:grid;place-items:center;font-size:17px;flex:none}
.rvp__who{flex:1;min-width:0}
.rvp__who b{display:block;font-size:12.5px;font-weight:900;line-height:1.15}
.rvp__who small{display:block;font-size:10.5px;opacity:.75;font-weight:700}
.rvp__x{border:0;background:rgba(0,0,0,.28);color:#fff;width:30px;height:30px;border-radius:50%;font-size:14px;
  cursor:pointer;font-weight:800;flex:none}
.rvp__stage{position:relative;z-index:3;flex:1;display:flex;flex-direction:column;justify-content:center;
  padding:18px 20px;text-align:left}
.rvp__k{font-size:10px;font-weight:900;letter-spacing:.2em;text-transform:uppercase;color:#ffd98a;margin-bottom:10px}
.rvp__big{font-family:Caprasimo,serif;font-size:clamp(30px,10vw,46px);line-height:.98;margin-bottom:10px;
  text-shadow:0 2px 18px rgba(0,0,0,.35)}
.rvp__sub{font-size:15px;line-height:1.5;font-weight:600;opacity:.94;max-width:22em}
.rvp__note{font-size:11.5px;opacity:.66;font-weight:700;margin-top:12px}
.rvp__foot{position:relative;z-index:3;padding:12px 14px 16px;display:flex;flex-direction:column;gap:9px}
.rvp__act{display:flex;gap:8px}
.rvp__act button{flex:1;border:0;border-radius:99px;padding:11px;font-size:12.5px;font-weight:800;cursor:pointer;
  background:rgba(255,255,255,.16);color:#fff;backdrop-filter:blur(6px)}
.rvp__act button.go{background:var(--amber);color:#3A1F06}
.rvp__hint{display:flex;justify-content:center;gap:14px;font-size:10px;font-weight:800;opacity:.6;letter-spacing:.04em}
.rvp__coach{position:absolute;inset:0;z-index:6;background:rgba(5,39,26,.82);display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:16px;text-align:center;padding:30px}
.rvp__coach b{font-family:Caprasimo,serif;font-size:23px;line-height:1.1}
.rvp__coach p{font-size:13px;opacity:.8;font-weight:600;line-height:1.6}
.rvp__coach .ar{font-size:26px;letter-spacing:8px}
/* ── reel action rail (ours: cream on the gradient, mono counts) ── */
.rvp__rail{position:absolute;right:10px;bottom:118px;z-index:4;display:flex;flex-direction:column;gap:13px;align-items:center}
.rvp__rail button{border:0;background:none;color:#fff;display:flex;flex-direction:column;align-items:center;gap:3px;
  cursor:pointer;font-family:inherit;padding:0}
.rvp__rail .ic{width:42px;height:42px;border-radius:50%;background:rgba(0,0,0,.3);border:1px solid rgba(245,234,216,.28);
  display:grid;place-items:center;font-size:19px;backdrop-filter:blur(6px);transition:transform .18s,background .18s}
.rvp__rail button:active .ic{transform:scale(.9)}
.rvp__rail .ct{font-family:'IBM Plex Mono',monospace;font-size:10.5px;font-weight:600;text-shadow:0 1px 4px rgba(0,0,0,.5)}
.rvp__rail .liked .ic{background:var(--red);border-color:var(--red)}
.rvp__rail .saved .ic{background:var(--amber);border-color:var(--amber);color:#3A1F06}
.rvp__stage{padding-right:66px}
.rvp__read{align-self:flex-start;border:1px solid rgba(245,234,216,.4);background:rgba(0,0,0,.32);color:#fff;
  border-radius:99px;padding:8px 15px;font-size:12px;font-weight:800;cursor:pointer;backdrop-filter:blur(6px);
  display:inline-flex;align-items:center;gap:7px;margin-bottom:9px}
/* ── THE WORLD PILL, UNDER THE HEAD (his pick: A) ──────────────────────────
   It used to ride the scene stage, which put it mid-frame — standing on the
   photograph on every beat. It answers "where am I", so it lives at the
   top-left edge, tucked under the title where the scrim already darkens:
   always readable, never on the picture's centre. Out of the flow entirely,
   so the stage's own text never moves to make room for it. */
.rvp__kind{position:absolute;top:64px;left:14px;z-index:6;margin:0;
  display:inline-block;background:rgba(10,14,12,.55);border:1px solid rgba(255,255,255,.32);
  backdrop-filter:blur(4px);border-radius:99px;
  padding:4px 11px;font-size:9.5px;font-weight:900;letter-spacing:.12em;text-transform:uppercase;color:#fff}

/* ── the mount inside the shell body ── */
.qqs-rvp-mount{position:absolute;inset:0}
.rvp__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.rvp__sacred{flex:1;text-align:center;font-size:11.5px;font-weight:700;opacity:.7;padding:11px}

/* ── comments / questions sheet ── */
.rvs{position:absolute;inset:0;z-index:95}
.rvs__scrim{position:absolute;inset:0;background:rgba(0,0,0,.55)}
.rvs__in{position:absolute;left:0;right:0;bottom:0;height:76%;background:var(--sh-screen,#FBF7EE);
  color:var(--sh-text,#20402F);border-radius:18px 18px 0 0;display:flex;flex-direction:column;padding:0 14px}
.rvs__h{display:flex;align-items:center;padding:14px 0 8px;flex:none}
.rvs__h b{font-family:Caprasimo,Georgia,serif;font-weight:400;font-size:19px}
.rvs__h button{margin-left:auto;background:none;border:0;font-size:18px;cursor:pointer;color:inherit;opacity:.6}
.rvs__body{flex:1;min-height:0;overflow-y:auto;padding:6px 0}
.rvs__c,.rvs__q{padding:10px 0;border-bottom:1px solid var(--sh-edge,#E4D7C0)}
.rvs__c b,.rvs__q b{display:block;font-size:12.5px;font-weight:800;margin-bottom:3px}
.rvs__c p,.rvs__q p{margin:0;font-size:12.5px;line-height:1.55;opacity:.8}
.rvs__empty{font-size:12.5px;opacity:.6;padding:16px 0}
.rvs__compose{flex:none;display:flex;gap:7px;padding:10px 0 max(12px,env(safe-area-inset-bottom));
  border-top:1px solid var(--sh-edge,#E4D7C0)}
.rvs__compose input{flex:1;background:transparent;border:1px solid var(--sh-edge,#E4D7C0);
  border-radius:10px;padding:9px 11px;font-family:inherit;font-size:12.5px;color:inherit}
.rvs__compose button{background:var(--sh-brand,#0E3F28);color:var(--sh-screen,#FBF7EE);border:0;
  border-radius:10px;padding:9px 14px;font-family:inherit;font-weight:800;font-size:12px;cursor:pointer}

@media (prefers-reduced-motion: reduce){
  .rvp{animation:none}
  .rvp__bars i span{transition:none!important}
}

/* captions pending — stated, never hidden */
.rvp__cap-pending{position:absolute;left:12px;bottom:12px;z-index:4;font-size:9.5px;font-weight:900;
  letter-spacing:.08em;text-transform:uppercase;background:rgba(0,0,0,.5);color:#fff;
  border:1px solid rgba(245,234,216,.3);border-radius:99px;padding:3px 9px}

/* ── the display slot, sized by what it holds ─────────────────────────────
   A fixed display size only works if every string is a name or a figure. Put a
   sentence in it and you get a wall. Four bands, chosen by length in
   sizeFor(): a number shouts, a sentence speaks. */

.rvp__big[data-len="xl"]{ font-size:clamp(38px,13vw,58px); line-height:.92; letter-spacing:-.015em }
.rvp__big[data-len="l"] { font-size:clamp(30px,9.5vw,44px); line-height:.98 }
.rvp__big[data-len="m"] { font-size:clamp(23px,6.4vw,30px); line-height:1.12; letter-spacing:0 }
/* Long lines stop being display type altogether — Figtree, not Caprasimo,
   because a serif display face at small sizes over an image is unreadable. */
.rvp__big[data-len="s"] {
	font-family:Figtree,system-ui,-apple-system,sans-serif;
	font-size:clamp(18px,4.9vw,23px);
	font-weight:800;
	line-height:1.28;
	letter-spacing:-.005em;
	max-width:20em;
}


/* ══════════════════ ONE SHEET — Say · Ask · Rate ═════════════════════════
   Three surfaces became one. The tabs are the only navigation, and a tab with
   nothing behind it never renders, so the sheet is always exactly as big as
   what there is to read. */

.rvs__grip{width:38px;height:4px;border-radius:99px;background:var(--sh-edge,#E4D7C0);
  margin:0 auto 10px;opacity:.9}

.rvs__tabs{display:flex;gap:4px;flex:none;padding:0 0 2px;border-bottom:1px solid var(--sh-edge,#E4D7C0)}
.rvs__tab{flex:1;background:none;border:0;padding:9px 4px 10px;font-family:inherit;cursor:pointer;
  color:var(--sh-dim,#8A7D68);position:relative;display:flex;align-items:center;justify-content:center;gap:5px}
.rvs__tab b{font-size:13px;font-weight:900}
.rvs__tab i{font-style:normal;font-size:10px;font-weight:800;background:var(--sh-card,#fff);
  border:1px solid var(--sh-edge,#E4D7C0);border-radius:99px;padding:1px 6px;line-height:1.5}
.rvs__tab.on{color:var(--sh-text,#20402F)}
.rvs__tab.on::after{content:"";position:absolute;left:14%;right:14%;bottom:-1px;height:2.5px;
  border-radius:2px;background:var(--sh-accent,#C67139)}

/* the rating summary reads like a printed panel, not a dashboard widget */
.rvs__sum{display:flex;gap:16px;align-items:center;padding:12px 0 10px}
.rvs__avg{text-align:center;flex:none}
.rvs__avg b{display:block;font-family:Caprasimo,Georgia,serif;font-weight:400;font-size:34px;
  line-height:1;color:var(--sh-brand,#0E3F28)}
.rvs__avg span{display:block;color:var(--sh-accent,#C67139);font-size:12px;letter-spacing:1px}
.rvs__avg small{display:block;font-size:10px;color:var(--sh-dim,#8A7D68);margin-top:2px}
.rvs__bars{flex:1;min-width:0}
.rvs__bar{display:flex;align-items:center;gap:6px;font-size:10px;color:var(--sh-dim,#8A7D68)}
.rvs__bar i{flex:1;height:5px;border-radius:3px;background:var(--sh-edge,#E4D7C0);overflow:hidden}
.rvs__bar i b{display:block;height:100%;background:var(--sh-accent,#C67139)}

.rvs__filters{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding-bottom:9px}
.rvs__filters::-webkit-scrollbar{display:none}
.rvs__filters button{flex:none;background:transparent;border:1px solid var(--sh-edge,#E4D7C0);
  border-radius:99px;padding:5px 11px;font-family:inherit;font-size:10.5px;font-weight:800;
  color:var(--sh-dim,#8A7D68);cursor:pointer;white-space:nowrap}
.rvs__filters button.on{background:var(--sh-brand,#0E3F28);color:var(--sh-screen,#FBF7EE);
  border-color:var(--sh-brand,#0E3F28)}

.rvs__r{padding:11px 0;border-bottom:1px solid var(--sh-edge,#E4D7C0)}
.rvs__rh{display:flex;align-items:center;gap:7px;margin-bottom:3px}
.rvs__rh b{font-size:12.5px;font-weight:800}
.rvs__v{font-size:8.5px;font-weight:900;border-radius:99px;padding:2px 7px;
  background:#e8f0e2;color:#3d5a2c}
[data-house="qipqop"] .rvs__v{background:rgba(42,82,64,.4);color:#BFE0CC}
.rvs__st{color:var(--sh-accent,#C67139);font-size:11px;letter-spacing:1px}
.rvs__r h5{margin:3px 0;font-size:12.5px}
.rvs__r p{margin:0;font-size:12px;line-height:1.55;color:var(--sh-dim,#8A7D68)}
.rvs__help{margin-top:7px;background:none;border:1px solid var(--sh-edge,#E4D7C0);border-radius:99px;
  padding:4px 10px;font-family:inherit;font-size:10px;font-weight:800;
  color:var(--sh-dim,#8A7D68);cursor:pointer}

.rvs__compose input[disabled]{opacity:.6}
.rvs__compose button[disabled]{opacity:.45;cursor:not-allowed}

/* ── the skip ─────────────────────────────────────────────────────────────
   Only ever on a video. A photo takes 5.2 seconds and slides; there is nothing
   to escape from. The chip counts down first so nobody is startled by it
   appearing, then becomes solid when it can actually be used. */

.rvp__skip{
	/* The rail owns the right column — the chip landed under the share button.
	   It sits clear of it, on the reading side of the screen. */
	position:absolute;right:74px;bottom:calc(100% + 10px);z-index:16;
	background:rgba(0,0,0,.5);border:1px solid rgba(245,234,216,.34);
	color:rgba(245,234,216,.72);
	border-radius:99px;padding:8px 15px;
	font-family:inherit;font-size:12px;font-weight:800;letter-spacing:.01em;
	cursor:default;backdrop-filter:blur(6px);
	transition:background .2s ease,color .2s ease,border-color .2s ease;
	/* a 44px target even though the chip is smaller */
	min-height:34px;display:flex;align-items:center;
}
.rvp__skip::after{content:"";position:absolute;inset:-6px}
.rvp__skip.ready{
	background:rgba(245,234,216,.94);
	border-color:transparent;
	color:#1b2a22;
	cursor:pointer;
}
[data-house="qipqop"] .rvp__skip.ready{background:rgba(237,226,210,.94);color:#1C1310}

.rvp__foot{position:relative}

@media (prefers-reduced-motion: reduce){
	.rvp__skip{transition:none}
}

/* "that is the last one here" — shown instead of silently re-rendering */
.rvp__flash{position:absolute;left:50%;bottom:34%;transform:translateX(-50%);z-index:40;
  background:rgba(0,0,0,.62);color:#fff;border:1px solid rgba(245,234,216,.28);
  border-radius:99px;padding:8px 15px;font-size:12px;font-weight:800;
  backdrop-filter:blur(6px);animation:fade .2s}

/* ══════════════════ SUPPORT ON EITHER SIDE, AND A PAD ══════════════════════
   The WhatsApp bubble was a foreign object bolted to a corner in somebody
   else's green. It joins the button family the reel already has.

   THE RULE FOR EVERYTHING IN THIS BLOCK: it may never hinder the work or the
   view. So every container is pointer-events:none and only the buttons
   themselves take a tap — a full-height rail that swallowed swipes would be a
   worse bug than the one it replaced. */

/* ── the left column: help, then the pad ──────────────────────────────────
   `.rvp__rail` is bottom-anchored, so inheriting it put the help disc straight
   on top of the byline — the @handle, the caption and the anchor pill all sat
   underneath it. The byline owns the bottom-left; this column is centred and
   stays out of it.

   Both are positioned from the same anchor so they can never drift into each
   other either. */
.rvp__rail--l{
	/* TOP-left, under the top bar. Centred it cleared the other buttons and
	   landed squarely on the headline — which is the most important thing on
	   the screen, and "must not hinder the work or the view" means the words
	   too, not just the taps. The upper-left is the only genuinely empty
	   column: the stage owns the middle, the byline owns the bottom. */
	left:12px;right:auto;
	top:84px;bottom:auto;
	pointer-events:none;
}
.rvp__rail--l > *{pointer-events:auto}

/* the same disc as the social rail, in the same weights */
.rvp__b{
	display:flex;flex-direction:column;align-items:center;gap:3px;
	background:none;border:0;padding:0;cursor:pointer;
	color:#fff;font-family:inherit;text-decoration:none;
}
.rvp__b .ic{
	width:44px;height:44px;border-radius:50%;
	display:grid;place-items:center;font-size:18px;
	background:rgba(0,0,0,.34);
	border:1px solid rgba(245,234,216,.22);
	backdrop-filter:blur(7px);
	transition:background .18s ease,transform .18s ease;
}
.rvp__b s{text-decoration:none;font-size:9.5px;font-weight:800;opacity:.82;letter-spacing:.02em}
.rvp__b:hover .ic{background:rgba(0,0,0,.5)}
.rvp__b:active .ic{transform:scale(.94)}

/* ── the pad ───────────────────────────────────────────────────────────────
   Sits centre-right, low, out of the way of the headline. Faint until touched,
   because it is the second way to do something, not the first. */

.rvp__pad{
	/* LEFT, not right. On the right it sat directly on top of the action
	   rail's avatar and intercepted every tap meant for it — the browser test
	   refused to click through and that is how this was found. The right
	   column belongs to the social rail; the left has room.

	   Sits just below the help disc, from the same anchor, clear of the
	   headline and clear of the byline. */
	position:absolute;left:12px;top:154px;transform:none;
	z-index:14;display:flex;flex-direction:column;align-items:center;gap:5px;
	pointer-events:none;opacity:.34;transition:opacity .2s ease;
}
.rvp__pad:hover,.rvp__pad:focus-within{opacity:1}
.rvp__pad > *{pointer-events:auto}
.rvp__pad > div{display:flex;gap:5px}
.rvp__pad button{
	width:34px;height:34px;border-radius:50%;
	background:rgba(0,0,0,.3);
	border:1px solid rgba(245,234,216,.2);
	color:#fff;font-size:14px;line-height:1;cursor:pointer;
	backdrop-filter:blur(6px);
	display:grid;place-items:center;
	transition:background .16s ease,transform .16s ease;
}
.rvp__pad button:hover{background:rgba(0,0,0,.52)}
.rvp__pad button:active{transform:scale(.9)}

/* A phone has a thumb and does not need arrows in the way of the picture. */
@media (max-width:820px) and (hover:none){
	.rvp__pad{opacity:.2}
	.rvp__pad button{width:30px;height:30px;font-size:12.5px}
}
@media (prefers-reduced-motion:reduce){
	.rvp__pad,.rvp__b .ic,.rvp__pad button{transition:none}
}

/* ═══════════════════════════ THE END CARD ═════════════════════════════════
   One scene past the last one. The natural end of the story, not a banner
   sitting on top of it. */

.rvo{position:absolute;inset:0;z-index:30;display:flex;align-items:flex-end;
	background:linear-gradient(180deg,rgba(0,0,0,.15),rgba(0,0,0,.72));animation:fade .22s}
.rvo__in{width:100%;background:var(--sh-screen,#FBF7EE);color:var(--sh-text,#20402F);
	border-radius:20px 20px 0 0;padding:18px 16px max(18px,env(safe-area-inset-bottom))}
.rvo__h b{display:block;font-family:Caprasimo,Georgia,serif;font-weight:400;font-size:21px;
	line-height:1.12;color:var(--sh-brand,#0E3F28)}
.rvo__h small{display:block;font-size:11.5px;color:var(--sh-dim,#8A7D68);margin-top:2px}
.rvo__p{font-family:Caprasimo,Georgia,serif;font-weight:400;font-size:30px;margin:9px 0 2px;
	color:var(--sh-brand,#0E3F28);font-variant-numeric:tabular-nums}
.rvo__t{font-size:11.5px;line-height:1.5;color:var(--sh-dim,#8A7D68);
	border-left:3px solid var(--sh-edge,#E4D7C0);padding-left:9px;margin:9px 0 12px}

/* WhatsApp is the real path here, so it is the first button — but it is our
   button, in our colours, not a borrowed brand badge. */
.rvo__wa{display:flex;align-items:center;justify-content:center;gap:8px;
	width:100%;background:#1F6B4A;color:#fff;border:0;border-radius:12px;padding:14px;
	font-family:inherit;font-size:14px;font-weight:900;text-decoration:none;margin-bottom:8px}
.rvo__wa span{font-size:16px}
.rvo__go{width:100%;background:var(--sh-brand,#0E3F28);color:var(--sh-screen,#FBF7EE);border:0;
	border-radius:12px;padding:13px;font-family:inherit;font-size:13.5px;font-weight:900;cursor:pointer}
.rvo__read{width:100%;background:transparent;border:1px solid var(--sh-edge,#E4D7C0);
	color:var(--sh-text,#20402F);border-radius:12px;padding:11px;margin-top:7px;
	font-family:inherit;font-size:12.5px;font-weight:800;cursor:pointer}
.rvo__n{font-size:11px;line-height:1.55;color:var(--sh-dim,#8A7D68);margin:11px 0 0}
.rvo__x{width:100%;background:none;border:0;color:var(--sh-dim,#8A7D68);margin-top:6px;
	font-family:inherit;font-size:11.5px;font-weight:800;cursor:pointer;text-decoration:underline}

/* ══════════════ THE NAVIGATION EVERYBODY ALREADY KNOWS ════════════════════
   Two links, both borrowed rather than invented:

     the face on the rail + the @handle  →  whoever made this
     the anchor pill                     →  the thing itself

   There used to be TWO read affordances — a 📖 disc on the rail and a
   "Read it out" button in the footer — doing one job in a shape nobody had
   been trained to look for. Both are gone. */

/* ── the face, at the top of the action rail, with a follow badge ──────── */
.rvp__who-b{
	position:relative;background:none;border:0;padding:0;cursor:pointer;
	margin-bottom:4px;transition:transform .16s ease;
}
.rvp__who-b:active{transform:scale(.93)}
.rvp__who-b .av{
	display:grid;place-items:center;width:44px;height:44px;border-radius:50%;
	font-size:20px;background:rgba(0,0,0,.34);
	border:1.5px solid rgba(245,234,216,.5);backdrop-filter:blur(7px);
}
.rvp__who-b .add{
	position:absolute;left:50%;bottom:-7px;transform:translateX(-50%);
	width:18px;height:18px;border-radius:50%;
	background:var(--red,#C0392B);color:#fff;
	font-size:12px;font-weight:900;line-height:16px;
	border:1.5px solid rgba(0,0,0,.4);
}

/* ── the byline: @handle, caption, anchor ─────────────────────────────── */
.rvp__by{position:relative;z-index:3;padding:0 74px 8px 14px}
.rvp__handle{
	background:none;border:0;padding:0;cursor:pointer;font-family:inherit;
	color:#fff;font-size:14px;font-weight:900;letter-spacing:-.01em;
	display:inline-flex;align-items:center;gap:4px;
}
.rvp__handle:active{opacity:.7}
.rvp__handle .tick{color:#8fe3b4;font-size:12px}
.rvp__cap{
	margin:3px 0 8px;font-size:12.5px;line-height:1.45;
	color:rgba(255,255,255,.9);
	display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}

/* ── the anchor ─────────────────────────────────────────────────────────
   The basket pill, where every other reel app puts it. */
.rvp__anchor{
	display:flex;align-items:center;gap:9px;width:100%;
	background:rgba(0,0,0,.44);
	border:1px solid rgba(245,234,216,.22);
	backdrop-filter:blur(8px);
	border-radius:11px;padding:9px 11px;
	font-family:inherit;color:#fff;cursor:pointer;text-align:left;
	transition:background .16s ease;
}
.rvp__anchor:hover{background:rgba(0,0,0,.62)}
.rvp__anchor:active{transform:scale(.99)}
.rvp__anchor .ic{font-size:15px;flex:none}
.rvp__anchor .tx{
	flex:1;min-width:0;font-size:12px;font-weight:800;
	white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.rvp__anchor .go{flex:none;opacity:.55;font-size:14px}

@media (prefers-reduced-motion:reduce){
	.rvp__anchor,.rvp__who-b{transition:none}
}

/* ══════════════════ THE SOFT ARRIVAL ═══════════════════════════════════════
   A photograph should never snap into place. Three layers, each ready before
   the last: the averaged colour on the first frame, a 20px blur that reads as
   the picture out of focus, then the real thing faded over both.

   The numbers matter more than they look. 520ms is long enough to read as a
   dissolve rather than a switch, short enough that nobody waits for it. The
   curve is ease-out — fast at the start, settling at the end — because a
   linear fade has a visible beginning and a visible end, and the whole point
   is that neither is noticed. */

.rvp__soft {
	position: absolute;
	inset: 0;
	overflow: hidden;
	display: block;
}

/* The blur. Scaled past the edges because blurring an image to its own
   boundary leaves a soft grey rim where the filter runs out of pixels. */
.rvp__blur {
	position: absolute;
	inset: -6%;
	width: 112%;
	height: 112%;
	object-fit: cover;
	filter: blur(18px) saturate(1.12);
	transform: scale(1.04);
}

.rvp__img--in {
	opacity: 0;
	transform: scale(1.012);
	transition: opacity 520ms cubic-bezier(.22,.61,.36,1),
	            transform 720ms cubic-bezier(.22,.61,.36,1);
	will-change: opacity, transform;
}

/* The settle: 1.012 → 1. Barely a pixel at this size, and that is the point —
   a movement you can measure is a movement you can see. This one is felt as
   the picture coming to rest rather than being noticed as an animation. */
.rvp__img--in.is-on {
	opacity: 1;
	transform: scale(1);
}

/* The blur fades out UNDER the photograph rather than being removed, so there
   is no frame where a half-transparent picture shows the background through it. */
.rvp__img--in.is-on ~ .rvp__blur,
.rvp__soft:has(.is-on) .rvp__blur {
	opacity: 0;
	transition: opacity 640ms cubic-bezier(.22,.61,.36,1);
}

/* Motion is a preference, not a decision we make for people. Everything still
   works — the picture simply appears, which is what it did before all this. */
@media (prefers-reduced-motion: reduce) {
	.rvp__img--in,
	.rvp__soft:has(.is-on) .rvp__blur {
		transition: none;
		transform: none;
	}
	.rvp__img--in { opacity: 1; }
}

/* ══════════════ TEXT THAT CHANGES SHAPE WITH WHAT IT SAYS ══════════════════
   Nine beats set in the same type is how a reel starts to feel like a form.
   A price is a figure and should be read as one; a trust line is an admission
   and should be quiet; a hook is a name and should carry the screen. The beat
   declares its style server-side and the stage wears it. */

.rvp[data-style="display"] .rvp__big { font-size: clamp(30px, 9vw, 46px); line-height: 1.06; letter-spacing: -.01em; }
.rvp[data-style="figure"]  .rvp__big { font-size: clamp(38px, 12vw, 62px); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.rvp[data-style="quiet"]   .rvp__sub { font-size: 13px; opacity: .84; letter-spacing: .01em; }
.rvp[data-style="plain"]   .rvp__sub { font-size: 14.5px; line-height: 1.55; max-width: 30ch; }

/* A caption belongs to the picture, so it sits lower and lighter than a beat
   that is making an argument — the eye should reach the photograph first. */
.rvp[data-style="caption"] .rvp__sub {
	font-size: 12.5px;
	opacity: .8;
	max-width: 28ch;
	font-style: italic;
}

/* The price beat gets a hairline above it. One rule, not a box: this company
   already lives on receipts, and a figure under a line reads as a total. */
.rvp[data-beat="price"] .rvp__big::before {
	content: "";
	display: block;
	width: 34px;
	height: 2px;
	background: currentColor;
	opacity: .55;
	margin-bottom: 11px;
}

/* ── the words arrive with the beat ──────────────────────────────────────── */
@keyframes rvpRise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
.rvp__big, .rvp__sub, .rvp__note {
	animation: rvpRise 460ms cubic-bezier(.22,.61,.36,1) both;
}
.rvp__sub  { animation-delay: 70ms; }
.rvp__note { animation-delay: 130ms; }

/* ── more, and ⓘ ─────────────────────────────────────────────────────────── */
.rvp__more {
	display: inline-block;
	margin-top: 7px;
	background: none;
	border: 0;
	padding: 0;
	color: inherit;
	font: inherit;
	font-size: 12.5px;
	font-weight: 800;
	opacity: .78;
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
}

.rvp__info {
	position: absolute;
	top: 52px;
	right: 14px;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	border: 1.5px solid rgba(255,255,255,.55);
	background: rgba(0,0,0,.28);
	color: #fff;
	font: 800 15px/1 Georgia, serif;
	cursor: pointer;
	backdrop-filter: blur(3px);
	z-index: 6;
}

/* ── the sheet ───────────────────────────────────────────────────────────── */
.rvi { position: fixed; inset: 0; z-index: 99997; }
.rvi__scrim { position: absolute; inset: 0; background: rgba(0,0,0,.55); opacity: 0; transition: opacity 240ms ease; }
.rvi.is-on .rvi__scrim { opacity: 1; }

.rvi__sheet {
	position: absolute;
	left: 0; right: 0; bottom: 0;
	max-height: 82vh;
	overflow: auto;
	background: #FDFBF6;
	color: #201e1d;
	border-radius: 20px 20px 0 0;
	padding: 20px 18px calc(22px + env(safe-area-inset-bottom));
	transform: translateY(101%);
	transition: transform 320ms cubic-bezier(.22,.61,.36,1);
}
.rvi.is-on .rvi__sheet { transform: none; }

.rvi__x { position: absolute; top: 12px; right: 14px; width: 30px; height: 30px; border-radius: 50%; border: 1px solid #E4D7C0; background: #fff; font-size: 17px; cursor: pointer; }
.rvi__t { margin: 0 34px 8px 0; font-size: 19px; line-height: 1.2; }
.rvi__what { margin: 0 0 14px; font-size: 14px; line-height: 1.6; color: #3A3428; }

/* Dotted leaders. A list of facts with prices in it IS a ledger, and this
   company already lives on them. */
.rvi__row { display: flex; align-items: baseline; gap: 6px; padding: 6px 0; font-size: 13.5px; }
.rvi__row span { color: #6b6152; flex: none; }
.rvi__row::after { content: ""; flex: 1; border-bottom: 1px dotted #C9B99B; transform: translateY(-3px); order: 1; }
.rvi__row b { order: 2; flex: none; font-weight: 800; }

.rvi__note { margin: 12px 0 0; font-size: 12px; line-height: 1.55; color: #6b6152; }

.rvi__do { display: flex; gap: 8px; margin-top: 16px; }
.rvi__ask, .rvi__share {
	flex: 1;
	text-align: center;
	padding: 12px 10px;
	border-radius: 12px;
	font-weight: 800;
	font-size: 14px;
	text-decoration: none;
	cursor: pointer;
	border: 1px solid #C9B99B;
}
.rvi__ask   { background: #20402F; color: #fff; border-color: #20402F; }
.rvi__share { background: #fff; color: #201e1d; }

@media (prefers-reduced-motion: reduce) {
	.rvp__big, .rvp__sub, .rvp__note { animation: none; }
	.rvi__sheet, .rvi__scrim { transition: none; }
}


/* ══════════════════ THE CLEAR VIEW — the picture wins ══════════════════════
   His screenshot: the price scene carried a headline, a kicker, a full
   sentence, the byline, the caption, the shop anchor AND the CTA — seven
   pieces of furniture on one photograph. TikTok's answer, adopted whole: on
   picture beats everything collapses to ONE line, and everything else lives
   behind the ⓘ. The reel breathes: spoken beats speak, picture beats show. */

/* Picture beats: the standing furniture steps back. The rail (likes, comments,
   save, share) stays — that is the outlook, and it is vertical, off the
   image's centre. The TEXT stack is what was covering the photograph. */
.rvp[data-style="caption"] .rvp__by .rvp__cap,
.rvp[data-style="caption"] .rvp__anchor { display: none; }
.rvp[data-style="caption"] .rvp__handle { opacity: .7; font-size: 11.5px; }

/* The one line a picture beat is allowed. Clamped to a single line the
   TikTok way — the ellipsis IS the more affordance. */
.rvp[data-style="caption"] .rvp__sub {
	display: -webkit-box;
	-webkit-line-clamp: 1;
	-webkit-box-orient: vertical;
	overflow: hidden;
	max-width: 62vw;
}

/* Spoken beats keep the words but lose the duplicate: while a beat is
   speaking, the byline caption underneath said the same thing twice. */
.rvp[data-style="display"] .rvp__cap,
.rvp[data-style="figure"] .rvp__cap,
.rvp[data-style="quiet"] .rvp__cap,
.rvp[data-style="plain"] .rvp__cap { display: none; }

/* The scrim earns its darkness only where text actually sits. A flat wash
   over the whole frame is why the photograph looked dim. */
.rvp[data-style="caption"] .rvp__bg::after {
	background: linear-gradient(180deg, transparent 55%, rgba(0,0,0,.44) 100%);
}

/* The CTA is the turn's job. On every other beat it was a standing billboard
   over the bottom third of every photograph. */
.rvp:not([data-beat="turn"]):not([data-beat="hook"]) .rvp__cta { display: none; }

/* Unfolded caption: the clamp releases and the scrim deepens behind it only
   while it is open — the photograph pays for the words only when asked. */
.rvp__sub[data-rvp="unfold"] { cursor: pointer; }
.rvp__sub.is-unfolded {
	display: block !important;
	-webkit-line-clamp: unset !important;
	max-width: 74vw !important;
	white-space: normal;
	background: rgba(0,0,0,.38);
	border-radius: 10px;
	padding: 8px 10px;
	backdrop-filter: blur(3px);
}
