/* ============================================================
   PHONE-HERO PACK (KAN-658) - owner-design
   Production CSS for the eight-brand phone heroes. Copy this file
   verbatim; do not re-derive values. Chrome/typography of the PAGE
   stays in the site's own stylesheet; this file owns only the phone.
   Poppins loads from the site per the design lock (not embedded here).
   No em dashes.

   LOCKED PHONE SPEC (do not adjust): 300px class, aspect-ratio 9/19.5,
   radius 48px, frame #0b0c0f, dynamic island, home bar. No side
   buttons, no perspective transforms, no gradients on the brand block.
   ============================================================ */

/* Scoped border-box, added 2026-07-31. The pack was authored against border-box but never
   declared it, so it inherited whatever reset the host site happened to have. On /v2 that
   was fine; in a bare render (a PDF export, a static composite for marketing creative) the
   cards clipped their "Tap to show code" hint, because .rc-in is height:100% plus 12px
   padding and overflowed its own card under content-box. Scoped to .ph-hero so it cannot
   reach the host page, and a no-op anywhere border-box is already set. */
.ph-hero,.ph-hero *,.ph-hero *::before,.ph-hero *::after{box-sizing:border-box}

/* ---------- shared phone ---------- */
.ph-hero{--ease:cubic-bezier(.22,.61,.36,1);
  --visitor:#dfa30b;--subscriber:#e99353;--customer:#6da7b9;--member:#80b73e;
  --visitor-soft:#fbf0d3;--visitor-tag:#8a6406;--subscriber-soft:#fbe5d7;--subscriber-tag:#a4521f;
  --customer-soft:#dcebef;--customer-tag:#2f6473;--member-soft:#e3f0d2;--member-tag:#4a7016;
  font-family:'Poppins',system-ui,sans-serif;line-height:1.6}
.ph-hero .phone{width:300px;aspect-ratio:9/19.5;background:#0b0c0f;border-radius:48px;padding:10px;box-shadow:0 26px 60px -20px rgba(22,24,29,.4),0 0 0 1px rgba(22,24,29,.08);position:relative;flex:none}
.ph-hero .p-screen{position:absolute;inset:10px;border-radius:39px;background:var(--s-page);overflow:hidden;display:flex;flex-direction:column}
.ph-hero .island{position:absolute;top:22px;left:50%;transform:translateX(-50%);width:92px;height:26px;border-radius:14px;background:#0b0c0f;z-index:30}
.ph-hero .homebar{position:absolute;bottom:18px;left:50%;transform:translateX(-50%);width:104px;height:4px;border-radius:2px;background:rgba(22,24,29,.28);z-index:30}
.ph-hero .statusbar{display:flex;justify-content:space-between;align-items:center;padding:16px 24px 4px;font-size:12px;font-weight:600;color:var(--s-on);position:relative;z-index:3}
.ph-hero .sb-r{display:flex;align-items:center;gap:5px}
.ph-hero .sig{display:inline-flex;align-items:flex-end;gap:1.5px;height:9px}
.ph-hero .sig i{width:2.5px;background:var(--s-on);border-radius:1px}
.ph-hero .sig i:nth-child(1){height:3px}.ph-hero .sig i:nth-child(2){height:5px}
.ph-hero .sig i:nth-child(3){height:7px}.ph-hero .sig i:nth-child(4){height:9px}
.ph-hero .batt{width:18px;height:9px;border:1px solid var(--s-on);border-radius:2.5px;position:relative;opacity:.9}
.ph-hero .batt::after{content:"";position:absolute;inset:1.5px;right:4px;background:var(--s-on);border-radius:1px}
.ph-hero .m-logo{border-radius:10px;background:var(--s-tile);display:flex;align-items:center;justify-content:center;flex:none;overflow:hidden}
.ph-hero .m-logo svg{width:76%;height:76%;display:block}
.ph-hero .drawer-ic{width:32px;height:32px;border-radius:9px;background:rgba(255,255,255,.16);display:flex;align-items:center;justify-content:center;flex:none}
.ph-hero .drawer-ic svg{width:16px;height:16px;fill:var(--s-on)}
.ph-hero .c-dots{display:flex;gap:7px;margin-top:8px}
.ph-hero .c-dots i{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.22);transition:background .45s var(--ease)}
.ph-hero .play .c-dots i:nth-child(1),.ph-hero.play .c-dots i:nth-child(1){background:var(--visitor);transition-delay:.2s}
.ph-hero .play .c-dots i:nth-child(2),.ph-hero.play .c-dots i:nth-child(2){background:var(--subscriber);transition-delay:.45s}
.ph-hero .play .c-dots i:nth-child(3),.ph-hero.play .c-dots i:nth-child(3){background:var(--customer);transition-delay:.7s}
.ph-hero .play .c-dots i:nth-child(4),.ph-hero.play .c-dots i:nth-child(4){background:var(--member);transition-delay:.95s;box-shadow:0 0 0 3px rgba(128,183,62,.25)}
.ph-hero .rise{opacity:0;transform:translateY(14px)}
.ph-hero .play .rise{animation:ph-rise .6s var(--ease) forwards}
.ph-hero .play .rise.d1{animation-delay:.15s}.ph-hero .play .rise.d2{animation-delay:.3s}
.ph-hero .play .rise.d3{animation-delay:.45s}.ph-hero .play .rise.d4{animation-delay:.6s}
@keyframes ph-rise{to{opacity:1;transform:none}}
.ph-hero .connect{display:flex;gap:8px}
.ph-hero .connect i{flex:1;height:32px;border-radius:11px;background:var(--s-card);box-shadow:0 3px 10px -6px rgba(22,24,29,.18);display:flex;align-items:center;justify-content:center;gap:5px;font-style:normal;font-size:10.5px;font-weight:600;color:var(--s-mut)}
.ph-hero .connect i b{color:var(--s-accent2,var(--s-accent));font-weight:800;font-size:11px}
.ph-hero .pg-title{display:flex;align-items:baseline;justify-content:space-between;padding:2px 3px 0}
.ph-hero .pg-title b{font-size:14px;font-weight:700;letter-spacing:-.2px;color:var(--s-ink)}
.ph-hero .count-pill{font-size:10px;font-weight:700;background:var(--s-soft);color:var(--s-ink);border-radius:99px;padding:2px 8px}
.ph-hero .rcard{border-radius:16px;background-size:cover;background-position:center;position:relative;overflow:hidden;box-shadow:0 10px 24px -12px rgba(22,24,29,.35)}
.ph-hero .rc-in{position:relative;padding:12px;display:flex;flex-direction:column;height:100%}
.ph-hero .rc-top{display:flex;align-items:center;gap:7px}
.ph-hero .cicon{width:24px;height:24px;border-radius:7px;background:rgba(255,255,255,.85);display:flex;align-items:center;justify-content:center;flex:none;font-size:11px;font-weight:800;color:var(--rc)}
.ph-hero .rc-name{font-size:11.5px;font-weight:700;color:var(--rc)}
.ph-hero .rc-val{font-size:26px;font-weight:800;letter-spacing:-.7px;color:var(--rc);margin-top:4px;font-variant-numeric:tabular-nums}
.ph-hero .rc-sub{font-size:9.5px;font-weight:600;color:var(--rc);opacity:.85}
.ph-hero .rc-meter{display:flex;align-items:center;gap:7px;margin-top:auto}
.ph-hero .ring{width:26px;height:26px;flex:none}
.ph-hero .ring circle{fill:none;stroke-width:3.4}
.ph-hero .ring .tr{stroke:var(--rc);opacity:.2}
.ph-hero .ring .pr{stroke:var(--rc);stroke-linecap:round;stroke-dasharray:69.1;stroke-dashoffset:69.1}
.ph-hero .play .ring .pr{animation:ph-sweep 2.6s var(--ease) 1s forwards}
@keyframes ph-sweep{to{stroke-dashoffset:0}}
.ph-hero .rc-meta{font-size:9px;font-weight:600;color:var(--rc);opacity:.85;line-height:1.4}
.ph-hero .tap-hint{font-size:9.5px;font-weight:600;color:var(--rc);background:rgba(255,255,255,.8);border-radius:99px;padding:3px 10px;position:absolute;right:12px;bottom:12px}
/* Dark card art. The library ships a dark design in most industries (Platinum Noir,
   New Year Midnight, Halloween Ember, Backstage Noir), and on those the card ink is a
   LIGHT colour. The white chips underneath it must flip too, or their labels vanish.
   Set --rc to the payment design's own fontColor and add .on-dark. */
.ph-hero .rcard.on-dark .cicon{background:rgba(11,12,15,.6);color:var(--rc)}
.ph-hero .rcard.on-dark .tap-hint{background:rgba(11,12,15,.6);color:var(--rc)}
.ph-hero .hero{border-radius:16px;padding:12px;display:flex;flex-direction:column;justify-content:flex-end;color:#fff;position:relative;overflow:hidden;background-size:cover;background-position:var(--s-pos,center)}
.ph-hero .hero .ov{position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.02) 30%,var(--s-ov))}
.ph-hero .hero b{font-size:11.5px;font-weight:700;position:relative}
.ph-hero .hero span{font-size:9.5px;opacity:.85;position:relative}
.ph-hero .awallet{display:flex;align-items:center;gap:8px;justify-content:center;background:#0b0c0f;color:#fff;border-radius:10px;padding:8px 12px;font-size:11px;font-weight:600}
.ph-hero .awallet .wglyph{display:inline-flex;flex-direction:column;gap:1.5px;width:14px}
.ph-hero .awallet .wglyph i{height:3px;border-radius:1.5px}
.ph-hero .awallet .wglyph i:nth-child(1){background:var(--subscriber)}
.ph-hero .awallet .wglyph i:nth-child(2){background:var(--customer)}
.ph-hero .awallet .wglyph i:nth-child(3){background:var(--member)}
.ph-hero .welcome{font-size:10.5px;color:var(--s-mut);line-height:1.5;padding:0 3px}
.ph-hero .welcome b{color:var(--s-ink);font-weight:600}

/* ---------- composition c: offer-led ---------- */
.ph-hero .v-c .c-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:12px;flex:none}
.ph-hero .v-c .m-row{display:flex;align-items:center;gap:9px;padding:8px 16px 0}
.ph-hero .v-c .m-logo{width:28px;height:28px;border-radius:8px}
.ph-hero .v-c .m-id{flex:1;min-width:0}
.ph-hero .v-c .m-id b{display:block;font-size:12.5px;font-weight:700;line-height:1.2}
.ph-hero .v-c .p-body{flex:1;overflow:hidden;padding:12px 13px 40px;display:flex;flex-direction:column;gap:9px;color:var(--s-ink)}
.ph-hero .v-c .rcard{height:172px}
.ph-hero .v-c .guest-row{display:flex;align-items:center;justify-content:space-between;background:var(--s-card);border-radius:13px;padding:9px 12px;box-shadow:0 3px 10px -6px rgba(22,24,29,.18)}
.ph-hero .v-c .guest-row b{font-size:11.5px;font-weight:700;color:var(--s-ink)}
.ph-hero .v-c .guest-row .c-dots{margin-top:0}
.ph-hero .v-c .hero{min-height:62px;padding:10px 13px}

/* ---------- composition g: lifecycle band ---------- */
.ph-hero .v-g .p-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:14px;flex:none}
.ph-hero .v-g .m-row{display:flex;align-items:center;gap:10px;padding:10px 16px 0}
.ph-hero .v-g .m-logo{width:34px;height:34px}
.ph-hero .v-g .m-id{flex:1;min-width:0}
.ph-hero .v-g .m-id b{display:block;font-size:13.5px;font-weight:700;line-height:1.25}
.ph-hero .v-g .m-id i{display:block;font-style:normal;font-size:10.5px;opacity:.72;font-weight:500}
.ph-hero .v-g .id-block{padding:12px 16px 0}
.ph-hero .v-g .hello{font-size:16.5px;font-weight:700;letter-spacing:-.2px;display:block}
.ph-hero .v-g .p-body{flex:1;overflow:hidden;padding:12px 13px 40px;display:flex;flex-direction:column;gap:9px;color:var(--s-ink)}
.ph-hero .v-g .stage-band{display:flex;gap:4px}
.ph-hero .v-g .sb-cell{flex:1;border-radius:9px;padding:5px 2px 4px;text-align:center;font-size:7.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;opacity:0;transform:translateY(8px)}
.ph-hero .play.v-g .sb-cell,.ph-hero .v-g.play .sb-cell{animation:ph-rise .5s var(--ease) forwards}
.ph-hero .play.v-g .sb-cell:nth-child(2),.ph-hero .v-g.play .sb-cell:nth-child(2){animation-delay:.15s}
.ph-hero .play.v-g .sb-cell:nth-child(3),.ph-hero .v-g.play .sb-cell:nth-child(3){animation-delay:.3s}
.ph-hero .play.v-g .sb-cell:nth-child(4),.ph-hero .v-g.play .sb-cell:nth-child(4){animation-delay:.45s}
.ph-hero .v-g .sb-cell.s1{background:var(--visitor-soft);color:var(--visitor-tag)}
.ph-hero .v-g .sb-cell.s2{background:var(--subscriber-soft);color:var(--subscriber-tag)}
.ph-hero .v-g .sb-cell.s3{background:var(--customer-soft);color:var(--customer-tag)}
.ph-hero .v-g .sb-cell.s4{background:var(--member);color:#fff}
.ph-hero .v-g .rcard{height:146px}
.ph-hero .v-g .hero{min-height:70px;padding:10px 13px}

/* ---------- composition f: editorial grid ---------- */
.ph-hero .v-f .c-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:12px;flex:none}
.ph-hero .v-f .m-row{display:flex;align-items:center;gap:9px;padding:8px 16px 0}
.ph-hero .v-f .m-logo{width:28px;height:28px;border-radius:8px}
.ph-hero .v-f .m-id{flex:1;min-width:0}
.ph-hero .v-f .m-id b{display:block;font-size:12.5px;font-weight:700;line-height:1.2}
.ph-hero .v-f .p-body{flex:1;overflow:hidden;padding:14px 13px 40px;display:flex;flex-direction:column;gap:10px;color:var(--s-ink)}
.ph-hero .v-f .greet b{display:block;font-size:22px;font-weight:800;letter-spacing:-.7px;line-height:1.12}
.ph-hero .v-f .greet span{font-size:10.5px;color:var(--s-mut);font-weight:500}
.ph-hero .v-f .tile-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.ph-hero .v-f .tile{border-radius:14px;min-height:102px;position:relative;overflow:hidden}
.ph-hero .v-f .tile.tphoto{background-size:cover;background-position:var(--s-pos,center)}
.ph-hero .v-f .tile.tphoto::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 40%,var(--s-ov))}
.ph-hero .v-f .tile.tphoto b{position:absolute;left:9px;bottom:7px;font-size:10.5px;font-weight:700;color:#fff;z-index:2}
.ph-hero .v-f .tile.toffer{background-size:cover;background-position:center;padding:9px;display:flex;flex-direction:column}
.ph-hero .v-f .tile.toffer .tval{font-size:19px;font-weight:800;letter-spacing:-.5px;color:var(--rc);font-variant-numeric:tabular-nums;line-height:1.15}
.ph-hero .v-f .tile.toffer .tdk{font-size:8px;font-weight:600;color:var(--rc);opacity:.85;line-height:1.35}
.ph-hero .v-f .tile.toffer .tnm{font-size:10px;font-weight:700;color:var(--rc);margin-top:auto}
.ph-hero .v-f .tile.tconnect{background:var(--s-card);box-shadow:0 3px 10px -6px rgba(22,24,29,.16);display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:5px;padding:10px 12px}
.ph-hero .v-f .tile.tconnect i{font-style:normal;font-size:10px;font-weight:600;color:var(--s-mut)}
.ph-hero .v-f .tile.tconnect i b{color:var(--s-accent2,var(--s-accent));font-weight:800;margin-right:5px}
.ph-hero .v-f .tile.tmember{background:var(--s-hd);color:var(--s-on);padding:10px 12px;display:flex;flex-direction:column;justify-content:center;gap:4px}
.ph-hero .v-f .tile.tmember b{font-size:11px;font-weight:700}
.ph-hero .v-f .tile.tmember span{font-size:8.5px;opacity:.7}

/* ---------- composition e: ledger ---------- */
.ph-hero .v-e .c-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:12px;flex:none}
.ph-hero .v-e .m-row{display:flex;align-items:center;gap:9px;padding:8px 16px 0}
.ph-hero .v-e .m-logo{width:28px;height:28px;border-radius:8px}
.ph-hero .v-e .m-id{flex:1;min-width:0}
.ph-hero .v-e .m-id b{display:block;font-size:12.5px;font-weight:700;line-height:1.2}
.ph-hero .v-e .p-body{flex:1;overflow:hidden;padding:12px 13px 40px;display:flex;flex-direction:column;gap:8px;color:var(--s-ink)}
.ph-hero .v-e .id-mini{display:flex;align-items:center;justify-content:space-between;padding:0 3px}
.ph-hero .v-e .id-mini b{font-size:11px;font-weight:700}
.ph-hero .v-e .id-mini .c-dots{margin-top:0}
.ph-hero .v-e .id-mini .c-dots i{width:8px;height:8px}
.ph-hero .v-e .dv-mini{display:flex;background:var(--s-card);border-radius:14px;overflow:hidden;box-shadow:0 6px 16px -9px rgba(22,24,29,.25)}
.ph-hero .v-e .dv-mini .thumb{width:80px;background-size:cover;background-position:center;flex:none}
.ph-hero .v-e .dv-mini .in{padding:8px 11px;flex:1;min-width:0}
.ph-hero .v-e .dv-mini .in b{display:block;font-size:11px;font-weight:700}
.ph-hero .v-e .dv-mini .val{font-size:17px;font-weight:800;letter-spacing:-.4px;font-variant-numeric:tabular-nums}
.ph-hero .v-e .dv-mini .dk{display:block;font-size:8.5px;font-weight:600;color:var(--s-mut)}
.ph-hero .v-e .msec{font-size:9.5px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--s-mut);padding:4px 3px 0}
.ph-hero .v-e .mrow{display:flex;align-items:center;gap:9px;background:var(--s-card);border-radius:12px;padding:8px 11px;font-size:11.5px;font-weight:600;box-shadow:0 3px 10px -6px rgba(22,24,29,.16)}
.ph-hero .v-e .mi{width:24px;height:24px;border-radius:7px;background:var(--s-soft);display:flex;align-items:center;justify-content:center;flex:none;font-size:10px;font-weight:800;color:var(--s-ink)}
.ph-hero .v-e .lbl{flex:1}
.ph-hero .v-e .val2{font-size:10.5px;font-weight:700;color:var(--s-accent2,var(--s-ink))}
.ph-hero .v-e .badge{min-width:19px;height:19px;border-radius:10px;background:var(--s-accent);color:var(--s-hd);font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center;padding:0 6px}

/* ---------- composition h: storefront ---------- */
.ph-hero .v-h .p-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:44px;flex:none}
.ph-hero .v-h .m-row{display:flex;align-items:center;gap:10px;padding:10px 16px 0}
.ph-hero .v-h .m-logo{width:34px;height:34px}
.ph-hero .v-h .m-id{flex:1;min-width:0}
.ph-hero .v-h .m-id b{display:block;font-size:13.5px;font-weight:700;line-height:1.25}
.ph-hero .v-h .m-id i{display:block;font-style:normal;font-size:10.5px;opacity:.72;font-weight:500}
.ph-hero .v-h .id-block{padding:12px 16px 0}
.ph-hero .v-h .hello{font-size:16.5px;font-weight:700;letter-spacing:-.2px;display:block}
.ph-hero .v-h .p-body{flex:1;overflow:visible;padding:0 13px 40px;display:flex;flex-direction:column;gap:9px;color:var(--s-ink)}
.ph-hero .v-h .rcard{height:126px;margin-top:-32px;position:relative;z-index:2;box-shadow:0 14px 30px -12px rgba(22,24,29,.45)}
.ph-hero .v-h .tk-flag{font-size:8.5px;font-weight:800;letter-spacing:.5px;border-radius:5px;padding:2.5px 7px;display:inline-block;margin-top:6px;background:var(--visitor-soft);color:var(--visitor-tag);align-self:flex-start;position:relative}
.ph-hero .v-h .storefront{border-radius:16px;overflow:hidden;background:var(--s-card);box-shadow:0 6px 16px -9px rgba(22,24,29,.22)}
.ph-hero .v-h .storefront .ph{height:74px;background-size:cover;background-position:var(--s-pos,center);position:relative}
.ph-hero .v-h .storefront .ph::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 35%,var(--s-ov))}
.ph-hero .v-h .storefront .ph b{position:absolute;left:10px;bottom:6px;font-size:10.5px;font-weight:700;color:#fff;z-index:2}
.ph-hero .v-h .storefront .info{display:flex;align-items:center;justify-content:space-between;padding:8px 11px;font-size:9.5px;color:var(--s-mut);font-weight:600}
.ph-hero .v-h .storefront .info b{color:var(--s-ink);font-weight:700;display:block;font-size:10px}
.ph-hero .v-h .storefront .open{color:var(--member-tag);background:var(--member-soft);border-radius:99px;padding:2px 8px;font-size:8.5px;font-weight:800}

/* ---------- composition b: immersive ---------- */
.ph-hero .v-b .b-hero{background-size:cover;background-position:var(--s-pos,center);position:relative;padding-bottom:30px;flex:none;color:var(--s-on)}
.ph-hero .v-b .b-hero::before{content:"";position:absolute;inset:0;background:linear-gradient(180deg,var(--s-ov),rgba(0,0,0,.12) 42%,var(--s-ov))}
.ph-hero .v-b .statusbar,.ph-hero .v-b .m-row,.ph-hero .v-b .id-block,.ph-hero .v-b .tag-line{position:relative}
.ph-hero .v-b .m-row{display:flex;align-items:center;gap:10px;padding:10px 16px 0}
.ph-hero .v-b .m-logo{width:34px;height:34px;box-shadow:0 4px 14px rgba(22,24,29,.35)}
.ph-hero .v-b .m-id{flex:1;min-width:0}
.ph-hero .v-b .m-id b{display:block;font-size:13.5px;font-weight:700;line-height:1.25;text-shadow:0 1px 10px rgba(22,24,29,.5)}
.ph-hero .v-b .m-id i{display:block;font-style:normal;font-size:10.5px;opacity:.85;font-weight:500}
.ph-hero .v-b .id-block{padding:24px 16px 0}
.ph-hero .v-b .hello{font-size:18px;font-weight:700;letter-spacing:-.3px;display:block;text-shadow:0 1px 10px rgba(22,24,29,.5)}
.ph-hero .v-b .tag-line{font-size:10.5px;opacity:.85;padding:2px 16px 0}
.ph-hero .v-b .b-sheet{flex:1;background:var(--s-page);border-radius:22px 22px 0 0;margin-top:-16px;position:relative;padding:14px 13px 40px;display:flex;flex-direction:column;gap:9px;color:var(--s-ink);box-shadow:0 -10px 24px -14px rgba(22,24,29,.35)}
.ph-hero .v-b .rcard{height:146px}

/* ---------- composition d: brand-forward (white-label; skin-agnostic partial) ---------- */
.ph-hero .v-d .d-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:16px;flex:none;position:relative;transition:background .5s var(--ease)}
/* LEFT, not right. The shipped wallet's nav is a left slide-out panel (#menu); the
   right-hand drawer is the merchants menu, which has its own trigger. This composition has
   no merchant row, so its side is set here rather than by markup order, which is exactly
   why it survived the audit that corrected the other thirteen. Development's inventory on
   KAN-112 is the source. */
.ph-hero .v-d .drawer-ic{position:absolute;left:14px;top:52px}
.ph-hero .v-d .d-brand{display:flex;flex-direction:column;align-items:center;gap:6px;padding-top:8px}
.ph-hero .v-d .m-logo{width:52px;height:52px;border-radius:15px;box-shadow:0 6px 18px rgba(0,0,0,.28)}
.ph-hero .v-d .d-brand b{font-size:14.5px;font-weight:700;letter-spacing:-.2px}
.ph-hero .v-d .d-brand i{font-style:normal;font-size:10px;opacity:.7;font-weight:500;margin-top:-4px}
.ph-hero .v-d .c-dots{margin-top:2px;justify-content:center}
.ph-hero .v-d .p-body{flex:1;overflow:hidden;padding:12px 13px 40px;display:flex;flex-direction:column;gap:9px;color:var(--s-ink)}
.ph-hero .v-d .hero{min-height:96px}
.ph-hero .v-d .rcard{height:146px}

/* ---------- creators surface (industry 1000) ----------
   Quick Links (product page link-book) is the creator's real link-in-bio surface, so the
   creators hero leads with it instead of the Connect row: a solo creator has no address to
   call or map. The two visitor states are that page's signature moment, the same link before
   and after the guest unlocks with one SMS code. Drive it with
   PhoneHero.setVisitorState(phone, 'new'|'return'); markup carries .only-new / .only-return. */
.ph-hero .qlinks{display:flex;flex-direction:column;gap:7px}
.ph-hero .ql{display:flex;align-items:center;gap:9px;background:var(--s-card);border:1px solid var(--s-soft);border-radius:12px;padding:9px 11px;font-size:11.5px;font-weight:600;color:var(--s-ink)}
.ph-hero .ql .qd{width:7px;height:7px;border-radius:50%;background:var(--s-accent);flex:none}
.ph-hero .ql.is-perk{background:var(--s-tile);border-color:var(--s-accent)}
.ph-hero .ql.is-perk .qd{background:var(--s-accent2)}
.ph-hero .greet{background:var(--s-card);border:1px solid var(--s-soft);border-radius:12px;padding:9px 11px;font-size:11px;line-height:1.45;color:var(--s-ink)}
.ph-hero .greet b{color:var(--s-accent2);font-weight:700}
.ph-hero .ptsrow{display:flex;align-items:center;justify-content:space-between;background:var(--s-soft);border-radius:11px;padding:7px 11px;font-size:10.5px;color:var(--s-ink)}
.ph-hero .ptsrow b{font-size:12.5px;font-weight:700}
.ph-hero [data-visitor="new"] .only-return,.ph-hero[data-visitor="new"] .only-return{display:none}
.ph-hero [data-visitor="return"] .only-new,.ph-hero[data-visitor="return"] .only-new{display:none}

/* ---------- prize moment (gamification), LAUNCH-GATED ----------
   Everything here is namespaced pz- so it cannot collide with the drawer's .scrim, which
   is driven by .play. State classes go on the .phone: pz-open, pz-spun, pz-landed, pz-won.
   Colours come from the skin, so the wheel reskins with the brand like everything else.
   DO NOT RENDER THIS unless the feature is live AND Legal's official-rules text exists;
   see the README. Preview before launch belongs on dev, never on a production URL. */
.ph-hero .pz-scrim{position:absolute;inset:0;background:rgba(11,12,15,.5);opacity:0;transition:opacity .5s var(--ease);z-index:10;pointer-events:none}
.ph-hero .phone.pz-open .pz-scrim{opacity:1}
.ph-hero .pz-game{position:absolute;left:16px;right:16px;top:50%;transform:translateY(-46%) scale(.92);opacity:0;
  transition:opacity .5s var(--ease),transform .5s var(--ease);z-index:20;background:#fff;border-radius:22px;
  padding:16px 14px 18px;text-align:center;box-shadow:0 24px 50px -18px rgba(22,24,29,.5)}
.ph-hero .phone.pz-open .pz-game{opacity:1;transform:translateY(-46%) scale(1)}
.ph-hero .pz-game h5{font-size:13.5px;font-weight:700;letter-spacing:-.2px;color:#16181d;margin:0}
.ph-hero .pz-game .pz-sub{font-size:10px;color:#6b7280;margin-top:1px}
.ph-hero .pz-wheel-wrap{position:relative;width:216px;height:216px;margin:12px auto 6px}
.ph-hero .pz-pointer{position:absolute;top:-6px;left:50%;transform:translateX(-50%);width:0;height:0;
  border-left:9px solid transparent;border-right:9px solid transparent;border-top:14px solid #16181d;z-index:3}
.ph-hero .pz-wheel{width:216px;height:216px;transition:transform 3.4s cubic-bezier(.16,.84,.22,1)}
.ph-hero .phone.pz-spun .pz-wheel{transform:rotate(-1485deg)}
.ph-hero .pz-hub{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;background:#16181d;
  color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:800;letter-spacing:1px;
  z-index:2;box-shadow:0 4px 14px rgba(22,24,29,.4)}
.ph-hero .pz-banner{margin:10px auto 0;max-width:220px;background:var(--member-soft);color:var(--member-tag);
  border-radius:12px;padding:9px 12px;font-size:12.5px;font-weight:700;opacity:0;transform:translateY(8px);
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.ph-hero .phone.pz-landed .pz-banner{opacity:1;transform:none}
.ph-hero .pz-fine{font-size:8.5px;color:#9aa1ad;margin-top:8px;line-height:1.5}
/* the won prize arriving in the wallet: the KAN-657 contract made visible */
.ph-hero .pz-prize{opacity:0;transform:translateY(10px);transition:opacity .6s var(--ease),transform .6s var(--ease)}
.ph-hero .phone.pz-won .pz-prize{opacity:1;transform:none}
.ph-hero .pz-wonnote{font-size:10.5px;color:var(--s-mut);text-align:center;line-height:1.5;padding:0 8px;opacity:0;
  transition:opacity .6s var(--ease) .2s}
.ph-hero .phone.pz-won .pz-wonnote{opacity:1}

/* ---------- the other three prize mechanics: dice, pick-a-card, scratch-off ----------
   SAME LAUNCH GATE as the wheel. All four exist in the product (demoed 2026-07-28, wiring
   lands week of 2026-08-03; behaviour recorded on Confluence 27492423), so these model a
   real feature rather than inventing one. They are still pre-launch and must not render
   until the feature is live AND Legal's official-rules text exists.

   All three hook a mechanic-agnostic state class, pz-play, which the runtime adds on the
   same beat as pz-spun. pz-spun is kept untouched so the already-integrated wheel does not
   change. Shared beats stay identical across mechanics: open, play, landed, close, won.
   Reduced motion is handled by the global block at the end of this file. */

/* -- dice roll: a real 3D cube, per the product. Faces carry a value AND a prize-type
      icon, the same pairing the wheel segments use. -- */
.ph-hero .pz-dice-wrap{position:relative;width:150px;height:142px;margin:14px auto 6px;perspective:520px}
.ph-hero .pz-die{position:absolute;inset:0;margin:auto;width:84px;height:84px;transform-style:preserve-3d;
  transform:rotateX(-24deg) rotateY(28deg);transition:transform 2.6s cubic-bezier(.18,.75,.24,1)}
/* ends on -16deg/18deg after 3 and 2 full turns, so face f1 rests toward the viewer */
.ph-hero .phone.pz-play .pz-die{transform:rotateX(-1096deg) rotateY(738deg)}
/* backface-visibility is load-bearing here, not a nicety: without it the far three faces
   show through the near ones and the cube renders as a wireframe scribble. */
.ph-hero .pz-face{position:absolute;inset:0;border-radius:14px;background:#fff;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  border:1.5px solid var(--s-accent,#c98a4b);display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:2px;box-shadow:inset 0 0 0 3px rgba(255,255,255,.55)}
.ph-hero .pz-face b{font-size:14px;font-weight:800;color:#16181d;letter-spacing:-.3px}
.ph-hero .pz-face svg{width:17px;height:17px;fill:var(--s-accent,#c98a4b)}
/* Side and top faces carry tone so the cube reads as a solid object mid-tumble. With every
   face pure white it renders as a set of outlines, which looks like a drawing bug. Plain
   background values rather than a filter, because filter on a preserve-3d child flattens it. */
.ph-hero .pz-face.f2,.ph-hero .pz-face.f4{background:#f1eee9}
.ph-hero .pz-face.f5,.ph-hero .pz-face.f6{background:#e4e0d9}
.ph-hero .pz-face.f3{background:#f7f5f2}
.ph-hero .pz-face.f1{transform:translateZ(42px)}
.ph-hero .pz-face.f2{transform:rotateY(90deg) translateZ(42px)}
.ph-hero .pz-face.f3{transform:rotateY(180deg) translateZ(42px)}
.ph-hero .pz-face.f4{transform:rotateY(-90deg) translateZ(42px)}
.ph-hero .pz-face.f5{transform:rotateX(90deg) translateZ(42px)}
.ph-hero .pz-face.f6{transform:rotateX(-90deg) translateZ(42px)}

/* -- pick-a-card: three face-down cards, the chosen one flips and lifts. The other two grey
      out and DO NOT reveal what they held, which is the product's behaviour and the more
      conservative choice in sweepstakes territory. Do not "improve" it into a near-miss
      reveal without Legal (KAN-307). -- */
.ph-hero .pz-cards{display:flex;gap:9px;justify-content:center;margin:16px 0 10px;perspective:620px}
.ph-hero .pz-card{width:56px;height:80px;position:relative;transform-style:preserve-3d;
  transition:transform .65s var(--ease),opacity .5s var(--ease),filter .5s var(--ease)}
.ph-hero .pz-card .fc{position:absolute;inset:0;border-radius:10px;backface-visibility:hidden;
  -webkit-backface-visibility:hidden;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:3px}
.ph-hero .pz-card .bk{background:var(--s-hd,#3b2a20);border:1.5px solid var(--s-accent,#c98a4b)}
.ph-hero .pz-card .bk i{width:20px;height:20px;border-radius:50%;border:2px solid var(--s-accent,#c98a4b);opacity:.7}
.ph-hero .pz-card .ft{background:#fff;border:1.5px solid var(--s-accent,#c98a4b);transform:rotateY(180deg)}
.ph-hero .pz-card .ft b{font-size:13px;font-weight:800;color:#16181d;letter-spacing:-.3px}
.ph-hero .pz-card .ft svg{width:16px;height:16px;fill:var(--s-accent,#c98a4b)}
.ph-hero .phone.pz-play .pz-card.is-pick{transform:translateY(-9px) rotateY(180deg)}
.ph-hero .phone.pz-play .pz-card:not(.is-pick){opacity:.4;filter:grayscale(1)}

/* -- scratch-off: the foil is a static layer and the prize is revealed through a growing
      circular window above it, which animates cleanly where an animated mask does not.
      The SCRATCH HERE label fades as the window opens. The shipped product leaves that
      label rendered on top of the revealed prize; that is a defect (KAN-686), not a thing
      to reproduce here. -- */
.ph-hero .pz-scratch{position:relative;width:198px;height:94px;margin:16px auto 10px;border-radius:14px;
  overflow:hidden;border:1.5px solid var(--s-accent,#c98a4b);background:#fff}
.ph-hero .pz-foil{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,#c6c9d0 0%,#eef0f3 44%,#a9aeb6 100%)}
.ph-hero .pz-foil span{font-size:9.5px;font-weight:800;letter-spacing:1.5px;color:#5f6672;
  transition:opacity .6s var(--ease)}
.ph-hero .phone.pz-play .pz-foil span{opacity:0}
.ph-hero .pz-window{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:#fff;-webkit-clip-path:circle(0% at 50% 52%);clip-path:circle(0% at 50% 52%);
  transition:-webkit-clip-path 2.9s var(--ease),clip-path 2.9s var(--ease)}
/* 76% is just past the corner distance for this box, so the foil clears fully and no
   further. Larger values finish early and the silver is gone before anyone sees it. */
.ph-hero .phone.pz-play .pz-window{-webkit-clip-path:circle(76% at 50% 52%);clip-path:circle(76% at 50% 52%)}
.ph-hero .pz-reveal{font-size:15px;font-weight:800;color:#16181d;text-align:center;line-height:1.25;
  padding:0 12px;letter-spacing:-.3px}
.ph-hero .pz-reveal i{display:block;font-style:normal;font-size:9.5px;font-weight:600;color:#6b7280;
  letter-spacing:.3px;margin-top:4px}

/* ---------- guest surfaces: Quick Links, Voucher, Virtual Business Card, Reps ----------
   Added 2026-08-09 for KAN-734 (blog heroes). Built from John's captures of the live guest
   wallet, so the STRUCTURE is product truth: the page-title chip, the Active/Expired tabs,
   the voucher flip, the day-countdown ring, the Quick Links group-with-legend pattern, the
   VBC action row, the Reps live-chat button.

   The PRESENTATION is deliberately ahead of the shipped build, on John's instruction of
   2026-08-09: Design draws the target state and development catches up, which is how the
   home page layouts became real merchant-selectable layouts. Two things that means here.
   Quick Links currently has almost no styling and John flagged it as the improvement area,
   so it gets the skin properly. And both the VBC and Reps ship with R2-D2 as the avatar,
   which is the licensing problem KAN-669 exists to fix, so they use the monogram avatars
   from that kit instead.

   The line held: presentation of a feature that EXISTS may run ahead of the build. A
   capability we do not have may not appear at all. All five surfaces here are live. */

/* Shared header for the guest surfaces. Every other composition redefines .p-hd, .m-row,
   .m-logo and .m-id locally, which is a lot of repetition; these four carry a common
   `v-gs` class so the merchant bar is defined once. Without it the logo has no size
   constraint at all and renders at its intrinsic size, which on first build filled most
   of the screen. */
.ph-hero .v-gs .p-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:12px;flex:none}
.ph-hero .v-gs .m-row{display:flex;align-items:center;gap:9px;padding:8px 16px 0}
.ph-hero .v-gs .m-logo{width:34px;height:34px}
.ph-hero .v-gs .m-id{flex:1;min-width:0}
.ph-hero .v-gs .m-id b{display:block;font-size:12.5px;font-weight:700;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ph-hero .v-gs .m-id i{display:block;font-style:normal;font-size:10px;opacity:.72;font-weight:500}

/* shared: the page-title chip that sits under the merchant bar on every guest surface */
.ph-hero .g-title{display:flex;align-items:center;gap:10px;padding:14px 14px 12px}
.ph-hero .g-title .gt-ic{width:30px;height:30px;border-radius:9px;background:var(--s-soft);display:flex;align-items:center;justify-content:center;flex:none}
.ph-hero .g-title .gt-ic svg{width:15px;height:15px;fill:var(--s-accent2)}
.ph-hero .g-title b{font-size:15.5px;font-weight:700;letter-spacing:-.3px;color:var(--s-ink)}
/* Top padding is load-bearing, not spacing taste: the Quick Links group legend sits above
   its border with a negative offset, and with overflow:hidden and no top padding the first
   legend on the screen gets sliced in half. */
.ph-hero .g-body{flex:1;overflow:hidden;padding:9px 14px 14px;display:flex;flex-direction:column;gap:13px}

/* -- Quick Links (composition ql) --
   The one screen John explicitly called out as under-designed. The legend-on-the-border
   grouping is kept because it is the product's own pattern and it genuinely works; what
   changes is that the rows now carry the skin, have real touch affordance, and the groups
   breathe. */
.ph-hero .ql-grp{border:1px solid var(--s-soft);border-radius:14px;padding:14px 11px 11px;position:relative;background:var(--s-card)}
.ph-hero .ql-grp>span.lg{position:absolute;top:-8px;left:14px;background:var(--s-page);padding:0 7px;font-size:10px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;color:var(--s-mut)}
.ph-hero .ql-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:11px;background:var(--s-tile);margin-bottom:7px}
.ph-hero .ql-row:last-child{margin-bottom:0}
.ph-hero .ql-row svg{width:15px;height:15px;fill:var(--s-accent2);flex:none}
.ph-hero .ql-row b{font-size:12.5px;font-weight:600;color:var(--s-ink)}
.ph-hero .ql-row i{margin-left:auto;width:6px;height:6px;border-right:1.5px solid var(--s-mut);border-bottom:1.5px solid var(--s-mut);transform:rotate(-45deg);opacity:.7}

/* -- Voucher (composition v) --
   The flip IS the interaction, so it gets the space. Front and back are stacked and
   cross-faded rather than 3D-rotated, because a rotateY on a card containing a QR reads
   as a gimmick and the QR is the point. */
.ph-hero .v-tabs{display:flex;background:var(--s-soft);border-radius:11px;padding:3px;gap:3px}
.ph-hero .v-tabs span{flex:1;text-align:center;padding:7px 0;border-radius:9px;font-size:12px;font-weight:700;color:var(--s-mut)}
.ph-hero .v-tabs span.on{background:var(--s-hd);color:var(--s-on)}
.ph-hero .vch{position:relative;border-radius:14px;min-height:150px}
.ph-hero .vch-face{border:2px dashed var(--s-accent);border-radius:14px;background:var(--s-card);padding:16px 14px;text-align:center;transition:opacity .5s var(--ease)}
.ph-hero .vch-back{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--s-card);border:2px dashed var(--s-accent);border-radius:14px;opacity:0;transition:opacity .5s var(--ease)}
/* The FRONT is the resting state, deliberately. It carries the value, the item and the
   merchant's colour, which is what makes a useful hero; the QR back is generic and looks
   the same for every merchant. The flip is a real interaction, so it is available by
   adding .flip to the phone, and export-png can ship both faces on request. Driving it
   from .play instead meant every still landed on the QR. */
.ph-hero .phone.flip .vch-back{opacity:1}
.ph-hero .phone.flip .vch-front{opacity:0}
.ph-hero .vch-val{font-size:34px;font-weight:800;letter-spacing:-1.4px;color:var(--s-accent2);line-height:1}
.ph-hero .vch-item{display:flex;align-items:center;justify-content:center;gap:7px;margin-top:6px;font-size:15px;font-weight:600;color:var(--s-ink)}
.ph-hero .vch-item svg{width:16px;height:16px;fill:var(--s-accent2)}
.ph-hero .vch-code{margin-top:3px;font-size:11.5px;font-weight:600;color:var(--s-mut);letter-spacing:.4px}
.ph-hero .vch-when{margin-top:9px;font-size:9.5px;line-height:1.5;color:var(--s-mut)}
.ph-hero .vch-hint{text-align:center;font-size:11px;font-weight:600;color:var(--s-mut);margin-top:9px}
/* A stand-in QR, not a scannable one. It needs the three FINDER squares or it reads as a
   checkerboard and nobody believes it: those corner eyes are what the eye uses to identify
   a QR code at a glance. The first version was a plain repeating grid and looked exactly
   like graph paper. Marketing composites a real code over this if an article needs one. */
.ph-hero .qr{width:104px;height:104px;position:relative;background-color:#fff;border:6px solid #fff;border-radius:4px;
  background-image:
    repeating-linear-gradient(90deg,#16181d 0 5px,transparent 5px 11px),
    repeating-linear-gradient(0deg,#16181d 0 5px,transparent 5px 9px)}
.ph-hero .qr::before,.ph-hero .qr::after{content:"";position:absolute;width:29px;height:29px;background:#fff;
  box-shadow:inset 0 0 0 5px #16181d,inset 0 0 0 9px #fff,inset 0 0 0 15px #16181d}
.ph-hero .qr::before{top:0;left:0}
.ph-hero .qr::after{top:0;right:0}
.ph-hero .vch-back span.qr i{content:"";position:absolute;bottom:0;left:0;width:29px;height:29px;background:#fff;
  box-shadow:inset 0 0 0 5px #16181d,inset 0 0 0 9px #fff,inset 0 0 0 15px #16181d}
.ph-hero .v-sec{display:flex;align-items:center;gap:7px;justify-content:center;font-size:13px;font-weight:700;color:var(--s-ink)}
.ph-hero .v-sec svg{width:14px;height:14px;fill:var(--s-accent2)}
.ph-hero .v-grp{background:var(--s-card);border-radius:12px;padding:11px 13px;box-shadow:0 3px 10px -6px rgba(22,24,29,.18)}
.ph-hero .v-grp b{display:flex;align-items:center;gap:6px;font-size:12.5px;font-weight:700;color:var(--s-ink)}
.ph-hero .v-grp b svg{width:14px;height:14px;fill:var(--s-accent2)}
.ph-hero .v-grp i{display:block;font-style:normal;font-size:10px;color:var(--s-mut);margin-top:3px}
.ph-hero .v-item{display:flex;align-items:center;justify-content:space-between;background:var(--s-card);border-radius:12px;padding:12px 13px;box-shadow:0 3px 10px -6px rgba(22,24,29,.18)}
.ph-hero .v-item .amt{font-size:19px;font-weight:800;letter-spacing:-.5px;color:var(--s-accent2)}
.ph-hero .v-item .exp{font-size:9.5px;font-weight:600;color:var(--s-mut);margin-top:2px}
.ph-hero .v-ring{width:40px;height:40px;position:relative;flex:none}
.ph-hero .v-ring svg{width:40px;height:40px;transform:rotate(-90deg)}
.ph-hero .v-ring .tr{fill:none;stroke:var(--s-soft);stroke-width:3.5}
.ph-hero .v-ring .pr{fill:none;stroke:var(--member);stroke-width:3.5;stroke-linecap:round;stroke-dasharray:100;stroke-dashoffset:38}
.ph-hero .v-ring span{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:var(--s-mut)}

/* -- Virtual Business Card (composition vc) and Representatives (composition rp) --
   Avatars are the KAN-669 monograms, never a photograph. The Representatives slot
   publishes a name, a role and a direct phone, so a synthetic face there is the asset most
   likely to be mistaken for a real employee. */
.ph-hero .vc-cover{height:74px;border-radius:14px 14px 0 0;background:linear-gradient(135deg,var(--s-hd),var(--s-accent2));position:relative}
.ph-hero .vc-card{background:var(--s-card);border-radius:14px;box-shadow:0 6px 18px -10px rgba(22,24,29,.3);overflow:hidden;text-align:center;padding-bottom:16px}
.ph-hero .vc-av{width:66px;height:66px;border-radius:20px;margin:-33px auto 0;border:3px solid var(--s-card);position:relative;display:block}
.ph-hero .vc-nm{margin-top:9px;font-size:17px;font-weight:700;letter-spacing:-.3px;color:var(--s-ink)}
.ph-hero .vc-role{font-size:11.5px;color:var(--s-mut);margin-top:2px}
.ph-hero .vc-acts{display:flex;justify-content:center;gap:9px;margin-top:14px}
.ph-hero .vc-acts a{width:52px;text-decoration:none}
.ph-hero .vc-acts i{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto}
.ph-hero .vc-acts i svg{width:16px;height:16px;fill:#fff}
.ph-hero .vc-acts span{display:block;font-size:9.5px;font-weight:600;color:var(--s-mut);margin-top:5px}
.ph-hero .vc-save{display:inline-flex;align-items:center;gap:6px;margin-top:14px;padding:8px 16px;border-radius:99px;background:var(--s-tile);font-size:11.5px;font-weight:600;color:var(--s-ink)}
.ph-hero .rp-chat{display:flex;align-items:center;justify-content:center;gap:8px;background:var(--s-hd);color:var(--s-on);border-radius:12px;padding:13px;font-size:12.5px;font-weight:700}
.ph-hero .rp-chat svg{width:15px;height:15px;fill:var(--s-on)}
.ph-hero .rp-card{display:flex;gap:11px;background:var(--s-card);border-radius:13px;padding:13px;box-shadow:0 4px 12px -8px rgba(22,24,29,.25)}
/* svg as well as img: the monogram avatars are inline SVG, and an unconstrained inline SVG
   in a flex row expands to fill, which made each card's avatar larger than the one above. */
.ph-hero .rp-card img,.ph-hero .rp-card svg{width:46px;height:46px;border-radius:14px;flex:none}
.ph-hero .rp-nm{font-size:13.5px;font-weight:700;color:var(--s-ink)}
.ph-hero .rp-l{display:flex;align-items:center;gap:6px;font-size:9.5px;color:var(--s-mut);margin-top:4px}
.ph-hero .rp-l svg{width:10px;height:10px;fill:var(--s-mut);flex:none}

/* ---------- Settings cog panel (composition cg) ----------
   KAN-743. An authenticated guest currently has no way to change anything, and the only
   thing in the right drawer is an unlabelled merchant switcher behind a location pin. This
   is the design pass on the replacement: a cog in the header's top-right opening a right
   panel that absorbs the switcher and becomes the account surface.

   THE PANEL IS SKINNED, NOT SYSTEM CHROME. The Active Memberships drawer above is
   hardcoded white because it predates the skins. This one runs on --s-page / --s-card /
   --s-accent2 like every other guest surface, which is what makes it survivable on a
   merchant's own domain: on white-label the panel has to look like the merchant's, because
   on that host Wallet is invisible by design.

   THE HARD CONSTRAINT, from AP: on a merchant's own custom domain the merchant switcher is
   deliberately suppressed so a branded experience cannot leak guests to other merchants.
   The .cg-sec carrying Your Merchants must simply not exist on that host. That is why the
   sections here are self-contained cards with a flex gap rather than a divided list: remove
   any one of them and nothing above or below it changes. Do not number the sections, do not
   give them an "n of 5", and do not separate them with rules that would leave a gap.

   Collapse is modelled with grid-template-rows 0fr/1fr rather than display:none, so the
   collapsed content stays in the layout tree and keeps its focus order. In the build the
   toggle is a checkbox plus label, no inline handler, so it survives KAN-372 dropping
   unsafe-inline. */
.ph-hero .cog-ic{width:32px;height:32px;border-radius:9px;background:rgba(255,255,255,.16);display:flex;align-items:center;justify-content:center;flex:none}
.ph-hero .cog-ic svg{width:17px;height:17px;fill:var(--s-on)}
.ph-hero .v-cg .m-row{padding:8px 14px 0}
/* line-height 1.35, not the pack's 1.6. The pack default is tuned for reading copy inside a
   card; this panel is a dense list of labels and values where 1.6 buys nothing and costs
   about 40px, which is the difference between the last section fitting and being sliced. */
.ph-hero .cg-drawer{position:absolute;top:0;right:0;bottom:0;width:88%;background:var(--s-page);z-index:20;border-radius:26px 0 0 26px;transform:translateX(105%);transition:transform .6s var(--ease);display:flex;flex-direction:column;color:var(--s-ink);line-height:1.35;box-shadow:-20px 0 44px -22px rgba(11,12,15,.55)}
.ph-hero .play .cg-drawer,.ph-hero .phone.play .cg-drawer{transform:none}
.ph-hero .cg-hd{flex:none;display:flex;align-items:center;justify-content:space-between;padding:42px 16px 8px}
.ph-hero .cg-hd b{font-size:16px;font-weight:700;letter-spacing:-.4px}
.ph-hero .cg-x{width:25px;height:25px;border-radius:8px;background:var(--s-soft);display:flex;align-items:center;justify-content:center;flex:none}
.ph-hero .cg-x svg{width:10px;height:10px;fill:var(--s-mut)}
/* The body scrolls and the footer does not. Five sections cannot fit a phone at any honest
   density, so the panel has to admit it scrolls; pinning Help / About / version means the
   support route never scrolls out of reach, which is exactly when someone needs it. */
.ph-hero .cg-body{flex:1;overflow:hidden;padding:2px 14px 6px;display:flex;flex-direction:column;gap:8px}
.ph-hero .cg-sec{background:var(--s-card);border-radius:14px;box-shadow:0 3px 10px -7px rgba(22,24,29,.22);flex:none}
.ph-hero .cg-sh{display:flex;align-items:center;gap:9px;padding:9px 12px}
.ph-hero .cg-sh .si{width:24px;height:24px;border-radius:8px;background:var(--s-soft);display:flex;align-items:center;justify-content:center;flex:none}
.ph-hero .cg-sh .si svg{width:12.5px;height:12.5px;fill:var(--s-accent2)}
.ph-hero .cg-sh .st{flex:1;min-width:0}
.ph-hero .cg-sh .st b{display:block;font-size:12.5px;font-weight:700;line-height:1.25}
/* The secondary line is the entire reason a section is allowed to collapse: it has to
   answer the question the section answers, so you do not open it to learn the state. A
   section with no state worth summarising should not be collapsible at all. */
.ph-hero .cg-sh .st i{display:block;font-style:normal;font-size:9.5px;font-weight:500;color:var(--s-mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
.ph-hero .cg-sh .chev{width:7px;height:7px;border-right:1.8px solid var(--s-mut);border-bottom:1.8px solid var(--s-mut);transform:rotate(225deg);margin-right:3px;flex:none;transition:transform .3s var(--ease)}
.ph-hero .cg-sec.shut .cg-sh .chev{transform:rotate(45deg)}
.ph-hero .cg-wrap{display:grid;grid-template-rows:1fr;transition:grid-template-rows .35s var(--ease)}
.ph-hero .cg-sec.shut .cg-wrap{grid-template-rows:0fr}
.ph-hero .cg-wrap>div{min-height:0;overflow:hidden}
.ph-hero .cg-in{padding:7px 12px 9px;border-top:1px solid var(--s-soft)}
.ph-hero .cg-row{display:flex;align-items:center;gap:10px;padding:7px 0}
.ph-hero .cg-row+.cg-row{border-top:1px solid var(--s-soft)}
.ph-hero .cg-row svg.ri{width:14px;height:14px;fill:var(--s-mut);flex:none}
.ph-hero .cg-row .lb{flex:1;min-width:0;font-size:11.5px;font-weight:600;color:var(--s-ink)}
.ph-hero .cg-row .vl{font-size:10.5px;font-weight:600;color:var(--s-mut);flex:none}
/* identity block: the phone number IS the account, so it gets the display weight */
.ph-hero .cg-id{display:flex;align-items:center;gap:10px;padding:1px 0 7px}
.ph-hero .cg-id .av{width:38px;height:38px;border-radius:13px;background:var(--s-hd);color:var(--s-on);display:flex;align-items:center;justify-content:center;flex:none}
.ph-hero .cg-id .av svg{width:18px;height:18px;fill:var(--s-on)}
.ph-hero .cg-id .who{min-width:0}
.ph-hero .cg-id .num{font-size:13.5px;font-weight:700;letter-spacing:-.2px;font-variant-numeric:tabular-nums;color:var(--s-ink)}
.ph-hero .cg-id .vf{display:inline-flex;align-items:center;gap:4px;font-size:8px;font-weight:800;letter-spacing:.5px;color:var(--member-tag);background:var(--member-soft);border-radius:5px;padding:2px 5px;margin-top:4px}
.ph-hero .cg-id .vf svg{width:9px;height:9px;fill:var(--member-tag)}
.ph-hero .cg-id .anon{font-size:13.5px;font-weight:700;letter-spacing:-.2px;color:var(--s-ink)}
.ph-hero .cg-id .anon i{display:block;font-style:normal;font-size:10px;font-weight:500;color:var(--s-mut);margin-top:3px;letter-spacing:0}
/* white-label: the current merchant is stated, never offered as a way out of the brand */
.ph-hero .cg-note{display:flex;align-items:center;gap:7px;font-size:10px;font-weight:600;color:var(--s-mut);padding:8px 0 0;border-top:1px solid var(--s-soft)}
.ph-hero .cg-note svg{width:12px;height:12px;fill:var(--s-mut);flex:none}
/* --s-on on --s-hd, NOT the --s-hd on --s-accent that .unlock-cta uses. That pairing is
   below 4.5:1 on juniper (3.69) and harborview (4.11), which is a pre-existing failure in
   the OTP partial, reported on the pack rather than quietly diverged from here. The header
   pairing is cleared on all eight skins because it is the merchant bar. */
.ph-hero .cg-cta{display:block;text-align:center;background:var(--s-hd);color:var(--s-on);border-radius:12px;padding:11px;font-size:12.5px;font-weight:700;margin-top:2px}
/* merchant rows are the EXISTING drawer rows, reused wholesale: same mark tile, same
   two-line block, same CURRENT badge on the balance line (John, 2026-07-31). The switcher
   is relocated, not redrawn, which is what makes it recognisable to a returning guest. */
.ph-hero .cg-sec .dr-m{padding:6px;border-radius:10px}
.ph-hero .cg-sec .dr-m.cur{background:var(--s-tile)}
/* --s-hd, not --s-accent2: accent2 is 3.95:1 on starlight against a white card. */
.ph-hero .cg-more{display:block;text-align:center;font-size:10.5px;font-weight:700;color:var(--s-hd);padding:7px 0 0;border-top:1px solid var(--s-soft);margin-top:4px}
/* OUTLINE-TO-FILL, not grey-to-green. The first draft was the conventional light track with
   a white knob, and both halves of it failed WCAG 1.4.11's 3:1 for non-text controls: the
   off track was 1.2:1 against the card (the switch was invisible until you knew it was
   there) and the white knob was 2.4:1 on the green track. Darkening the green to
   --member-tag did not fix the knob either, at 2.42:1. So the state is carried by the
   shape, outline versus solid, and every part clears 3:1 on all eight skins. */
.ph-hero .sw{width:34px;height:20px;border-radius:99px;background:var(--s-card);box-shadow:inset 0 0 0 1.5px var(--s-mut);position:relative;flex:none}
.ph-hero .sw::after{content:"";position:absolute;top:4px;left:4px;width:12px;height:12px;border-radius:50%;background:var(--s-mut)}
.ph-hero .sw.on{background:var(--member-tag);box-shadow:none}
.ph-hero .sw.on::after{top:3px;left:3px;width:14px;height:14px;background:#fff;transform:translateX(14px)}
/* Help and About are two links and a version string. Giving them a collapsible section
   header with nothing to summarise would be an accordion built for its own sake. */
.ph-hero .cg-ft{flex:none;display:flex;align-items:center;gap:16px;padding:9px 18px 26px;font-size:10.5px;font-weight:600;color:var(--s-mut);border-top:1px solid var(--s-soft)}
.ph-hero .cg-ft .ver{margin-left:auto;font-weight:500;opacity:.75}

/* ---------- Active Memberships drawer (homepage hero overlay) ---------- */
.ph-hero .scrim{position:absolute;inset:0;background:rgba(11,12,15,.44);opacity:0;transition:opacity .5s var(--ease);z-index:10}
.ph-hero .play .scrim,.ph-hero .phone.play .scrim{opacity:1}
.ph-hero .am-drawer{position:absolute;top:0;right:0;bottom:0;width:83%;background:#fff;z-index:20;border-radius:26px 0 0 26px;transform:translateX(105%);transition:transform .6s var(--ease);display:flex;flex-direction:column;padding:58px 14px 40px;color:#16181d}
.ph-hero .play .am-drawer,.ph-hero .phone.play .am-drawer{transform:none}
.ph-hero .dr-hd{display:flex;align-items:center;justify-content:space-between;padding:0 4px 10px;border-bottom:1px solid #ececec}
.ph-hero .dr-hd b{font-size:14.5px;font-weight:700;letter-spacing:-.2px}
.ph-hero .dr-count{font-size:11px;font-weight:700;background:#f3f0ea;border-radius:99px;padding:2px 9px;color:#3a3f49}
.ph-hero .dr-cat{border-bottom:1px solid #f3f0ea;padding:9px 4px}
.ph-hero .dr-cat .cat-h{display:flex;align-items:center;justify-content:space-between;font-size:11px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:#6b7280}
.ph-hero .dr-cat .chev{width:7px;height:7px;border-right:1.8px solid #9aa1ad;border-bottom:1.8px solid #9aa1ad;transform:rotate(45deg);transition:transform .3s}
.ph-hero .dr-cat.openc .chev{transform:rotate(225deg)}
.ph-hero .dr-m{display:flex;align-items:center;gap:9px;padding:9px 2px 3px}
.ph-hero .dr-logo{width:30px;height:30px;border-radius:9px;font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center;color:#fff;flex:none;overflow:hidden}
.ph-hero .dr-logo.lt{background:var(--tile,#f3f0ea)}
.ph-hero .dr-logo svg{width:23px;height:23px;display:block}
.ph-hero .dr-nm{flex:1;min-width:0}
.ph-hero .dr-nm b{display:block;font-size:12px;font-weight:700;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#16181d}
.ph-hero .dr-nm i{font-style:normal;font-size:10px;color:#9aa1ad;font-weight:500}
/* The CURRENT / FEATURED badge sits on the SECOND line, beside the balance, not beside the
   name. As a sibling of .dr-nm it was flex:none against the whole block, so it took width
   off the name line it never needed, and every badged row truncated while every unbadged
   row did not. Moving it down gives the name the full row and costs nothing: the balance
   line is short and is the one that can afford to give. John, 2026-07-31. */
.ph-hero .dr-sub{display:flex;align-items:center;gap:6px;min-width:0}
.ph-hero .dr-sub i{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ph-hero .feat{font-size:8.5px;font-weight:800;letter-spacing:.5px;background:var(--visitor-soft);color:var(--visitor-tag);border-radius:5px;padding:2.5px 6px;flex:none}
.ph-hero .curr{font-size:8.5px;font-weight:800;letter-spacing:.5px;background:var(--member-soft);color:var(--member-tag);border-radius:5px;padding:2.5px 6px;flex:none}

/* ---------- OTP unlock (section-six moment; skin-agnostic partial) ---------- */
.ph-hero .v-otp .p-hd{background:var(--s-hd);color:var(--s-on);padding-bottom:14px;flex:none}
.ph-hero .v-otp .m-row{display:flex;align-items:center;gap:10px;padding:10px 16px 0}
.ph-hero .v-otp .m-logo{width:34px;height:34px}
.ph-hero .v-otp .m-id{flex:1;min-width:0}
.ph-hero .v-otp .m-id b{display:block;font-size:13.5px;font-weight:700;line-height:1.25}
.ph-hero .v-otp .m-id i{display:block;font-style:normal;font-size:10.5px;opacity:.72;font-weight:500}
.ph-hero .v-otp .id-block{padding:12px 16px 0}
.ph-hero .v-otp .hello{font-size:16.5px;font-weight:700;letter-spacing:-.2px;display:block}
.ph-hero .v-otp .c-dots i{transition:background .4s var(--ease),box-shadow .4s var(--ease)}
.ph-hero .v-otp .c-dots i.on:nth-child(1){background:var(--visitor)}
.ph-hero .v-otp .c-dots i.on:nth-child(2){background:var(--subscriber)}
.ph-hero .v-otp .c-dots i.on:nth-child(3){background:var(--customer)}
.ph-hero .v-otp .c-dots i.on:nth-child(4){background:var(--member);box-shadow:0 0 0 3px rgba(128,183,62,.28)}
.ph-hero .v-otp .p-body{flex:1;overflow:hidden;padding:12px 13px 40px;display:flex;flex-direction:column;gap:8px;color:var(--s-ink)}
.ph-hero .v-otp .msec{font-size:9.5px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--s-mut);padding:4px 3px 0}
.ph-hero .v-otp .mrow{display:flex;align-items:center;gap:9px;background:var(--s-card);border-radius:12px;padding:8px 11px;font-size:11.5px;font-weight:600;box-shadow:0 3px 10px -6px rgba(22,24,29,.16)}
.ph-hero .v-otp .mi{width:24px;height:24px;border-radius:7px;background:var(--s-soft);display:flex;align-items:center;justify-content:center;flex:none;font-size:10px;font-weight:800;color:var(--s-ink)}
.ph-hero .v-otp .lbl{flex:1}
.ph-hero .v-otp .val2{font-size:10.5px;font-weight:700;color:var(--s-accent2,var(--s-ink))}
.ph-hero .v-otp .badge{min-width:19px;height:19px;border-radius:10px;background:var(--s-accent);color:var(--s-hd);font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center;padding:0 6px}
.ph-hero .lockg{display:inline-block;width:12px;height:12px;position:relative}
.ph-hero .lockg::before{content:"";position:absolute;left:2.5px;top:0;width:7px;height:7px;border:1.8px solid currentColor;border-bottom:none;border-radius:4px 4px 0 0}
.ph-hero .lockg::after{content:"";position:absolute;left:0;bottom:0;width:12px;height:7.5px;background:currentColor;border-radius:2.5px}
.ph-hero .unlock-cta{margin-top:4px;background:var(--s-accent);color:var(--s-hd);border-radius:13px;padding:11px;text-align:center;font-size:12.5px;font-weight:700;transition:opacity .4s}
.ph-hero .otp-sheet{position:absolute;left:10px;right:10px;bottom:0;background:#fff;border-radius:22px 22px 0 0;padding:18px 16px 46px;z-index:15;transform:translateY(110%);transition:transform .6s var(--ease);box-shadow:0 -12px 34px -14px rgba(22,24,29,.35);color:#16181d}
.ph-hero .otp-sheet.up{transform:none}
.ph-hero .otp-sheet h5{font-size:13px;font-weight:700;letter-spacing:-.2px;margin:0}
.ph-hero .otp-sheet p{font-size:10.5px;color:#6b7280;margin:2px 0 0;line-height:1.45}
.ph-hero .ph-field{margin-top:12px;border:1.5px solid #e0ddd6;border-radius:11px;padding:9px 12px;font-size:13px;font-weight:600;color:#16181d;min-height:38px;font-variant-numeric:tabular-nums}
.ph-hero .ph-field .caret{display:inline-block;width:1.5px;height:14px;background:#16181d;vertical-align:-2px;animation:ph-blink 1s steps(1) infinite}
@keyframes ph-blink{50%{opacity:0}}
.ph-hero .otp-boxes{display:flex;gap:7px;margin-top:12px}
.ph-hero .otp-boxes i{flex:1;aspect-ratio:.82;border:1.5px solid #e0ddd6;border-radius:10px;display:flex;align-items:center;justify-content:center;font-style:normal;font-size:16px;font-weight:700;color:#16181d;background:#faf8f4;transition:border-color .2s}
.ph-hero .otp-boxes i.fill{border-color:var(--member);background:#fff}

@media(prefers-reduced-motion:reduce){
  .ph-hero *,.ph-hero *::before,.ph-hero *::after{animation-duration:.001s!important;animation-delay:0s!important;transition-duration:.001s!important;transition-delay:0s!important}
}
