
/* ===================== TOKENS (bolder reinvention pass) ===================== */
:root{
  /* Real peacock-teal + real saffron-gold — the vars were always named teal/saffron but had
     drifted to a muted burnt-orange/wine. Deliberately higher-contrast, jewel-toned pairing:
     reads like teal silk with gold zari work rather than the earlier safe terracotta look. */
  --teal:#FF5500; --teal-d:#E04A00; --teal-tint:#FFF1EB;
  --saffron:#F59E0B; --saffron-d:#C77F09; --saffron-tint:#FEF0D9;
  --bg:#F9F8F5; --card:#FFFFFF;
  --ink:#0F1729; --muted:#6B7280; --hairline:#E9E5DE;
  --live:#EF4444; --badge:#0F1729; --success:#15A363; --amber:#F59E0B;
  /* Studio cockpit base was still the old warm "lantern" brown even after the token pass above —
     it never actually inherited the teal/saffron reinvention, it just kept its original amber-lit
     look. Real teal-charcoal now, so the livestream screen reads as the same brand as everywhere
     else instead of a leftover orange/brown theme. */
  --dark-bg:#161318; --dark-surface:#211C24; --dark-surface-2:#2D2732; --dark-text:#F6F1EE; --dark-muted:#AEA4AE; --dark-hair:#372F3B;
  --live-grad:linear-gradient(120deg,#D946EF 0%,#F43F5E 50%,#F97316 100%);
  --brand-grad:linear-gradient(120deg,#FF7A18 0%,#FF5500 55%,#F43F5E 100%);
  --live-violet:#D946EF; --live-pink:#F43F5E;
  --radius-card:18px; --radius-pill:999px;
  --shadow:0 2px 10px rgba(11,60,70,.12);
  --shadow-lg:0 8px 28px rgba(6,30,36,.32);
  --glow-teal:0 8px 24px rgba(255,85,0,.35);
  --glow-saffron:0 8px 22px rgba(245,158,11,.4);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
html,body{margin:0;padding:0;background:#0b0f0d;height:100%;}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:var(--ink);}
button,input{font-family:inherit;}
a{text-decoration:none;color:inherit;}
::-webkit-scrollbar{display:none;}

#app{max-width:430px;margin:0 auto;min-height:100vh;background:var(--bg);position:relative;padding-bottom:88px;overflow-x:hidden;}
/* On a real phone, 100vh IS the phone's own screen, so a mockup that just fills the viewport
   already looks right. On a desktop browser, the "phone" is really just a box floating in a much
   taller window — nothing before this stopped it from stretching to match the window's actual
   height, which reads as an unrealistically tall/narrow sliver rather than a phone on any
   sufficiently tall monitor. --frame-h caps that box's height at a real device's own logical
   size (iPhone 14/15/16 Pro Max: 430x932pt, a natural pairing with the 430px width already used
   everywhere in this file) — min() still shrinks to fit a shorter browser window, it just stops
   GROWING once the window is taller than a real phone would be. Every other place that mirrors
   #app's own desktop height (studio-family screens, the hub screen, the boot skeleton, the sheet
   scrim) reads this same variable so none of them can drift out of lockstep with #app or with
   each other — see each of their own desktop overrides elsewhere in this file. */
@media (min-width:431px){
  body{padding:0;}
  :root{ --frame-h: 100vh; }
  #app{min-height:var(--frame-h);box-shadow:var(--shadow-lg);overflow:hidden;}
}
.screen{position:relative;}
@keyframes fade{from{opacity:0}to{opacity:1}}

/* ===================== HEADER / SEARCH / CATEGORIES ===================== */
.header{display:flex;align-items:center;justify-content:space-between;padding:calc(14px + env(safe-area-inset-top)) 16px 6px;}
.logo{display:flex;align-items:baseline;gap:6px;}
.logo .en{font-size:23px;font-weight:800;letter-spacing:-.6px;background:var(--brand-grad);background-size:200% 200%;-webkit-background-clip:text;background-clip:text;color:transparent;}
.logo .hi{font-size:14px;font-weight:700;color:var(--saffron);}
.icon-btn{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:transparent;border:none;font-size:18px;}
.avatar-btn{width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,#FF7A2E,var(--teal-d));color:#fff;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;border:none;box-shadow:0 3px 10px rgba(255,85,0,.4);}

.search-wrap{padding:4px 16px 12px;}
.search{display:flex;align-items:center;gap:8px;background:var(--card);border-radius:var(--radius-pill);padding:11px 16px;color:var(--muted);box-shadow:var(--shadow);font-size:13.5px;border:none;width:100%;text-align:left;}

.cat-row{display:flex;gap:10px;padding:2px 16px 16px;overflow-x:auto;}
.cat{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:6px;width:60px;background:none;border:none;padding:0;}
.cat .tile{width:56px;height:56px;border-radius:16px;background:#fff;display:flex;align-items:center;justify-content:center;font-size:24px;box-shadow:var(--shadow);transition:transform .15s cubic-bezier(.34,1.56,.64,1),box-shadow .15s ease;}
.cat:active .tile{transform:scale(.9);}
.cat.active .tile{background:linear-gradient(135deg,#FF7A2E,var(--teal-d));box-shadow:0 6px 16px rgba(255,85,0,.4);}
.cat span{font-size:11px;color:var(--ink);font-weight:600;}
.cat.active span{color:var(--teal);}

/* ===================== COLLAPSING HOME HEADER ===================== */
.home-header-wrap{position:fixed;top:0;left:50%;transform:translateX(-50%);width:100%;max-width:430px;z-index:30;background:var(--bg);}
/* top:0/bottom:0 fixed-position bars throughout this file anchor to the real browser viewport,
   which on a real phone IS the frame (so top:0 is correct there) but on desktop is a much taller
   box than the capped #app frame sitting inside it — every one of these needs its own desktop
   override so it hugs the frame's actual edge instead of the far-away real viewport edge. This is
   the first one in file order; see .tabbar below for the bottom-edge version of the same fix
   (a bit more arithmetic since --frame-h can be shorter than the viewport once capped). */
@media (min-width:431px){ .home-header-wrap{top:0;} }
.home-content{transition:padding-top .28s cubic-bezier(.4,0,.2,1);}
.home-header-wrap .header{transition:padding .28s cubic-bezier(.4,0,.2,1);}
.home-header-wrap .logo{transition:transform .28s cubic-bezier(.4,0,.2,1);transform-origin:left center;}
.search-compact{display:none;flex:0 0 auto;width:0;opacity:0;height:36px;border-radius:50%;background:var(--card);box-shadow:var(--shadow);border:none;font-size:14px;align-items:center;justify-content:center;transition:width .28s cubic-bezier(.4,0,.2,1),opacity .2s ease;overflow:hidden;margin:0;}
.home-header-wrap .search-wrap{transition:max-height .28s cubic-bezier(.4,0,.2,1),opacity .18s ease,padding .28s cubic-bezier(.4,0,.2,1);max-height:60px;opacity:1;overflow:hidden;}
.home-header-wrap .cat-row{transition:padding .28s cubic-bezier(.4,0,.2,1);}
.home-header-wrap .cat{transition:width .28s cubic-bezier(.4,0,.2,1);}
.home-header-wrap .cat .tile{transition:transform .28s cubic-bezier(.4,0,.2,1),border-radius .28s ease;}
.home-header-wrap .cat-label{display:block;max-width:60px;opacity:1;transition:max-width .22s ease,opacity .16s ease;overflow:hidden;white-space:nowrap;}
.home-header-wrap.collapsed .header{padding-bottom:2px;}
.home-header-wrap.collapsed .logo{transform:scale(.727);}
.home-header-wrap.collapsed .search-compact{display:flex;width:36px;opacity:1;}
.home-header-wrap.collapsed .search-wrap{max-height:0;opacity:0;padding-top:0;padding-bottom:0;}
.home-header-wrap.collapsed .cat-row{padding:2px 16px 8px;}
.home-header-wrap.collapsed .cat{width:40px;}
.home-header-wrap.collapsed .cat .tile{transform:scale(.679);border-radius:12px;}
.home-header-wrap.collapsed .cat-label{max-width:0;opacity:0;}

/* ===================== NUDGE CARD ===================== */
.nudge{position:relative;margin:0 16px 18px;background:var(--card);border-radius:var(--radius-card);padding:14px 14px 14px 17px;display:flex;align-items:center;gap:12px;box-shadow:var(--shadow);border:1px solid var(--hairline);width:calc(100% - 32px);text-align:left;overflow:hidden;}
.nudge::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--teal);}
.nudge .ic{width:40px;height:40px;border-radius:50%;background:var(--teal-tint);display:flex;align-items:center;justify-content:center;color:var(--teal-d);font-size:17px;flex:0 0 auto;}
.nudge .body{flex:1;min-width:0;}
.nudge .title{font-weight:700;font-size:14.5px;}
.nudge .progress{display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap;}
.nudge .bar{display:flex;gap:3px;}
.nudge .bar span{width:18px;height:4px;border-radius:2px;background:var(--hairline);}
.nudge .bar span.done{background:var(--teal);}
.nudge .step-label{font-size:11px;color:var(--muted);}
.nudge .cta{color:var(--teal);font-weight:700;font-size:13px;white-space:nowrap;}

/* ===================== FEED GRID ===================== */
.section-label{padding:4px 16px 10px;font-size:13px;font-weight:700;color:var(--ink);}
.feed{display:grid;grid-template-columns:1fr 1fr;gap:14px;padding:0 16px 16px;}
.discover-row-wrap{padding:6px 0 10px;}
.discover-row-title{font-weight:800;font-size:14.5px;padding:0 16px 10px;}
.discover-scroll{display:flex;gap:12px;overflow-x:auto;padding:0 16px 4px;}
.tile-card.compact{flex:0 0 134px;width:134px;}
.tile-card.compact .thumb{aspect-ratio:3/4.2;}
.tile-card{display:flex;flex-direction:column;gap:6px;background:none;border:none;padding:0;text-align:left;transition:transform .15s ease;}
.tile-card:active{transform:scale(.97);}
.seller-row{display:flex;align-items:center;gap:6px;}
.seller-row .av{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex:0 0 auto;overflow:hidden;box-shadow:inset 0 0 0 1.5px var(--card);}
.seller-row .av-img{width:100%;height:100%;object-fit:cover;display:block;}
.seller-row .handle{font-size:12px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.thumb{position:relative;border-radius:14px;overflow:hidden;aspect-ratio:3/4;}
.thumb .art{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:34px;}
.live-badge{position:absolute;top:8px;left:8px;background:var(--live-grad);background-size:200% 200%;animation:live-grad-shift 3s ease infinite;color:#fff;font-size:10.5px;font-weight:800;padding:4px 8px;border-radius:var(--radius-pill);display:flex;align-items:center;gap:4px;box-shadow:0 2px 10px rgba(244,63,94,.45);}
.live-badge .dot{width:6px;height:6px;background:#fff;border-radius:50%;animation:live-blink 1.1s ease-in-out infinite;}
.live-badge.upcoming{background:rgba(36,31,27,.78);animation:none;box-shadow:none;}
.live-badge.upcoming .dot{background:var(--live);animation:none;}
.thumb-scrim{position:absolute;left:0;right:0;bottom:0;padding:22px 10px 9px;background:linear-gradient(to top,rgba(0,0,0,.75),rgba(0,0,0,.32) 65%,transparent);}
.thumb-title{color:#fff;font-size:12.5px;font-weight:700;line-height:1.25;text-shadow:0 1px 3px rgba(0,0,0,.35);}
.thumb-meta{color:rgba(255,255,255,.88);font-size:11px;font-weight:600;margin-top:2px;}

/* ===================== BOTTOM TAB BAR ===================== */
.tabbar{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:430px;background:#fff;border-top:1px solid var(--hairline);display:flex;align-items:center;justify-content:space-around;padding:8px 4px calc(6px + env(safe-area-inset-bottom));z-index:40;}
/* bottom:0 means "flush with the frame's own bottom edge" on a real phone, but on desktop the
   frame (#app) doesn't reach the real viewport's bottom edge anymore once --frame-h caps it — it
   ends 24px (body's own bottom padding) up from there when uncapped, or further up once actually
   capped. calc(100vh - 24px - var(--frame-h)) is the distance from the true viewport bottom up to
   the frame's own bottom edge in EITHER case, so this bar tracks the frame instead of floating
   off in the dead space below it on a tall monitor. Every other bottom-fixed bar in this file
   (cta-bar, fab-wrap, hub-golive-bar, toast-root) reuses this same formula, just adding whatever
   its own extra offset from the frame's edge already was. */
/* bars sit flush at bottom:0 now the frame fills the viewport */
.tab{display:flex;flex-direction:column;align-items:center;gap:3px;background:none;border:none;color:var(--muted);font-size:10px;font-weight:600;flex:1;padding:2px 0;}
.tab.active{color:var(--teal);}
.tab .ic{font-size:19px;}
.tab .sell-fab{width:46px;height:46px;border-radius:50%;background:var(--teal);color:#fff;display:flex;align-items:center;justify-content:center;font-size:24px;margin-top:-24px;box-shadow:0 6px 16px rgba(255,85,0,.45);border:3px solid #fff;transition:transform .15s cubic-bezier(.34,1.56,.64,1);}
.tab:active .sell-fab{transform:scale(.92);}

/* ===================== TOAST ===================== */
#toast-root{position:fixed;left:50%;bottom:96px;transform:translateX(-50%);z-index:999;width:100%;max-width:380px;pointer-events:none;display:flex;justify-content:center;}
/* Same frame-relative bottom fix as .tabbar, plus its own 96px offset above the frame's edge. */

.toast{background:var(--badge);color:#fff;padding:10px 18px;border-radius:var(--radius-pill);font-size:12.5px;font-weight:600;box-shadow:0 6px 20px rgba(0,0,0,.3);opacity:0;transform:translateY(8px);transition:all .25s ease;text-align:center;}
.toast.show{opacity:1;transform:translateY(0);}

/* ===================== FORMS / WIZARD (Stage 2) ===================== */
#app.no-tabbar{padding-bottom:0;}
.wiz-header{display:flex;align-items:center;gap:10px;padding:calc(14px + env(safe-area-inset-top)) 16px 10px;}
.wiz-back{width:34px;height:34px;border-radius:50%;background:var(--card);border:none;box-shadow:var(--shadow);font-size:16px;display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
.wiz-title{font-size:16px;font-weight:700;flex:1;}
.wiz-dots{display:flex;gap:5px;}
.wiz-dots span{width:6px;height:6px;border-radius:50%;background:var(--hairline);}
.wiz-dots span.on{background:var(--teal);}

.form-wrap{padding:4px 16px 96px;}
.field{margin-bottom:20px;}
.field label{display:block;font-size:13px;font-weight:700;color:var(--ink);margin-bottom:8px;}
.field .hint{font-size:11.5px;color:var(--muted);font-weight:400;margin-top:8px;}
.step-row{display:flex;align-items:center;gap:12px;width:100%;background:var(--card);border-radius:14px;padding:14px;box-shadow:var(--shadow);border:none;text-align:left;}
.step-row.done{background:var(--teal-tint);}
.step-num{width:28px;height:28px;border-radius:50%;background:var(--hairline);color:var(--ink);font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
.step-row.done .step-num{background:var(--teal);color:#fff;}
.step-row-body{flex:1;min-width:0;}
.step-row-title{font-weight:700;font-size:14px;}
.step-row-sub{font-size:12px;color:var(--muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.step-row-chevron{font-size:13px;color:var(--teal-d);font-weight:700;flex:0 0 auto;}
.step-row.locked{opacity:.5;}
.step-row.locked .step-row-chevron{color:var(--muted);}
.step-row.locked .step-num{background:none;font-size:15px;}

/* ===================== ONBOARDING HERO / CELEBRATION ===================== */
.ob-close{position:absolute;top:calc(14px + env(safe-area-inset-top));right:16px;width:32px;height:32px;border-radius:50%;background:rgba(36,31,27,.06);display:flex;align-items:center;justify-content:center;font-size:13px;color:var(--ink);z-index:5;border:none;}
.ob-hero{position:relative;height:110px;display:flex;align-items:center;justify-content:center;margin:calc(20px + env(safe-area-inset-top)) 0 4px;overflow:visible;}
.ob-badge{width:72px;height:72px;border-radius:50%;background:var(--brand-grad);background-size:200% 200%;animation:ob-pop .4s cubic-bezier(.34,1.56,.64,1),live-grad-shift 6s ease infinite;color:#fff;font-size:30px;font-weight:800;display:flex;align-items:center;justify-content:center;box-shadow:0 10px 26px rgba(255,85,0,.4);position:relative;z-index:2;}
@keyframes ob-pop{from{transform:scale(.4);opacity:0}to{transform:scale(1);opacity:1}}
.ob-ring{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:100px;height:100px;border-radius:50%;border:2px dashed #D4A72C;opacity:.45;animation:ob-spin 12s linear infinite;z-index:1;}
.ob-ring.ring2{width:120px;height:120px;border-color:var(--saffron);opacity:.22;animation-duration:16s;animation-direction:reverse;}
@keyframes ob-spin{to{transform:translate(-50%,-50%) rotate(360deg);}}
.ob-spark{position:absolute;color:#D4A72C;font-size:15px;animation:ob-twinkle 1.6s ease-in-out infinite;}
.ob-spark.s1{top:4px;left:29%;animation-delay:.2s;}
.ob-spark.s2{top:16px;right:26%;font-size:11px;animation-delay:.6s;}
.ob-spark.s3{bottom:6px;right:31%;font-size:13px;animation-delay:1s;color:var(--saffron);}
@keyframes ob-twinkle{0%,100%{opacity:.2;transform:scale(.8)}50%{opacity:1;transform:scale(1.15)}}
.ob-confetti-wrap{position:absolute;inset:0;pointer-events:none;overflow:visible;}
.ob-confetti{position:absolute;top:-12px;font-size:14px;line-height:1;opacity:0;animation:ob-fall 1.8s ease-in forwards;}
@keyframes ob-fall{0%{opacity:1;transform:translateY(0) rotate(0deg);}100%{opacity:0;transform:translateY(160px) rotate(180deg);}}
.ob-confetti.c1{left:4%;animation-delay:.05s;}
.ob-confetti.c2{left:17%;animation-delay:.3s;font-size:16px;}
.ob-confetti.c3{left:29%;animation-delay:.12s;font-size:12px;}
.ob-confetti.c4{left:41%;animation-delay:.4s;}
.ob-confetti.c5{left:57%;animation-delay:0s;font-size:13px;}
.ob-confetti.c6{left:69%;animation-delay:.45s;font-size:16px;}
.ob-confetti.c7{left:81%;animation-delay:.18s;}
.ob-confetti.c8{left:92%;animation-delay:.35s;font-size:12px;}
.ob-title{font-size:23px;font-weight:800;text-align:center;margin:2px 0 6px;}
.ob-subtitle{font-size:13px;color:var(--muted);text-align:center;margin:0 0 22px;}
.input{width:100%;background:var(--card);border:1px solid var(--hairline);border-radius:12px;padding:12px 14px;font-size:14px;color:var(--ink);}
.input:focus{outline:none;border-color:var(--teal);}
/* Native <select> chrome renders its own arrow glyph flush to the edge, which eats into the
   14px right padding every other .input shares — swap it for a custom chevron with real
   breathing room on both sides so dropdowns don't look lopsided next to text fields. */
select.input{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding-right:38px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236E645C' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 14px center;background-size:11px 7px;}
.select-row{width:100%;background:var(--card);border:1px solid var(--hairline);border-radius:12px;padding:13px 14px;font-size:14px;color:var(--ink);display:flex;align-items:center;justify-content:space-between;text-align:left;gap:10px;}
.select-row .ph{color:var(--muted);}
.pick-row{display:flex;align-items:flex-start;gap:12px;padding:12px;border-radius:12px;border:1px solid var(--hairline);background:var(--card);text-align:left;width:100%;margin-bottom:8px;}
.pick-row.on{border-color:var(--teal);background:var(--teal-tint);}
.pick-row .pr-radio{width:18px;height:18px;border-radius:50%;border:2px solid var(--hairline);flex:0 0 auto;margin-top:1px;position:relative;background:#fff;}
.pick-row.on .pr-radio{border-color:var(--teal);}
.pick-row.on .pr-radio::after{content:'';position:absolute;inset:2px;border-radius:50%;background:var(--teal);}
.pick-row .pr-body{flex:1;}
.pick-row .pr-title{font-weight:700;font-size:13.5px;}
.pick-row .pr-detail{font-size:11.5px;color:var(--muted);margin-top:2px;line-height:1.4;}
.toggle-row{display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--card);border-radius:14px;padding:14px;box-shadow:var(--shadow);}
.toggle-row .trow-title{font-weight:700;font-size:14px;}
.toggle-row .trow-desc{font-size:12px;color:var(--muted);margin-top:4px;line-height:1.45;}
.toggle-sw{width:46px;height:28px;border-radius:999px;background:var(--hairline);position:relative;flex:0 0 auto;border:none;padding:0;}
.toggle-sw.on{background:var(--teal);}
.toggle-sw .knob{position:absolute;top:2px;left:2px;width:24px;height:24px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3);transition:transform .18s ease;}
.toggle-sw.on .knob{transform:translateX(18px);}
.qty-stepper{display:flex;align-items:center;justify-content:space-between;background:var(--card);border:1px solid var(--hairline);border-radius:12px;padding:8px 14px;}
.qty-btn{width:30px;height:30px;border-radius:50%;background:var(--bg);border:1px solid var(--hairline);font-size:16px;font-weight:700;display:flex;align-items:center;justify-content:center;color:var(--ink);}
.qty-val{font-size:15px;font-weight:700;min-width:24px;text-align:center;}
.more-details-toggle{display:flex;align-items:center;justify-content:space-between;padding:14px 2px;background:none;border:none;width:100%;text-align:left;border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline);margin-bottom:4px;}
.more-details-toggle .mdt-chevron{font-size:12px;color:var(--muted);transition:transform .15s ease;}
.more-details-toggle.open .mdt-chevron{transform:rotate(180deg);}

.chip-set{display:flex;gap:8px;flex-wrap:wrap;}
.chip{padding:9px 14px;border-radius:var(--radius-pill);background:var(--card);border:1px solid var(--hairline);font-size:13px;font-weight:600;color:var(--ink);}
.chip{transition:transform .12s ease;}
.chip:active{transform:scale(.95);}
.chip.on{background:var(--teal);border-color:var(--teal);color:#fff;box-shadow:0 4px 12px rgba(255,85,0,.3);}
.chip .tag{font-size:9.5px;font-weight:700;background:var(--teal-tint);color:var(--teal);padding:2px 6px;border-radius:6px;margin-left:6px;vertical-align:1px;}
.chip.on .tag{background:rgba(255,255,255,.25);color:#fff;}
.chip.disabled{opacity:.45;cursor:not-allowed;}
.chip.disabled .tag{background:var(--hairline);color:var(--muted);}

.upload-tile{width:100%;aspect-ratio:16/9;border-radius:14px;border:1.5px dashed var(--hairline);background:var(--card);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;color:var(--muted);font-size:13px;font-weight:600;overflow:hidden;position:relative;}
.upload-tile.has-img{border-style:solid;color:#fff;}
.upload-tile .icon{font-size:22px;}
.upload-tile-label{position:absolute;bottom:8px;left:8px;background:rgba(0,0,0,.55);color:#fff;font-size:11.5px;font-weight:700;padding:5px 10px;border-radius:var(--radius-pill);}

.cta-bar{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:430px;background:#fff;border-top:1px solid var(--hairline);padding:12px 16px calc(12px + env(safe-area-inset-bottom));z-index:40;}
/* Same frame-relative bottom fix as .tabbar. */

.btn-primary{width:100%;background:var(--teal);color:#fff;border:none;border-radius:14px;padding:15px;font-size:15px;font-weight:700;box-shadow:0 6px 18px rgba(255,85,0,.35);transition:transform .12s ease;}
.btn-golive{width:100%;background:var(--live-grad);color:#fff;border:none;border-radius:14px;padding:15px;font-size:15px;font-weight:700;opacity:.55;cursor:not-allowed;display:flex;align-items:center;justify-content:center;gap:8px;transition:transform .12s ease;}
.btn-golive.enabled{opacity:1;cursor:pointer;box-shadow:0 8px 26px rgba(244,63,94,.5);background-size:200% 200%;animation:live-grad-shift 4s ease infinite;}
.btn-golive.enabled:active{transform:scale(.98);}
@keyframes live-grad-shift{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}
.golive-dot{width:8px;height:8px;border-radius:50%;background:#fff;box-shadow:0 0 0 3px rgba(255,255,255,.35);}
.golive-note{text-align:center;font-size:11.5px;color:var(--muted);margin-top:8px;}
.fab-wrap{position:fixed;left:50%;transform:translateX(-50%);width:100%;max-width:430px;bottom:88px;height:0;z-index:45;pointer-events:none;}
/* Same frame-relative bottom fix as .tabbar, plus its own 88px offset above the frame's edge
   (clearing the tab bar it floats above). */

.fab-add{position:absolute;right:18px;bottom:0;width:56px;height:56px;border-radius:50%;background:var(--teal);color:#fff;border:none;font-size:28px;font-weight:400;line-height:1;display:flex;align-items:center;justify-content:center;box-shadow:0 8px 22px rgba(255,85,0,.45);pointer-events:auto;transition:transform .15s cubic-bezier(.34,1.56,.64,1);}
.fab-add:active{transform:scale(.92);}
.fab-coach{position:absolute;right:8px;bottom:64px;display:flex;flex-direction:column;align-items:flex-end;pointer-events:auto;cursor:pointer;animation:fab-bob 2s ease-in-out infinite;}
.fab-coach-bubble{background:var(--ink);color:#fff;font-size:12.5px;font-weight:600;padding:10px 14px;border-radius:14px;white-space:nowrap;box-shadow:0 6px 16px rgba(0,0,0,.25);}
.fab-coach-arrow{width:0;height:0;border-left:7px solid transparent;border-right:7px solid transparent;border-top:8px solid var(--ink);margin-right:22px;margin-top:-1px;}
@keyframes fab-bob{0%,100%{transform:translateY(0);}50%{transform:translateY(-5px);}}
.btn-primary:active{background:var(--teal-d);transform:scale(.98);}
.btn-ghost{width:100%;background:none;color:var(--muted);border:none;padding:12px;font-size:13.5px;font-weight:600;}

/* ===================== MODAL / SHEET ===================== */
.scrim-screen{min-height:100vh;background:rgba(10,20,16,.72);display:flex;align-items:flex-end;}
/* Every sheet/scrim in app.js sets position:fixed;top:0;bottom:0 as an INLINE style (see e.g.
   qaLogHtml) — harmless on an actual phone (the viewport IS the screen) but on desktop it means
   the dimmed backdrop always ran the full height of the browser window, well past the now-capped
   #app frame's own top/bottom edges once --frame-h stopped that frame from growing to match. The
   !important is deliberate and the only way to win here: an inline style always beats a stylesheet
   rule of any specificity except !important, and rewriting ~29 identical inline style="..." call
   sites across app.js just to drop two properties would be far riskier than one override rule.
   Aligning to the same 24px offset + --frame-h #app itself uses keeps the scrim matched to the
   visible phone silhouette instead of bleeding out above and below it. */
@media (min-width:431px){
  .scrim-screen{top:0 !important;bottom:0 !important;min-height:0;height:var(--frame-h);}
}
.sheet{width:100%;background:var(--card);border-radius:24px 24px 0 0;padding:28px 20px calc(24px + env(safe-area-inset-bottom));text-align:center;animation:sheetup .22s ease;max-height:88vh;overflow-y:auto;}
.why-pill{font-size:11.5px;font-weight:700;color:var(--teal-d);background:var(--teal-tint);padding:6px 12px;border-radius:var(--radius-pill);}
.how-steps{display:flex;align-items:flex-start;justify-content:center;gap:2px;margin-bottom:22px;}
.how-step{display:flex;flex-direction:column;align-items:center;gap:6px;width:76px;}
.how-step .num{width:26px;height:26px;border-radius:50%;background:var(--teal);color:#fff;font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center;}
.how-step:last-child .num{background:var(--teal-d);}
.how-step span.lbl{font-size:11px;font-weight:700;text-align:center;line-height:1.25;color:var(--ink);}
.how-arrow{color:var(--hairline);font-size:16px;margin-top:6px;}
@keyframes sheetup{from{transform:translateY(30px);opacity:0}to{transform:translateY(0);opacity:1}}
.sheet .hero{width:64px;height:64px;border-radius:50%;background:var(--teal-tint);color:var(--teal);font-size:30px;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;}
.sheet h2{font-size:19px;font-weight:800;margin:0 0 8px;color:var(--teal-d);}
body.scroll-locked{position:fixed;left:0;right:0;overflow:hidden;}
.sheet p{font-size:13.5px;color:var(--muted);line-height:1.5;margin:0 0 22px;}
.sheet-handle{width:36px;height:4px;border-radius:2px;background:var(--hairline);margin:0 auto 18px;}
.sheet .features{text-align:left;margin-bottom:24px;display:flex;flex-direction:column;gap:16px;}
.sell-feature{display:flex;gap:12px;align-items:flex-start;}
.sf-icon{width:34px;height:34px;border-radius:50%;background:var(--teal-tint);color:var(--teal-d);display:flex;align-items:center;justify-content:center;font-size:15px;flex:0 0 auto;}
.sf-title{font-weight:700;font-size:14px;margin-bottom:2px;}
.sf-desc{font-size:12.5px;color:var(--muted);line-height:1.45;}
.btn-row{display:flex;gap:10px;}
.btn-row .btn-primary{flex:1;box-shadow:none;}
.btn-outline{padding:0 20px;border-radius:14px;border:1.5px solid var(--hairline);background:var(--card);color:var(--ink);font-weight:700;font-size:14px;transition:transform .12s ease,border-color .15s ease;}
.btn-outline:active{transform:scale(.97);border-color:var(--teal);}
.rte-check{flex:0 0 auto;width:18px;height:18px;border-radius:5px;border:1.5px solid var(--hairline);background:var(--card);display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff;margin-top:1px;}
.rte-check.on{background:var(--teal);border-color:var(--teal);}

/* ===================== STUDIO / LIVE (dark, warm-lantern palette) ===================== */
.studio-dark{background:var(--dark-bg);color:var(--dark-text);min-height:100vh;padding-bottom:100px;animation:none;}
.studio-dark .hint,.studio-dark .muted{color:var(--dark-muted);}
.studio-setup-head{padding:calc(16px + env(safe-area-inset-top)) 20px 4px;display:flex;align-items:center;justify-content:space-between;}
.sclose{width:32px;height:32px;border-radius:50%;background:rgba(10,20,19,.55);backdrop-filter:blur(6px);border:1px solid rgba(251,240,227,.15);color:var(--dark-text);font-size:14px;display:flex;align-items:center;justify-content:center;}
.studio-setup-head .stitle{font-weight:800;font-size:16px;}
.cam-preview{margin:14px 20px;border-radius:20px;overflow:hidden;position:relative;aspect-ratio:9/13;background:linear-gradient(135deg,var(--dark-surface),var(--dark-surface-2),#2D2732,var(--dark-surface));background-size:300% 300%;animation:cam-breathe 9s ease infinite;display:flex;align-items:center;justify-content:center;}
@keyframes cam-breathe{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}
.cam-face{font-size:52px;opacity:.5;}
.cam-preview-box{position:relative;border-radius:16px;overflow:hidden;aspect-ratio:9/13;background:var(--dark-surface-2);display:flex;align-items:center;justify-content:center;}
.camera-off-banner{display:flex;align-items:center;gap:10px;margin:10px 68px 0 14px;background:rgba(10,20,19,.7);backdrop-filter:blur(8px);border:1px solid rgba(251,240,227,.15);border-radius:12px;padding:10px 12px;flex:0 0 auto;font-size:12px;color:var(--dark-text);line-height:1.35;}
.camera-off-banner button{flex:0 0 auto;background:var(--live-grad);color:#fff;border:none;border-radius:8px;padding:7px 12px;font-size:11.5px;font-weight:800;}
.cam-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transform:scaleX(-1);}
.cam-denied{position:absolute;top:12px;left:12px;right:52px;font-size:11px;color:var(--dark-muted);line-height:1.4;background:rgba(16,30,28,.66);border-radius:10px;padding:8px 10px;}
.studio-cam-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;transform:scaleX(-1);}
.rb-card{position:relative;z-index:2;flex:0 0 auto;margin:8px 14px calc(14px + env(safe-area-inset-bottom));background:rgba(10,20,19,.78);backdrop-filter:blur(14px);border-radius:20px;padding:18px;border:1px solid rgba(251,240,227,.14);box-shadow:0 12px 32px rgba(0,0,0,.35);overflow:hidden;}
.rb-card>*{position:relative;z-index:1;}
/* A plain horizontal progress bar reads at a glance and doesn't compete visually with the bid
   amount above it — replaces the earlier rising-water-level animation, which read as too playful
   for what's meant to be a quick, functional reserve-progress indicator. Violet while climbing,
   gold once reserve is met — same "reached" signal color as the rest of the cockpit. */
.reserve-bar{margin:2px 0 14px;}
.reserve-bar-track{height:6px;border-radius:4px;background:rgba(251,240,227,.14);overflow:hidden;}
.reserve-bar-fill{height:100%;border-radius:4px;background:var(--teal);transition:width .5s cubic-bezier(.4,0,.2,1);}
.reserve-bar-fill.met{background:#FFC93C;}
.reserve-bar-label{margin-top:6px;font-size:10.5px;font-weight:800;color:var(--dark-muted);letter-spacing:.02em;text-align:right;}
.reserve-bar-label.met{color:#FFC93C;}
.rb-eyebrow{font-size:11.5px;font-weight:800;color:var(--dark-muted);letter-spacing:.2px;margin-bottom:12px;}
.bid-ladder.compact{max-height:96px;margin:10px 0;padding:8px;}
/* Full width solved the "squeezed into a narrow column" complaint, but this card is now one of
   four full-width blocks stacked between chat and the sale CTA (chat, this, pinned-strip, CTA
   bar) — at the default .rb-card/.outcome-card type scale, a sold outcome with its revenue
   breakdown was tall enough to occasionally push chat and the side-controls rail's measured
   clearance into negative territory. Trimmed padding/margins/type scale here keeps it full width
   and still easily readable while leaving enough room for everything else in the stack. */
.bid-info-card{margin:0 14px 10px;padding:14px;}
.bid-info-card .bid-hero{padding:2px 0 6px;}
.bid-info-card .bh-amount{font-size:32px;margin:1px 0;}
.bid-info-card .outcome-card{padding:8px 4px 10px;}
.bid-info-card .outcome-emoji{font-size:20px;margin-bottom:2px;}
.bid-info-card .outcome-title{font-size:16px;margin-bottom:3px;}
.bid-info-card .outcome-sub{font-size:12.5px;}
.bid-info-card .revenue-breakdown{padding:10px 14px;margin:2px 0 4px;}
.bid-info-card .rb-row{padding:3px 0;}
.bid-info-card .rb-row.total{padding-top:7px;}
.cam-controls{position:absolute;top:12px;right:12px;display:flex;flex-direction:column;gap:8px;}
.cam-ctrl-btn{width:38px;height:38px;border-radius:50%;background:rgba(16,30,28,.6);backdrop-filter:blur(4px);border:1px solid rgba(251,240,227,.2);color:var(--dark-text);font-size:15px;display:flex;align-items:center;justify-content:center;}
/* This card is placed in normal flow (position:relative, set inline) with symmetric left/right
   margins so it centers naturally under the flex-column .screen — but this rule's leftover
   left:12px/bottom:12px from an earlier absolute-positioned version were still being applied as
   *relative offsets* (position:relative honors left/top/bottom/right as shifts from the normal-flow
   position, not as box edges), nudging the whole card 12px right and 12px up from where its
   margins actually placed it. That's what read as "not centered, cramped top margin." */
.cam-check{background:rgba(16,30,28,.66);backdrop-filter:blur(4px);border-radius:12px;padding:10px 12px;display:flex;flex-direction:column;gap:8px;}
.cam-check-row{display:flex;align-items:center;justify-content:space-between;font-size:12px;font-weight:600;}
.cam-check-row .ok{color:var(--success);font-weight:800;}
.mic-bars{display:flex;align-items:flex-end;gap:2px;height:16px;}
.mic-bars span{width:3px;background:var(--success);border-radius:2px;animation:mic-bounce 1s ease-in-out infinite;}
.mic-bars span:nth-child(1){height:40%;animation-delay:0s;}
.mic-bars span:nth-child(2){height:100%;animation-delay:.15s;}
.mic-bars span:nth-child(3){height:65%;animation-delay:.3s;}
.mic-bars span:nth-child(4){height:85%;animation-delay:.45s;}
.mic-bars span:nth-child(5){height:50%;animation-delay:.6s;}
@keyframes mic-bounce{0%,100%{transform:scaleY(.5);opacity:.7}50%{transform:scaleY(1);opacity:1}}
.ros-build-row{display:flex;align-items:center;gap:10px;background:var(--dark-surface);border:1px solid var(--dark-hair);border-radius:14px;padding:10px;margin-bottom:8px;}
.ros-build-row .rbr-thumb{width:44px;height:44px;border-radius:10px;background-size:cover;background-position:center;flex:0 0 auto;display:flex;align-items:center;justify-content:center;font-size:19px;}
.ros-build-row .rbr-body{flex:1;min-width:0;}
.ros-build-row .rbr-title{font-weight:700;font-size:13.5px;color:var(--dark-text);}
.ros-build-row .rbr-sub{font-size:11.5px;color:var(--dark-muted);}
.ros-build-row .rbr-actions{display:flex;gap:4px;flex:0 0 auto;}
.rbr-btn{width:28px;height:28px;border-radius:50%;background:var(--dark-surface-2);color:var(--dark-text);border:none;font-size:12px;line-height:1;display:flex;align-items:center;justify-content:center;}
/* Filled and colored rather than the neutral grey used for "remove" (✕) — the add affordance
   needs to read as inviting/tappable at a glance, not just structurally identical to a delete. */
.rbr-btn.add{background:var(--teal);color:#fff;font-size:15px;font-weight:700;}
.rbr-check{width:24px;height:24px;border-radius:50%;border:2px solid var(--dark-hair);flex:0 0 auto;display:flex;align-items:center;justify-content:center;font-size:12px;color:transparent;}
.rbr-check.on{background:var(--teal);border-color:var(--teal);color:#fff;}
/* Shop-tray line-up row: same card shell as .ros-build-row, but a block container (not a single
   tap target) so a thumb+body+status top line can sit above an explicit Pin/Edit/Delete action
   row instead of the whole card being one implicit "tap to pin" button. */
.lineup-row{background:var(--dark-surface);border:1px solid var(--dark-hair);border-radius:14px;padding:10px;margin-bottom:8px;}
.lineup-row-top{display:flex;align-items:center;gap:10px;}
.lineup-row-actions{display:flex;gap:6px;margin-top:9px;}
.lineup-action-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:5px;padding:8px 4px;border-radius:10px;background:var(--dark-surface-2);border:1px solid var(--dark-hair);color:var(--dark-text);font-size:11.5px;font-weight:700;font-family:inherit;}
/* Same color-intent language as the sale CTAs elsewhere: teal = primary/affirmative (Pin),
   neutral outline = secondary (Edit), red = destructive (Delete). */
.lineup-action-btn.primary{background:var(--teal);border-color:var(--teal);color:#fff;}
.lineup-action-btn.danger{color:var(--live);border-color:rgba(255,90,90,.35);}
.ros-build-row.off{opacity:.45;}
.ros-build-row.big{padding:12px;margin-bottom:10px;transition:transform .15s ease,box-shadow .15s ease;position:relative;}
.ros-build-row.big.dragging{transition:none;box-shadow:0 10px 26px rgba(0,0,0,.45);background:var(--dark-surface-2);}
.rbr-thumb.big{width:58px;height:58px;border-radius:12px;font-size:24px;}
.rbr-grip{flex:0 0 auto;width:26px;height:36px;display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--dark-muted);font-size:16px;cursor:grab;touch-action:none;}
.ros-build-row.big.dragging .rbr-grip{cursor:grabbing;color:var(--dark-text);}
/* The preview viewport: normal-flow flex:1 box spanning from the cam-check card down to the
   Go-live bar, sharing their 20px side gutters. The camera feed, connecting skeleton, and the
   line-up tray all live INSIDE it — so the tray automatically matches the cam-check card's
   horizontal alignment, and the video can never sprawl behind the whole screen again. */
.setup-preview{position:relative;z-index:2;flex:1 1 auto;min-height:0;margin:14px 20px 0;border-radius:16px;overflow:hidden;background:#08120F;border:1px solid rgba(251,240,227,.12);}
.setup-preview .studio-cam-bg{border-radius:inherit;}
.setup-preview-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;}
/* All four corners at the preview's 16px radius: the tray sits flush against the preview's
   rounded bottom corners, so square bottom corners were getting clipped at an angle by the
   preview's overflow:hidden — matching the radius keeps the two outlines concentric. */
.setup-lineup-panel{position:absolute;bottom:0;left:0;right:0;z-index:2;background:rgba(10,20,19,.78);backdrop-filter:blur(14px);border-radius:16px;border:1px solid rgba(251,240,227,.12);max-height:82%;display:flex;flex-direction:column;}
.setup-panel-handle{width:100%;background:none;border:none;padding:10px 0 6px;display:flex;flex-direction:column;align-items:center;flex:0 0 auto;}
.setup-panel-toggle-label{font-size:11px;font-weight:800;color:var(--dark-muted);text-transform:uppercase;letter-spacing:.3px;}
.setup-panel-body{padding:0 20px 20px;overflow-y:auto;min-height:0;}
/* Camera-focus mode used to just shrink the line-up panel down to a 60px handle bar while still
   keeping the Go Live button on screen — still visual clutter over the camera preview, just less
   of it. Now camera-focus hides the panel AND the Go Live button completely, leaving only this one
   small, low-contrast link to bring both back — the camera preview genuinely has the screen to
   itself until the seller asks for the line-up again. */
.setup-show-lineup-link{position:absolute;bottom:12px;left:50%;transform:translateX(-50%);z-index:2;display:flex;align-items:center;gap:6px;background:rgba(10,20,19,.5);backdrop-filter:blur(6px);border:1px solid rgba(251,240,227,.16);color:var(--dark-muted);font-size:12.5px;font-weight:700;padding:9px 18px;border-radius:var(--radius-pill);white-space:nowrap;}

/* Studio live cockpit */
.studio-backdrop{position:relative;min-height:100vh;background-size:cover;background-position:center;overflow:hidden;}
.studio-scrim{position:absolute;inset:0;background:linear-gradient(180deg,rgba(6,13,12,.75) 0%,rgba(6,13,12,.25) 22%,rgba(6,13,12,.35) 60%,rgba(4,9,8,.92) 100%);}
.studio-content{position:relative;z-index:2;min-height:100vh;display:flex;flex-direction:column;}
/* Both .studio-dark's padding-bottom:100px AND .studio-content's own (now-removed) 104px were
   stacking on top of each other, plus on top of a min-height:100vh box — two nested
   min-height:100vh boxes don't share one viewport-height, so the outer just grows to fit the
   inner PLUS both of those redundant paddings, producing a page-level scroll/overflow that
   pushed "Start the sale"/the bid card below the visible screen. Neither padding is actually
   needed: every bottom-section variant that lives in this column (.sell-cta-bar, .rb-card)
   already supplies its own bottom margin/padding with calc(...+ env(safe-area-inset-bottom)),
   so the column itself doesn't need to reserve any extra space beneath them. Zeroing it here
   (cockpit only — screenStudioSetup also uses .studio-dark.studio-backdrop but has no inner
   .studio-content and lays its CTA out directly, so it still needs .studio-dark's own padding
   and must NOT be touched by this rule). */
.studio-cockpit{padding-bottom:0;}
/* On the desktop "floating phone" preview (see the #app rule under the same breakpoint near the
   top of this file), #app is 48px shorter than 100vh — body adds 24px of padding above AND below
   it to frame it. Every studio-family screen hardcodes min-height:100vh on .studio-dark/
   .studio-backdrop (correct for a real mobile viewport, where #app IS the full 100vh), so on
   desktop specifically each of those screens rendered 48px taller than the #app box actually
   holding it. #app has no fixed height, only min-height, so it simply grew to fit rather than
   clipping — pushing <body> 48px past the viewport and leaving a stray page scrollbar with the
   bottom controls (Start the sale / bid card / Go live) scrolled out of view. This must come
   after the base .studio-dark/.studio-backdrop/.studio-content rules above so the override
   actually wins the cascade (an earlier, equal-specificity rule loses to these regardless of
   being inside a @media block). */
@media (min-width:431px){
  .studio-dark,.studio-backdrop{min-height:var(--frame-h);}
  .studio-cockpit .studio-content{min-height:var(--frame-h);}
}
.studio-topbar{display:flex;align-items:center;gap:8px;padding:calc(14px + env(safe-area-inset-top)) 14px 0;flex-wrap:wrap;row-gap:6px;}
.live-pill{display:flex;align-items:center;gap:5px;background:var(--live-grad);background-size:200% 200%;animation:live-grad-shift 3s ease infinite;color:#fff;font-size:11px;font-weight:800;padding:5px 10px 5px 8px;border-radius:var(--radius-pill);letter-spacing:.3px;box-shadow:0 2px 10px rgba(244,63,94,.4);}
.live-pill .dot{width:6px;height:6px;border-radius:50%;background:#fff;animation:live-blink 1.1s ease-in-out infinite;}
@keyframes live-blink{0%,100%{opacity:1}50%{opacity:.25}}
.viewer-chip,.gmv-chip,.tip-chip{display:flex;align-items:center;gap:4px;background:rgba(10,20,19,.55);backdrop-filter:blur(4px);color:var(--dark-text);font-size:11.5px;font-weight:700;padding:5px 10px;border-radius:var(--radius-pill);border:none;white-space:nowrap;}
.gmv-chip{color:var(--success);}
/* Tips were only ever visible after the fact, in the post-stream Insights tray — this mirrors
   the GMV chip so the running total is visible live, right in the topbar, the moment a tip lands. */
.tip-chip{color:#FF9478;}
.gmv-chip.tappable-chip{font-family:inherit;cursor:pointer;}
.studio-end-btn{margin-left:auto;background:rgba(10,20,19,.55);color:var(--dark-text);border:none;font-size:12px;font-weight:700;padding:6px 12px;border-radius:var(--radius-pill);}
.giveaway-corner{position:absolute;top:64px;right:12px;background:rgba(10,20,19,.6);backdrop-filter:blur(4px);color:var(--dark-text);font-size:11px;font-weight:700;padding:6px 10px;border-radius:12px;text-align:center;z-index:2;}
.ros-rail{display:flex;gap:8px;overflow-x:auto;padding:14px 14px 0;flex:0 0 auto;}
.ros-item{flex:0 0 auto;width:52px;text-align:center;opacity:.55;cursor:pointer;}
.ros-item.now{opacity:1;}
.ros-item.resolved{cursor:default;}
.ros-item.locked{cursor:not-allowed;}
.ros-item .ri-thumb{width:44px;height:44px;border-radius:10px;background-size:cover;background-position:center;border:2px solid transparent;margin:0 auto 3px;}
.ros-item.now .ri-thumb{border-color:var(--teal);box-shadow:0 0 0 3px rgba(255,85,0,.3);}
/* Plain colored text directly over a photo/camera background was unreadable depending on what
   was behind it — bare teal-on-photo at 9px, worse still at the .55 opacity non-pinned items sit
   at. A small solid pill behind the text guarantees contrast regardless of what's underneath. */
.ros-item .ri-label{font-size:9.5px;font-weight:800;color:var(--dark-text);text-transform:uppercase;letter-spacing:.3px;background:rgba(6,13,12,.72);border-radius:5px;padding:2px 5px;display:inline-block;}
.ros-item.now .ri-label{background:var(--teal);color:#fff;}
.ros-item.locked:not(.resolved) .ri-label{background:var(--amber);color:#241a05;}
.ros-item .ri-sold{font-size:12px;}
.ros-add-item{flex:0 0 auto;width:52px;text-align:center;background:none;border:none;padding:0;}
.ros-add-item .ri-add-thumb{width:44px;height:44px;border-radius:10px;margin:0 auto 3px;border:1.5px dashed var(--dark-hair);color:var(--dark-muted);display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:700;}
.studio-cam-zone{position:relative;flex:1;min-height:0;display:flex;flex-direction:column;}
.ai-pulse-row{display:flex;align-items:center;gap:6px;padding:10px 68px 0 14px;flex-wrap:wrap;flex:0 0 auto;}
.ai-pulse-label{font-size:10px;font-weight:800;color:var(--dark-muted);text-transform:uppercase;letter-spacing:.3px;}
.pulse-pill{font-size:11px;font-weight:700;color:var(--dark-text);background:rgba(245,158,11,.22);border:1px solid rgba(245,158,11,.5);padding:3px 9px;border-radius:var(--radius-pill);}
.ai-question-chip{display:flex;align-items:center;gap:8px;margin:8px 68px 0 14px;background:rgba(245,158,11,.18);border:1px solid rgba(245,158,11,.45);border-radius:12px;padding:9px 11px;text-align:left;width:calc(100% - 82px);flex:0 0 auto;}
.ai-question-chip.poll-chip{background:rgba(255,85,0,.16);border-color:rgba(255,85,0,.4);}
.aiq-badge{flex:0 0 auto;background:var(--teal);color:#fff;font-size:9.5px;font-weight:800;padding:3px 7px;border-radius:7px;}
.aiq-text{flex:1;min-width:0;font-size:12px;font-weight:600;color:var(--dark-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.aiq-cta{flex:0 0 auto;font-size:11.5px;font-weight:800;color:var(--teal);}
.aiq-sheet-badge{display:inline-block;background:var(--teal);color:#fff;font-size:10.5px;font-weight:800;padding:4px 10px;border-radius:8px;}
.pinned-note-banner{margin:8px 68px 0 14px;background:rgba(255,201,60,.16);border:1px solid rgba(255,201,60,.4);border-radius:10px;padding:8px 11px;font-size:12px;font-weight:700;color:var(--dark-text);flex:0 0 auto;}
/* Bottom-cluster layout, top to bottom: .chat-cta-row (a flex ROW holding two column-flex
   siblings — chat left, sale CTA(s) right with buttons stacked vertically), then the
   pinned-product strip, then the bidding-details card at the very bottom. Chat and the CTAs
   being separate columns in one row is what structurally prevents them from ever overlapping:
   chat can grow only within its own column's width/height, never into the CTA box. When a
   phase has no tappable action, .cta-col isn't rendered and chat takes the full row. */
/* No align-items:flex-end here — that would let a 32vh chat overflow out the TOP of a row that
   flex has shrunk shorter than it (bottom-anchored children aren't height-capped by their row).
   Default stretch gives both columns the row's real height; each column then bottom-aligns its
   own content with justify-content:flex-end, and chat's min-height:0 lets it actually shrink. */
/* 14px side padding to line up with the cards below (.rb-card margins use 14px), so the chat
   box's left edge and the icon rail's right edge sit flush with the pinned/bid cards' edges. */
.chat-cta-row{display:flex;flex-direction:row;gap:16px;flex:0 1 auto;min-height:0;padding:0 14px;}
/* ONE consolidated auction card at the bottom (industry pattern — Whatnot/TikTok Shop dock a
   single card with product + current bid + timer + action, they never stack two cards that
   repeat the same product): the pinned strip hosts the live bid info AND the sale CTA inside
   itself. flex:0 0 auto and no overflow — this card must never scroll internally or get pushed
   off; CHAT (flex:0 1 auto above) is the one region that compresses when space runs out. */
.pinned-strip-slot{flex:0 0 auto;}
.pinned-strip-slot .rb-card{margin:10px 14px 0;padding:14px;}
/* Live bid info embedded in the card: strip the nested rb-card chrome, hide the duplicate
   product-name label (the strip's title row already says it), and flatten the hero into a
   single row — amount, winner, countdown — instead of a tall centered block. */
.bid-info-inline{margin-top:10px;border-top:1px solid rgba(251,240,227,.12);}
.bid-info-inline .rb-card{margin:0;padding:10px 0 0;background:none;border:none;backdrop-filter:none;border-radius:0;overflow:visible;}
.bid-info-inline .bh-label{display:none;}
.bid-info-inline .bid-hero{display:flex;align-items:center;gap:10px;text-align:left;padding:0;}
.bid-info-inline .bh-amount{font-size:24px;margin:0;}
.bid-info-inline .bh-winner{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bid-info-inline .bid-countdown{margin-top:0;flex:0 0 auto;}
/* Compact in-card sale CTA. Multi-button phases still stack vertically inside the card. */
.pinned-strip-card .sell-cta-bar{padding:0;margin-top:10px;}
.pinned-strip-card .sell-cta{padding:10px 14px;font-size:13.5px;border-radius:12px;box-shadow:0 4px 14px rgba(255,85,0,.4);}
.studio-bottom-cluster{padding-bottom:calc(12px + env(safe-area-inset-bottom));}
.chat-col{display:flex;flex-direction:column;justify-content:flex-end;flex:1 1 auto;min-width:0;min-height:0;position:relative;}
/* Content-sized, not a fixed 45%: a hard 45% basis left dead space between chat's right edge and
   the narrow icon rail whenever the tallest CTA was just the 40px icons. Sizing to content lets
   chat run right up to the column; max-width still stops long sale-CTA labels from starving chat
   (they wrap instead). */
.cta-col{display:flex;flex-direction:column;justify-content:flex-end;flex:0 1 auto;max-width:45%;min-width:0;}
/* The row itself carries the shared side/bottom padding, so the CTA bar drops its own. */
.chat-cta-row .sell-cta-bar{padding:0;align-self:stretch;}
/* Everything below the camera controls (chat, bid-info card, pinned strip, sale CTA) lives inside
   one cluster, pushed to the bottom via margin-top:auto. syncStudioBottomCluster() (called at the
   end of every render()) sets this cluster's max-height inline, in real measured pixels, to
   "camZone's height minus 270px" — 270px being the icon rail's reserved zone (its 14px top offset
   + up to 256px of height — 5 buttons + gaps, see .studio-side-controls). A pure-CSS
   max-height:calc(100% - 270px)
   here looked like it should work but didn't actually apply in testing (camZone's own height
   comes from flex:1 rather than an explicit height, and that wasn't resolving as a definite
   height for a percentage-height child to measure against) — real pixels sidestep that ambiguity
   entirely. Because the cap applies to the CLUSTER itself, not a sibling being measured after the
   fact, the browser's normal flex-shrink behavior can act on it correctly: chat and the CTA bar
   keep their natural size (flex-shrink:0 below), and .bid-status-stack — the one part whose height
   genuinely varies by phase (a two-button "reserve not met" outcome vs. a single "Start the sale"
   button) — is what shrinks and scrolls internally if the cluster doesn't have room for everything.
   This guarantees the cluster's top edge can never creep above the reserved rail zone, regardless
   of how much chat or sale history piles up. */
.studio-bottom-cluster{display:flex;flex-direction:column;flex:0 1 auto;min-height:0;margin-top:auto;overflow:hidden;}
.bid-status-stack{display:flex;flex-direction:column;flex:0 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;}
.bid-status-stack::-webkit-scrollbar{display:none;}
/* Pinned-product strip: full width now, so .pinned-lot's normal horizontal thumb+text+status row
   (defined further down) just works — no compacting needed. It's the last thing in its card since
   the action button moved out to its own bar, so drop the trailing margin that used to separate it
   from that button. */
.pinned-strip-card .pinned-lot{margin-bottom:0;}
.pinned-strip-card .pl-status{white-space:nowrap;}
/* Taller (44vh) and with a LONG top fade: the old 4% mask cut messages off almost sharply.
   Ramping transparent → full over the top ~28% makes the oldest visible messages progressively
   ghost out, so chat looks like it's vanishing into the stream rather than being clipped. */
/* Fixed flex-basis (not "auto") on purpose: a content-sized box grows taller every time a new
   message arrives (up to the old max-height), which reads as the whole panel jumping around as
   chat fills up. Pinning the basis to 44vh means the box is always 44vh — few messages just leave
   blank space at the top (chat-overlay-inner still bottom-aligns them) — and only genuinely tight
   vertical space (flex-shrink:1, see .studio-bottom-cluster above) ever makes it smaller. */
.chat-overlay{flex:0 1 44vh;min-height:0;padding:8px 12px;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;background:rgba(10,20,19,.4);backdrop-filter:blur(10px);border-radius:16px;border:1px solid rgba(251,240,227,.1);-webkit-mask-image:linear-gradient(to bottom,transparent,rgba(0,0,0,.18) 10%,rgba(0,0,0,.55) 19%,#000 28%);mask-image:linear-gradient(to bottom,transparent,rgba(0,0,0,.18) 10%,rgba(0,0,0,.55) 19%,#000 28%);scrollbar-width:thin;scrollbar-color:rgba(251,240,227,.25) transparent;}
.chat-overlay::-webkit-scrollbar{width:4px;}
.chat-overlay::-webkit-scrollbar-thumb{background:rgba(251,240,227,.25);border-radius:4px;}
.chat-overlay::-webkit-scrollbar-track{background:transparent;}
/* Inner flex wrapper does the bottom-alignment. Doing justify-content:flex-end directly on the
   scrollable (.chat-overlay) element is a known Chromium gotcha: it suppresses scrollable
   overflow entirely, so the container silently stops scrolling once content exceeds its height.
   min-height:100% here lets this wrapper bottom-align when short and grow (and overflow the
   parent, enabling real scrolling) when the message list is tall. */
.chat-overlay-inner{display:flex;flex-direction:column;justify-content:flex-end;min-height:100%;gap:4px;}
/* Anchored to .chat-col (its own positioned parent). The chat/CTA row is the TOP block of the
   bottom cluster, with only free camera space above it, so floating just above the chat box is
   safe again — it can't land on the pinned strip or bid card, which both sit BELOW the row. */
.chat-jump-btn{position:absolute;bottom:calc(100% + 8px);right:0;background:rgba(10,20,19,.78);backdrop-filter:blur(8px);border:1px solid rgba(251,240,227,.18);color:var(--dark-text);font-size:10.5px;font-weight:700;padding:6px 10px;border-radius:20px;z-index:6;box-shadow:0 4px 12px rgba(0,0,0,.3);white-space:nowrap;}
/* Sits below the message list now (not above it) — anchored to the stable bottom edge of a
   fixed-height chat box instead of floating at a top edge that used to move with content. */
.chat-tab-row{display:flex;gap:6px;margin-top:6px;flex:0 0 auto;}
.chat-tab-btn{background:none;border:none;color:var(--dark-muted);font-size:11.5px;font-weight:800;padding:5px 11px;border-radius:var(--radius-pill);}
.chat-tab-btn.on{color:#fff;background:var(--teal);box-shadow:0 2px 8px rgba(255,85,0,.4);}
.watching-list{display:flex;flex-direction:column;gap:2px;}
.watching-row{display:flex;align-items:center;gap:10px;flex-shrink:0;padding:5px 2px;}
.watching-avatar{width:30px;height:30px;border-radius:50%;background:var(--dark-surface-2);flex:0 0 auto;object-fit:cover;box-shadow:0 0 0 1.5px rgba(251,240,227,.14);}
.watching-name{font-size:12.5px;font-weight:700;color:var(--dark-text);text-shadow:0 1px 3px rgba(0,0,0,.6);}
/* Compact chat: smaller type, tighter leading, slimmer bubble padding, 4px message gap. */
.chat-msg{flex-shrink:0;font-size:11.5px;line-height:1.3;color:var(--dark-text);text-shadow:0 1px 3px rgba(0,0,0,.6);background:none;border:none;text-align:left;padding:0;}
.chat-msg .chat-name{font-weight:800;color:var(--dark-muted);margin-right:5px;}
.chat-msg.question{background:rgba(245,158,11,.22);border:1px solid rgba(245,158,11,.55);border-radius:8px;padding:4px 7px;}
.chat-msg.question .q-badge{background:var(--teal);color:#fff;font-size:9px;font-weight:800;padding:1px 6px;border-radius:6px;margin-right:5px;vertical-align:1px;}
.chat-msg.seller-reply{background:rgba(255,85,0,.22);border:1px solid rgba(255,85,0,.5);border-radius:8px;padding:4px 7px;text-shadow:none;}
.chat-msg.seller-ask{background:rgba(255,85,0,.2);border:1px solid rgba(255,85,0,.5);border-radius:8px;padding:4px 7px;text-shadow:none;}
.chat-msg.quick-reply{background:rgba(255,85,0,.16);border:1px solid rgba(255,85,0,.4);border-radius:8px;padding:4px 7px;text-shadow:none;}
.chat-msg.celebration{background:linear-gradient(135deg,rgba(255,201,60,.28),rgba(245,158,11,.24));border:1px solid rgba(255,201,60,.55);border-radius:8px;padding:5px 8px;text-shadow:none;font-weight:800;text-align:center;color:var(--dark-text);}
.chat-msg.tip{background:linear-gradient(135deg,rgba(255,201,60,.3),rgba(255,148,120,.24));border:1px solid rgba(255,148,120,.55);border-radius:8px;padding:5px 8px;text-shadow:none;font-weight:800;text-align:center;color:var(--dark-text);}
.chat-msg.ai-detected{background:rgba(245,158,11,.22);border:1px solid rgba(245,158,11,.55);border-radius:8px;padding:5px 8px 6px;text-shadow:none;font-weight:700;}
.chat-msg.ai-detected .reply-feedback{color:var(--saffron);font-weight:800;}
.chat-msg.tappable{cursor:pointer;}
.seller-badge{background:var(--success);color:#fff;font-size:9px;font-weight:800;padding:1px 6px;border-radius:6px;margin-right:5px;vertical-align:1px;display:inline-block;}
.reply-feedback{font-size:10.5px;color:var(--dark-muted);margin-top:4px;text-shadow:none;}
.reply-to-line{font-size:10.5px;color:var(--dark-muted);margin-bottom:2px;text-shadow:none;font-style:italic;}
.tagged-row{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:4px;}
.tagged-row.small{margin-bottom:6px;}
.tag-chip{background:rgba(255,85,0,.2);color:#8FDDE8;font-size:10px;font-weight:700;padding:2px 7px;border-radius:8px;}
.thread-list{margin-bottom:8px;}
.thread-reply{background:var(--dark-surface-2);border-radius:10px;padding:8px 10px;margin-bottom:6px;font-size:12.5px;line-height:1.5;color:var(--dark-text);}
.thread-close-btn{background:var(--dark-surface-2);border:1px solid var(--dark-hair);color:var(--dark-text);width:28px;height:28px;border-radius:50%;font-size:12px;line-height:1;flex:0 0 auto;}
.qa-thread-scroll{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;margin:0 -20px;padding:0 20px;}
.qa-bubble{max-width:88%;border-radius:16px;padding:10px 13px;margin-bottom:10px;font-size:13px;line-height:1.5;}
.qa-bubble-buyer{background:var(--dark-surface-2);color:var(--dark-text);border-bottom-left-radius:4px;margin-right:auto;}
.qa-bubble-seller{background:linear-gradient(135deg,#FF7A2E,var(--teal-d));color:#fff;border-bottom-right-radius:4px;margin-left:auto;}
.qa-bubble-meta{font-size:10.5px;font-weight:700;opacity:.75;}
.qa-bubble-buyer .qa-bubble-meta{margin-bottom:4px;}
.qa-bubble-seller .qa-bubble-meta{margin-top:5px;}
.qa-bubble-text{white-space:pre-wrap;}
.insights-chip{background:rgba(245,158,11,.16) !important;border-color:rgba(245,158,11,.45) !important;}
.insights-chip .aiq-badge{background:var(--saffron) !important;}
.reply-again-link{background:none;border:none;color:var(--teal);font-weight:800;font-size:10.5px;padding:0;margin-left:6px;text-decoration:underline;}
.chat-menu-action{display:block;width:100%;text-align:left;background:var(--dark-surface-2);border:1px solid var(--dark-hair);color:var(--dark-text);font-weight:700;font-size:14px;padding:13px 14px;border-radius:12px;margin-bottom:8px;}
.chat-menu-action.danger{color:#FF6B6B;}
/* Lives inside .rb-card now (the awaiting-sale state uses the same card chrome as the live bid
   card, for visual continuity between "about to sell" and "selling now") so it no longer needs
   its own background/border/margin — .rb-card already supplies those. */
.pinned-lot{display:flex;align-items:center;gap:10px;margin-bottom:14px;cursor:pointer;}
.pinned-lot .pl-thumb{width:48px;height:48px;border-radius:10px;background-size:cover;background-position:center;flex:0 0 auto;}
.pinned-lot .pl-body{flex:1;min-width:0;}
.pinned-lot .pl-title{font-weight:800;font-size:13.5px;color:var(--dark-text);}
.pinned-lot .pl-sub{font-size:11.5px;color:var(--dark-muted);}
.pl-status{flex:0 0 auto;font-size:10px;font-weight:800;color:var(--dark-muted);background:rgba(251,240,227,.08);padding:6px 9px;border-radius:8px;white-space:nowrap;}
/* The rail is NO LONGER an absolutely-positioned overlay floating over the camera zone — that
   out-of-flow positioning was the root cause of every "chat overlaps the CTAs" round: an overlay
   participates in no row/column, so nothing could ever reserve space for it. It now lives in
   normal flow inside .cta-col (chat's sibling in .chat-cta-row), stacked above the sale CTA:
   one row = [chat] [mic/camera/flip/questions/AI + sale button]. Overlap is now impossible. */
.studio-side-controls{display:flex;flex-direction:column;align-items:center;gap:6px;align-self:flex-end;flex:0 0 auto;padding:7px 6px;border-radius:26px;background:rgba(255,255,255,.12);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(255,255,255,.18);box-shadow:0 10px 26px rgba(0,0,0,.34);}
.side-ctrl-btn{position:relative;width:44px;height:44px;border-radius:50%;background:transparent;border:0;color:var(--dark-text);display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
.side-ctrl-btn.off{color:var(--live);}
.side-ctrl-btn.engage-btn{background:var(--live-grad);color:#fff;border-color:transparent;}
/* Shop is the rail's most-used, most-important button (the only way into tonight's whole line-up),
   so it reads with more weight than a plain icon: same gradient fill as engage-btn, plus a size bump
   the badge (unchanged position/size) still sits correctly on since it's just a bigger relative parent. */
.side-ctrl-btn.shop-btn{width:44px;height:44px;background:var(--live-grad);color:#fff;border-color:transparent;}
.side-ctrl-gap{height:4px;}
.side-ctrl-badge{position:absolute;top:-4px;right:-4px;background:var(--live-pink);color:#fff;font-size:9px;font-weight:800;min-width:16px;height:16px;border-radius:8px;display:flex;align-items:center;justify-content:center;padding:0 3px;}
.sell-cta-bar{position:relative;z-index:2;padding:10px 14px calc(12px + env(safe-area-inset-bottom));flex:0 0 auto;}
.sell-cta{width:100%;background:linear-gradient(135deg,#FF7A2E,var(--teal));color:#fff;border:none;border-radius:16px;padding:16px;font-size:15.5px;font-weight:800;box-shadow:0 8px 24px rgba(255,85,0,.5);transition:transform .12s ease;}
.sell-cta:active{transform:scale(.98);}
.sell-cta.golive-cta{background:var(--live-grad);background-size:200% 200%;animation:live-grad-shift 4s ease infinite;box-shadow:0 8px 24px rgba(244,63,94,.45);}
/* Same dimmed/no-glow/not-allowed language as .btn-golive's own disabled default, applied here so
   an untitled ad-hoc stream reads as clearly not-ready-yet rather than a bug when Go live won't tap. */
.sell-cta:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;animation:none;}
.countdown-glow{position:absolute;width:280px;height:280px;border-radius:50%;background:var(--live-grad);filter:blur(50px);opacity:.55;animation:countdown-pulse 1.1s ease-in-out infinite;}
@keyframes countdown-pulse{0%,100%{transform:scale(.9);opacity:.45}50%{transform:scale(1.08);opacity:.7}}
.countdown-live-text{text-shadow:0 4px 24px rgba(244,63,94,.6);}
.awaiting-banner{width:100%;background:rgba(251,240,227,.05);color:var(--dark-muted);border:1px solid rgba(251,240,227,.12);border-radius:16px;padding:15px;font-size:13.5px;font-weight:700;text-align:center;cursor:default;}
.awaiting-row{display:flex;gap:8px;align-items:stretch;}

/* Sell-format sheet + bid setup/live share the dark sheet look */
.dsheet{width:100%;background:var(--dark-surface);color:var(--dark-text);border-radius:24px 24px 0 0;padding:22px 20px calc(22px + env(safe-area-inset-bottom));animation:sheetup .22s ease;max-height:92vh;overflow-y:auto;}
.dsheet .sheet-handle{background:var(--dark-hair);}
.dfield{margin-bottom:18px;}
.dfield label{display:block;font-size:13px;font-weight:700;margin-bottom:8px;color:var(--dark-text);}
.dinput{width:100%;background:var(--dark-bg);border:1.5px solid var(--dark-hair);border-radius:12px;padding:13px 14px;font-size:15px;color:var(--dark-text);font-family:inherit;}
.dinput::placeholder{color:var(--dark-muted);}
/* Same native-select-arrow fix as the light .input — without it the browser's own arrow sits
   flush against the border, which reads as "missing padding" on the live create-product form. */
select.dinput{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding-right:38px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%239DBDB8' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 14px center;background-size:11px 7px;}
textarea.dinput{resize:vertical;}
.dchip-set{display:flex;flex-wrap:wrap;gap:8px;}
.dchip{padding:9px 14px;border-radius:var(--radius-pill);background:var(--dark-surface-2);border:1.5px solid var(--dark-hair);font-size:12.5px;font-weight:700;color:var(--dark-text);}
.dchip.on{background:var(--teal);border-color:var(--teal);color:#fff;}
.dphoto-tile{width:100%;aspect-ratio:4/3;border-radius:14px;background:var(--dark-surface-2);border:1.5px dashed var(--dark-hair);display:flex;align-items:center;justify-content:center;text-align:center;padding:12px;color:var(--dark-muted);font-size:12.5px;font-weight:700;background-size:cover;background-position:center;}
/* ===================== SKELETONS / MOCKED LATENCY ===================== */
@keyframes shimmer-sweep{ 0%{background-position:-300px 0;} 100%{background-position:300px 0;} }
.shimmer{background:linear-gradient(90deg, rgba(255,255,255,.06) 25%, rgba(255,255,255,.16) 37%, rgba(255,255,255,.06) 63%); background-size:600px 100%; animation:shimmer-sweep 2.6s ease-in-out infinite;}
.shimmer.light{background:linear-gradient(90deg, rgba(20,15,10,.06) 25%, rgba(20,15,10,.13) 37%, rgba(20,15,10,.06) 63%); background-size:600px 100%;}
.cam-connecting-skel{position:absolute;inset:0;}
.btn-loading{position:relative;color:transparent !important;pointer-events:none;}
.btn-loading::after{content:'';position:absolute;top:50%;left:50%;width:18px;height:18px;margin:-9px 0 0 -9px;border-radius:50%;border:2.5px solid rgba(255,255,255,.4);border-top-color:#fff;animation:btn-spin .7s linear infinite;}
@keyframes btn-spin{ to{ transform:rotate(360deg); } }
#boot-skeleton{max-width:430px;margin:0 auto;min-height:100vh;background:var(--bg);}
@media (min-width:431px){ #boot-skeleton{min-height:var(--frame-h);} }
.boot-skel-top{height:54px;background:var(--card);border-bottom:1px solid var(--hairline);}
.boot-skel-row{display:flex;gap:10px;padding:14px 16px;}
.boot-skel-pill{width:64px;height:26px;border-radius:999px;flex:0 0 auto;}
.boot-skel-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:4px 16px;}
.boot-skel-card{display:flex;flex-direction:column;gap:6px;}
.boot-skel-thumb{width:100%;aspect-ratio:3/4;border-radius:14px;}
.boot-skel-line{height:11px;border-radius:6px;width:80%;}
.boot-skel-line.short{width:45%;}
.pv-photo{width:100%;aspect-ratio:4/3;border-radius:16px;background-size:cover;background-position:center;margin-bottom:4px;}
.pv-detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px 14px;}
.pv-detail{display:flex;flex-direction:column;gap:1px;font-size:12.5px;}
.pv-detail-k{color:var(--dark-muted);font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.3px;}
.pv-detail-v{color:var(--dark-text);font-weight:600;}
.engage-option{display:flex;align-items:center;gap:12px;width:100%;background:var(--dark-surface-2);border:1px solid var(--dark-hair);border-radius:14px;padding:13px;text-align:left;margin-bottom:10px;}
.eo-icon{width:38px;height:38px;border-radius:50%;background:rgba(255,85,0,.18);color:var(--teal);display:flex;align-items:center;justify-content:center;font-size:17px;flex:0 0 auto;}
.eo-body{flex:1;min-width:0;}
.eo-title{font-weight:800;font-size:14px;color:var(--dark-text);}
.eo-desc{font-size:11.5px;color:var(--dark-muted);margin-top:2px;line-height:1.4;}
.qa-log-row{border-bottom:1px solid var(--dark-hair);padding:12px 0;}
.qa-log-row:last-child{border-bottom:none;}
.qa-log-q{font-weight:700;font-size:13.5px;color:var(--dark-text);margin-bottom:6px;}
.qa-log-a{font-size:12.5px;color:var(--dark-muted);line-height:1.5;margin-bottom:6px;}
.qa-log-feedback{font-size:11.5px;color:var(--dark-muted);}
.poll-bar-row{margin-bottom:16px;}
.poll-bar-label{display:flex;justify-content:space-between;font-size:12.5px;font-weight:700;color:var(--dark-text);margin-bottom:6px;}
.poll-bar-track{height:10px;background:var(--dark-surface-2);border-radius:6px;overflow:hidden;}
.poll-bar-fill{height:100%;background:var(--teal);border-radius:6px;transition:width .4s ease;}
/* Tabbed "Live activity" tray — one place to see every kind of interaction (questions, polls,
   comments, pinned notes) instead of buyer questions vanishing because they only ever showed up
   in a log meant for answered Q&A. */
.activity-tabs{display:flex;gap:4px;margin-bottom:14px;border-bottom:1px solid var(--dark-hair);flex:0 0 auto;}
.activity-tab-body{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;margin:0 -20px;padding:0 20px 6px;scrollbar-width:thin;scrollbar-color:rgba(251,240,227,.25) transparent;}
.activity-tab-body::-webkit-scrollbar{width:4px;}
.activity-tab-body::-webkit-scrollbar-thumb{background:rgba(251,240,227,.25);border-radius:4px;}
.activity-tab{flex:1;background:none;border:none;padding:0 2px 10px;font-size:12px;font-weight:700;color:var(--dark-muted);border-bottom:2px solid transparent;display:flex;align-items:center;justify-content:center;gap:5px;white-space:nowrap;}
.activity-tab.active{color:var(--dark-text);border-bottom-color:var(--teal);}
.activity-tab-count{background:var(--live);color:#fff;font-size:9.5px;font-weight:800;min-width:15px;height:15px;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;padding:0 4px;}
.activity-section-title{font-size:11px;font-weight:800;color:var(--dark-muted);text-transform:uppercase;letter-spacing:.4px;margin:14px 0 8px;}
.activity-section-title:first-child{margin-top:0;}
.activity-empty{text-align:center;color:var(--dark-muted);font-size:13px;padding:22px 0;}
.activity-unanswered-row{background:var(--dark-surface-2);border-radius:12px;padding:10px 12px;margin-bottom:8px;border-left:3px solid var(--live);width:100%;text-align:left;}
.qa-thread-list{display:flex;flex-direction:column;}
.qa-thread-row{background:var(--dark-surface-2);border-radius:12px;padding:10px 12px;margin-bottom:8px;border-left:3px solid transparent;width:100%;text-align:left;}
.qa-thread-row.unread{border-left-color:var(--live);background:rgba(229,72,63,.12);}
.qa-thread-top{display:flex;align-items:flex-start;gap:6px;}
.qa-thread-dot{width:6px;height:6px;border-radius:50%;background:var(--live);flex:0 0 auto;margin-top:6px;}
.qa-thread-q{font-size:13px;line-height:1.4;color:var(--dark-text);font-weight:600;}
.qa-thread-row.unread .qa-thread-q{font-weight:800;}
.qa-thread-q.answered{font-weight:600;color:var(--dark-muted);}
.qa-thread-preview{font-size:12px;line-height:1.4;color:var(--dark-muted);margin-top:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.qa-thread-meta{font-size:10.5px;font-weight:700;color:var(--dark-muted);margin-top:5px;}
.qa-thread-row.unread .qa-thread-meta{color:var(--live);}
.activity-unanswered-q{font-size:13px;font-weight:700;color:var(--dark-text);margin-bottom:2px;}
.activity-unanswered-meta{font-size:11px;color:var(--dark-muted);}
.activity-poll-row{background:var(--dark-surface-2);border-radius:12px;padding:10px 12px;margin-bottom:8px;width:100%;text-align:left;}
.activity-poll-row .apr-q{font-size:13px;font-weight:700;color:var(--dark-text);margin-bottom:3px;}
.activity-poll-row .apr-meta{font-size:11px;color:var(--dark-muted);}
.chat-msg.log-row{display:block;padding:9px 0;border-bottom:1px solid var(--dark-hair);text-shadow:none;}
.chat-msg.log-row:last-child{border-bottom:none;}
.activity-note-card{background:var(--dark-surface-2);border-radius:14px;padding:14px;margin-bottom:12px;}
.activity-note-text{font-size:13.5px;color:var(--dark-text);line-height:1.5;margin-bottom:10px;}
/* 3-step "feature this item" wizard: pick product -> pick bid type + details -> final preview
   & pin. Same step header/dots across all three sheets so it reads as one continuous flow even
   though each step is still its own bottom sheet, matching how every other tray in this screen works. */
.wizard-step-label{font-size:11px;font-weight:800;color:var(--teal);text-transform:uppercase;letter-spacing:.4px;margin-bottom:8px;}
.wizard-dots{display:flex;gap:5px;margin-bottom:16px;}
.wizard-dot{flex:1;height:4px;border-radius:2px;background:var(--dark-hair);}
.wizard-dot.done{background:var(--teal);}
.wizard-preview-bid-card{background:var(--dark-surface-2);border-radius:14px;padding:4px 14px;margin-bottom:16px;}
.wpbc-row{display:flex;justify-content:space-between;font-size:13px;padding:10px 0;border-bottom:1px solid var(--dark-hair);}
.wpbc-row:last-child{border-bottom:none;}
.wpbc-row span:first-child{color:var(--dark-muted);font-weight:600;}
.wpbc-row span:last-child{color:var(--dark-text);font-weight:800;}
.activity-note-old{font-size:12px;color:var(--dark-muted);padding:8px 0;border-top:1px solid var(--dark-hair);}
.bid-hero{text-align:center;padding:6px 0 10px;}
.bid-hero .bh-label{font-size:12px;color:var(--dark-muted);font-weight:700;}
.bid-hero .bh-amount{font-size:42px;font-weight:800;background:linear-gradient(120deg,#FFC93C,#FFE9A8 45%,#FFB800);-webkit-background-clip:text;background-clip:text;color:transparent;line-height:1.1;margin:2px 0;filter:drop-shadow(0 2px 14px rgba(255,201,60,.35));}
.bid-hero .bh-winner{font-size:13.5px;font-weight:700;color:var(--teal);}
.bid-countdown{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:15px;font-weight:800;color:var(--dark-text);background:var(--dark-surface-2);padding:5px 12px;border-radius:var(--radius-pill);display:inline-block;margin-top:8px;}
.bid-countdown.danger{color:#fff;background:var(--live);animation:live-blink 1s ease-in-out infinite;}
/* Flash Sale — layered onto the same .bid-hero/.bid-countdown skeleton bidInfoHtml already uses
   (see buyNowInfoHtml), just with an eyebrow banner + a strike-through/discounted price pair
   dropped in ahead of the existing amount. Reuses --live-grad (the "energetic live selling"
   gradient from the palette pass) so a flash sale reads as an extension of that same urgency
   language rather than a new color introduced just for this. */
.flash-banner{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:800;letter-spacing:.04em;color:#fff;background:var(--live-grad);padding:3px 10px;border-radius:var(--radius-pill);margin-bottom:8px;}
.flash-price-row{display:flex;align-items:baseline;justify-content:center;gap:8px;flex-wrap:wrap;}
.flash-strike{font-size:15px;font-weight:700;color:var(--dark-muted);text-decoration:line-through;}
.flash-pct-badge{font-size:11px;font-weight:800;color:#fff;background:var(--live);padding:2px 8px;border-radius:var(--radius-pill);align-self:center;}
.bid-info-card.flash-card{border:1px solid rgba(229,72,63,.35);box-shadow:0 0 0 1px rgba(229,72,63,.12) inset;}
.bid-info-inline .flash-price-row{flex:0 0 auto;gap:5px;}
.bid-info-inline .flash-strike{font-size:12px;}
.bid-info-inline .flash-pct-badge{font-size:9.5px;padding:1px 6px;}
/* Step-3 preview + rail-label variants — same accent, lighter touch since neither is the live
   urgency moment itself, just a preview/status of it. */
.flash-preview-card{border:1px solid rgba(229,72,63,.35);}
.flash-preview-card .wpbc-row span:last-child{color:#FFB4AE;}
.bid-ladder{display:flex;flex-direction:column-reverse;gap:6px;max-height:150px;overflow-y:auto;margin:14px 0;padding:10px;background:var(--dark-bg);border-radius:14px;}
.bid-row{display:flex;justify-content:space-between;font-size:13px;padding:4px 2px;}
.bid-row .br-name{color:var(--dark-muted);font-weight:600;}
.bid-row .br-amt{color:var(--dark-text);font-weight:800;}
.bid-row.top .br-name{color:var(--teal);}
.bid-row.top .br-amt{color:var(--teal);}
.bidbar{display:flex;gap:10px;margin-top:6px;}
.bidbar .bb-custom{flex:0 0 auto;padding:0 18px;border-radius:14px;background:var(--dark-surface-2);color:var(--dark-text);border:1.5px solid var(--dark-hair);font-weight:700;font-size:13.5px;}
.bidbar .bb-hammer{flex:1;background:linear-gradient(135deg,#FF7A2E,var(--teal));color:#fff;border:none;border-radius:14px;font-weight:800;font-size:15px;padding:14px;box-shadow:0 6px 18px rgba(255,85,0,.4);transition:transform .12s ease;}
.bidbar .bb-hammer:active{transform:scale(.97);}
.bidbar .bb-hammer:disabled{background:var(--dark-surface-2);color:var(--dark-muted);opacity:.7;box-shadow:none;}
.outcome-card{text-align:center;padding:20px 4px;}
.outcome-emoji{font-size:44px;margin-bottom:8px;}
.outcome-title{font-size:19px;font-weight:800;color:var(--dark-text);margin-bottom:4px;}
.outcome-sub{font-size:13.5px;color:var(--dark-muted);line-height:1.5;}
.confirming-spinner{width:38px;height:38px;margin:4px auto 14px;border-radius:50%;border:3px solid rgba(251,240,227,.18);border-top-color:var(--teal);animation:btn-spin .8s linear infinite;}
.revenue-breakdown{background:var(--dark-surface-2);border:1px solid var(--dark-hair);border-radius:14px;padding:14px 16px;margin:4px 0 16px;}
.rb-row{display:flex;align-items:center;justify-content:space-between;font-size:13px;font-weight:700;color:var(--dark-text);padding:5px 0;}
.rb-row.muted{color:var(--dark-muted);font-weight:600;}
.rb-row.total{border-top:1px solid var(--dark-hair);margin-top:4px;padding-top:10px;font-size:15px;font-weight:800;color:var(--success);}
.order-status-chip{flex:0 0 auto;background:rgba(58,196,125,.16);border:1px solid rgba(58,196,125,.4);color:var(--success);font-size:11px;font-weight:800;padding:4px 10px;border-radius:var(--radius-pill);}
.insight-kpi-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:18px;}
.insight-kpi{background:var(--dark-surface-2);border:1px solid var(--dark-hair);border-radius:14px;padding:12px 14px;}
.ikpi-val{font-size:20px;font-weight:800;color:var(--dark-text);}
.ikpi-of{font-size:13px;font-weight:700;color:var(--dark-muted);}
.ikpi-lbl{font-size:11px;font-weight:700;color:var(--dark-muted);margin-top:2px;}
.insight-bar{display:flex;height:10px;border-radius:6px;overflow:hidden;background:var(--dark-surface-2);margin-bottom:8px;}
.insight-bar-seg{height:100%;}
.insight-bar-seg.sold{background:var(--success);}
.insight-bar-seg.reserve{background:#FFC93C;}
.insight-bar-seg.nobid{background:#8a7563;}
.insight-bar-seg.remaining{background:rgba(255,255,255,.14);}
.insight-legend{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:18px;}
.insight-legend-item{font-size:11px;font-weight:700;color:var(--dark-muted);display:flex;align-items:center;gap:5px;}
.insight-legend-item .dot{width:7px;height:7px;border-radius:50%;display:inline-block;}
.insight-legend-item .dot.sold{background:var(--success);}
.insight-legend-item .dot.reserve{background:#FFC93C;}
.insight-legend-item .dot.nobid{background:#8a7563;}
.insight-legend-item .dot.remaining{background:rgba(255,255,255,.3);}
.insight-stat-row{display:flex;align-items:center;justify-content:space-between;font-size:12.5px;font-weight:700;color:var(--dark-text);padding:6px 0;border-bottom:1px solid var(--dark-hair);}
.insight-tip{display:flex;gap:9px;align-items:flex-start;background:var(--dark-surface-2);border-radius:12px;padding:10px 12px;margin-bottom:8px;font-size:12.5px;line-height:1.45;color:var(--dark-text);}
.insight-tip-icon{font-size:15px;flex:0 0 auto;}
/* Shared between the Insights tray (dark) and the Stream Summary screen (light) — tips used to be
   a single muted row folded into the same revenue-breakdown table as sale earnings, easy to miss
   and easy to mentally lump in with sales money. Its own card with its own heading and a distinct
   tip-colored gradient makes it impossible to miss and visually says "this is separate money."
   Deliberately no explicit text-color here so it inherits whichever theme (dark studio text or
   light ink) it's dropped into rather than needing a light/dark variant of the whole component. */
.tip-summary-card{display:flex;align-items:center;gap:12px;background:linear-gradient(135deg,rgba(255,201,60,.22),rgba(255,148,120,.16));border:1px solid rgba(255,148,120,.45);border-radius:14px;padding:14px;}
.tip-summary-icon{font-size:26px;flex:0 0 auto;line-height:1;}
.tip-summary-body{flex:1;min-width:0;}
.tip-summary-amount{font-size:19px;font-weight:800;}
.tip-summary-sub{font-size:11.5px;font-weight:600;opacity:.72;margin-top:1px;}
/* Hub-level analytics trend — one bar per recent stream's gross sales, reusing the same
   dark-glass card language as the per-stream Insights tray so the Hub's aggregate view and
   the Studio's live view feel like the same product. */
.trend-bars{display:flex;align-items:flex-end;gap:6px;height:64px;margin:12px 0 4px;}
.trend-bar{flex:1;min-width:0;border-radius:4px 4px 0 0;background:linear-gradient(180deg,#FF7A2E,var(--teal));opacity:.9;}

/* Celebration banner — deliberately NOT a full-screen blocker. It used to be a fixed inset-0
   overlay with a near-opaque backdrop, which meant the seller couldn't tap anything else on
   screen for the full 2.6s every time it fired (which is often — it fires on every single sale).
   Now it's a small floating card near the top: pointer-events:none on the wrapper so clicks pass
   straight through to the cockpit underneath, and it doesn't dim or block the rest of the screen. */
.celebration-overlay{position:fixed;top:10px;left:50%;transform:translateX(-50%);width:100%;max-width:430px;z-index:70;display:flex;justify-content:center;overflow:visible;pointer-events:none;}
/* Same frame-relative top fix as .home-header-wrap, plus its own 10px offset below the frame's edge. */
@media (min-width:431px){ .celebration-overlay{top:34px;} }
.celebration-card{text-align:center;padding:12px 20px;position:relative;z-index:2;background:rgba(20,14,8,.94);border-radius:16px;box-shadow:0 8px 24px rgba(0,0,0,.35);animation:cel-drop .4s cubic-bezier(.34,1.56,.64,1);max-width:88%;}
@keyframes cel-drop{0%{transform:translateY(-16px);opacity:0}100%{transform:translateY(0);opacity:1}}
.celebration-glow{position:absolute;top:50%;left:50%;width:130px;height:130px;margin:-65px 0 0 -65px;border-radius:50%;background:var(--brand-grad);filter:blur(30px);opacity:.4;z-index:-1;animation:cel-glow-pulse 1.6s ease-in-out infinite;}
@keyframes cel-glow-pulse{0%,100%{opacity:.3}50%{opacity:.5}}
.celebration-emoji{font-size:32px;margin-bottom:4px;animation:cel-pop .5s cubic-bezier(.34,1.56,.64,1);}
@keyframes cel-pop{0%{transform:scale(.3);opacity:0}100%{transform:scale(1);opacity:1}}
.celebration-title{font-size:16px;font-weight:800;background:var(--brand-grad);-webkit-background-clip:text;background-clip:text;color:transparent;margin-bottom:2px;}
.celebration-sub{font-size:12px;color:var(--dark-muted);}
.confetti-wrap{position:absolute;top:0;left:0;right:0;height:120px;pointer-events:none;overflow:hidden;}
.confetti-bit{position:absolute;top:-10px;font-size:14px;animation:conf-fall 1.6s ease-in forwards;}
@keyframes conf-fall{0%{transform:translateY(0) rotate(0);opacity:1}100%{transform:translateY(140px) rotate(300deg);opacity:0}}

/* Stream summary (light, since it's a post-stream report) */
.summary-hero{text-align:center;padding:28px 20px 8px;}
.summary-hero .sh-emoji{font-size:42px;}
.summary-kpi-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:12px 16px;}
.summary-kpi{background:var(--card);border-radius:14px;padding:14px;box-shadow:var(--shadow);}
.summary-kpi .sk-label{font-size:11.5px;color:var(--muted);font-weight:700;margin-bottom:4px;}
.summary-kpi .sk-val{font-size:20px;font-weight:800;}
.summary-kpi .sk-val.success{color:var(--success);}
.sale-row{display:flex;align-items:center;gap:12px;background:var(--card);border-radius:14px;padding:10px;box-shadow:var(--shadow);margin-bottom:8px;}
.sale-row .sr-thumb{width:44px;height:44px;border-radius:10px;background-size:cover;background-position:center;flex:0 0 auto;}
.sale-row .sr-body{flex:1;min-width:0;}
.sale-row .sr-title{font-weight:700;font-size:13.5px;}
.sale-row .sr-buyer{font-size:11.5px;color:var(--muted);}
.sale-row .sr-amt{font-weight:800;color:var(--success);font-size:14px;}

/* ===================== SELLER HUB (v2) ===================== */
.hub-screen{background:var(--bg);min-height:100vh;padding-bottom:calc(84px + env(safe-area-inset-bottom));}
/* Same fix as the studio-family screens: this is a normal-flow child of #app, not a sibling, so
   its own uncapped min-height:100vh was pushing #app taller right along with it on desktop (a
   min-height parent doesn't clip an oversized child) — capping #app alone wasn't enough while
   this rule still independently demanded the full, uncapped viewport height. */
@media (min-width:431px){ .hub-screen{min-height:var(--frame-h);} }
.hub-header{display:flex;align-items:center;justify-content:space-between;padding:calc(18px + env(safe-area-inset-top)) 18px 12px;}
.hub-greet{font-weight:800;font-size:20px;color:var(--ink);}
.hub-sub{font-size:12px;font-weight:700;color:var(--teal-d);text-transform:uppercase;letter-spacing:.4px;margin-top:2px;}
.hub-shop-link{background:var(--card);border:1px solid var(--hairline);border-radius:var(--radius-pill);padding:8px 13px;font-size:12.5px;font-weight:700;color:var(--ink);box-shadow:var(--shadow);transition:transform .12s ease;}
.hub-shop-link:active{transform:scale(.95);}
.hub-body{padding:4px 18px 0;}
.hub-momentum{display:flex;align-items:center;gap:10px;width:100%;background:var(--teal-tint);border:none;border-radius:14px;padding:12px 14px;margin-bottom:14px;text-align:left;transition:transform .12s ease;}
.hub-momentum:active{transform:scale(.98);}
.hub-momentum .hm-emoji{font-size:17px;flex:0 0 auto;}
.hub-momentum .hm-text{flex:1;min-width:0;font-size:12.5px;font-weight:600;color:var(--teal-d);line-height:1.4;}
.hub-momentum .hm-arrow{font-size:17px;font-weight:700;color:var(--teal-d);flex:0 0 auto;}
.hub-stat-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}
.hub-stat{background:var(--card);border:none;border-radius:var(--radius-card);padding:14px;text-align:left;box-shadow:var(--shadow);transition:transform .12s ease;}
.hub-stat:active{transform:scale(.96);}
.hub-stat-val{font-weight:800;font-size:20px;color:var(--ink);letter-spacing:-.2px;}
.hub-stat-label{font-size:11.5px;font-weight:700;color:var(--muted);margin-top:2px;}
/* The seller's real, spendable money — the one number on this screen that matters most.
   Gradient + glow singles it out from the other three plain-count stats at a glance. */
.hub-stat-hero{background:var(--brand-grad);background-size:200% 200%;box-shadow:var(--glow-teal);}
.hub-stat-hero .hub-stat-val{color:#fff;font-size:22px;}
.hub-stat-hero .hub-stat-label{color:rgba(255,255,255,.85);}
.hub-card{background:var(--card);border-radius:var(--radius-card);padding:14px;box-shadow:var(--shadow);margin-bottom:10px;}
.hub-card-hero{background:var(--brand-grad);background-size:200% 200%;box-shadow:var(--glow-teal);}
.hub-card-hero .hub-card-kicker{color:rgba(255,255,255,.75);}
.hub-card-hero .hub-stat-val{color:#fff;font-size:23px;}
.hub-card-hero .hub-stat-label{color:rgba(255,255,255,.75);}
.hub-card-kicker{font-size:10.5px;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.4px;}
.hub-card-title{font-weight:800;font-size:15px;color:var(--ink);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hub-card-sub{font-size:12.5px;color:var(--muted);margin-top:2px;}
.hub-actions{display:flex;gap:8px;margin-top:12px;}
.hub-btn{padding:10px 16px;font-size:13.5px;border-radius:12px;width:auto;}
.hub-btn-outline{background:none;border:1.5px solid var(--hairline);border-radius:12px;padding:10px 14px;font-size:13px;font-weight:700;color:var(--ink);}
.hub-btn-danger{background:none;border:none;padding:10px 8px;font-size:13px;font-weight:700;color:var(--live);}
.hub-empty{text-align:center;color:var(--muted);font-size:13px;padding:26px 16px;line-height:1.5;}
.hub-seg{display:flex;background:rgba(36,31,27,.06);border-radius:var(--radius-pill);padding:3px;margin-bottom:12px;}
.hub-seg-btn{flex:1;border:none;background:none;border-radius:var(--radius-pill);padding:8px 4px;font-size:12.5px;font-weight:700;color:var(--muted);white-space:nowrap;}
.hub-seg-btn.on{background:var(--card);color:var(--ink);box-shadow:var(--shadow);}
/* Dark-sheet variant (live "Add a product" tray) — same segmented control, restyled with dark
   tokens so it reads correctly against .dsheet instead of nearly disappearing (the light version's
   near-transparent track + white active pill were tuned for a cream background). */
.hub-seg.dark{background:var(--dark-surface-2);}
.hub-seg.dark .hub-seg-btn{color:var(--dark-muted);}
.hub-seg.dark .hub-seg-btn.on{background:var(--teal);color:#fff;box-shadow:none;}
.hub-pill{flex:0 0 auto;font-size:10px;font-weight:800;color:var(--teal-d);background:var(--teal-tint);padding:4px 9px;border-radius:var(--radius-pill);white-space:nowrap;}
.hub-pill.ok{color:var(--success);background:rgba(30,158,107,.12);}
.hub-pill.draft{color:var(--amber);background:rgba(245,158,11,.14);}
.hub-pill.muted{color:var(--muted);background:rgba(110,100,92,.10);}
.hub-table-head{display:flex;gap:8px;padding:0 14px 8px;font-size:10.5px;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.4px;}
.hub-order-row{display:flex;gap:8px;align-items:center;background:var(--card);border-radius:var(--radius-card);padding:12px 14px;box-shadow:var(--shadow);margin-bottom:8px;font-size:12.5px;color:var(--ink);}
.hub-demo-note{font-size:11.5px;color:var(--muted);background:rgba(36,31,27,.05);border-radius:10px;padding:8px 12px;margin-bottom:12px;text-align:center;}
.hub-escrow{font-size:12px;color:var(--ink);background:var(--teal-tint);border-radius:10px;padding:10px 12px;margin-top:10px;line-height:1.5;}
.hub-tabbar .tab.active{color:var(--teal-d);}
/* Docked at the bottom of the screen, sitting just above the hub tab bar. */
.hub-golive-bar{position:fixed;bottom:calc(62px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);width:100%;max-width:430px;padding:10px 18px;z-index:39;}
/* Same frame-relative bottom fix as .tabbar, plus its own 62px offset above the frame's edge
   (clearing the tab bar it floats above, same reasoning as .fab-wrap). */

.hub-fab{font-size:18px;}
.hub-fab-label{font-size:10px;font-weight:800;color:var(--teal-d);margin-top:2px;}

.shop-tabs{display:flex;gap:22px;border-bottom:1px solid var(--dark-hair);margin:12px 0 10px;}
.shop-tab{background:none;border:0;border-bottom:2px solid transparent;color:var(--dark-muted);font:inherit;font-size:14.5px;font-weight:700;padding:8px 0;margin-bottom:-1px;display:inline-flex;align-items:center;gap:7px;cursor:pointer;}
.shop-tab.on{color:var(--dark-text);border-bottom-color:var(--teal);}
.shop-tab-n{font-size:11px;font-weight:700;color:var(--dark-muted);background:rgba(255,255,255,.09);padding:1px 8px;border-radius:999px;}
.shop-tab.on .shop-tab-n{background:var(--teal);color:#fff;}

.fmt-tabs{display:flex;gap:20px;border-bottom:1px solid var(--hairline);margin:2px 0 8px;}
.fmt-tab{background:none;border:0;border-bottom:2px solid transparent;color:var(--muted);font:inherit;font-size:14.5px;font-weight:700;padding:8px 0;margin-bottom:-1px;cursor:pointer;}
.fmt-tab.on{color:var(--ink);border-bottom-color:var(--teal);}
