/* Bazaar — royal casual UI. Tokens first, then components, then screens. */

:root{
  --ink:#3B1F0E;           /* outlines */
  --wood:#7A441C; --muted:#9A6B3F;
  --cream1:#FFF9EA; --cream2:#F8E7C2; --cream3:#E9CF9A;
  --gold1:#FFE28A; --gold2:#F3B634; --gold3:#B7791F;
  --red1:#F4574D; --red2:#C92A22; --red3:#861914;
  --green1:#9BE34A; --green2:#43AE1E; --green3:#1F6A0C;
  --blue1:#4F8BE6; --blue2:#2458B8; --blue3:#163A7E;
  --purple1:#A57BEA; --purple2:#6A3CC0; --purple3:#40217E;
  --pos:#2F8A12; --neg:#C92A22;
  --band-g1:#04A36B; --band-g2:#004522; --band-y1:#F9C93F; --band-y2:#E5A01D; --band-r1:#DF1E3B; --band-r2:#A2031B;   /* the quantity slider's price bands */
  --display:"Lilita One","Baloo 2",system-ui,sans-serif;
  --body:"Baloo 2","Segoe UI",system-ui,sans-serif;
  --phone-w:430px;
  --safe-t:env(safe-area-inset-top,0px);
  --safe-b:env(safe-area-inset-bottom,0px);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;height:100%}
/* Added to the home screen, iOS takes 100% as the screen less the status bar
   while drawing from the very top, so the page stopped short and the body's
   blue showed as a band under the tab bar (2026-10-22). The dynamic viewport
   is the whole screen there and the visible area in a browser tab. */
@supports (height:100dvh){html,body{height:100dvh}}
body{
  font-family:var(--body);font-variant-numeric:tabular-nums;color:var(--ink);
  background:radial-gradient(circle at 50% -10%,#7FD3F7 0%,#2E8FD6 42%,#12518F 100%) fixed #12518F;
  display:flex;justify-content:center;align-items:center;overflow:hidden;-webkit-font-smoothing:antialiased;
}
body::before{content:"";position:fixed;inset:0;pointer-events:none;opacity:.12;
  background-image:radial-gradient(circle,#fff 2px,transparent 2.5px);background-size:34px 34px}
img{max-width:100%}
/* iPhone Safari draws a button its own way (a white face, rounded corners,
   padding, its own alignment) unless told not to: the tool slots came out as
   white-backed ovals and the portrait sat off-centre in its frame (testers,
   2026-10-22). Every button here is drawn by this stylesheet, so none is native. */
button{font:inherit;color:inherit;cursor:pointer;-webkit-appearance:none;appearance:none}
p{margin:0 0 10px;line-height:1.4}

/* ---------- phone frame + background art ---------- */
#phone{position:relative;width:100%;max-width:var(--phone-w);height:100%;overflow:hidden;isolation:isolate;background:#2A1608}
@media (min-width:560px) and (min-height:640px){
  #phone{height:min(900px,calc(100% - 40px));border-radius:36px;border:4px solid rgba(255,255,255,.55);
    box-shadow:0 24px 60px rgba(8,40,80,.5)}
  /* A transformed child escapes a rounded `overflow:hidden` — the corners clip
     square for as long as the transform lasts. So the screen and the overlay
     carry the frame's own radius and clip themselves, rather than trusting the
     frame to do it. Without this the arrival animation squared off the phone's
     corners for its whole 260ms, every time a tab was tapped. 32px, because the
     frame's 36px is measured outside its 4px border. */
  #screen,#overlay{border-radius:32px}
}
#bg{position:absolute;inset:-12px;z-index:0;background:url("../assets/bg/muziris.jpg") center 35%/cover no-repeat;transition:filter .3s}
#phone:not([data-view="home"]) #bg{filter:blur(5px) brightness(.62) saturate(1.1)}
#screen{position:absolute;inset:0;z-index:1;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;scrollbar-width:none}
#screen::-webkit-scrollbar{display:none}
/* Arriving somewhere new: the screen rises into place. Short enough that it
   never delays a tap, since it is decoration over content that is already
   there and already interactive. */
#screen.entering{animation:screenin .26s cubic-bezier(.25,.9,.35,1)}
@keyframes screenin{from{opacity:0;transform:translateY(12px) scale(.985)}}
@media (prefers-reduced-motion:reduce){
  #screen.entering{animation:none}
  .flygood,.flycoin.burst{display:none}
}
#overlay{position:absolute;inset:0;z-index:5;pointer-events:none}
#overlay.on{pointer-events:auto}
.screen{position:relative;min-height:100%;display:flex;flex-direction:column}
.screen.dim{background:rgba(20,10,4,.25)}
.grow{flex:1}

/* ---------- type helpers ---------- */
.out,.rtext,.btn,.tab span,.tile .tl{font-family:var(--display);font-weight:400;letter-spacing:.3px}
.out{color:#fff;text-shadow:0 2px 0 var(--ink),2px 0 0 var(--ink),-2px 0 0 var(--ink),0 -2px 0 var(--ink),2px 2px 0 var(--ink),-2px 2px 0 var(--ink),2px -2px 0 var(--ink),-2px -2px 0 var(--ink),0 4px 0 rgba(0,0,0,.3)}
.pos{color:var(--pos)} .neg{color:var(--neg)}
.fine{font-size:12.5px;font-weight:700;color:var(--muted);text-align:center;margin:6px 0 10px}
.note{font-size:12.5px;font-weight:700;color:#fff;text-align:center;text-shadow:0 1px 3px rgba(0,0,0,.7);margin:6px 8px 12px}
.hint{font-size:12px;font-weight:800;color:var(--muted);text-align:center;margin:0 0 8px}
.hint.light{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.7);margin:0 0 10px}
.center{text-align:center}
.stack{display:grid;}
.ico{display:block;width:40px;height:40px;object-fit:contain;flex:none;user-select:none;-webkit-user-drag:none}
.ico.inl{display:inline-block;width:18px;height:18px;vertical-align:-3px}

/* ---------- buttons ---------- */
.btn{--b1:var(--green1);--b2:var(--green2);--b3:var(--green3);
  position:relative;display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:0;
  padding:9px 14px 10px;border-radius:16px;border:3px solid var(--ink);color:#fff;font-size:18px;line-height:1.05;
  background:linear-gradient(var(--b1) 0%,var(--b1) 8%,var(--b2) 92%);
  box-shadow:inset 0 3px 0 rgba(255,255,255,.45),inset 0 -4px 0 rgba(0,0,0,.18),0 4px 0 var(--b3),0 7px 12px rgba(0,0,0,.3);
  transition:transform .06s,box-shadow .06s}
.btn::after{content:"";position:absolute;left:10px;right:10px;top:4px;height:34%;border-radius:10px;background:linear-gradient(rgba(255,255,255,.35),rgba(255,255,255,0));pointer-events:none}
.btn:active:not(:disabled){transform:translateY(3px);box-shadow:inset 0 3px 0 rgba(255,255,255,.45),inset 0 -4px 0 rgba(0,0,0,.18),0 1px 0 var(--b3)}
.btn:disabled{filter:grayscale(.75) brightness(.95);opacity:.6;cursor:default}
.btn small{font-family:var(--body);font-weight:800;font-size:12px;opacity:.95;}
.btn.red{--b1:var(--red1);--b2:var(--red2);--b3:var(--red3)}
.btn.gold{--b1:#FFE9A0;--b2:var(--gold2);--b3:var(--gold3);}

.btn.purple{--b1:var(--purple1);--b2:var(--purple2);--b3:var(--purple3)}
.btn.blue{--b1:var(--blue1);--b2:var(--blue2);--b3:var(--blue3)}
.btn.cream{--b1:#FFFBEF;--b2:var(--cream3);--b3:#A77E45;}

.btn.wide{display:flex;width:100%}
.btn.xl{display:flex;width:100%;font-size:30px;padding:10px 16px 12px;border-radius:20px;border-width:4px}

.buyrow{flex-direction:row!important;justify-content:space-between!important;}
.buyrow .cost{display:inline-flex;align-items:center;gap:4px;background:rgba(0,0,0,.2);border-radius:999px;padding:2px 12px 2px 6px}
.buyrow .cost .inl{width:22px;height:22px}

.xbtn{position:absolute;;z-index:3;;border-radius:50%;;color:#fff;font-family:var(--display);font-size:22px;line-height:1}
.xbtn span{display:block;margin-top:-2px;text-shadow:0 2px 0 var(--red3)}
.xbtn:active{transform:translateY(2px)}

/* ---------- ribbon + crest ---------- */
.ribbon{--r1:var(--red1);--r2:var(--red2);--r3:var(--red3);
  position:relative;display:flex;justify-content:center;align-items:center;margin:0 18px;padding:9px 18px 10px;min-height:52px;
  background:linear-gradient(var(--r1),var(--r2));border:3px solid var(--ink);border-radius:12px;
  box-shadow:inset 0 3px 0 rgba(255,255,255,.35),inset 0 -5px 0 rgba(0,0,0,.18),0 4px 0 rgba(0,0,0,.25)}
.ribbon::before,.ribbon::after{content:"";position:absolute;top:14px;bottom:-10px;width:30px;z-index:-1;
  background:var(--r3);border:3px solid var(--ink)}
.ribbon::before{left:-20px;clip-path:polygon(0 0,100% 0,100% 100%,0 100%,30% 50%)}
.ribbon::after{right:-20px;clip-path:polygon(0 0,100% 0,70% 50%,100% 100%,0 100%)}
.ribbon .rtext{position:relative;z-index:1;font-size:28px;line-height:1;color:#FFF4D6;
  text-shadow:0 2px 0 var(--ink),2px 0 0 var(--ink),-2px 0 0 var(--ink),0 -2px 0 var(--ink),2px 2px 0 var(--ink),-2px 2px 0 var(--ink),0 4px 0 rgba(0,0,0,.25)}
.ribbon .crest{position:absolute;left:50%;top:-36px;width:92px;height:46px;transform:translateX(-50%);z-index:0;filter:drop-shadow(0 2px 0 rgba(0,0,0,.25))}
.ribbon.purple{--r1:var(--purple1);--r2:var(--purple2);--r3:var(--purple3)}
.ribbon.gold{--r1:#FFD86B;--r2:#E39A1B;--r3:#9A5E0C}
.ribbon.green{--r1:#7FD23C;--r2:#35961A;--r3:#1B5A0A}
.ribbon.blue{--r1:var(--blue1);--r2:var(--blue2);--r3:var(--blue3)}

/* ---------- dialog ---------- */
.scrim{position:absolute;inset:0;display:flex;justify-content:center;
  background:rgba(12,6,2,.62);animation:fade .18s;overflow-y:auto}
@keyframes fade{from{opacity:0}}
.dialog{position:relative;width:100%;max-width:380px;animation:pop .28s cubic-bezier(.3,1.5,.5,1)}
@keyframes pop{from{transform:scale(.85);opacity:0}}
.dlg-head{position:relative;z-index:2;}
.dlg-body{position:relative;padding:40px 18px 18px;border-radius:24px;text-align:center;
  background:linear-gradient(var(--cream1),var(--cream2));border:4px solid var(--gold2);
  box-shadow:0 0 0 4px var(--ink),inset 0 0 0 3px #FFF6DC,0 16px 34px rgba(0,0,0,.45)}
.dlg-body p{font-size:14px;font-weight:700;color:#6A4020}
.bigicon{display:grid;place-items:center;margin:0 auto 6px}
.bigicon .ico{width:92px;height:92px;filter:drop-shadow(0 4px 3px rgba(0,0,0,.25))}
.bignum{font-family:var(--display);font-size:40px;line-height:1.05;margin:0 0 8px}

.nearmiss{background:#FFF0B8;border:2.5px solid var(--gold3);border-radius:12px;padding:6px 10px;font-weight:800!important;color:var(--ink)!important}

.opts{display:grid;gap:9px;grid-template-columns:1fr 1fr}
.opts.n3{grid-template-columns:1fr}
.opts .btn{font-size:16px}

/* panel boxes inside dialogs */
.panelbox{background:#FFF6E0;border:2.5px solid var(--cream3);border-radius:18px;padding:8px 10px 10px;margin:0 0 10px}
.boxlabel{font-family:var(--display);font-size:17px!important;color:#6A4020!important;margin:0 0 6px!important}
.slots{display:flex;justify-content:center;flex-wrap:wrap;gap:8px}
.slot{display:grid;justify-items:center;align-content:center;min-width:74px;padding:6px 6px 4px;border-radius:14px;
  background:linear-gradient(#FFFDF6,#F3E2BD);border:2.5px solid var(--cream3);box-shadow:inset 0 2px 0 #fff}
.slot .ico{width:44px;height:44px}
.slot b{font-family:var(--display);font-size:17px;line-height:1.1;color:var(--ink)}
.slots.big .slot{min-width:84px}.slots.big .slot .ico{width:52px;height:52px}
.slots.small .slot{min-width:56px}.slots.small .slot .ico{width:34px;height:34px}
.slot.bad{background:linear-gradient(#FFEDEA,#F6C9C2)}
.tasklines{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:3px}
.tasklines li{font-size:13px;font-weight:800;color:#6A4020}

/* ---------- top bar ---------- */
.topbar{position:relative;z-index:3;display:flex;align-items:center;gap:6px;padding:calc(12px + var(--safe-t)) 10px 6px 12px}
.pill{position:relative;flex:1 1 0;min-width:0;display:flex;align-items:center;height:36px;margin-left:16px;padding:0 6px 0 26px;
  background:linear-gradient(#FFF8E6,#F2D9A6);border:3px solid var(--ink);border-radius:999px;
  box-shadow:inset 0 2px 0 #fff,0 3px 0 rgba(0,0,0,.3);font-family:var(--display);color:var(--ink)}
button.pill{cursor:pointer}
.topbar .pill:nth-child(2){flex-grow:1.1}
.pill > .pi,.pill .heart{position:absolute;left:-18px;top:50%;transform:translateY(-50%);width:44px;height:44px;filter:drop-shadow(0 2px 1px rgba(0,0,0,.35))}
.pill .heart .pi{width:44px;height:44px}
.pill .heart b{position:absolute;inset:0;display:grid;place-items:center;padding-bottom:3px;color:#fff;font-size:17px;
  text-shadow:0 2px 0 var(--red3),1px 0 0 var(--red3),-1px 0 0 var(--red3)}
.pill .pv{flex:1;text-align:center;font-size:17px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pill .pv.sm{font-size:15px}
.pill .plus{flex:none;width:26px;height:26px;padding:0;margin-right:-4px;border-radius:50%;border:2.5px solid var(--ink);
  background:radial-gradient(circle at 35% 30%,#B8F07A,var(--green2));color:#fff;font-family:var(--display);font-size:20px;line-height:1;text-shadow:0 1px 0 var(--green3)}
.pill.bump,[data-coinbox].bump{animation:bump .25s}
@keyframes bump{50%{transform:scale(1.1)}}
.gearbtn{flex:none;width:42px;height:42px;padding:3px;border-radius:12px;border:3px solid var(--ink);
  background:linear-gradient(var(--blue1),var(--blue2));box-shadow:0 0 0 2px var(--gold2),0 3px 0 rgba(0,0,0,.3)}
.gearbtn .ico{width:100%;height:100%}

/* ---------- nav ---------- */
.navbar{position:sticky;bottom:0;z-index:4;display:grid;align-items:end;
  margin-top:auto;padding:0 6px calc(6px + var(--safe-b));
  background:linear-gradient(#3F78D8,#1E4BA3);border-top:4px solid var(--gold2);box-shadow:0 -3px 0 var(--ink),0 -8px 18px rgba(0,0,0,.3)}
.tab{position:relative;display:grid;justify-items:center;align-content:end;gap:0;height:64px;padding:0 2px 4px;border:none;background:none;color:#fff;font-size:13px}
.tab + .tab::before{content:"";position:absolute;left:0;top:12px;bottom:10px;width:2px;background:rgba(0,0,0,.25)}
.tab .ti{width:40px;height:40px;filter:drop-shadow(0 2px 1px rgba(0,0,0,.35));transition:transform .15s}
.tab span{position:relative;text-shadow:0 2px 0 var(--ink),1px 0 0 var(--ink),-1px 0 0 var(--ink)}
.tab::after{content:"";position:absolute;left:3px;right:3px;top:-16px;bottom:3px;z-index:-1;border-radius:18px 18px 10px 10px;
  background:linear-gradient(#FFF8E6,#EFD39C);border:3px solid var(--gold2);box-shadow:0 0 0 3px var(--ink);opacity:0;transition:opacity .15s}
.tab.on::after{opacity:1}
.tab.on::before,.tab.on + .tab::before{display:none}
.tab.on .ti{transform:translateY(-12px) scale(1.25)}
.tab.on span{color:var(--ink);text-shadow:none}

/* ---------- home ---------- */
.tiles{position:absolute;z-index:2;top:calc(66px + var(--safe-t));display:grid;}
.tiles.left{left:10px}.tiles.right{right:10px}
.tile{position:relative;display:grid;justify-items:center;;border-radius:18px;;}
.tile:active{transform:translateY(2px)}

.tile .tl{line-height:1.1;white-space:nowrap}
.badge{position:absolute;top:-8px;right:-8px;min-width:24px;height:24px;padding:0 6px;border-radius:999px;display:grid;place-items:center;
  background:radial-gradient(circle at 35% 30%,#FF7B6B,var(--red2));border:2.5px solid #fff;box-shadow:0 0 0 2px var(--ink);
  color:#fff;font-family:var(--display);font-size:14px;font-style:normal;line-height:1}
.tile .tag{position:absolute;top:-12px;left:50%;transform:translateX(-50%);font-style:normal;white-space:nowrap;
  font-family:var(--display);font-size:12px;color:#fff;background:linear-gradient(var(--purple1),var(--purple2));
  border:2px solid #fff;box-shadow:0 0 0 2px var(--ink);border-radius:999px;padding:0 9px}
.tilebar{display:block;height:7px;margin-top:2px;border-radius:9px;background:#D9BD86;border:1.5px solid var(--ink);overflow:hidden}
.tilebar b{display:block;height:100%;background:linear-gradient(var(--gold1),var(--gold2))}

.playzone{position:relative;z-index:3;display:grid;justify-items:center;padding:0 28px 20px}

.levelbtn{--b3:#1F6A0C;position:relative;width:100%;max-width:300px;;
  display:grid;place-items:center;border-radius:26px;border:4px solid var(--ink);}
.levelbtn::after{content:"";position:absolute;left:14px;right:14px;top:6px;height:36%;border-radius:18px;background:linear-gradient(rgba(255,255,255,.4),rgba(255,255,255,0));pointer-events:none}
.levelbtn:active{transform:translateY(4px)}
.levelbtn .lvtext{font-family:var(--display);font-size:42px;line-height:1;color:#fff;}
.levelbtn .lvsub{font-size:13px;font-weight:800;color:#F2FFE4;text-shadow:0 1px 0 var(--b3)}
/* In the play row this is overridden to match the Haveli exactly — see below. */
.levelbtn.hard{--b1:#FF8A7A;--b2:var(--red2);--b3:var(--red3)}
.levelbtn.superhard{--b1:var(--purple1);--b2:var(--purple2);--b3:var(--purple3)}

/* ---------- tab pages ---------- */
.pagebody{padding:34px 14px 22px}

.ranklist{list-style:none;margin:0;padding:0;display:grid;gap:7px}
.ranklist li{display:grid;grid-template-columns:40px 1fr auto;align-items:center;gap:8px;padding:7px 12px;border-radius:16px;
  background:linear-gradient(var(--cream1),var(--cream2));border:3px solid var(--gold2);box-shadow:0 0 0 2px var(--ink);font-weight:800}
.ranklist li.me{background:linear-gradient(#C8F29A,#8ED45A)}
.ranklist .rk{font-family:var(--display);font-size:18px;text-align:center}

.ranklist .nm{font-size:16px}.ranklist .lv{font-size:13px;color:var(--muted)}

.eventcard{display:grid;grid-template-columns:56px 1fr auto;gap:10px;align-items:center;text-align:left;padding:8px 12px;border-radius:18px;
  background:linear-gradient(var(--cream1),var(--cream2));border:3px solid var(--gold2);box-shadow:0 0 0 2px var(--ink),0 4px 0 rgba(0,0,0,.3)}

.ename b{display:block;font-family:var(--display);font-size:17px;font-weight:400}
.ename small{display:block;font-size:12px;font-weight:700;color:#6A4020;line-height:1.3}

/* shop */
.wallet{display:flex;justify-content:center;gap:10px;margin:0 0 10px}
.wallet span{display:flex;align-items:center;gap:4px;padding:2px 12px 2px 4px;border-radius:999px;background:linear-gradient(#FFF8E6,#F2D9A6);border:2.5px solid var(--ink);font-family:var(--display);font-size:16px}
.wallet .ico{width:28px;height:28px}
.tabs{display:grid;;margin:0 0 10px;padding:4px;border-radius:14px;background:rgba(59,31,14,.55)}
.tabs button{border-radius:10px;border:none;background:transparent;color:#FFE9C0;font-family:var(--display);}
.tabs button.on{background:linear-gradient(var(--red1),var(--red2));color:#fff;box-shadow:inset 0 2px 0 rgba(255,255,255,.3),0 2px 0 var(--red3);text-shadow:0 1px 0 var(--red3)}

.shoprow{position:relative;display:grid;grid-template-columns:60px 1fr auto;align-items:center;gap:10px;padding:8px 10px;border-radius:18px;
  background:linear-gradient(var(--cream1),var(--cream2));border:3px solid var(--gold2);box-shadow:0 0 0 2px var(--ink),0 4px 0 rgba(0,0,0,.3)}

.shoprow .price{min-width:92px;font-size:17px;padding:8px 10px;flex-direction:row;gap:3px}
.rowtag{position:absolute;top:-10px;right:14px;font-style:normal;font-family:var(--display);font-size:12px;color:#fff;
  background:linear-gradient(var(--red1),var(--red2));border:2px solid #fff;box-shadow:0 0 0 2px var(--ink);border-radius:999px;padding:0 9px}

/* ---------- brief (level popup) ---------- */
.brief{justify-content:center;padding:56px 16px 24px}

.introbox{display:flex;gap:10px;align-items:center;text-align:left;margin:0 0 10px;padding:8px 10px;border-radius:16px;background:#E6F3FF;border:2.5px solid #9CC3EA}
.introbox .ico{width:46px;height:46px}
.introbox b{display:block;font-size:14px}
.introbox p{font-size:12.5px!important;margin:0!important;color:#34506F!important}
.boosts{justify-content:center;padding:8px 0 4px}
.boost{flex:0 0 auto;width:50px;height:50px;padding:4px;border-radius:50%;border:3px solid var(--ink);
  background:radial-gradient(circle at 40% 30%,#C6F08D,var(--green2) 70%);box-shadow:0 0 0 3px var(--gold2),0 4px 0 rgba(0,0,0,.3)}
.boost .ico{width:100%;height:100%}
.boost .badge{top:-6px;right:-8px;min-width:22px;height:22px;font-size:12px}
.boost .badge.free{background:radial-gradient(circle at 35% 30%,#FFD27A,#E0701C)}
.boost .tick{right:auto;}

.boost.empty{filter:grayscale(.8);opacity:.7}
.boost.locked{background:radial-gradient(circle,#B9B3A6,#7C7466);box-shadow:0 0 0 3px #CFC6B3}
.facts{display:flex;justify-content:center;gap:6px;flex-wrap:wrap;}
.facts span{display:inline-flex;align-items:center;gap:4px;padding:2px 9px 2px 3px;border-radius:999px;background:#FFF6E0;border:2px solid var(--cream3);font-size:12px;white-space:nowrap}
.facts .ico{width:21px;height:21px}

/* ---------- game ---------- */
.game .navbar{display:none}
.hud{position:sticky;top:0;z-index:4;padding:calc(8px + var(--safe-t)) 10px 8px;
  background:linear-gradient(#2E5DB8,#1D3F88);border-bottom:4px solid var(--gold2);box-shadow:0 3px 0 var(--ink),0 8px 16px rgba(0,0,0,.35)}
.hudrow{position:relative;;;}
.hudexit{;;;border-radius:50%;;color:#fff;font-family:var(--display);font-size:18px;line-height:1}
.hudexit span{display:block;margin-top:-2px;text-shadow:0 2px 0 var(--red3)}

.hslot{justify-items:center}

.hslot b{font-family:var(--display);;min-height:15px}
.hmark{width:15px!important;height:15px!important;vertical-align:-2px}
.hslot.done b{color:var(--pos)} .hslot.failed{opacity:.55} .hslot.failed b{color:var(--neg)}
@keyframes pulse{50%{transform:scale(1.1)}}

.portrait .ico{width:100%;height:100%;}
.statbar{display:grid;;}
.stat{;min-width:0;;
  background:rgba(255,248,230,.95);border:2px solid var(--ink);font-family:var(--display);font-size:13.5px;white-space:nowrap}

.stat b{font-weight:400;overflow:hidden;text-overflow:ellipsis}
.stat.loan{color:var(--red2)}
.stat.pos b{color:var(--pos)} .stat.neg b{color:var(--neg)}
.gamebody{flex:1;padding:10px 12px 18px}
.marketbanner{display:flex;align-items:center;gap:10px;margin:0 0 10px;padding:6px 12px 6px 6px;border-radius:18px;
  background:linear-gradient(rgba(59,31,14,.8),rgba(59,31,14,.6));border:2.5px solid var(--gold2)}
.mbicon{width:60px!important;height:60px!important}
.marketbanner h1{margin:0;font-family:var(--display);font-weight:400;font-size:24px;color:#FFE9B8;line-height:1.1}
.marketbanner p{margin:0;font-size:12px;font-weight:700;color:#F2DDB0;line-height:1.3}

.news{display:flex;align-items:flex-start;gap:8px;margin:0 0 8px;padding:7px 11px;border-radius:14px;border:2.5px solid var(--ink);
  font-size:13px;font-weight:700;line-height:1.35;color:var(--ink);background:linear-gradient(#FFEFC0,#FFD36B)}
/* Only on arrival. The board is rebuilt from strings on every tap, so opening a
   different good re-created the same note element and replayed this, and one
   headline looked like it was arriving over and over in the same market. */
.news.fresh{animation:drop .3s backwards}
.news .b{font-size:17px;line-height:1.2}
.news.good{background:linear-gradient(#E9FFD6,#B9EE8B)} .news.bad{background:linear-gradient(#FFE5E0,#FFB5AA)}
.news.cool{background:linear-gradient(#E0F4FF,#A7DAF7)} .news.tip{background:linear-gradient(#F0E7FF,#CDB8F6)}
@keyframes drop{from{transform:translateY(-8px);opacity:0}}
.deliver{display:flex;width:100%;margin:0 0 10px;font-size:17px}

.goodslist{display:grid;}
.goods{border-radius:18px;background:linear-gradient(var(--cream1),var(--cream2));border:3px solid var(--gold2);box-shadow:0 0 0 2.5px var(--ink),0 4px 0 rgba(0,0,0,.3);overflow:hidden}
.goods.own{background:linear-gradient(#FFF6CF,#FFE08F)}
.grow-row{display:grid;grid-template-columns:58px 1fr auto;gap:10px;align-items:center;width:100%;padding:6px 12px 6px 8px;border:none;background:none;text-align:left}
.gicon{position:relative}
.gicon .ico{width:54px;height:54px;filter:drop-shadow(0 2px 1px rgba(0,0,0,.25))}
.gicon .badge{top:-4px;right:-6px;background:radial-gradient(circle at 35% 30%,#8FB9F2,var(--blue2))}
.gname b{display:block;font-family:var(--display);font-weight:400;font-size:18px;line-height:1.1}
.gname small{display:block;font-size:12px;font-weight:700;color:var(--muted)}
.gprice{text-align:right}
.gprice b{display:block;font-family:var(--display);font-weight:400;font-size:21px;line-height:1.05}
.ptag{display:inline-block;margin-top:2px;padding:0 8px;border-radius:999px;border:2px solid var(--ink);font-size:10.5px;font-weight:800;color:#fff}
.ptag.cheap{background:linear-gradient(var(--green1),var(--green2))} .ptag.dear{background:linear-gradient(var(--red1),var(--red2))}
.ptag.fair{background:linear-gradient(#D9C9AC,#B0966F)}
.sheet{padding:8px 10px 10px;border-top:3px dashed var(--cream3);background:rgba(255,255,255,.35)}
.seg{display:grid;grid-template-columns:1fr 1fr;gap:4px;margin:0 0 4px;padding:3px;border-radius:12px;background:rgba(59,31,14,.18)}
.seg button{padding:3px 5px;border:none;border-radius:9px;background:none;font-family:var(--display);font-size:15px;color:var(--wood)}
.seg button.on{background:#fff;color:var(--ink);box-shadow:0 2px 0 rgba(0,0,0,.2)}
/* The quantity picker: a slider with the amount beside it, the one way to
   choose how many. The rail is the game's meter (cream, ink outline, round),
   coloured by price band — green, yellow, red, deep red (the --band tokens) —
   and washed past the thumb, so what is chosen is what is bright. The rail is
   15px; the knob draws 22px, in proportion, inside a 36px invisible touch area,
   so a thumb still finds it. With market depth (.banded) each band's unit price
   sits above the rail and its edges below, clear of the knob. */
.bandpick{display:grid;grid-template-columns:minmax(0,1fr) 56px;gap:18px;align-items:center;margin:0 0 2px;padding-left:8px}
.bandslide{position:relative;min-width:0}
.bandpick.banded .bandslide{padding:19px 0}
.bandprices,.bandedges{position:absolute;left:0;right:0;height:14px}
.bandprices{top:0} .bandedges{bottom:0}
.bandprices span,.bandedges span{position:absolute;transform:translateX(-50%);white-space:nowrap;line-height:14px}
.bandprices span{font-family:var(--display);font-size:14px;color:var(--ink)}
.bandedges span{font-size:11px;font-weight:800;color:var(--muted)}
.bandedges span:last-child{transform:translateX(-100%)}
.bandrail{position:relative;height:15px}
.bandtrack{position:absolute;inset:0;display:flex;border-radius:999px;overflow:hidden;background:#E8D2A6;border:2px solid var(--ink);
  box-shadow:0 2px 0 rgba(0,0,0,.2)}
.bandtrack span{min-width:0}
.bandtrack .b0{background:linear-gradient(var(--band-g1) 35%,var(--band-g2))}
.bandtrack .b1{background:linear-gradient(var(--band-y1) 35%,var(--band-y2))}
.bandtrack .b2{background:linear-gradient(var(--band-r1) 35%,var(--band-r2))}
.bandtrack .b3{background:linear-gradient(var(--band-r2) 35%,#5E0010)}
.bandtrack::after{content:"";position:absolute;top:0;bottom:0;left:var(--fill,0%);right:0;background:rgba(255,249,234,.4)}
.bandpick input[type=range]{position:absolute;left:-18px;top:-10.5px;width:calc(100% + 36px);height:36px;margin:0;
  background:transparent;-webkit-appearance:none;appearance:none;touch-action:none;cursor:pointer}
.bandpick input[type=range]::-webkit-slider-runnable-track{height:36px;background:transparent}
.bandpick input[type=range]::-moz-range-track{height:36px;background:transparent}
.bandpick input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:36px;height:36px;border:none;border-radius:50%;
  background:radial-gradient(circle at 50% 50%,#FFF6D0 0,var(--band-y1) 5px,var(--band-y2) 8.5px,var(--ink) 9px,var(--ink) 11px,transparent 11.5px),
    radial-gradient(circle at 50% 60%,rgba(0,0,0,.3) 11px,transparent 12px)}
.bandpick input[type=range]::-moz-range-thumb{width:36px;height:36px;border:none;border-radius:50%;
  background:radial-gradient(circle at 50% 50%,#FFF6D0 0,var(--band-y1) 5px,var(--band-y2) 8.5px,var(--ink) 9px,var(--ink) 11px,transparent 11.5px),
    radial-gradient(circle at 50% 60%,rgba(0,0,0,.3) 11px,transparent 12px)}
.bandpick input[type=range]:focus-visible::-webkit-slider-thumb{outline:3px solid var(--blue2);outline-offset:-4px}
.qty{display:grid;place-items:center;height:40px;border-radius:12px;background:var(--ink);color:#FFE9B8;font-family:var(--display);font-size:22px;
  box-shadow:0 0 0 2px var(--gold2),0 3px 0 rgba(0,0,0,.3)}
.bandnote{margin:0 0 4px;font-size:12.5px;font-weight:700;color:var(--muted);line-height:1.25}
.bandnote b{color:var(--ink);font-size:13px}
.sheet .hint{margin:0 0 6px;text-align:left;line-height:1.25}
.sheet .hint.gain{color:var(--ink)}
.sheet .hint.gain:empty{display:none}
/* The sheet's buttons: one or two, side by side, the same size. */
.tradebtns{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:8px;margin-top:2px}
.tradebtns .btn{display:flex;width:100%;min-width:0}
.tradebtns .btn.btn.btn{min-height:44px;border-width:10px 26px;border-image-width:10px 26px;font-size:17px}
.util{display:grid;grid-template-columns:1fr 1fr;}
.util .btn{font-size:15px}
.sectiontitle{margin:14px 0 6px;text-align:center;font-family:var(--display);font-weight:400;font-size:22px;color:#fff;
  text-shadow:0 2px 0 var(--ink),2px 0 0 var(--ink),-2px 0 0 var(--ink),0 -2px 0 var(--ink)}
.destlist{display:grid;}
.dest{position:relative;display:grid;grid-template-columns:52px 1fr auto;align-items:center;gap:8px;width:100%;padding:5px 10px 5px 6px;
  border-radius:18px;text-align:left;background:linear-gradient(var(--cream1),var(--cream2));border:3px solid var(--gold2);
  box-shadow:0 0 0 2.5px var(--ink),0 4px 0 rgba(0,0,0,.3),inset 6px 0 0 var(--mc)}
.dest:active:not(:disabled){transform:translateY(2px)}
.dest:disabled{filter:grayscale(.8);opacity:.6}
.dicon{width:50px!important;height:50px!important}
.dname b{display:block;font-family:var(--display);font-weight:400;font-size:17px;line-height:1.1}
.dname small{display:block;font-size:12px;font-weight:800;color:var(--muted)}
.watch{padding:1px 9px;border-radius:999px;border:2px solid var(--ink);font-size:11px;font-weight:800;white-space:nowrap}

.scoutrow{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:4px;padding:2px 0 2px 4px}
.scoutrow span{display:inline-flex;align-items:center;gap:2px;padding:0 7px 0 2px;border-radius:999px;background:#fff;border:1.5px solid var(--cream3);font-size:11px;font-weight:800}
.scoutrow .ico{width:18px;height:18px}
.scoutrow .c{background:#DDF7C9} .scoutrow .d{background:#FFD0C9}
.finishbtn{display:flex;width:100%;margin-top:12px}
.powerbar{position:sticky;bottom:0;z-index:4;display:flex;justify-content:space-around;align-items:center;gap:4px;
  padding:10px 8px calc(10px + var(--safe-b));background:linear-gradient(#2E5DB8,#1D3F88);border-top:4px solid var(--gold2);box-shadow:0 -3px 0 var(--ink)}
.pu{position:relative;width:54px;height:54px;padding:5px;border-radius:50%;border:3px solid var(--ink);
  background:radial-gradient(circle at 40% 30%,#C6F08D,var(--green2) 70%);box-shadow:0 0 0 3px var(--gold2),0 4px 0 rgba(0,0,0,.35)}
.pu .ico{width:100%;height:100%}
/* In the bar, a slot is 54px when there is room and shrinks evenly when there
   is not — a sixth tool (the Broker, with market depth) must never push the bag
   off the edge of the phone. */
/* Sized outright, not by aspect-ratio: Safari does not keep a button square
   that way, and the slots were ovals on an iPhone. Six slots and the gaps fit
   any phone from 320px; 54px when there is room. */
.powerbar .pu{--pu:min(54px, calc((min(100vw, var(--phone-w)) - 84px) / 6));
  flex:0 0 var(--pu);width:var(--pu);height:var(--pu);min-width:0;min-height:0}
.pu .badge{top:-6px;right:-8px}
.pu .badge.on{background:radial-gradient(circle at 35% 30%,#8FB9F2,var(--blue2));font-size:10px}
.pu.active{box-shadow:0 0 0 3px #fff,0 0 0 6px var(--blue1),0 4px 0 rgba(0,0,0,.35);animation:pulse 1.2s infinite}
.pu.empty .ico{filter:grayscale(.85);opacity:.7}
.pu.locked{background:radial-gradient(circle,#B9B3A6,#7C7466);box-shadow:0 0 0 3px #CFC6B3}
.pu.locked .ico{filter:grayscale(1);opacity:.55}
.pu.menu{background:radial-gradient(circle at 40% 30%,#8FB9F2,var(--blue2) 70%)}

/* ---------- results ---------- */
.result{align-items:center;padding:calc(12px + var(--safe-t)) 16px 24px}
.rtop{align-self:stretch;display:flex;justify-content:flex-end;padding-right:6px}
.rtop .pill{flex:0 0 auto;min-width:140px}
.bigstar{margin:6px 0 -34px;z-index:3;}
.bigstar .ico{width:96px;height:96px;filter:drop-shadow(0 6px 6px rgba(0,0,0,.35));animation:starpop .5s .2s cubic-bezier(.3,1.7,.5,1) backwards}
.bigstar.off .ico{filter:grayscale(1) brightness(.8)}
@keyframes starpop{from{transform:scale(0) rotate(-30deg)}}

.mascot{display:grid;place-items:center;margin:-6px 0 0}
.mascot .ico{width:120px;height:120px}
.profit{font-family:var(--display);font-size:40px;line-height:1.05}
.seed{font-size:11px!important;color:var(--muted)!important;margin:10px 0 0!important}

/* ---------- unlock / purchase card ---------- */
.ucard{position:relative;width:100%;max-width:380px;margin:auto;padding:44px 16px 16px;border-radius:26px;text-align:center;
  background:linear-gradient(#3C5FB0,#27438A);border:4px solid var(--gold2);box-shadow:0 0 0 4px var(--ink),0 20px 50px rgba(0,0,0,.5);animation:pop .35s cubic-bezier(.3,1.5,.5,1)}
.ucard.claimed{animation:none}

.bigcoin .ico{width:120px;height:120px}

/* The card takes the window colour it was asked for; blue stays the default. */
.ucard.t-red{background:linear-gradient(#95061B,#DC1D2A)}
.ucard.t-purple{background:linear-gradient(#5B2BB0,#3A1878)}

/* The buy button is one shape: what you get on the left, what it costs on the
   right. It was xl in one window and wide in another. */
.buyrow{font-size:19px!important}
.buyrow .cost{font-size:17px}

/* ---------- lists in dialogs ---------- */
.tasklist{list-style:none;margin:0 0 8px;padding:0;display:grid;gap:7px;text-align:left}
.tasklist li{position:relative;display:grid;grid-template-columns:44px 1fr;gap:8px;align-items:center;padding:6px 10px 12px 6px;border-radius:14px;background:#FFF6E0;border:2.5px solid var(--cream3);overflow:hidden}
.tasklist li .ico{width:42px;height:42px}
.tasklist b{display:block;font-size:13.5px}
.tasklist small{font-size:12px;font-weight:800;color:var(--muted)}
.tasklist .tbar{position:absolute;left:10px;right:10px;bottom:4px;height:5px;border-radius:9px;background:#E6D1A6}
.tasklist .tbar b{display:block;height:100%;border-radius:9px;background:linear-gradient(var(--green1),var(--green2))}
.tasklist li.done{background:#E8FAD8} .tasklist li.failed{background:#FFEDEA}
.tips{list-style:none;margin:0 0 12px;padding:0;display:grid;gap:6px;text-align:left}
.tips li{display:grid;grid-template-columns:40px 1fr;gap:8px;align-items:center;padding:5px 8px;border-radius:12px;background:#FFF6E0;border:2px solid var(--cream3);font-size:13px;font-weight:700}
.tips .ico{width:38px;height:38px}
.toggle{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px 12px;border-radius:14px;border:3px solid var(--ink);
  background:linear-gradient(#FFFBEF,var(--cream2));font-family:var(--display);font-size:18px}
.toggle i{position:relative;width:54px;height:30px;border-radius:999px;background:#C9B18A;border:3px solid var(--ink)}
.toggle i b{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:#fff;border:2px solid var(--ink);transition:left .2s}
.toggle.on i{background:var(--green2)} .toggle.on i b{left:24px}
.lifebig{position:relative;width:110px;height:110px;margin:-4px auto 6px}
.lifebig .ico{width:100%;height:100%}
.lifebig b{position:absolute;inset:0;display:grid;place-items:center;padding-bottom:8px;font-family:var(--display);font-size:40px;color:#fff;text-shadow:0 3px 0 var(--red3)}
.meter{position:relative;height:28px;margin:6px 0 10px;border-radius:999px;background:#E8D2A6;border:3px solid var(--ink);overflow:hidden}
.meter > b{position:absolute;inset:0 auto 0 0;background:linear-gradient(var(--gold1),var(--gold2))}
.meter span{position:relative;display:flex;justify-content:center;align-items:center;gap:4px;height:100%;font-family:var(--display);font-size:15px}
.tiers{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin:4px 0 8px}
.tier{padding:5px 3px;border-radius:14px;border:2.5px solid var(--cream3);background:#F1E4C8;opacity:.75}
.tier.on{background:linear-gradient(#FFE3BC,#FFB870);border-color:var(--gold3);opacity:1}
.tier small{display:block;font-family:var(--display);font-size:14px}
.tier span{display:flex;justify-content:center;flex-wrap:wrap;gap:2px}
.tier .ico{width:30px;height:30px}

/* daily gift */
.calendar{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:0 0 8px}
.day{position:relative;display:grid;justify-items:center;border-radius:12px;}
.day small{font-family:var(--display);font-size:12px;}
.day .ico{width:38px;height:38px}
.day.wide{grid-column:span 2;border-color:var(--gold3)}
.day.wide .ico{width:48px;height:48px}
.day.now{border-color:var(--green2);}
@keyframes glow{50%{box-shadow:0 0 0 5px var(--green1)}}
.day.got{opacity:.65}
/* Above the inner gold border, which is an ::after and therefore paints later
   than the tick that sits on the corner. Without this the tick goes under it. */
.tick{position:absolute;z-index:3;top:-7px;right:-7px;width:23px;height:23px;display:grid;place-items:center;font-style:normal;
  filter:drop-shadow(0 1.5px 2px rgba(0,0,0,.35))}
.tick .ico{width:23px;height:23px}

/* ---------- test checkout + fake ad ---------- */

@keyframes up{from{transform:translateY(100%)}}

.testmode{margin:0;padding:6px 10px;border-radius:12px;background:#FFF3D2;border:2px dashed #B99257;color:var(--ink);font-size:12px;font-weight:800;text-align:center}
.spinner{width:36px;height:36px;margin:8px auto 0;border-radius:50%;border:4px solid #ddd;border-top-color:var(--green2);animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.adscrim{background:rgba(0,0,0,.88)}
.fakead{width:100%;border-radius:22px;overflow:hidden;background:#111;border:3px solid #333;color:#fff;text-align:center;padding-bottom:14px}
.adtop{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;font-size:12px;font-weight:800;color:#bbb}
.adcount{width:30px;height:30px;border-radius:50%;border:2px solid #bbb;display:grid;place-items:center;color:#fff}
.adbody{padding:40px 18px;background:repeating-linear-gradient(45deg,#1d1d2e 0 14px,#23233a 14px 28px)}
.adlogo{font-size:64px}
.adbody b{display:block;font-size:22px;margin-top:6px}
.adbody p{color:#aaa;font-size:13px}
.fakead .btn{width:calc(100% - 28px);margin:14px auto 0}

.flycoin{position:absolute;left:0;top:0;z-index:9999;pointer-events:none;width:30px;height:30px}
.flycoin .ico{width:30px;height:30px}
/* A burst throws coins outward and lets them fall; they land nowhere, so they
   must not sit above the windows the way a delivering coin does. */
.flycoin.burst{z-index:60}
.flycoin.burst .ico{filter:drop-shadow(0 3px 4px rgba(0,0,0,.4))}

/* Goods carried between the shelf and the hold. */
.flygood{position:absolute;left:0;top:0;z-index:60;pointer-events:none;width:42px;height:42px}
.flygood .ico{width:42px;height:42px;filter:drop-shadow(0 4px 5px rgba(0,0,0,.4))}

/* The stat pills answer a trade: the figure that changed gives a knock. */
.stat.bump{animation:statbump .28s cubic-bezier(.3,1.5,.5,1)}
@keyframes statbump{40%{transform:scale(1.13)}}

@media (max-width:370px){
  .tile{width:66px}.tile .ico{width:44px;height:44px}
  .levelcard .ribbon .rtext{font-size:26px}
  .btn.xl{font-size:26px}
  .pill .pv{font-size:15px}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ---------- task cards ---------- */
.taskcards{list-style:none;margin:0;padding:0;display:grid;gap:7px;text-align:left}
/* A task is the same row as a rung and a room; it only needs its title back to
   the size a sentence wants. */
.taskcard .tctitle{font-size:15px;font-weight:400;font-family:var(--display)}
.taskcard .tcbody{min-width:0}
.facts{margin:2px 0 0}
.taskcard{display:grid;;padding:8px 10px;border-radius:16px;background:#FFFDF6;border:2.5px solid var(--cream3)}
.taskcard.done{background:#EAFBDB;border-color:#A9D98A}
.taskcard.failed{background:#FFEDEA;border-color:#EDB1A8}
.tcicon{position:relative}
.tcicon .ico{width:50px;height:50px}
.tcicon .tick{top:-4px;right:-4px}
.tctitle{display:block;font-size:14.5px;line-height:1.3;color:var(--ink)}
.taskcard.failed .tctitle{text-decoration:line-through}
.tchint{display:block;margin-top:1px;font-size:12px;font-weight:700;color:var(--muted);line-height:1.3}
.parts{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.part{display:inline-flex;align-items:center;gap:3px;padding:1px 8px 1px 2px;border-radius:999px;background:#F2E6CC;border:2px solid var(--cream3);font-size:12px;font-weight:800;color:#6A4020}
.part .ico{width:22px;height:22px}

.part.done{background:#D9F5C2;border-color:#8FCF63;color:#265E0E}
.tcmeta{display:flex;justify-content:space-between;align-items:center;gap:6px;margin-top:5px;font-size:12.5px;font-weight:800;color:var(--muted)}
.due{padding:0 9px;border-radius:999px;background:#FFF0B8;border:2px solid var(--gold3);color:var(--ink);white-space:nowrap}
.due.late{background:#FFD0C9;border-color:var(--red2);color:var(--red2)}
.tcbar{display:block;height:6px;margin-top:4px;border-radius:9px;background:#E6D1A6;overflow:hidden}
.tcbar b{display:block;height:100%;background:linear-gradient(var(--green1),var(--green2))}
.tcreward{margin-top:4px;font-size:12px;font-weight:800;color:var(--muted)}

/* ================= v0.7: live-ops, tutorial, task market ================= */

.levelbtn.boss{--b1:#7B55C8;--b2:#2E1B57;--b3:#1A0F33}

.goods{position:relative}
.goods.tasksell{box-shadow:0 0 0 2.5px var(--ink),0 0 0 6px var(--green1),0 4px 0 rgba(0,0,0,.3)}
.sellribbon{position:absolute;top:-2px;right:12px;z-index:1;padding:0 10px;border-radius:0 0 10px 10px;background:linear-gradient(var(--green1),var(--green2));
  border:2px solid var(--ink);border-top:none;color:#fff;font-family:var(--display);font-size:12px;text-shadow:0 1px 0 var(--green3)}
.coachbar{align-items:center;;;;font-size:14px;font-weight:800;animation:drop .3s}
.coachbar .ico{width:44px;height:44px;flex:none}
.coach{position:relative;animation:coach 1.1s ease-in-out infinite}
@keyframes coach{50%{box-shadow:0 0 0 3px var(--ink),0 0 0 9px rgba(255,217,94,.95),0 0 22px 10px rgba(255,217,94,.6)}}
.destlist.coach{border-radius:20px}

.dialog.tall .dlg-body{overflow-y:auto}
.livelist{list-style:none;margin:0 0 10px;padding:0;display:grid;gap:7px;text-align:left}
.liverow{display:grid;grid-template-columns:44px 1fr auto;gap:8px;align-items:center;padding:6px 8px;border-radius:14px;background:#FFFDF6;border:2.5px solid var(--cream3)}
.liverow > .ico{width:42px;height:42px}
/* .liverow .ico sizes the row's own picture, and it was catching the little
   inline icons in the text as well — a coin beside a reward came out at 42px and
   pushed the line it belonged to onto two. Inline icons keep the inline size. */
.liverow .ico.inl{width:18px;height:18px}
.liverow b{display:block;font-size:14px}
.liverow small{display:block;font-size:12px;font-weight:800;color:var(--muted)}
.liverow.done{background:#EAFBDB;border-color:#A9D98A}
.liverow .tick{position:static}
.liverow .btn.small{font-size:14px}
.lbar{display:block;height:6px;margin-top:3px;border-radius:9px;background:#E6D1A6;overflow:hidden}
.lbar b{display:block;height:100%;background:linear-gradient(var(--gold1),var(--gold2))}

.passhead{display:grid;grid-template-columns:60px 1fr;gap:10px;align-items:center;text-align:left;margin-bottom:6px}
.passhead .ico{width:58px;height:58px}
.passhead b{font-family:var(--display);font-weight:400;font-size:22px}
.passhead small{display:block;font-size:12px;font-weight:800;color:var(--muted)}
.passlanes{display:grid;gap:6px;margin:4px 0;font-family:var(--display);font-size:15px}
.passlanes b:last-child{color:var(--purple2)}
.passtrack{display:grid;;overflow-y:auto;padding:2px}
.passrow{display:grid;;}

/* The row being asked about comes forward, and comes out of its own fog.
   `opacity` below 1 creates a stacking context, so an un-reached row sealed
   everything inside it — no z-index on the cell or the bubble could escape, and
   the bubble was drawn under the row below. That is why the bubble on a claimed
   stop looked right (those rows are .open, opacity 1, no stacking context) and
   the one on an unreached stop did not. Same markup, different fate, decided by
   a property nobody associates with layering. */

.tiernum{;color:#FFE9B8;font-family:var(--display);font-size:15px}
.passcell{display:flex;flex-wrap:wrap;align-items:center;;;
  border:2.5px solid var(--cream3);background:#FFFDF6;font-size:12px;font-weight:800;color:var(--ink)}
.passcell.prem{background:#F1E9FF;border-color:#C9B4F2}

/* A claimed stop keeps its colour. The tick and the changed background already
   say it is taken; dimming it as well makes a road you have walked look like a
   road you have lost. */
.passcell .tick{top:-6px;right:-6px}

.relics{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.relic{position:relative;display:grid;justify-items:center;border-radius:12px;}
.relic .ico{width:46px;height:46px;filter:brightness(0) opacity(.25)}
.relic.got{background:#FFFDF6}.relic.got .ico{filter:none}
.relic small{;color:#6A4020}
.relic .badge{top:-6px;right:-6px;min-width:20px;height:20px;font-size:11px}

.racelist{list-style:none;margin:0 0 8px;padding:0;display:grid;gap:6px;text-align:left}
.racelist li{display:grid;gap:6px;align-items:center;padding:6px 10px;border-radius:12px;background:#FFFDF6;border:2px solid var(--cream3);font-weight:800;font-size:13px}
.racelist li.me{background:#E2F6CF;border-color:#8FCF63}
.racelist .rk{font-family:var(--display)}
.camels{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
.camels i{height:10px;border-radius:4px;background:#E6D1A6}
.camels i.on{background:linear-gradient(var(--gold1),var(--gold2))}

.bundle{flex-direction:row!important;justify-content:space-between!important;gap:8px;text-align:left;font-size:13px!important}
.bundle span:first-child{font-family:var(--body);font-weight:800;text-shadow:none}
.bundle b{font-family:var(--display);font-weight:400;font-size:15px}

@media (max-height:780px){
  .tiles{top:calc(60px + var(--safe-t))}
  
  
  .tile .tl{font-size:12px}
}

/* ================= v0.8: designer icon set v2 ================= */
.xbtn{background:none!important;border:none!important;box-shadow:none!important;padding:0;width:48px;height:48px;;filter:drop-shadow(0 3px 2px rgba(0,0,0,.35))}
.xbtn .ico{width:100%;height:100%}
.hudexit{;;margin-top:-19px;}

.news .nicon{width:30px;height:30px;margin:-3px 0}
.coachbar .ico{border-radius:50%}
.ico.face{width:24px;height:24px;margin-right:4px;border-radius:50%;background:#F2E3C5}
.racelist li{grid-template-columns:24px 96px 1fr auto}
.racelist .nm{display:flex;align-items:center;white-space:nowrap;overflow:hidden}

.portrait .ico{transform:none;object-fit:contain;padding:2px}
.avatars{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:0 0 6px}
.avatar{padding:3px;border-radius:50%;border:3px solid var(--cream3);background:#FFF6E0}
.avatar .ico{width:100%;height:auto;aspect-ratio:1}
.avatar.on{border-color:var(--green2);box-shadow:0 0 0 3px var(--green1)}

/* ================= v1.1: designer UI chrome ================= */
/* Ribbon art (tassels hang over the panel below; text sits on the band at 47%) */
.ribbon.art{background:none!important;border:none!important;box-shadow:none!important;padding:0;margin:0 auto;min-height:0;
  width:min(330px,100%);background-image:url("../assets/ui/indian-ribbon-ruby.webp")!important;background-size:100% 100%!important}
.ribbon.art.teal{background-image:url("../assets/ui/indian-ribbon-teal.webp")!important}
.ribbon.art::before,.ribbon.art::after{display:none}
.ribbon.art .rtext{position:absolute;left:19%;right:19%;transform:translateY(-50%);text-align:center;white-space:nowrap;
  font-size:clamp(18px,6.4vw,26px);text-overflow:ellipsis}
.dlg-head{margin-bottom:-78px}
.dlg-body{padding-top:84px}
.levelpop .dlg-body{padding-top:84px}
.xbtn{top:14px;right:-10px}
.pagehead .ribbon.art{width:min(300px,86%)}
.pagehead{margin:0 0 -8px;position:relative}
.pagehead .xbtn{top:50%;right:10px;transform:translateY(-50%)}
.pagehead .xbtn:active{transform:translateY(calc(-50% + 2px))}

/* No margin-top: it overrides the auto top margin that centres the card, so the
   free space all went to the bottom and the card sat against the top edge. The
   scrim's own padding already makes room for the ribbon overhang. */
.ucard{padding-top:72px}

/* 9-slice designer buttons: gem ends stay crisp, the middle stretches */
.btn.green,.btn.red{background:none;box-shadow:0 5px 8px rgba(0,0,0,.3);border-style:solid;border-width:14px 34px;padding:2px 6px 4px;
  border-image:url("../assets/ui/emerald-button.webp") 44 118 fill / 14px 34px stretch;min-height:52px}
.btn.red{border-image-source:url("../assets/ui/ruby-button.webp")}
.btn.green::after,.btn.red::after{display:none}
.btn.green:active:not(:disabled),.btn.red:active:not(:disabled){box-shadow:0 2px 4px rgba(0,0,0,.3)}
.btn.green{text-shadow:0 2px 0 #0B4A22,1px 0 0 #0B4A22,-1px 0 0 #0B4A22,0 -1px 0 #0B4A22}
.btn.red{text-shadow:0 2px 0 #6B0F0F,1px 0 0 #6B0F0F,-1px 0 0 #6B0F0F,0 -1px 0 #6B0F0F}
.btn.xl.green,.btn.xl.red{border-width:18px 44px;border-image-width:18px 44px;min-height:66px}
.btn.small.green,.btn.small.red{border-width:9px 22px;border-image-width:9px 22px;min-height:38px;font-size:14px}
.shoprow .btn.price.green{border-width:10px 24px;border-image-width:10px 24px;min-height:42px;min-width:96px}
.levelbtn{--b1:transparent;--b2:transparent;background:none;border-style:solid;border-width:20px 50px;min-height:92px;padding:0 6px;
  border-image:url("../assets/ui/emerald-button.webp") 44 118 fill / 20px 50px stretch;box-shadow:0 10px 18px rgba(0,0,0,.45)}
.levelbtn::after{display:none}
.levelbtn .lvtext{text-shadow:0 3px 0 #0B4A22,2px 0 0 #0B4A22,-2px 0 0 #0B4A22,0 -2px 0 #0B4A22,2px 2px 0 #0B4A22,-2px 2px 0 #0B4A22}
.levelbtn.hard,.levelbtn.boss,.levelbtn.superhard{border-image-source:url("../assets/ui/ruby-button.webp")}
.levelbtn.hard .lvtext,.levelbtn.boss .lvtext,.levelbtn.superhard .lvtext{text-shadow:0 3px 0 #6B0F0F,2px 0 0 #6B0F0F,-2px 0 0 #6B0F0F,0 -2px 0 #6B0F0F,2px 2px 0 #6B0F0F,-2px 2px 0 #6B0F0F}

/* Jeweled round frame for portraits and avatars */
.framed{position:relative}
.framed::after{content:"";position:absolute;inset:-9%;background:url("../assets/ui/round-jeweled-frame.webp") center/100% 100% no-repeat;pointer-events:none}
.portrait.framed{border:none;box-shadow:none;border-radius:50%;background:radial-gradient(circle at 50% 35%,#FFE9B8,#C9853A);overflow:visible}
.portrait.framed .ico{border-radius:50%;transform:scale(.82)}
/* The jewelled frame's opening sits 3% below the middle of its artwork (the top
   lotus dips into it): the face is moved down to its real centre. */
.portrait.framed > .masc{transform:translate(-1px,2px)}
.avatar.framed{border:none;box-shadow:none;background:#FFF6E0}
.avatar.framed.on{box-shadow:0 0 0 4px var(--green1)}
.framed.big{width:110px;height:110px;margin:0 auto 10px;border-radius:50%;background:#F2E3C5}
.framed.big .ico{width:100%;height:100%;border-radius:50%;transform:scale(.84)}

/* Jaipur arch frame on home tiles */
.tile{border:none;box-shadow:none;width:78px;height:84px;padding:14px 8px 6px;}

.tile .tl{position:absolute;left:50%;transform:translateX(-50%);border-radius:999px;background:var(--ink);color:#FFE9B8;}

.tilebar{position:absolute;left:14px;right:14px;bottom:9px;width:auto}

/* Chakra crest behind the result star */
.bigstar{position:relative;display:grid;place-items:center}

.bundleicon{width:44px!important;height:44px!important;flex:none}

/* Guards: 4 levels */

.watch.h1{background:#E6F7D6;color:#3D6B21}
.watch.h2{background:#FFF0B8;color:#7A5206}
.watch.h3{background:#FFD0C9;color:#A32220}

/* Spacing: keep framed cards and buttons from touching */
.destlist{gap:14px}
.goodslist{gap:14px}

.stack{gap:12px;margin-top:14px}
.dlg-body > .btn{margin-top:12px}
.dlg-body > .panelbox,.dlg-body > .nearmiss{margin-top:12px}
.util{gap:12px;margin:18px 0 8px}
@media (max-height:780px){ .tiles{gap:18px} .tile{width:68px;height:74px;padding:12px 6px 5px}  }

/* ================= v1.1.1: readable home tiles, ribbon proportions ================= */

.ribbon.art .rtext{top:43%}

/* Tile = cream arch panel (back) · icon (middle) · Jaipur arch frame (front) */
.tile{background:none;filter:drop-shadow(0 4px 4px rgba(0,0,0,.5))}
.tile::before{content:"";position:absolute;z-index:0;left:13%;right:13%;top:15%;bottom:10%;
  border-radius:48% 48% 10px 10px / 34% 34% 10px 10px;
  background:radial-gradient(circle at 50% 42%,#FFFBEA 0%,#F6E2B3 58%,#D9B475 100%);
  box-shadow:inset 0 0 0 2px rgba(122,68,28,.35),inset 0 -6px 10px rgba(122,68,28,.25)}
.tile::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:url("../assets/ui/jaipur-arch-frame.webp") center/100% 100% no-repeat}
.tile .ico{position:relative;z-index:1;;filter:drop-shadow(0 2px 2px rgba(0,0,0,.35))}
.tile .tl,.tile .badge,.tile .tag,.tile .tilebar{z-index:3}
.tile .tilebar{bottom:12px;left:18px;right:18px}
@media (max-height:780px){ .tile .ico{width:42px;height:42px} }

/* ================= v1.1.2: designer button pack ================= */
.tile .ico{width:45px;height:45px;margin-top:10px}

/* Pack buttons are 4 pieces: caps and crest keep their shape, the strip stretches. */
.btn.gold,.btn.purple,.btn.cream,.btn.blue{
  border:none;box-shadow:none;border-radius:0;;
  background:
    var(--bl) left center / auto 100% no-repeat,
    var(--br) right center / auto 100% no-repeat,
    var(--bc) center center / auto 100% no-repeat,
    var(--bs) center center / 100% 100% no-repeat;
  filter:drop-shadow(0 4px 4px rgba(0,0,0,.3))}
.btn.gold::after,.btn.purple::after,.btn.cream::after,.btn.blue::after{display:none}
.btn.gold:active:not(:disabled),.btn.purple:active:not(:disabled),.btn.cream:active:not(:disabled),.btn.blue:active:not(:disabled){
  box-shadow:none;filter:drop-shadow(0 1px 2px rgba(0,0,0,.3))}

.btn.gold{--bl:url("../assets/ui/btn/gold-l.webp");--br:url("../assets/ui/btn/gold-r.webp");--bc:url("../assets/ui/btn/gold-c.webp");--bs:url("../assets/ui/btn/gold-s.webp");}

.btn.purple{--bl:url("../assets/ui/btn/royal-purple-l.webp");--br:url("../assets/ui/btn/royal-purple-r.webp");--bc:url("../assets/ui/btn/royal-purple-c.webp");--bs:url("../assets/ui/btn/royal-purple-s.webp");}

.btn.cream{--bl:url("../assets/ui/btn/ivory-cream-l.webp");--br:url("../assets/ui/btn/ivory-cream-r.webp");--bc:url("../assets/ui/btn/ivory-cream-c.webp");--bs:url("../assets/ui/btn/ivory-cream-s.webp");}

.btn.blue{--bl:url("../assets/ui/btn/sapphire-blue-l.webp");--br:url("../assets/ui/btn/sapphire-blue-r.webp");--bc:url("../assets/ui/btn/sapphire-blue-c.webp");--bs:url("../assets/ui/btn/sapphire-blue-s.webp");}

/* strip starts inside the caps (transparent side borders clip it), taller to match emerald buttons */
.btn.gold,.btn.purple,.btn.cream,.btn.blue{
  border-style:solid;border-color:transparent;border-width:0 20px;padding:8px 14px 10px;min-height:60px;
  background-origin:border-box,border-box,border-box,padding-box;
  background-clip:border-box,border-box,border-box,padding-box}
.btn.gold.xl,.btn.purple.xl,.btn.cream.xl,.btn.blue.xl{border-width:0 26px;min-height:76px;padding:10px 18px 12px}
.btn.gold.small,.btn.purple.small,.btn.cream.small,.btn.blue.small{border-width:0 14px;min-height:44px;padding:4px 10px 6px}

/* ================= v1.1.3: classic button colours (same style as emerald/ruby) ================= */
.btn.gold,.btn.purple,.btn.cream,.btn.blue,.btn.teal,.btn.orange,.btn.navy,.btn.bronze,.btn.silver,.btn.black,.btn.brown{background:none;box-shadow:0 5px 8px rgba(0,0,0,.3);filter:none;border-radius:0;
  border-style:solid;border-color:transparent;border-width:14px 34px;padding:2px 6px 4px;min-height:52px;
  border-image:var(--bi) 48 130 fill / 14px 34px stretch}
.btn.gold::after,.btn.purple::after,.btn.cream::after,.btn.blue::after,.btn.teal::after,.btn.orange::after,.btn.navy::after,.btn.bronze::after,.btn.silver::after,.btn.black::after,.btn.brown::after{display:none}
.btn.gold:active:not(:disabled),.btn.purple:active:not(:disabled),.btn.cream:active:not(:disabled),.btn.blue:active:not(:disabled),.btn.teal:active:not(:disabled),.btn.orange:active:not(:disabled),.btn.navy:active:not(:disabled),.btn.bronze:active:not(:disabled),.btn.silver:active:not(:disabled),.btn.black:active:not(:disabled),.btn.brown:active:not(:disabled){box-shadow:0 2px 4px rgba(0,0,0,.3);filter:none}
.btn.gold.xl,.btn.purple.xl,.btn.cream.xl,.btn.blue.xl,.btn.teal.xl,.btn.orange.xl,.btn.navy.xl,.btn.bronze.xl,.btn.silver.xl,.btn.black.xl,.btn.brown.xl{border-width:18px 44px;border-image-width:18px 44px;min-height:66px;padding:2px 6px 4px}
.btn.gold.small,.btn.purple.small,.btn.cream.small,.btn.blue.small,.btn.teal.small,.btn.orange.small,.btn.navy.small,.btn.bronze.small,.btn.silver.small,.btn.black.small,.btn.brown.small{border-width:9px 22px;border-image-width:9px 22px;min-height:38px;padding:1px 4px 2px}
.shoprow .btn.price{border-width:10px 24px;border-image-width:10px 24px;min-height:42px;padding:0 4px;min-width:96px}
.btn.gold{--bi:url("../assets/ui/btn-classic/gold.webp");color:#4A2A05;text-shadow:0 2px 0 rgba(255,240,190,.75),1px 0 0 rgba(255,240,190,.75),-1px 0 0 rgba(255,240,190,.75),0 -1px 0 rgba(255,240,190,.75)}
.btn.gold small{color:#4A2A05;text-shadow:none}
.btn.purple{--bi:url("../assets/ui/btn-classic/royal-purple.webp");color:#fff;text-shadow:0 2px 0 #3A0F5E,1px 0 0 #3A0F5E,-1px 0 0 #3A0F5E,0 -1px 0 #3A0F5E}
.btn.purple small{color:#fff;text-shadow:none}
.btn.cream{--bi:url("../assets/ui/btn-classic/ivory-cream.webp");color:#3B1F0E;text-shadow:0 2px 0 rgba(255,255,255,.7),1px 0 0 rgba(255,255,255,.7),-1px 0 0 rgba(255,255,255,.7),0 -1px 0 rgba(255,255,255,.7)}
.btn.cream small{color:#3B1F0E;text-shadow:none}
.btn.blue{--bi:url("../assets/ui/btn-classic/sapphire-blue.webp");color:#fff;text-shadow:0 2px 0 #0B2A6B,1px 0 0 #0B2A6B,-1px 0 0 #0B2A6B,0 -1px 0 #0B2A6B}
.btn.blue small{color:#fff;text-shadow:none}
.btn.teal{--bi:url("../assets/ui/btn-classic/turquoise.webp");color:#fff;text-shadow:0 2px 0 #0B4A4A,1px 0 0 #0B4A4A,-1px 0 0 #0B4A4A,0 -1px 0 #0B4A4A}
.btn.teal small{color:#fff;text-shadow:none}
.btn.orange{--bi:url("../assets/ui/btn-classic/saffron-orange.webp");color:#fff;text-shadow:0 2px 0 #7A3300,1px 0 0 #7A3300,-1px 0 0 #7A3300,0 -1px 0 #7A3300}
.btn.orange small{color:#fff;text-shadow:none}

.btn.navy{--bi:url("../assets/ui/btn-classic/midnight-navy.webp");color:#fff;text-shadow:0 2px 0 #050F2E,1px 0 0 #050F2E,-1px 0 0 #050F2E,0 -1px 0 #050F2E}
.btn.navy small{color:#fff;text-shadow:none}
.btn.bronze{--bi:url("../assets/ui/btn-classic/antique-bronze.webp");color:#fff;text-shadow:0 2px 0 #3B2A10,1px 0 0 #3B2A10,-1px 0 0 #3B2A10,0 -1px 0 #3B2A10}
.btn.bronze small{color:#fff;text-shadow:none}
.btn.silver{--bi:url("../assets/ui/btn-classic/silver.webp");color:#2A2A30;text-shadow:0 2px 0 rgba(255,255,255,.7),1px 0 0 rgba(255,255,255,.7),-1px 0 0 rgba(255,255,255,.7),0 -1px 0 rgba(255,255,255,.7)}
.btn.silver small{color:#2A2A30;text-shadow:none}
.btn.black{--bi:url("../assets/ui/btn-classic/obsidian-black.webp");color:#FFE9B8;text-shadow:0 2px 0 #000,1px 0 0 #000,-1px 0 0 #000,0 -1px 0 #000}
.btn.black small{color:#FFE9B8;text-shadow:none}

.btn.brown{--bi:url("../assets/ui/btn-classic/chocolate-brown.webp");color:#FFE9B8;text-shadow:0 2px 0 #2A1405,1px 0 0 #2A1405,-1px 0 0 #2A1405,0 -1px 0 #2A1405}
.btn.brown small{color:#FFE9B8;text-shadow:none}

/* image buttons: shadow follows the artwork, not the box */
.btn.green,.btn.red,.btn.gold,.btn.purple,.btn.cream,.btn.blue,.btn.teal,.btn.orange,.btn.navy,.btn.bronze,.btn.silver,.btn.black,.btn.brown,.levelbtn{box-shadow:none!important;filter:drop-shadow(0 4px 4px rgba(0,0,0,.32))}
.btn.green:active:not(:disabled),.btn.red:active:not(:disabled),.btn.gold:active:not(:disabled),.btn.purple:active:not(:disabled),.btn.cream:active:not(:disabled),.btn.blue:active:not(:disabled),.btn.teal:active:not(:disabled),.btn.orange:active:not(:disabled),.btn.navy:active:not(:disabled),.btn.bronze:active:not(:disabled),.btn.silver:active:not(:disabled),.btn.black:active:not(:disabled),.btn.brown:active:not(:disabled){filter:drop-shadow(0 1px 2px rgba(0,0,0,.3))}
.btn.green:disabled,.btn.red:disabled,.btn.gold:disabled,.btn.purple:disabled,.btn.cream:disabled,.btn.blue:disabled,.btn.teal:disabled,.btn.orange:disabled,.btn.navy:disabled,.btn.bronze:disabled,.btn.silver:disabled,.btn.black:disabled,.btn.brown:disabled{filter:grayscale(.75) brightness(.95) drop-shadow(0 2px 2px rgba(0,0,0,.2))}

/* ---------- royal frames on the small boxes (gift days, haveli parts, relics, pass tiers) ---------- */
.day,.relic,.passcell,.liverow,.tier,.racelist li{position:relative;border-color:#8A5A1E;box-shadow:0 2px 0 rgba(0,0,0,.16)}
.day::after,.relic::after,.passcell::after,.liverow::after,.tier::after,.racelist li::after{
  content:"";position:absolute;inset:2px;border-radius:9px;pointer-events:none;
  border:2px solid rgba(233,194,107,.9);box-shadow:inset 0 1px 0 rgba(255,255,255,.55)}
.day.wide::after{border-color:rgba(122,74,22,.55)}
.racelist li::after,.liverow::after{border-radius:8px}

/* ---------- Silk Road Pass ---------- */
/* No overflow:hidden. It was clipping two things that live outside the box on
   purpose — the tick at the top-right corner, and the bubble that says why a
   stop cannot be taken, which drops below the cell. The bubble was rendering
   correctly the whole time and being cut off, so every tap looked dead.
   Long labels are held by `.passcell b`, which ellipsizes on its own. */
.passcell{min-width:0}
.passtrack{overflow-x:hidden}

/* no double-tap zoom, no long-press callout, no text selection on a game surface */
html{touch-action:manipulation;-webkit-text-size-adjust:100%}
body{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}
button,.tile,.boost,.passcell{touch-action:manipulation}

/* ---------- result verdict plaque ---------- */

.slots.small .slot b{font-size:12px;font-family:var(--body);font-weight:800;text-align:center}
.cashcost{opacity:.95}

/* ---------- Daily Haat board ---------- */
.ranklist.board{gap:5px}
.ranklist.board li{position:relative;grid-template-columns:28px 1fr auto;gap:8px;padding:5px 10px;border-radius:12px;
  border:2.5px solid #8A5A1E;background:linear-gradient(#FFFDF4,#F6E7C4);box-shadow:0 2px 0 rgba(0,0,0,.14)}
.ranklist.board li::after{content:"";position:absolute;inset:2px;border-radius:8px;pointer-events:none;
  border:2px solid rgba(233,194,107,.9);box-shadow:inset 0 1px 0 rgba(255,255,255,.55)}
.ranklist.board .rk{font-size:16px;color:#7A4A16}
.ranklist.board .nm{display:flex;align-items:center;gap:6px;font-size:13px;overflow:hidden;white-space:nowrap}
.ranklist.board .nm b{font-weight:800;overflow:hidden;text-overflow:ellipsis}
.ranklist.board .lv{font-family:var(--display);font-size:15px}
.ranklist.board .lv.pos{color:var(--pos)}.ranklist.board .lv.neg{color:var(--neg)}
.ranklist.board li.t1{background:linear-gradient(#FFF1C2,#F3CE74)}
.ranklist.board li.t2{background:linear-gradient(#FBFBFB,#DCDCDC)}
.ranklist.board li.t3{background:linear-gradient(#FBE5CD,#DFAE80)}
.ranklist.board li.me{background:linear-gradient(#DFF6C4,#A9DE76);border-color:#4E7A22}

/* the ad icon needs room to read as artwork, not a smudge */
.btn.purple .ico.inl{width:26px;height:26px;vertical-align:-6px}

/* ---------- standard card: the Thank-you card look, for every dialog ----------
   A jewel-coloured card with a gold rim, and every piece of content sitting in a
   cream box on top of it. Tone comes from dialog({ tone }). */
.dialog.card .dlg-body{
  box-shadow:0 0 0 4px var(--ink),inset 0 0 0 3px rgba(255,255,255,.14),0 16px 34px rgba(0,0,0,.45);
  color:#F3F7FF}

.dialog.card .dlg-body p{color:#FBF0D8}
.dialog.card .dlg-body .fine{color:rgba(255,246,224,.82)}
.dialog.card .seed{color:rgba(255,246,224,.6)!important}
.dialog.card .passhead,.dialog.card .passlanes,.dialog.card .bignum{color:#FFF3D2}
.dialog.card .passhead small{color:rgba(255,243,210,.78)}

/* the art box in the middle, like the Thank-you card's */
.dialog.card .bigicon{padding:12px;margin:0 auto 12px;border-radius:18px;
  background:radial-gradient(circle,#FFFDF0,#F3E7C4 72%);border:4px solid rgba(0,0,0,.25);
  box-shadow:inset 0 0 0 2px rgba(255,255,255,.6)}

/* cream boxes need a touch more separation from a coloured card than from cream */
.dialog.card .panelbox,.dialog.card .taskcard,.dialog.card .liverow,.dialog.card .day,.dialog.card .tips li,.dialog.card .tasklist li,
.dialog.card .ranklist li,.dialog.card .racelist li{
  box-shadow:0 2px 0 rgba(0,0,0,.22)}
.dialog.card .introbox{border-color:#7FA9D6}

/* Claimed / spent boxes: dim the contents, never the box, or they sink into the card */
.dialog.card .day.got,.dialog.card .passcell.got,.dialog.card .liverow.done{opacity:1}
/* The daily-gift tiles fade their contents when taken. The pass does not: the
   line above sets a claimed stop to full opacity and this one put it back to a
   half — the cell, not its icon, which reads as a slip in the selector list.
   A stop you have walked keeps its colour; the tick and the changed background
   are what say it is yours. */
.dialog.card .day.got .ico,.dialog.card .day.got b,.dialog.card .day.got small,
/* claimed rows are green, not faded — opacity is not a state */
.dialog.card .day.got,.dialog.card .passcell.got{background:linear-gradient(#F2EADA,#DFD2B8)}
.dialog.card .passcell.got{color:var(--ink)}
.dialog.card .liverow.done{background:#E3F4D2}
.dialog.card .day.got .tick,.dialog.card .passcell.got .tick,.dialog.card .liverow.done .tick{opacity:1}

/* ---------- ornamental frames (back/frames → assets/ui/frames) ----------
   Fixed-aspect art, not 9-slices: the arch crown and lotus foot are centred
   ornaments that smear if stretched. The frame is an <img> laid over the slot
   with object-fit:contain, so it keeps its own proportions at any size. */
.frm{position:relative;display:inline-grid;place-items:center;flex:0 0 auto}
.frm .fart{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none}
.frm > .ico{position:relative;z-index:1}
.frm.sq{width:78px;height:86px}
.frm.sq > .ico{width:42px!important;height:42px!important}
.frm.rd{width:72px;height:72px}
.frm.rd > .ico{width:38px!important;height:38px!important}

/* a frame-slot drops its own box — the frame art is the box.
   NB: `.framed` is the avatar frame; reward slots use `.fslot`. */

/* coin counts step down a size before they can ever be clipped */
.pill .pv.sm2{font-size:15px;letter-spacing:-.2px}
.pill .pv.xs{font-size:13.5px;letter-spacing:-.3px}

/* free lane stays cream against a purple card so the two lanes read apart */
.dialog.card .passcell{background:linear-gradient(#FFFDF6,#F6EAD2)}
.dialog.card .passcell.prem{background:linear-gradient(#EFE6FF,#DCCBF8);border-color:#6A3CC0}
.dialog.card .passlanes b:last-child{color:#EBDCFF}

/* ---------- card fixes ----------
   Text inside a cream box must stay ink-dark: the card sets a light colour for
   the text that sits directly on the colour, and boxes were inheriting it. */
.dialog.card .panelbox,.dialog.card .liverow,.dialog.card .day,.dialog.card .taskcard,.dialog.card .tips li,.dialog.card .tasklist li,
.dialog.card .ranklist li,.dialog.card .racelist li,.dialog.card .relic,
.dialog.card .passcell,.dialog.card .facts span,
.dialog.card .slot,.dialog.card .introbox,.dialog.card .nearmiss,
.dialog.card .album,.dialog.card .haveli{color:var(--ink)}
.dialog.card .panelbox p,.dialog.card .liverow p,.dialog.card .taskcard p{color:#6A4020}
.dialog.card .panelbox .fine{color:var(--muted)}
.dialog.card .ranklist.board .nm b{color:var(--ink)}
.dialog.card .liverow small,.dialog.card .tchint,.dialog.card .tcmeta{color:var(--muted)}

/* pages keep their top bar and tabs in place; only the list scrolls */
.page .topbar{position:sticky;top:0;z-index:6;
  background:linear-gradient(rgba(10,26,58,.55),rgba(10,26,58,0));backdrop-filter:blur(2px)}
.page .tabs{position:sticky;top:calc(52px + var(--safe-t));z-index:5}

/* event rows use the real button art, not a flat pill */
/* .evbtn began as a decorative <em> label ("Soon", "Open"), so it turned off
   pointer events. The firman and gift lists then reused the class on real
   <button> elements — and every Claim in those lists became unclickable. The
   decorative uses sit inside a card that carries the action, so they lose
   nothing; .done and .locked keep their own opt-out below. */
.evbtn{flex:none;font-style:normal;min-width:78px;font-size:15px;padding:6px 12px}

/* firman row: title, payout, bar and count each get their own line so nothing wraps mid-phrase */
.liverow.firman{grid-template-columns:46px 1fr auto;align-items:center}

.liverow.firman .lbar{margin:1px 0}

/* ---------- Silk Road Pass track ---------- */

.frm.num{width:40px;height:40px}
.passrow{gap:7px;align-items:center;opacity:.78}
.passrow.open{opacity:1}
/* The row being asked about comes forward, and comes out of its own fog.
   `opacity` below 1 creates a stacking context, so an un-reached row sealed
   everything inside it — no z-index on the cell or the bubble could escape, and
   the bubble was drawn under the row below. That is why the bubble on a claimed
   stop looked right (those rows are .open, opacity 1, no stacking context) and
   the one on an unreached stop did not. Same markup, different fate, decided by
   a property nobody associates with layering. */
.passrow.asking{opacity:1;z-index:30}
.tiernum{position:relative;display:grid;place-items:center;width:42px;height:42px;background:none;border-radius:0}
.tiernum .frm{position:absolute;inset:1px}
.tiernum i{font-style:normal;;}
.passcell{flex-direction:row;;padding:5px 8px 5px 5px;border-radius:14px;justify-content:flex-start}
.passcell b{font-family:var(--display);font-weight:400;line-height:1}

.passcell .lockmini{position:absolute;right:6px;bottom:4px}
.lockmini .ico{width:18px;height:18px}
.passtrack{gap:7px}

/* framed contents inside gift days, haveli parts and relic slots */
.frm.day{width:56px;height:62px;margin:1px 0}
.frm.day > .ico{width:32px!important;height:32px!important}
.day.wide .frm.day{width:66px;height:73px}
.day.wide .frm.day > .ico{width:40px!important;height:40px!important}
.frm.part{width:60px;height:66px}
.frm.part > .ico{width:34px!important;height:34px!important}

.relic .frm.part > .ico{filter:brightness(0) opacity(.25)}
.relic.got .frm.part > .ico{filter:none}
.relic{background:none!important;border:none!important;box-shadow:none!important;padding:2px 0}
.relic::after{display:none}

/* A gold card is light, so its text has to be dark, not cream */

/* buttons and toggles keep their own text colour inside a card */
.dialog.card .btn{color:#fff}
.dialog.card .btn.cream,.dialog.card .btn.silver{color:var(--ink)}
.dialog.card .toggle{color:var(--ink)}
.dialog.card .boxlabel{color:#FFF3D2!important}
.dialog.card .avatars,.dialog.card .meter{color:#fff}

/* the tier number sits between the two lanes, where both can be read against it */
.passrow{grid-template-columns:1fr 44px 1fr}
.passlanes{grid-template-columns:1fr 44px 1fr}
.passlanes b:last-child{text-align:center}
.passlanes b:first-child{text-align:center}

/* a framed gift day is the frame — no second cream box around it */
.day{background:none;border:none;box-shadow:none;padding:2px 0 4px}
.day::after{display:none}
.day.wide{background:none;border:none}
.day.now{box-shadow:none;animation:none}

.day small{color:#FFF3D2}
.day b{color:#FFF3D2}
.dialog.card .day{color:#FFF3D2}

/* claimed days keep the same shape as the rest; only their contents dim */
.dialog.card .day.got{background:none}
.dialog.card .day.got .ico{opacity:.45}
.day.now .frm .fart{filter:drop-shadow(0 0 4px rgba(155,227,74,.9))}
/* tier medallion: a cream disc behind the numeral so it reads on any card colour */
.tiernum i{position:relative;z-index:2;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;
  background:radial-gradient(circle at 50% 35%,#FFF7E2,#EBD3A2);
  color:#5B3310;font-family:var(--display);font-size:16px;line-height:1;text-shadow:none;
  box-shadow:inset 0 -2px 0 rgba(0,0,0,.12)}
.passrow.open .tiernum i{background:radial-gradient(circle at 50% 35%,#FFE9A8,#F0B93F)}

/* ---------- Shreni (guild) ---------- */

/* Ranks: same head plate as the guild, same framed rows as the Haat board */

/* ---------- .arch: the home tile treatment, reused ----------
   Same three layers as .tile — cream arch panel behind, icon, Jaipur arch frame
   in front — so gift days, haveli parts and relics read as one family. */
.arch{position:relative;display:grid;place-items:center;width:78px;height:84px;
  filter:drop-shadow(0 4px 4px rgba(0,0,0,.45))}
.arch::before{content:"";position:absolute;z-index:0;left:13%;right:13%;top:15%;bottom:10%;
  border-radius:48% 48% 10px 10px / 34% 34% 10px 10px;
  background:radial-gradient(circle at 50% 42%,#FFFBEA 0%,#F6E2B3 58%,#D9B475 100%);
  box-shadow:inset 0 0 0 2px rgba(122,68,28,.35),inset 0 -6px 10px rgba(122,68,28,.25)}
.arch::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:url("../assets/ui/jaipur-arch-frame.webp") center/100% 100% no-repeat}
.arch > .ico{position:relative;z-index:1;width:44px!important;height:44px!important;margin-top:4px;
  filter:drop-shadow(0 2px 2px rgba(0,0,0,.35))}

/* gift days, haveli parts and relics: arch tile, label under, badge on the corner */
.day,.relic{display:grid;justify-items:center;gap:1px;background:none;border:none;box-shadow:none;padding:0}
.day::after,.relic::after{display:none}
.day .frm,.relic .frm{display:none}
.day.wide .arch{width:92px;height:99px}
.day.wide .arch > .ico{width:52px!important;height:52px!important;margin-top:5px}
.day small,.day b,.relic small{color:#FFF3D2}
.dialog.card .day,.dialog.card .relic{color:#FFF3D2}
.relic small{margin-top:3px}
/* badges sit on the tile's top corner, clear of the label underneath */
.arch .tick{position:absolute;;bottom:auto;z-index:4;filter:none}
.arch .badge{position:absolute;top:-4px;right:-4px;z-index:4;filter:none}

/* not yet earned: dim the art, keep the arch bright so the shape still reads */
.day.got .arch > .ico,.relic:not(.got) .arch > .ico{filter:grayscale(1) opacity(.4)}

.day.now .arch::after{filter:drop-shadow(0 0 4px rgba(155,227,74,.95))}
.day.got small,.day.got b{opacity:.65}

/* Cream text is right for boxes sitting straight on the card, wrong inside a
   cream panel — the haveli and ledger blocks live in panels. */
.dialog.card .panelbox .boxlabel{color:#6A4020!important}
.dialog.card .panelbox .relic,.dialog.card .panelbox .relic small{color:var(--ink)}

.relic{gap:2px}

/* a button whose label and cost stay on one line */
.btn.inline{flex-direction:row;justify-content:center;gap:10px;flex-wrap:nowrap}
.btn.inline .cost{display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
.btn.inline .ico.inl{width:20px;height:20px}

/* ---------- standard tiles in royal windows ---------- */
/* Small arch tile for dense rows (pass lanes). */
.arch.sm{width:56px;height:60px}
.arch.sm > .ico{width:31px!important;height:31px!important;margin-top:3px}
.arch.sm .tick,.arch.sm .badge{transform:scale(.8);transform-origin:top right}

/* Daily gift now sits in a cream panel like the haveli block, so its labels
   are ink-dark again rather than cream-on-colour. */

/* reward slots: arch tile with the name underneath */

/* pass cells hold an arch tile plus the amount */
.passcell{min-height:64px;gap:7px}

/* ---------- Daily Gift: the events-row layout ---------- */

.daynum{font-style:normal;display:grid;place-items:center;width:30px;height:30px;border-radius:50%;
  background:linear-gradient(#F2E7CE,#DFCDA6);border:2.5px solid #A77E45;
  font-family:var(--display);font-size:15px;color:#7A4A16}

/* an events row is a cream box, so its text is ink-dark on a coloured card too */
.dialog.card .eventcard,.dialog.card .eventcard .ename b{color:var(--ink)}
.dialog.card .eventcard .ename small{color:#6A4020}
/* a booster carried twice: one free from the streak, one added */
.boost.double{box-shadow:0 0 0 3px #fff,0 0 0 6px var(--gold2),0 4px 0 rgba(0,0,0,.3)}
.stackpip{position:absolute;left:-7px;bottom:-5px;z-index:4;font-style:normal;padding:0 5px;border-radius:999px;
  background:linear-gradient(var(--gold1),var(--gold2));border:2px solid var(--ink);
  font-family:var(--display);font-size:12px;color:#5B3310}
.pu.ready{box-shadow:0 0 0 3px var(--green1),0 3px 0 rgba(0,0,0,.3)}

.perk{display:block;font-style:normal;font-size:10.5px;font-weight:800;line-height:1.25;text-align:center;color:#4E7A22;margin-top:1px}
.chapterbox{background:#FFF3D8;border-color:#E0BE72}
.chapterbox p{color:#6A4020!important}
/* a market the city has but this chapter has not opened yet */
.dest.shut{filter:grayscale(.9);opacity:.72;cursor:default}
.dest.shut .dicon{width:38px!important;height:38px!important;margin:0 6px}

/* ---------- The Trade Route (map) ---------- */

.maphead{position:relative;z-index:5;text-align:center;padding:2px 12px 10px;margin-top:-4px;
  background:linear-gradient(rgba(10,26,58,.6),rgba(10,26,58,0))}
.maphead b{display:block;font-family:var(--display);font-weight:400;font-size:22px;color:#FFF3D2;
  text-shadow:0 2px 0 rgba(0,0,0,.45)}
.maphead small{display:block;font-size:12.5px;font-weight:800;color:rgba(255,243,210,.85)}
/* the map scrolls in #screen, not in its own box, so one flick moves the road */

/* One painted band per city, exactly one band tall — so nothing repeats inside a
   city the way the old single tile did, four times over. */
.band{position:relative;background-size:100% 100%;background-repeat:no-repeat;
  box-shadow:inset 0 0 40px rgba(20,10,4,.35)}
.band.far{filter:grayscale(.85) brightness(.6)}

/* The road is painted now, and it follows the waypoints instead of running dead
   straight down the middle past them. Its own layer, so the travelled part can
   be lit behind the caravan later — and so a sea leg can look like a sea leg. */
.road{position:absolute;inset:0;background-size:100% 100%;background-repeat:no-repeat;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.45))}

/* a chapter stop */
.stop{position:absolute;left:50%;width:96px;margin-left:-48px;display:grid;justify-items:center}
.stop .plinth{width:64px;height:auto;filter:drop-shadow(0 3px 3px rgba(0,0,0,.45))}
.stop .wico{position:absolute;top:6px;width:34px!important;height:34px!important;
  filter:drop-shadow(0 2px 2px rgba(0,0,0,.4))}
.stop:not(.open) .wico{opacity:.75;filter:grayscale(1)}
.slabel{margin-top:-2px;padding:1px 8px;border-radius:999px;background:rgba(40,20,8,.78);
  color:#FFF3D2;font-size:11px;font-weight:800;white-space:nowrap;max-width:132px;
  overflow:hidden;text-overflow:ellipsis}
/* the glow keyframes animate a box-shadow, which on an <img> draws a rectangle.
   The stop you are on gets a shaped glow instead. */
.stop.here .plinth{animation:stopglow 1.6s ease-in-out infinite}
@keyframes stopglow{
  0%,100%{filter:drop-shadow(0 3px 3px rgba(0,0,0,.45)) drop-shadow(0 0 4px rgba(155,227,74,.9))}
  50%{filter:drop-shadow(0 3px 3px rgba(0,0,0,.45)) drop-shadow(0 0 10px rgba(155,227,74,1))}
}
.stop .token{position:absolute;left:58px;bottom:14px;width:62px;height:auto;
  filter:drop-shadow(0 3px 3px rgba(0,0,0,.5))}

/* the city medallion, with a ring that fills across its thousand levels */
.citymark{position:absolute;left:0;right:0;bottom:4px;display:grid;justify-items:center;gap:1px}
.ring{position:relative;display:grid;place-items:center;width:128px;height:128px;border-radius:50%;
  background:conic-gradient(var(--gold2) calc(var(--pct) * 1%),rgba(20,10,4,.45) 0);
  padding:6px;box-shadow:0 0 0 3px var(--ink),0 6px 14px rgba(0,0,0,.5)}
.ring::after{content:"";position:absolute;inset:6px;border-radius:50%;background:rgba(28,52,104,.55)}
.cityart{position:relative;z-index:1;width:104px;height:104px;object-fit:contain;
  filter:drop-shadow(0 3px 3px rgba(0,0,0,.45))}
.citymark b{font-family:var(--display);font-weight:400;font-size:20px;color:#FFF3D2;
  text-shadow:0 2px 0 rgba(0,0,0,.5)}
.citymark small{padding:1px 10px;border-radius:999px;background:rgba(40,20,8,.78);
  color:#FFE9B8;font-size:11.5px;font-weight:800}
.band.far .citymark small{background:rgba(40,20,8,.9)}
/* map stops are buttons now */
.stop{border:none;background:none;padding:0;cursor:pointer}
.stop:active{transform:translateX(var(--sx,0)) scale(.94)}
.citymark{border:none;background:none;padding:0;cursor:pointer}
.citymark:active{transform:scale(.97)}
@media (hover:hover){
  .stop:hover .plinth{filter:drop-shadow(0 3px 3px rgba(0,0,0,.45)) drop-shadow(0 0 7px rgba(255,226,138,.95))}
  .citymark:hover .ring{box-shadow:0 0 0 3px var(--ink),0 0 18px rgba(255,226,138,.7),0 6px 14px rgba(0,0,0,.5)}
}

/* ---------- ribbons ----------
   Three in use: the new red in place of the old ruby, the original teal
   unchanged, and the new amethyst so violet cards stop borrowing the red. The
   rest of the colour pack is exported and sitting in assets/ui/ribbon if we ever
   want it. No gold ribbons. */
.ribbon.art.r-ruby{background-image:url("../assets/ui/ribbon/ruby-red.webp")!important}
.ribbon.art.r-purple{background-image:url("../assets/ui/ribbon/amethyst-purple.webp")!important}
.ribbon.art.r-blue{background-image:url("../assets/ui/ribbon/sapphire-blue.webp")!important}

/* Card grounds stay as they were — the v1.17 colours, which were right. */

/* ================= one screen, always =================
   A royal window is never taller than the screen and never scrolls the page.
   Three parts: the ribbon stays, the middle scrolls, the foot holds the buttons.
   Content stops above the foot rather than sliding underneath it. */

/* The crest and ribbon hang 71px above the cream card, and they are part of the
   box being centred — so centring the box put the card itself 36px low on every
   window. The eye reads the card, not the ribbon, so the card is what has to sit
   in the middle. The extra 71px of bottom padding lifts the box by half of it,
   which lands the card dead centre while keeping the ribbon inside the box, so
   nothing can be cut off at the top the way scrolling the box up would. */
.scrim{align-items:center;overflow:hidden;
  padding:calc(14px + var(--safe-t)) 14px calc(85px + var(--safe-b))}
.dialog{display:flex;flex-direction:column;max-height:100%;margin:auto}
.dlg-head{flex:none}
.dlg-body{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.dlg-scroll{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none}

.dlg-scroll::-webkit-scrollbar{display:none}
.dlg-scroll > :last-child{margin-bottom:0}
.dlg-foot{flex:none;display:grid;gap:9px;padding-top:10px}
.dialog.tall .dlg-body{max-height:none}

/* --- royal scrolls (pages) --- */
.screen.page{height:100%;min-height:0}
.pagebody{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none;padding-top:0}
.pagebody::-webkit-scrollbar{display:none}
.page .topbar,.page .pagehead,.page .wallet,.page .tabs{flex:none}
.page .wallet,.page .tabs{margin-left:14px;margin-right:14px}

/* four tabs have to fit one line */
.tabs{grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:3px}
.tabs button{font-size:15px;padding:7px 2px;white-space:nowrap}

/* --- the map scrolls inside its own body --- */
.mapbody{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none}
.mapbody::-webkit-scrollbar{display:none}

/* Every ribbon keeps the proportions the Settings window had. */
.ribbon.art{aspect-ratio:400/181}

/* Cream buttons read as blank paper, so secondary actions use gold. The classic
   buttons draw from border-image art, so this is a class swap, not a recolour. */

/* premium as a state on the pass header, not a button in the way */

/* firman rows use the shop row shape */
.firmrow{gap:8px;padding:5px 10px 5px 4px}
.firmrow .arch{width:60px;height:65px}
.firmrow .arch > .ico{width:33px!important;height:33px!important;margin-top:3px}
.firmrow .ename b{font-size:15.5px;line-height:1.15}
.firmrow .evbtn{font-size:14px;padding:5px 8px}
.firmrow .ename small{display:flex;align-items:center;gap:4px;color:#6A4020}
.firmrow .ename small .ico.inl{width:16px;height:16px}
.firmrow .lbar{margin-top:4px}

/* The level card and the result live on their own screen rather than in a
   scrim, so they need the same height limit: as tall as the screen less a
   margin, ribbon fixed, buttons fixed, middle scrolling. */
.screen.brief,.screen.result{height:100%;min-height:0;overflow:hidden;
  align-items:center;justify-content:center;
  padding:calc(14px + var(--safe-t)) 14px calc(85px + var(--safe-b))}

.resultpop{margin-top:0}
.result .bigstar{flex:none}

/* ---------- card grounds ----------
   The red was right: dark at the top, vivid at the foot. The others follow it,
   pitched from the shop button gradients rather than mixed by eye. Nothing
   pastel, and no yellow window. */
.dialog.card .dlg-body{background:linear-gradient(#173C82,#2F6BD6)}
.dialog.card.t-red .dlg-body{background:linear-gradient(#95061B,#DC1D2A)}
.dialog.card.t-purple .dlg-body{background:linear-gradient(#3F1F80,#7A3FD0)}
/* Tijori and the ledger were a yellow box. They are amber now, with the teal
   ribbon against it. */

/* The encounter's basis chip ("15% of your cash") is a <p> on a pale cream
   pill, so the dialog's near-white paragraph colour made it invisible — the
   pickpocket never showed what his cut was measured against. It keeps ink. */

.dialog.card.t-gold .boxlabel{color:#FFF3D2!important}
.dialog.card.t-gold .meter span{color:#FFF3D2;text-shadow:0 1px 2px rgba(0,0,0,.45)}

.dialog.card .dlg-body{--card:#2F6BD6}
.dialog.card.t-red .dlg-body{--card:#DC1D2A}
.dialog.card.t-purple .dlg-body{--card:#7A3FD0}

/* ---------- "done" without draining the colour ----------
   Greying a finished row made the window look broken. A finished row keeps all
   of its colour and says so with a seal on the left of its tile and a gold
   Done chip where its button was. */
.firmrow.done{filter:none}
.firmrow.done .ename b,.firmrow.done .ename small{opacity:1}
.firmrow.done .arch > .ico,
.dialog.card .day.got .ico{filter:none;opacity:1}
.firmrow.done .arch::after{filter:drop-shadow(0 0 4px rgba(67,174,30,.85))}
.arch .tick{top:-4px;left:-4px;right:auto}

/* every firman card the same width: the action column does not flex */

/* Button labels were wearing a four-way outline that reads as a smudge at small
   sizes. One soft shadow under the text instead. */
.btn{text-shadow:0 2px 0 rgba(0,0,0,.28)}
.btn small{text-shadow:0 1px 0 rgba(0,0,0,.25)}
.btn.gold,.btn.cream,.btn.silver{color:#4A2A08;text-shadow:0 1px 0 rgba(255,255,255,.55)}
.dialog.card .btn.gold{color:#4A2A08}

/* The amber window was still a yellow box. Tijori and the ledger take the red. */
.dialog.card.t-gold .dlg-body{background:linear-gradient(#95061B,#DC1D2A);--card:#DC1D2A;color:#FFF3D2}
.dialog.card.t-gold .dlg-body p,.dialog.card.t-gold .dlg-body p b{color:#FFF3D2}

.dialog.card.t-gold .dlg-body .fine{color:rgba(255,243,210,.85)}

/* the done marker is a real button, not a flat pill */

.btn.green .ico.inl,.btn.gold .ico.inl{width:18px;height:18px;vertical-align:-3px}
.evbtn.done{pointer-events:none}

/* the verdict plaque is cream, so its small print is ink like any other panel */
/* checkout inside a royal window */

/* the test-checkout note is a cream box, so it keeps ink text on a card */
.dialog.card .testmode{color:var(--ink)}

/* the pass track scrolls with the window, not inside its own little box */
.passtrack{max-height:none;overflow:visible}

/* a tier you can take says so, instead of the cell blinking */

.takeit{;;border-radius:999px;;
  color:#fff;font-family:var(--display);font-size:11px;}

/* gift and firman rows: one button column, one width */

.firmrow{grid-template-columns:62px 1fr 104px}
.firmrow .evbtn{width:100%;justify-content:center;min-width:0}
.evbtn.locked{pointer-events:none;opacity:1}
.evbtn.ready{animation:glow 1.5s ease-in-out infinite}

/* a relic you have not found reads as a shadow in its frame, not a blank tile */
.relic:not(.got) .arch > .ico{filter:brightness(0) opacity(.22)}
.relic.got .arch::after{filter:drop-shadow(0 0 4px rgba(255,214,107,.9))}
.relic small{font-size:11px;font-weight:800;line-height:1.2;text-align:center}
.dialog.card .panelbox .album .fine,.dialog.card .album .fine{color:#6A4020}

/* the Tijori meter's label sits on a gold bar, so it reads in ink */
.dialog.card .meter span{color:#4A2A08;text-shadow:0 1px 0 rgba(255,255,255,.5)}

/* A list used as a <ul> keeps the browser's indent unless it is reset — that was
   the margin down the left of the firman cards. */

/* Small royal buttons used as labels: price tags and guard chips.
   These carry the real button artwork — only the slice is smaller. An earlier
   version set border-image:none and drew a flat gradient pill, which is exactly
   what they must not be. Both button families need their own slice numbers:
   emerald/ruby are cut 44/118, the classic colours 48/130. */
.btn.tiny{min-height:26px;font-size:11px;letter-spacing:-.2px;pointer-events:none;
  border-radius:0;}
.btn.tiny.green,.btn.tiny.red{border-width:6px 15px;border-image-width:6px 15px}
.btn.tiny.gold,.btn.tiny.purple,.btn.tiny.cream,.btn.tiny.blue,.btn.tiny.teal,
.btn.tiny.orange,.btn.tiny.navy,.btn.tiny.bronze,
.btn.tiny.silver,.btn.tiny.black,.btn.tiny.brown{border-width:6px 15px;border-image-width:6px 15px}
.btn.tiny::after{display:none}
.ptag{justify-self:end;min-width:64px}
.watch{min-width:62px}

/* task cards carry the arch tile, like every other card */
.taskcard{grid-template-columns:66px 1fr;gap:9px;align-items:center}
.taskcard .arch{width:64px;height:69px}
.taskcard .arch > .ico{width:35px!important;height:35px!important;margin-top:3px}

/* the profit turning into coins, and rewards flying to where they belong */
.coinout{display:flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--display);font-size:38px;line-height:1.05;}
.coinout .ico{width:46px;height:46px;}
.flyreward{position:absolute;left:0;top:0;z-index:9999;pointer-events:none;width:76px;height:76px}
.flyreward .ico{width:76px;height:76px;filter:drop-shadow(0 4px 6px rgba(0,0,0,.45))}

/* ---------- the in-level stat row ----------
   Four numbers with nothing to say what they were. Each carries a small label
   now, they share one width, and the figures are shortened so nothing crowds. */
.statbar{grid-template-columns:repeat(4,1fr);}
.stat{position:relative;;gap:0;border-radius:14px}
.stat em{position:absolute;top:-8px;left:50%;transform:translateX(-50%);white-space:nowrap;
  padding:1px 9px;border-radius:9px;background:var(--ink);color:#FFE9B8;
  font-family:var(--display);font-size:11px;font-style:normal;line-height:1.45}
.stat .ico{width:20px;height:20px}
.stat b{font-size:15px;line-height:1.15}
.stat.cash,.stat.loan,.stat.hold{display:grid;grid-template-columns:20px auto;gap:4px;
  align-items:center;justify-content:center}
.stat.worth b{font-size:16px}

/* the Tasks and Moves labels sit clear of their boxes */

/* A class that sets `display` beats the browser's own [hidden] rule, which is
   why the coin figure showed before its animation ran. This settles it for good. */
[hidden]{display:none!important}

/* ================= v1.27 ================= */

/* ---------- the in-game top bar ----------
   The exit button had a column of its own on the left, which was the widest
   thing in the row and held nothing else. It hangs over the portrait now, the
   way a lamp hangs over a doorway, and Tasks and Moves take back the width. */
.hudrow{display:grid;;padding-left:0;}

.hudexit .ico{width:100%;height:100%}

/* the task icons in the bar wear the same arch frame as everywhere else */

.hslot b{margin-top:1px}

/* Every label in the bar is a small royal button. A .btn sets its own
   position, so these ride up over the box edge on a negative margin rather
   than being positioned absolutely — which is what knocked them out of place. */
.tasksbox em,.movesgem em,.stat em{position:static;left:auto;top:auto;transform:none;
  display:inline-flex;align-self:center;margin:-17px auto 1px;
  background:none;border:0;font-style:normal;white-space:nowrap}
/* the old absolute placement centred with translateX(-50%); left in place it
   dragged every label half its own width off the box */
.tasksbox em:active,.movesgem em:active,.stat em:active{transform:none}
.statbar{gap:7px;margin-top:15px}
.stat{padding:6px 5px 4px}
.stat em.btn.tiny{min-height:22px;font-size:10.5px;border-width:5px 13px;border-image-width:5px 13px}
.tasksbox em.btn.tiny{min-height:24px;font-size:12.5px;border-width:5px 14px;border-image-width:5px 14px}

/* ---------- the result screen has to fit the phone ----------
   The window was capped at 100% of the screen while the star and the coin pill
   sat above it, so together they were always taller than the screen and the
   ends were cut off. The window shrinks with the space left over instead. */
.screen.brief,.screen.result{display:flex;flex-direction:column}
.screen.result .rtop,.screen.result .bigstar{flex:none}
.screen.brief .dialog,.screen.result .dialog{flex:0 1 auto;min-height:0;max-height:none;margin:0}

/* ---------- the coin figure on the win screen ----------
   It was cream, and it lands on the cream plaque — white on white. Coins are
   gold, so it reads in gold on a light ground. */
.coinout{color:#A8650A;text-shadow:0 1px 0 rgba(255,255,255,.7)}
.coinout .ico{filter:drop-shadow(0 1px 1px rgba(0,0,0,.25))}

/* ---------- the Tijori meter ----------
   Its fill is gold and its groove is pale, so the figure has to be ink on both.
   The t-gold rule was painting it cream, which vanished against the fill. */
.dialog.card .meter span,.dialog.card.t-gold .meter span{
  color:#4A2A08;text-shadow:0 1px 0 rgba(255,255,255,.6)}

/* the coin count in the top bar never gets an ellipsis */
.topbar .pill:nth-child(1){flex-grow:1.6}
.topbar .pill:nth-child(3){flex-grow:.55}

/* ---------- where you stand, in the Out-of-moves window ----------
   It was a red figure on a red card. It sits on its own plaque now, the same
   cream the rest of the window uses, so the number is the thing you see. */
.standing{display:grid;justify-items:center;gap:0;margin:0 0 10px;padding:7px 14px 8px;
  border-radius:14px;border:2.5px solid #8A5A1E;background:linear-gradient(#FFFDF4,#F6E7C4)}
.standing,.dialog.card .dlg-body p.standing{color:#6A4020}
.standing b{font-family:var(--display);font-weight:400;font-size:30px;line-height:1.05}
.standing.below b{color:var(--neg)}
.standing small{font-size:12px;font-weight:800;color:#6A4020}

/* How to play uses the row card every other list uses: arch tile, then text. */

/* The stat pills carry their label above and their figure below, so the icon
   and the number share one row of their own rather than fighting the label for
   the grid. */
.stat{display:flex!important;flex-direction:column;align-items:center;justify-content:flex-start;
  grid-template-columns:none!important}
.stat .sv{display:flex;align-items:center;justify-content:center;gap:4px;min-width:0;width:100%}
.stat .sv .ico{flex:none;width:20px;height:20px}
.stat .sv b{min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:15px}
.stat.hold .sv b{font-size:13.5px;letter-spacing:-.3px}

/* Moves needs a touch more width than its label, and the exit hangs just above
   the portrait rather than floating at the top of the row. */

/* Monsoon Rush was the last list still showing a bare icon; it wears the arch
   tile now, so its rows match the firmans, the gift and the Haat. */
.liverow.tiled{grid-template-columns:58px 1fr auto}
.liverow.tiled .arch{width:56px;height:60px}
.liverow.tiled .arch > .ico{width:31px!important;height:31px!important;margin-top:3px}

/* Tasks and Moves sat inside their boxes while Cash/Loan/Hold/Profit straddled
   theirs. The labels ride up over the box edge — the boxes were block
   container, so the label was inline-level, and vertical margins do not move an
   inline-level box. The stat pills are flex columns, which is why only they
   worked. Making the boxes flex columns too puts all six on the same footing. */

/* ---------- Moves as a jewelled medallion (v1.30) ----------
   The Moves box held one number in a box sized for three tiles, so it always
   carried a block of dead cream. A box that cannot look empty is a box that
   isn't there: Moves is a gold ring on the blue now, like the coin and star
   pills, and the Tasks panel takes the width it gives up. */

.movesgem{position:relative;display:grid;place-items:center;;flex:none;
  filter:drop-shadow(0 3px 3px rgba(0,0,0,.4))}
.movesgem .gart{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none}
/* a cream disc behind the number so it reads against the ring, not the sky */
.movesgem::before{content:"";position:absolute;;border-radius:50%;
  background:radial-gradient(circle at 50% 35%,#FFFDF4,#F0DCB4)}
.movesgem b{position:relative;z-index:2;font-family:var(--display);font-weight:400;line-height:1;color:var(--ink)}
.movesgem.low b{color:var(--red2);animation:pulse 1s infinite}
/* the label rides the ring's top edge, as every other label rides its box */
.movesgem em{position:absolute;z-index:3;top:-9px;left:50%;margin:0;
  transform:translateX(-50%);align-self:auto}

/* the exit sits on the portrait's shoulder now that the medallion is above it */
.portrait{position:relative;;}

.hudexit{position:absolute;;left:auto;bottom:auto;transform:none;
  z-index:4;;margin:0;padding:0;
  background:none!important;border:none!important;box-shadow:none!important;
  filter:drop-shadow(0 2px 2px rgba(0,0,0,.45))}
.hudexit:active{transform:translateY(2px)}

/* The medallion column is taller than a panel of three tiles, so the panel
   stretches to meet it and centres its tiles rather than leaving blue beneath.
   The tiles grow a little into that height so the panel reads full, not sparse. */

/* the label has to fit inside a 70px ring, so it is cut finer than the others */
.movesgem em.btn.tiny{min-height:20px;font-size:10px;border-width:4px 11px;border-image-width:4px 11px}

/* Tightened: the medallion column had grown the bar by ~30px of screen, which
   is play space. The ring and the portrait overlap slightly, the way a seal
   overlaps a scroll, and the bar comes back to the height it was. */
.movesgem{width:66px;height:66px}
.movesgem::before{width:45px;height:45px}
.movesgem b{font-size:26px}

/* a hair of daylight between the ring and the portrait frame */
.portrait{margin-top:-1px}

/* One task: the tile keeps company with what the task asks, so the panel is
   full and the goal is legible without opening anything. */

/* the running figure is progress, not a second heading */

/* ---------- price tags: centre the word (v1.31) ----------
   min-width on the tag pushed the label about 4px right of the button's middle.
   Measured, not guessed: with min-width the text sat -3.0px off centre, without
   it +1.0px. The tags size to their word now, with even padding instead. */
.ptag,.watch{min-width:0}
.btn.tiny{padding:0 7px 1px}

/* ---------- the bar in one line (v1.31) ----------
   Tasks, Moves and the trader now share a single row. The Tasks panel is built
   like the Cash/Loan/Hold pills under it — cream, rounded, its label on the top
   edge — and its icons are bare, which is where the width came from. */
.hudrow{;margin-top:11px}

.tasksbox{position:relative;display:flex;flex-direction:row;align-items:center;
  justify-content:space-around;gap:8px;width:100%;min-width:0;cursor:pointer;border-radius:14px;background:rgba(255,248,230,.95);
  border:2px solid var(--ink);font-family:var(--display);white-space:nowrap}
.tasksbox em{position:absolute;top:-12px;left:50%;transform:translateX(-50%);margin:0;z-index:2}
.hslots{display:flex;align-items:center;;width:100%;min-width:0}
.hslot{display:flex;align-items:center;min-width:0}
.hslot .ico{flex:none;}
.hslot b{font-weight:400;line-height:1.1;min-width:0;overflow:hidden;text-overflow:ellipsis}
.hslot .hmark{width:16px!important;height:16px!important}
/* one task: the icon, then what it asks with the running figure beneath */

/* the trader is a button now: tap her to change who runs the caravan */
.portrait{margin:0;padding:0;;overflow:visible;cursor:pointer}

.hudexit{;cursor:pointer}

/* a move spent should be felt; the ledger should show on her face */
@keyframes movepop{0%{transform:scale(1)}35%{transform:scale(1.2)}100%{transform:scale(1)}}

@keyframes cheer{0%,100%{transform:rotate(0) scale(1)}30%{transform:rotate(-7deg) scale(1.12)}
  65%{transform:rotate(5deg) scale(1.08)}}
.portrait.cheer{animation:cheer .55s ease-out}
@keyframes flinch{0%,100%{transform:translateX(0)}20%{transform:translateX(-4px)}
  45%{transform:translateX(4px)}70%{transform:translateX(-3px)}}
.portrait.flinch{animation:flinch .42s ease-out}
@media (prefers-reduced-motion:reduce){
  .movesgem.pop,.portrait.cheer,.portrait.flinch{animation:none}
}

/* ---------- symmetry across the bar (v1.32) ----------
   The Tasks label sat higher than Moves and was cut larger, which is the sort
   of mismatch you feel before you can name it. Both boxes are one height now,
   both labels one size, so the two ride at exactly the same line. */
.hudrow{grid-template-columns:1fr 66px 62px;align-items:center;gap:9px}
.tasksbox{height:66px;}
.tasksbox em,.movesgem em{top:-9px}
.tasksbox em.btn.tiny,.movesgem em.btn.tiny{
  min-height:20px;font-size:10px;border-width:4px 11px;border-image-width:4px 11px}

/* the two rings carry the same shadow; the portrait art brings its own frame,
   so the square border it used to sit in is gone */
.movesgem,.portrait{filter:drop-shadow(0 3px 3px rgba(0,0,0,.4))}
.portrait{width:62px;height:62px;border:0;box-shadow:none;background:none;border-radius:0;
  display:grid;place-items:center;padding:0}
.portrait > .ico{width:100%;height:100%;object-fit:contain;border-radius:0;transform:none}
.hudexit{right:-6px;top:-4px;width:27px;height:27px}

/* ---------- the panel's own furniture ----------
   Corner flourishes and a divider between slots, so one task looks composed
   rather than adrift. */
.orn{position:absolute;;pointer-events:none;opacity:.9;
  background:url("../assets/ui/orn/corner.webp") center/contain no-repeat}
.orn.tl{left:4px;top:4px}
.orn.tr{right:4px;top:4px;transform:scaleX(-1)}
.orn.bl{left:4px;bottom:4px;transform:scaleY(-1)}
.orn.br{right:4px;bottom:4px;transform:scale(-1,-1)}
.vdiv{flex:none;;opacity:.85;
  background:url("../assets/ui/orn/divider.webp") center/contain no-repeat}

/* a move spent should register, not startle */
@keyframes movepop{0%{transform:scale(1)}40%{transform:scale(1.07)}100%{transform:scale(1)}}
.movesgem.pop{animation:movepop .26s ease-out}

/* The corners and dividers cost width, and the figures were clipping to "0…".
   Content clears the flourishes, and the slots are cut finer to pay for them. */

.hslots{justify-content:space-between}

/* ---------- naming: the tail rides under the tile (v1.33) ----------
   A flavour word alone teaches nothing. The tile keeps its name and carries
   what the thing actually is underneath, in plain words. */
.tile .tl{bottom:-11px;font-size:11.5px;padding:0 7px}
.tile .tsub{position:absolute;left:50%;bottom:-26px;transform:translateX(-50%);
  white-space:nowrap;font-size:9.5px;font-weight:800;letter-spacing:.2px;
  color:#FFE9B8;text-shadow:0 1px 2px rgba(0,0,0,.8),0 0 6px rgba(0,0,0,.6)}
.tiles{gap:34px}
/* the left rail holds up to five live events, so it is cut a little tighter */

/* the Collection page's two halves */
.tabs2{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px;margin:0 0 10px;
  padding:0 14px;box-sizing:border-box}
/* the count of trophies waiting to be collected, on the tab that holds them */

.tabs2 .btn{position:relative;overflow:visible}

/* ---------- the trophy shelf ---------- */
/* the trophy shelf uses .liverow like every other claim list */

/* ---------- Veer and Devi (v1.33) ----------
   They talk to each other, not at the player, and the box sits over the board
   rather than covering it — so whatever is being pointed at stays visible.
   Devi faces right, Veer faces left, so an exchange reads as a conversation. */
.coachbar{display:grid;gap:5px;margin:0 0 9px;padding:8px 9px;border-radius:16px;
  border:2.5px solid var(--gold2);background:linear-gradient(rgba(59,31,14,.88),rgba(59,31,14,.72));
  box-shadow:0 3px 0 rgba(0,0,0,.25)}
/* row-reverse, not direction:rtl — rtl reorders the grid tracks too and
   squeezed Veer's bubble to a column of single words */
.csay{display:flex;align-items:center;gap:9px}
.csay.veer{flex-direction:row-reverse}
.masc{flex:none;width:44px;height:44px;object-fit:contain;border-radius:50%;
  background:radial-gradient(circle at 50% 35%,#FFE9B8,#E0A04A);
  border:2.5px solid var(--gold2);box-shadow:0 0 0 2px rgba(0,0,0,.45)}
/* the delivered art is drawn facing forward, so it is never mirrored */
.cbub{flex:1 1 auto;min-width:0;position:relative;padding:6px 11px;border-radius:13px;
  background:linear-gradient(#FFFDF4,#F6E7C4);border:2px solid #8A5A1E;
  font-size:12.5px;font-weight:800;line-height:1.35;color:#3B1F0E}

/* ---------- v1.34 ---------- */

/* A window that re-renders in place (claiming a tier, say) kept replaying its
   open animation, which read as the window closing and another opening. */
.samewindow .dialog{animation:none}

/* The pass's "Take" was a hand-rolled green pill and the ready cell blinked with
   a green border — both off-brand. Take is a small royal button; ready is a gold
   glow, which is how everything else in the game says "this one". */
.takeit{position:absolute;right:4px;bottom:3px;padding:0;border:0;background:none;
  font-style:normal;line-height:1}
.passcell.ready{animation:none;border-color:var(--gold2);
  box-shadow:0 0 0 2px var(--gold1),0 0 10px rgba(255,214,107,.55)}
.takeit .btn.tiny{min-height:18px;font-size:9.5px;border-width:4px 10px;border-image-width:4px 10px;padding:0 5px 1px}

/* ---------- the win streak as five steps ----------
   Each step you hold turns on the next free booster, so the row sits with the
   booster picker rather than being explained in a sentence somewhere else. */

/* a broken streak: the lights go out one after another, left to right */

/* ---------- a page that needs a window's ground ----------
   The Collection page had its text on the bare background, so the fine print
   vanished into the bazaar behind it. It sits on the same royal ground a window
   uses, with the same text colours. */

.dialog .panelbox{color:#6A4020}

/* .note is written for text standing on the background photo, where it needs a
   shadow to be legible. Inside a cream panel the shadow is just dirt. */

/* task cards in a list share one height, so a one-line card does not sit short
   beside a two-line one */
.taskcards .taskcard{min-height:74px}

/* ---------- Veer and Devi on the home screen ----------
   One line, the most useful thing that is true now. Tapping puts it away for
   the session so it never becomes wallpaper. */
.homesay{position:relative;z-index:3;display:flex;align-items:center;gap:9px;
  width:calc(100% - 28px);margin:0 auto 10px;padding:7px 10px;border-radius:16px;
  border:2.5px solid var(--gold2);background:linear-gradient(rgba(59,31,14,.9),rgba(59,31,14,.74));
  box-shadow:0 3px 0 rgba(0,0,0,.25);text-align:left;cursor:pointer}
@keyframes sayin{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.homesay .cbub{font-size:12.5px}
/* Veer and Devi's chat: a conversation that has to be read. It stacks, a line
   at a time; only the chat and the newest line animate in, so a tap adds a
   line and never replays the ones above it. It never leaves by itself: after
   the last line a small × shows and a tap anywhere closes it (main.js). */
.homesay.opening{flex-direction:column;align-items:stretch;gap:7px;cursor:pointer;padding:9px 10px}
.homesay.enter{animation:sayin .45s ease-out both}
.homesay .csay.new{animation:sayin .45s ease-out both}
.homesay.opening .masc{width:38px;height:38px}
.homesay .sayx{position:absolute;top:-12px;right:-10px;width:30px;height:30px;filter:drop-shadow(0 2px 1px rgba(0,0,0,.35));
  animation:sayin .3s ease-out both}
.homesay .sayx[hidden]{display:none}
.homesay .sayx .ico{width:100%;height:100%}
.homesay .saytap{align-self:flex-end;font-size:11px;font-weight:800;color:var(--gold1);opacity:.85}
/* While they talk, the rest of the home screen waits, and looks it. */
#phone.chatting .screen.home > :not(.homesay){filter:brightness(.55) saturate(.7);transition:filter .3s}
@media (prefers-reduced-motion:reduce){ .homesay.enter,.homesay .csay.new,.homesay .sayx{animation:none} }

/* ---------- the events rail and its windows (v1.35) ---------- */
/* Every rail tile carries its own clock; a tile without one is a menu, not an
   event. The sub-line is the timer, so it reads at a glance. */
.tiles.rail .tsub{font-variant-numeric:tabular-nums}

/* ---------- the reward celebration (v1.36) ----------
   Every claim ends here. The prizes arrive together in the middle, then fly to
   the place they now live — so the player learns where their things are kept. */
.celebrate{position:absolute;inset:0;z-index:60;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:18px;
  background:radial-gradient(circle at 50% 45%,rgba(20,10,4,.55),rgba(20,10,4,.82));
  animation:celin .25s ease-out}
@keyframes celin{from{opacity:0}to{opacity:1}}
.celebrate.going{background:transparent;transition:background .3s}

.celtitle{max-width:86%;font-family:var(--display);font-weight:400;font-size:30px;
  line-height:1.1;text-align:center;color:#FFE9B8;
  text-shadow:0 3px 0 #6B0F0F,0 0 18px rgba(255,214,107,.5),2px 0 0 #6B0F0F,-2px 0 0 #6B0F0F,0 -2px 0 #6B0F0F}
.celebrate.going .celtitle{opacity:0;transition:opacity .25s}

.celitems{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:16px;max-width:92%}
.celitem{position:relative;display:grid;place-items:center;width:96px;height:96px;
  filter:drop-shadow(0 6px 10px rgba(0,0,0,.5))}
.celitem .ico{width:96px;height:96px}
.celitem b{position:absolute;bottom:-6px;left:50%;transform:translateX(-50%);
  padding:2px 12px 3px;border-radius:999px;border:2.5px solid var(--ink);
  background:linear-gradient(var(--green1),var(--green2));color:#fff;
  font-family:var(--display);font-weight:400;font-size:17px;white-space:nowrap;
  text-shadow:0 2px 0 var(--green3)}

.celtap{font-family:var(--display);font-weight:400;font-size:17px;color:#FFF3D2;
  text-shadow:0 2px 3px rgba(0,0,0,.7);animation:celtap 1.4s ease-in-out infinite}
@keyframes celtap{50%{opacity:.45}}

.confetto{position:absolute;left:0;top:0;width:8px;height:13px;border-radius:2px;pointer-events:none}

@media (prefers-reduced-motion:reduce){
  .celebrate,.celtap{animation:none}
}

/* ---------- boosters and the streak, read as one thing (v1.37) ----------
   Five boosters, five dashes, one under each: the dash lit is the booster free.
   Before this the dashes carried booster icons of their own, which invited you
   to read them as a second row of boosters rather than as a streak. */
.boosts{display:grid;grid-template-columns:repeat(5,1fr);justify-items:center;}

/* a broken streak: the dashes go out left to right, and stay legible doing it */

/* a free booster wears a gold ring and says so; the flame used to sit on top of
   the artwork, so you could not see which booster it was */
.freetag{position:absolute;left:50%;bottom:-9px;transform:translateX(-50%);
  z-index:4;padding:0 7px 1px;border-radius:999px;border:2px solid var(--ink);
  background:linear-gradient(var(--gold1),var(--gold2));color:#4A2A05;
  font-family:var(--display);font-weight:400;font-style:normal;font-size:10.5px;
  line-height:1.5;letter-spacing:.2px}
.boost.on{box-shadow:0 0 0 3px #fff,0 0 0 6px var(--gold2),0 4px 0 rgba(0,0,0,.3)}
.boost .tick{left:-6px;bottom:auto;top:-6px}

/* the tasks pill holds three figures without clipping any of them */
.hslot .ico{width:23px;height:23px}
.hslot b{font-size:12.5px;letter-spacing:-.3px}
.hslots{gap:3px}
.hslot{gap:4px}
.tasksbox{padding:0 17px}
.vdiv{width:6px;height:26px}
/* two across when three would cut a figure short (main.js fitTaskRow) */
.hslots.two{flex-wrap:wrap;justify-content:space-around;row-gap:2px}
.hslots.two .vdiv{display:none}
.hslots.two .hslot{flex:0 0 calc(50% - 3px);justify-content:center}
.hslots.two .hslot .ico,.hslots.two .hslot.always .ico{width:18px;height:18px;margin-top:0}
.hslots.two .hslot b{min-height:0}
.orn{width:13px;height:12px}
/* one task: the title clears the Tasks label above it rather than running under */

/* The road ahead lived here and has gone: it repeated the map, and worse, its
   .stop and .road classes collided with the map's own waypoints and route line
   and silently restyled them. What it said now comes from Veer and Devi. */

/* the rail carries five tiles without reaching the mascot's line */

/* the haveli strip, tightened so the home screen still breathes */

/* the rail stops above the mascot's line rather than sitting under it */

/* ---------- arriving home ----------
   Coming back from a level, the screen settles into place: the rails slide in
   from their edges, the house and the road rise, the level button lands last.
   It plays once, on arrival, and never when you are just sitting there. */
@keyframes railin{from{opacity:0;transform:translateX(-26px)}to{opacity:1;transform:none}}
@keyframes railinR{from{opacity:0;transform:translateX(26px)}to{opacity:1;transform:none}}
@keyframes risein{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes landin{from{opacity:0;transform:scale(.86)}to{opacity:1;transform:none}}
.home.arriving .tiles.left .tile{animation:railin .4s ease-out both}
.home.arriving .tiles.right .tile{animation:railinR .4s ease-out both}
.home.arriving .tiles .tile:nth-child(1){animation-delay:.04s}
.home.arriving .tiles .tile:nth-child(2){animation-delay:.10s}
.home.arriving .tiles .tile:nth-child(3){animation-delay:.16s}
.home.arriving .tiles .tile:nth-child(4){animation-delay:.22s}
.home.arriving .tiles .tile:nth-child(5){animation-delay:.28s}
.home.arriving .playrow{animation:risein .45s .18s ease-out both}
.home.arriving .levelbtn{animation:landin .42s .34s cubic-bezier(.3,1.5,.5,1) both}
@media (prefers-reduced-motion:reduce){
  .home.arriving .tile,.home.arriving .playrow,
  .home.arriving .levelbtn{animation:none}
}

/* a swipe needs somewhere to go, so the line is not clipped while it leaves */
.homesay{touch-action:pan-y;will-change:transform,opacity}

/* ---------- both rails, one size (v1.39) ----------
   The left column had been shrunk to make room and ended up a different size
   from the right, which reads as a mistake before you can name it. One size for
   both; the left carries five, so it is spaced a little tighter. */
.tiles.rail{gap:24px}

/* a royal button stacks its children, so the build label is one span, one line */

/* room names were too faint and too small to be worth printing */
/* plain block, not -webkit-box: the clamp collapsed these to nothing */

/* ---------- the house sits beside the level (v1.40) ----------
   A strip was in the way and a drawer had to be opened. As a button it shares
   the row with the level: the house, how much of it stands, and one tap to the
   window that builds it. The level button can spare the width. */
/* The two buttons are a pair: same height, same fonts, same two-line structure,
   centred the same way. Only the colour differs.
   `auto 1fr` used to let the Haveli size itself to its own text and take 55% of
   the row; then a 1fr/1.3fr split fixed that and broke the symmetry instead —
   different heights, different type, the icon shunted to one side. Equal columns
   give both the same interior, which is what lets both carry the same layout. */
.playrow{display:grid;grid-template-columns:1fr;justify-items:center;gap:10px;align-items:stretch;width:100%}   /* one button since v2.92: the Haveli moved to the tabs */

.playrow .lvsub{white-space:nowrap}
.playrow .levelbtn{width:100%;min-width:0}
/* One size for the pair, at each breakpoint, written on one line so a change
   to the level button cannot quietly leave the Haveli behind. */

/* The two lines under the titles are one line of CSS, not two that happen to
   agree. They did not agree: the level's was #F2FFE4 with a shadow, the
   Haveli's was white at 95% with none, and side by side they read as different
   type. Every property that could differ is stated here. */
.playrow .lvsub{
  font-family:inherit;font-style:normal;font-weight:800;font-size:10px;line-height:1.1;
  letter-spacing:0;text-transform:none;color:#fff;opacity:1;
  text-shadow:0 1px 0 var(--b3)}

   /* size, weight and colour: see .playrow .lvsub */

/* ---------- both columns label their tiles the same ----------
   The rail's sub-line sat four pixels higher than the right column's, so the two
   sides never lined up and it was impossible to say why. */
.tiles.rail .tsub{bottom:-26px}
/* "Level 900" was breaking over two lines once it shared the row */
.playrow .lvtext{font-size:27px;white-space:nowrap}
.playrow .levelbtn{border-width:16px 30px;border-image-width:16px 30px;min-height:74px}

/* the "build me" badge belongs on the corner, not across the word */
/* An absolutely-positioned child measures from the padding box, and a royal
   button's border-image is 14px top and 34px wide — so right:-8px landed the
   badge 26px inside the artwork, across the word. The offsets clear the border. */

/* ---------- v1.43: the chapter card ---------- */

/* Shown once every hundred levels, on the level card. Two halves, deliberately
   kept apart: the exchange is the story and the panel under it is the fact. The
   card frames them together so they read as one moment without ever being one
   sentence — a story line that quoted a price would be wrong by level 400. */
.chaptercard{margin:0 0 10px;padding:9px 9px 8px;border-radius:18px;
  border:2.5px solid var(--gold2);background:linear-gradient(rgba(59,31,14,.5),rgba(59,31,14,.28));
  box-shadow:inset 0 0 0 2px rgba(255,226,138,.18)}
.chmark{margin:0 0 1px;font-size:11px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;color:rgba(255,232,178,.75)}
.chtitle{margin:0 0 7px;font-family:var(--display);font-weight:400;font-size:21px;
  line-height:1.1;color:#FFE9B0;text-shadow:0 2px 0 rgba(0,0,0,.35)}
.chsay{display:grid;gap:5px;margin:0 0 8px}
.chaptercard .chapterbox{margin:0}

/* ---------- v1.59: the town crier ---------- */

/* A consequence gets a window and a tap; afterwards the same words sit in the
   strip at the top of the market. Same voice in both places, so acknowledging
   it does not make it disappear. */
.crierline{display:flex;align-items:center;gap:11px;text-align:left;
  margin:0 0 9px;padding:9px 12px;border-radius:15px;
  background:linear-gradient(#FFFDF4,#F6E7C4);border:2.5px solid #8A5A1E}
.crierline:last-child{margin-bottom:0}
.crierline p{margin:0;font-size:13.5px;font-weight:800;line-height:1.35;color:#3B1F0E!important}
.crierico{width:46px;height:46px;flex:none}
.crierline.bad{background:linear-gradient(#FFF1EC,#FBDFD3);border-color:#A8442A}
.crierline.tip{background:linear-gradient(#FFFBE8,#FDF0C4);border-color:#B0862A}

/* ---------- the guided levels ---------- */
/* Levels 1-7 allow only the tap the coach is asking for. What is refused is
   faded rather than removed: the player can see the whole board, learn where
   things are, and find out by looking that it is not their turn for it yet. */
.guidedim{opacity:.34;filter:saturate(.35);transition:opacity .2s}
.goods.coach,.destlist.coach,.btn.coach{position:relative}
@keyframes guidenudge{
  0%,100%{transform:translateX(0)}
  15%{transform:translateX(-6px)}35%{transform:translateX(5px)}
  55%{transform:translateX(-4px)}75%{transform:translateX(3px)}
}
.nudge{animation:guidenudge .42s ease-in-out}
.coachbar.nudge{animation:guidenudge .42s ease-in-out}

/* ---------- step tracks (the Spice Ledger) ---------- */
/* Eight entries filling with ink. The step rewards are deliberately small and
   the last one is not, so the page reads as a run-up to one prize rather than
   eight small ones. */
/* A gold-toned window paints every paragraph in its body near-white, for the
   gold card behind them. A panelbox is cream, so anything inside one is white
   on cream: present, styled, and invisible. That is exactly how the
   pickpocket's fee chip survived four versions, and it was waiting here for the
   next cream box in a gold window — this one.
   Stated for panelboxes generally, not just this track, so the next one is
   already right. */
.dialog.card.t-gold .dlg-body .panelbox,
.dialog.card.t-gold .dlg-body .panelbox p,
.dialog.card.t-gold .dlg-body .panelbox p b,
.dialog.card.t-gold .dlg-body .panelbox .fine{color:#6A4020}
.dialog.card.t-gold .dlg-body .panelbox .boxlabel{color:var(--ink)}
.tstep .fine{color:var(--muted)}
.tstep .trew{color:var(--ink)}
.panelbox.track .trackhead{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin:2px 0 6px}
.panelbox.track .tkn{font-family:var(--display);font-size:17px;color:var(--wood)}
.panelbox.track .tkn b{font-size:21px;color:var(--ink)}
.panelbox.track .featured{margin-top:6px;color:var(--wood)}
.panelbox.track .featured b{text-transform:capitalize}
.tsteps{display:flex;flex-direction:column;gap:5px;margin:10px 0 6px}
.tstep{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:8px;
  padding:7px 9px;border-radius:12px;border:2px solid var(--cream3);background:var(--cream1)}
.tstep.done{border-color:var(--green2);background:#F2FBE9}
.tstep.ready{border-color:var(--gold2);background:#FFF6DC;box-shadow:0 0 0 3px rgba(243,182,52,.28)}
.tstep.grand{border-width:3px;border-color:var(--gold3);background:linear-gradient(var(--gold1),#FFF6DC)}
.tstep .tgoal{font-family:var(--display);font-size:15px;color:var(--wood);white-space:nowrap}
.tstep .trew{font-size:13px;font-weight:700;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.tstep .tdone{color:var(--green3);display:flex}
.tstep .tdone svg{width:20px;height:20px}
.btn.sm{padding:5px 11px;font-size:13px;border-radius:12px}

/* ---------- Saakh: your standing with the munim ---------- */
/* Five slots under the Play button, lit as far as the munim trusts you. It sits
   where the thumb already is because the whole point is that it is seen on
   every visit — buried behind a tile, this mechanic existed for months and
   nobody knew it was there. */
.saakh{display:flex;align-items:center;gap:9px;width:100%;margin:0 0 8px;padding:6px 10px;
  border:3px solid var(--ink);border-radius:16px;background:linear-gradient(#5A3410,#3E2410);
  box-shadow:0 3px 0 rgba(0,0,0,.45)}
.saakh.on{background:linear-gradient(#7A4A17,#5A3410);box-shadow:0 0 0 2px var(--gold3),0 3px 0 rgba(0,0,0,.45)}
.saakh .skico{width:34px;height:34px;flex:0 0 auto;border-radius:50%;overflow:hidden;
  border:2px solid var(--gold2);background:#2A1608;display:flex}
.saakh .skico .ico{width:100%;height:100%;object-fit:cover}
.skslots{display:flex;gap:4px;flex:1 1 auto;justify-content:center}
.skslot{width:30px;height:30px;border-radius:9px;border:2px solid #2A1608;background:rgba(0,0,0,.35);
  display:flex;align-items:center;justify-content:center;opacity:.5;transition:opacity .2s}
.skslot .ico{width:20px;height:20px}
.skslot.lit{opacity:1;background:linear-gradient(var(--gold1),var(--gold2));border-color:var(--gold3)}
.skslot.shut{opacity:.22}

/* a slot lighting up, and the whole strip going out */
@keyframes skpop{0%{transform:scale(1)}45%{transform:scale(1.28)}100%{transform:scale(1)}}
.skslot.pop{animation:skpop .32s ease-out}
@keyframes skbreak{0%,100%{transform:translateX(0)}20%{transform:translateX(-5px)}45%{transform:translateX(4px)}70%{transform:translateX(-3px)}}
.saakh.broke{animation:skbreak .4s ease-in-out}
.dialog .says{font-style:italic;text-align:center;color:#FFE9C0}

/* ---------- saakh on the level card ---------- */
.skrow{display:flex;align-items:center;gap:8px;margin:-2px 0 10px;padding:6px 9px;
  border:2px solid var(--cream3);border-radius:14px;background:linear-gradient(#FFF6E2,#F6E6C4)}
.skrow .skico{width:30px;height:30px;flex:0 0 auto;border-radius:50%;overflow:hidden;border:2px solid var(--gold2);background:#2A1608;display:flex}
.skrow .skico .ico{width:100%;height:100%;object-fit:cover}
.skrow .sktitle{display:flex;flex-direction:column;line-height:1.15;flex:1 1 auto;min-width:0}
.skrow .sktitle b{font-family:var(--display);font-size:14px;color:var(--ink)}
.skrow .sktitle em{font-style:normal;font-size:11px;font-weight:700;color:var(--muted)}
.skrow .skcount{font-family:var(--display);font-size:15px;color:var(--wood);flex:0 0 auto}
.skrow .skslots{display:flex;gap:3px;flex:0 0 auto}
.skrow .skslot{width:9px;height:14px;border-radius:3px;background:var(--cream3);border:1px solid #B9945A}
.skrow .skslot.lit{background:linear-gradient(var(--gold1),var(--gold2));border-color:var(--gold3)}
.skrow .skslot.shut{opacity:.35}

/* the booster row: a name and a count on every one */
/* The name under the circle, and the saakh tag above it — they shared a line
   and the tag sat on top of the word. */
.boost .bname{position:absolute;left:-6px;right:-6px;font-size:9.5px;font-weight:800;
  color:var(--wood);text-align:center;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.boosts{gap:14px}
.boost{position:relative;overflow:visible}
.boost .badge.none{background:#C9B18A;color:#6A4020}
.boost .freetag{letter-spacing:.2px;;;}
.boost.locked .bname{color:var(--muted)}
.ibtn{width:19px;height:19px;margin-left:6px;border-radius:50%;border:2px solid var(--wood);
  background:var(--cream1);color:var(--wood);font:800 12px/1 var(--body);vertical-align:middle;padding:0}
.ownpill{min-width:26px;padding:3px 7px;border-radius:9px;background:var(--cream3);
  color:var(--ink);font-weight:800;font-size:13px;text-align:center}
.liverow.shut{opacity:.55}

/* what giving up costs */
.stakes{list-style:none;margin:8px 0;padding:0;display:flex;flex-direction:column;gap:6px}
.stakes li{display:flex;align-items:center;gap:7px;padding:7px 10px;border-radius:12px;
  background:rgba(0,0,0,.18);font-size:13.5px;font-weight:700}
.stakes .ico{width:20px;height:20px;flex:0 0 auto}
.btn.small{padding:6px 12px;font-size:14px}

/* boosters carried into the run, beside the tools */
.pudiv{width:2px;align-self:stretch;margin:6px 2px;border-radius:2px;background:rgba(0,0,0,.25);flex:0 0 auto}
.pu.boostpu{border-color:var(--gold3)}
.pu.boostpu.ready{box-shadow:0 0 0 3px rgba(243,182,52,.45)}

/* the bag: one slot on the run bar, opening a list */
.pu.bagpu{border-color:var(--gold3)}
.pu.bagpu.ready{box-shadow:0 0 0 3px rgba(243,182,52,.45)}
.pu.bagpu.empty{opacity:.6}
.pu .badge.none{background:#8A7150;color:#F4E6CC}
.eventcard.shut{opacity:.55}

/* ---------- a booster in play, shown where its effect lands ---------- */
/* Scout works because the effect *is* the information — you see prices you
   could not see. The others change a number that was already on screen, and a
   changed number with no before-state is invisible. So: show the before. */
/* Haggle, on one line: what it was, what it is, and by how much. The old price
   small and struck, the new one in green, the figure beside it as plain green
   type. The filled pill it used to wear was the rookie part — a badge shouting
   at a row that was already telling you. */
/* The row's own layout is price on the top line hard against the card edge,
   tag below it. Haggle adds to that line; it does not take it over. A flex row
   here made the price a content-sized item and pulled it left, so the one
   number the row exists for moved the moment the booster came on. */
.hag{display:block;text-align:right;white-space:nowrap}
.hag b{display:inline}
.hag s{font-size:12px;font-weight:700;color:var(--muted);opacity:.8;text-decoration-thickness:1.5px;margin-right:4px}
.hag b{color:var(--pos)}
.hag em{font-style:normal;font-size:10.5px;font-weight:800;color:var(--pos);
  letter-spacing:.02em;opacity:.9;margin-right:5px}
/* The row is a grid of 58px / 1fr / auto, and a grid child will not shrink
   below its content without this. The haggled row is the widest the price
   column ever gets, and without it the Cheap/Dear tag was pushed off the edge. */
.gname{min-width:0}
.gname b{overflow-wrap:anywhere}
.dest .was{font-size:11.5px;font-weight:700;color:var(--muted);
  text-decoration:line-through;margin-right:5px;opacity:.85}
/* Big Bag renames the chip rather than crowding it — the number was truncating
   to "0/1…" once an icon was squeezed in beside it. */
.stat.hold.boosted .sv b{color:var(--pos)}
.stat.hold.boosted .lbl{background:linear-gradient(var(--green1),var(--green2))}

/* the camel, once, across the middle of the screen */
.camelrun{position:absolute;left:0;right:0;top:44%;z-index:60;pointer-events:none;
  display:flex;flex-direction:column;align-items:center;gap:6px;animation:camelcross 1.5s ease-out forwards}
.camelrun .ico{width:96px;height:96px;filter:drop-shadow(0 6px 14px rgba(0,0,0,.5))}
.camelrun span{font-family:var(--display);font-size:20px;color:#fff;
  text-shadow:0 2px 0 var(--ink),2px 0 0 var(--ink),-2px 0 0 var(--ink),0 -2px 0 var(--ink),0 4px 10px rgba(0,0,0,.6)}
@keyframes camelcross{
  0%{opacity:0;transform:translateX(-40%) scale(.8)}
  18%{opacity:1;transform:translateX(-8%) scale(1)}
  70%{opacity:1;transform:translateX(8%) scale(1)}
  100%{opacity:0;transform:translateX(42%) scale(.9)}
}

/* The two that are always true — clear the loan, finish in profit — sit in the
   task bar whenever the level left room. They are drawn a shade back from a
   real task because they are the floor, not the job: every level wants them, so
   nothing is learned by having them shout. Ticked green like anything else the
   moment they are satisfied. */
/* Not dimmed. They were drawn back a shade to read as "the floor, not the job",
   but on the bar that just looks like a disabled control — and they are not
   optional, they are two of the things you lose the level without. */
.hslot.always .ico{width:30px;height:30px;margin-top:2px}
.hslot.always b{font-size:12.5px}
.hslot.always.done b{color:var(--pos)}

/* And as cards in the tasks window, where they are always present. The "always"
   stamp is what tells you this one is not from this level. */
.taskcard.settle .tctitle{color:var(--ink)}
.taskcard.settle .always{font-size:11px;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);opacity:.75}

/* A panelbox is a cream box, whatever colour card it sits on and whatever tone
   that card paints its text. So the text inside one is dark. Always.
   This is the third time text has gone invisible here. The first fix coloured
   paragraphs inside a panelbox; the second scoped that to gold cards. Both
   missed `<p class="panelbox">` — a panelbox that IS the paragraph rather than
   one wrapping it — which `.dialog.card .dlg-body p` then painted cream on
   cream. Stated once, for every tone, for the box and for anything in it. */
.dialog.card .dlg-body p.panelbox,
.dialog.card .dlg-body p.panelbox b,
.dialog.card .dlg-body .panelbox p,
.dialog.card .dlg-body .panelbox p b,
.dialog.card .dlg-body .panelbox .fine{color:#6A4020}
.dialog.card .dlg-body p.panelbox b,
.dialog.card .dlg-body .panelbox p b{color:var(--ink)}

/* Continuing after the level is won is a gamble with the star on it, so the
   line that says so sits under the choice rather than somewhere else. */
.dialog.card .dlg-body .fine.risk{margin-top:10px;line-height:1.35}

/* The two figures in the loan window sat on whatever baseline their glyphs
   happened to give them: "+4.68%" and "+₹94" are set in different scripts, the
   rupee sign comes from a fallback face with its own metrics, and the two cards
   drifted apart. Centre the content of each card explicitly, in both directions,
   so the cards match whatever is printed in them. */

/* The house, taking the credit it earned. */

/* What is in the cart. */

/* The sum behind the Worth chip. */

/* Fourth time, so stated for everything a panelbox can contain rather than for
   the one element that went missing. A panelbox is a cream box on whatever
   colour card, so ALL of its text is dark — paragraphs, the big number, the
   label above it, the fine print under it. */
.dialog.card .dlg-body .panelbox .bignum{color:var(--ink)}
.dialog.card .dlg-body .panelbox .bignum.pos{color:var(--pos)}
.dialog.card .dlg-body .panelbox .bignum.neg{color:var(--neg)}
.dialog.card .dlg-body .panelbox .boxlabel{color:#6A4020}

/* The Haveli's rooms, as rows. Icon left, what it is and what it gives in the
   middle, the price on the right — the same shape as every other row in the
   game, so a room reads at a glance instead of needing a second tap to find out
   what it does. */
/* The house itself, above the rooms you are putting into it. Before v2.10 the
   haveli was a list with a label and no building anywhere in it. */

/* The little "i" beside the tier count, and the table it opens. Three lines of
   standing text used to sit on top of the reward track; a dot asks to be
   pressed and gets out of the way when it is not. */
.infodot{display:inline-grid;place-items:center;width:20px;height:20px;margin-left:6px;vertical-align:middle;
  border-radius:50%;border:2px solid rgba(255,255,255,.75);background:rgba(0,0,0,.18);
  color:#fff;font-family:var(--display);font-size:13px;line-height:1;cursor:pointer}
.tiercount{display:inline-flex;align-items:center}

/* The road: one line down the track, lit as far as the caravan has walked.
   Drawn per-row first, which left a gap at every row boundary and read as
   thirty dashes rather than a road. One element, one gradient, --walked set
   from the tier the player has reached. */
.passtrack{position:relative}
.passtrack::before{content:"";position:absolute;left:50%;top:6px;bottom:6px;width:7px;margin-left:-3.5px;
  border-radius:99px;z-index:0;
  background:linear-gradient(#F0A31C 0 var(--walked,0%),#B87407 var(--walked,0%) var(--walked,0%),
    rgba(0,0,0,.30) var(--walked,0%) 100%)}
.passrow{position:relative}
.passrow .tiernum{position:relative;z-index:2}
/* Every tenth stop is a place the caravan stops at, and the last is the palace. */
.passrow.mark .tiernum{transform:scale(1.18)}
.passrow.last .passcell{box-shadow:0 0 0 3px rgba(255,212,112,.9),0 6px 14px rgba(0,0,0,.35)}
/* A stop not yet reached keeps its colour. It was dimmed and desaturated, which
   at nought kos meant the whole road looked switched off — the lock and the
   missing Take button already say it is not yours yet. */
.passcell{position:relative}
/* What a dead cell says when you press it. */
/* The cell carrying a bubble has to come forward, not just the bubble. Each
   cell paints in document order, so a z-index *inside* an earlier cell cannot
   lift anything above a later one — the bubble on stop 3 kept appearing behind
   stop 4. The class goes on the cell, which is what stacks. */
.passcell.tipped{z-index:20}
.passtip{position:absolute;left:50%;top:100%;transform:translate(-50%,6px);z-index:6;
  background:#FFF6E0;color:#4A2C13;border-radius:10px;padding:6px 10px;font-size:11px;font-weight:800;
  line-height:1.2;white-space:normal;width:max-content;max-width:150px;
  box-shadow:0 4px 10px rgba(0,0,0,.35)}
.passtip::before{content:"";position:absolute;left:50%;top:-5px;margin-left:-5px;
  border:5px solid transparent;border-bottom-color:#FFF6E0;border-top:0}
/* One line per cell, whatever the name is: the track is a ladder and a rung
   that grows to fit its label stops looking like a rung. */
.passcell b{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;font-size:15px}
.koslist{display:grid;grid-template-columns:repeat(10,1fr);gap:4px;margin:10px 0}
.kosrow{display:grid;justify-items:center;gap:2px;padding:5px 0;border-radius:8px;background:rgba(0,0,0,.16)}
.kosrow b{font-size:10px;font-weight:800;opacity:.7}
.kosrow i{font-style:normal;font-family:var(--display);font-size:16px}
.kosrow.big{background:linear-gradient(#F0A31C,#B87407)}

/* .btn stacks its children (flex-direction:column) so a cost sits under a label.
   Here the star and the number are one phrase, so the row runs across. */

/* Built: the row steps back, the tick leads. */

/* The one you can raise next sits forward. */

/* Everything past it is priced but not yet yours. */

/* Built is a state, not an offer — a tick where the button was. */

/* A room you cannot afford yet. This used to paint a flat gradient and a solid
   border over the button, which covered the bronze art's rounded end caps and
   left a rectangle — the real reason these read as square. The button keeps its
   own art and simply steps back. */

/* The room window. */
/* .arch pins its inner picture at 44px, so scaling only the frame leaves a big
   empty niche. The picture grows with it. */

.roomstory{font-style:italic;line-height:1.4}

.giftgrid{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin:10px 0 2px}
.giftone{display:grid;justify-items:center;gap:3px;width:78px}
.giftone .arch{width:64px;height:68px}
.giftone small{font-size:11.5px;font-weight:800;color:#6A4020;line-height:1.2;text-align:center}

/* What the house earns, at the top of the Haveli. Shown even when empty, so a
   player learns the house pays at all and can see what one more room is worth. */

/* ---------- Profile, name and the rank ladder ---------- */
/* The badge that stands in for a player on any screen. */
.pchip{display:inline-flex;align-items:center;gap:8px;background:none;border:0;padding:0;text-align:left;cursor:pointer}
.pchip .frm.pface{width:46px;height:46px;flex:none}
/* A bigger ring does not bring its picture with it: .frm sets the inner icon to
   38px with !important, so every resized frame has to say its own icon size or
   the portrait sits lost in the middle of the jewels. */
.pchip .frm.pface > .ico{width:26px!important;height:26px!important}
.ptext b{display:block;font-family:var(--display);font-weight:400;font-size:17px;line-height:1.1;color:var(--ink)}
.ptext small{display:block;font-size:11.5px;font-weight:800;color:var(--muted)}

/* A row that opens the profile says so by lifting, the way a button does. */
.ranklist li.tapme{cursor:pointer}
.ranklist li.tapme:active{transform:translateY(1px)}

/* Four numbers, one row, no table: a stat line should be readable at a glance. */
.pstats{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;list-style:none;margin:10px 0 4px;padding:0}
.pstats li{background:#FFF6E0;border:2px solid var(--cream3);border-radius:14px;padding:6px 2px;text-align:center}
.pstats b{display:block;font-family:var(--display);font-weight:400;font-size:16px;color:var(--ink);line-height:1.1}
.pstats small{display:block;font-size:9.5px;font-weight:800;color:var(--muted);line-height:1.2;margin-top:2px}

.nameinput{display:block;width:100%;box-sizing:border-box;margin:4px 0 8px;padding:10px 12px;
  font-family:var(--display);font-weight:400;font-size:21px;text-align:center;color:var(--ink);
  background:#FFF9EA;border:2.5px solid var(--cream3);border-radius:14px;outline:none}
.nameinput:focus{border-color:var(--gold2)}

.namewin .fine.warn{color:var(--neg)}

/* The ladder reuses the haveli's room row. A rank already passed stays at full
   opacity and shows a tick — a dimmed row is a row nobody reads. */

/* The head of a full-length window: the picture on the left, the name, the meter
   and what is next on the right. Same shape as .passhead in the Silk Road Pass,
   on the cream of a panel instead of the window's own ground, so every
   full-length screen opens the same way. */
.headrow{display:grid;grid-template-columns:72px 1fr;gap:10px;align-items:center;text-align:left;
  margin:2px 0;cursor:pointer}

.headrow > div{min-width:0}
.headrow b{display:block;font-family:var(--display);font-weight:400;font-size:22px;line-height:1.15;color:var(--ink)}
.headrow small{display:block;font-size:12px;font-weight:800;color:var(--muted)}
.headrow .lbar{margin:5px 0 3px}
.headkos{color:var(--wood)!important;font-weight:900;margin-top:1px;white-space:nowrap}
.headnext{color:#4E7A22}

.headnext b{display:inline;font-family:var(--body);font-size:12px;font-weight:900;color:var(--gold3)}

/* "you" on the rank you hold, the tier word on a trophy: one small cap, one
   place, so a row never grows a second kind of label. */
.nowtag{display:inline-block;vertical-align:2px;margin-left:5px;padding:1px 7px;border-radius:999px;
  background:var(--gold2);border:1.5px solid var(--gold3);color:#4A2A05;
  font-family:var(--body);font-size:10px;font-weight:900;text-transform:uppercase;letter-spacing:.4px}
.liverow .rowcount{font-size:11px;font-weight:800;color:var(--muted);margin-top:1px}

/* A heading for a list that sits on the window's own ground rather than in a
   cream panel — the lucky stall and the festivals put their rows straight on the
   card, and a claim list reads as one place when they all do. .boxlabel is brown
   because it is written for cream, so it cannot be reused here. */
/* Every button on a rung is the same box, whatever it says: one word, one tick or
   one lock. Different widths made the ladder look like three different lists. */
.liverow .evbtn{min-width:94px;min-height:40px;box-sizing:border-box;
  display:inline-flex;align-items:center;justify-content:center;padding:1px 10px 2px}
.liverow .evbtn .ico{width:23px;height:23px}
.liverow .evbtn .tick{display:inline-grid;place-items:center;margin:0}
.liverow .evbtn .hmark{width:23px;height:23px}

/* The meter fills in the author's green, which reads on cream where the gold did
   not. */
.liverow .lbar{background:#E3D7BC}
.liverow .lbar b{background:linear-gradient(#14690C,#39A81B)}

/* The rank emblems are painted with their own border, so they are set plain —
   no arch tile, no jewelled frame. A border around a border is what made the old
   crests look stuck on. */
.emblem{display:grid;place-items:center;width:58px;height:58px;flex:none}
.emblem .ico{width:58px!important;height:58px!important}
.eventcard > .emblem{width:54px;height:56px}
.eventcard > .emblem .ico{width:54px!important;height:54px!important}
.emblem.sm{width:44px;height:44px}
.emblem.sm .ico{width:44px!important;height:44px!important}
.emblem.big{width:76px;height:76px}
.emblem.big .ico{width:76px!important;height:76px!important}

/* The standing panel's meter is the ladder's meter: one green for progress
   everywhere in this window, not gold up top and green below. */
.panelbox .headrow .lbar{background:#E3D7BC}
.panelbox .headrow .lbar b{background:linear-gradient(#14690C,#39A81B)}

/* The prize and its "Claimed" are one phrase on one line. */
.liverow > div{min-width:0}
.liverow > div > small{min-width:0}
/* .liverow b is the ROW TITLE and is display:block. A <b> inside the small line
   inherited that and was pushed onto a line of its own, which is why "Claimed"
   kept dropping under the prize whatever width the line was given. The title
   rule belongs to the title. */
.liverow > div > small b{display:inline;font-size:inherit;line-height:inherit}
/* The face picker, on the window ground like any other list. */
.avatars.two{display:grid;;margin:0 0 4px}
.avatars.two .avatar{;background:rgba(255,255,255,.12);cursor:pointer}
.avatars.two .avatar img{width:100%;height:auto;display:block;border-radius:13px 13px 0 0}
.avatars.two .avatar small{display:block;font-size:11px;font-weight:800;color:#E6EEFF;}
.avatars.two .avatar.on{box-shadow:0 0 0 3px rgba(243,182,52,.45)}

.headrow .owed{color:var(--neg)}
.namewin .nameinput{margin:0 0 4px}
.namewin .headrow small.warn{color:var(--neg)}

/* The opening lines, one at a time. Only the newest animates — replaying the
   whole exchange on every tap is what made five bubbles look like a wall. */
.csay.new{animation:sayin .32s cubic-bezier(.3,1.5,.5,1) backwards}
.saytap{display:block;text-align:center;font-size:12px;font-weight:800;
  color:rgba(255,255,255,.75);text-shadow:0 1px 3px rgba(0,0,0,.6);margin-top:4px}

.gotit{color:#2E7D32;font-weight:900}
.ongoing{color:var(--gold3);font-weight:900}
.liverow .evbtn.done .tick{margin:0}
.liverow.here{border-color:var(--gold2);box-shadow:0 0 0 2px rgba(243,182,52,.55)}
/* A line under a list that sits on the window ground, not in a panel. */
.afterlist{margin:8px 4px 2px;font-size:12.5px;font-weight:800;text-align:center;color:#FFF3D2}
.listlabel{margin:12px 0 7px;font-family:var(--display);font-weight:400;font-size:19px;
  text-align:center;color:#FFF3D2;text-shadow:0 2px 0 rgba(0,0,0,.28)}

/* The line under the ribbon that says what a full-length window is for. */

/* .btn stacks its children in a column so a cost can sit under a label. The
   lock and the words are one phrase here, so this one runs across. */
.btn.oneline{flex-direction:row;gap:8px}
.btn.oneline .ico.inl{vertical-align:0}

/* ---------- online only: the line to the server ----------
   Shown while a call to the server is being retried (net/server.js). The game
   does not carry on without the server; this says it is waiting, not stuck. */
.netwait{position:fixed;left:50%;top:max(10px,env(safe-area-inset-top));transform:translate(-50%,-160%);z-index:300;
  padding:8px 16px;border-radius:99px;background:#1A1D23;color:#FFE28A;font:700 13px/1 system-ui,sans-serif;
  box-shadow:0 6px 20px rgba(0,0,0,.35);transition:transform .25s ease,opacity .25s,visibility .25s;pointer-events:none;
  opacity:0;visibility:hidden}
/* Hidden means hidden. Lifting it by its own height was not enough under a
   59 pt status bar: it sat behind the Dynamic Island, unseen on the phone but
   drawn in every screenshot, and read as "the server is down" (2026-10-22). */
.netwait.on{transform:translate(-50%,0);opacity:1;visibility:visible}

/* dev (?dev&noanim): every animation at its end state, for screenshots. */
.noanim *,.noanim *::before,.noanim *::after{animation-duration:0s!important;animation-delay:0s!important;transition:none!important}

/* The result window centres like every other (v2.92). The coin pill above it
   took space in the column and pushed the card 37px low; it now sits in the
   corner, out of the layout, where the coins still fly to it. */
.screen.result{position:relative}
.screen.result .rtop{position:absolute;top:calc(10px + var(--safe-t));right:14px;z-index:3}
/* The window starts below the purse (rtop), so its × never lands on the purse
   on a short phone (testers, 2026-10-23: the lost-level × sat under the Mudra). */
.screen.result{padding-top:calc(70px + var(--safe-t))}

/* The level's difficulty, inside the button under "Level N" (v2.94). The game's
   display face in gold, shadowed in the button's own dark, so it reads as part
   of the button and not as a label stuck on it. */
.levelbtn .lvtier{font-family:var(--display);font-size:16px;line-height:1;letter-spacing:.3px;color:var(--gold1);margin-top:2px;
  text-shadow:0 2px 0 #6B0F0F,1px 0 0 #6B0F0F,-1px 0 0 #6B0F0F,0 -1px 0 #6B0F0F}

/* The level card's difficulty, on the tasks heading (v2.95): gold, as on the
   home button. */
.listlabel .lltier{color:var(--gold1)}

/* The level card keeps the tab bar under it, undimmed (the author, v2.96): it
   is reached from home, and the space below the card is the bar's. */
.screen.brief > .navbar{position:absolute;left:0;right:0;bottom:0}
/* As many columns as there are tabs: before level 7 the Haveli tab is not
   there, and four tabs in five fixed columns sat off-centre. */
.navbar{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:1fr}

/* ================= the info card (v2.98, docs/WINDOWS.md) =================
   Ribbon, title, panel, text, buttons. The panel's sizes are the Trophies
   standing box's; the beige ground is the author's. */
.panelbox{background-color:#FFF6E0;background-image:linear-gradient(rgba(255,255,255,.5),rgba(255,255,255,.5)),url("../assets/ui/beige-panel.webp");
  background-size:cover;background-position:center;background-repeat:no-repeat;width:100%;box-sizing:border-box}
.dialog.card.info .ctitle{margin:0 0 10px;font-family:var(--display);font-weight:400;font-size:24px;line-height:1.1;color:#FFF3D2;
  text-align:center;text-shadow:0 2px 0 rgba(0,0,0,.28)}
.dialog.card.info .cpanel{margin:0 0 10px}
.cpanel.pic{display:grid;place-items:center;height:150px;padding:10px}
.cpanel.pic .ico{width:120px;height:120px;filter:drop-shadow(0 6px 4px rgba(0,0,0,.25))}
.cpanel.num{display:grid;grid-template-columns:76px minmax(0,1fr);gap:12px;align-items:center;text-align:left;padding:10px 12px}
.cpanel.num .cart{display:grid;place-items:center}
.cpanel.num .cart .ico{width:76px;height:76px;filter:drop-shadow(0 4px 3px rgba(0,0,0,.22))}
.cpanel .cbody{display:grid;gap:2px;min-width:0}
.cpanel .clabel{font-family:var(--display);font-size:17px;line-height:1.2;color:#6A4020}
.cpanel .cname{font-family:var(--display);font-weight:400;font-size:22px;line-height:1.15;color:var(--ink)}
.cpanel .camount{font-family:var(--display);font-weight:400;font-size:30px;line-height:1.05;color:var(--ink)}
.cpanel .camount.neg{color:var(--neg)} .cpanel .camount.pos{color:var(--pos)}
.cpanel .csmall{font-size:12px;font-weight:800;line-height:1.3;color:#9A6B3F}
.cpanel .cfoot{font-size:12px;font-weight:800;line-height:1.3;color:#7A441C}
.cpanel .cmeter{position:relative;display:block;height:8px;margin:4px 0 2px;border-radius:9px;background:#E3D7BC;overflow:hidden}
.cpanel .cmeter b{position:absolute;top:0;bottom:0;left:0;border-radius:9px;background:linear-gradient(#14690C,#39A81B)}
.cpanel .cmeter s{position:absolute;top:0;bottom:0;background:linear-gradient(#F4574D,#C92A22);text-decoration:none}
.cpanel .ctimer{display:flex;align-items:center;gap:6px;font-family:var(--display);font-size:20px;line-height:1.2;color:var(--ink)}
.cpanel .ctimer .ico{width:20px;height:20px}
.dialog.card.info .ctext{margin:0 0 10px;padding:10px 12px;border-radius:14px;text-align:center;background:#8E1119}
.dialog.card.info .dlg-body .ctext p{margin:0;font-size:14px;font-weight:700;line-height:1.4;color:#FFE9E4}
.dialog.card.info .dlg-body .ctext p + p,.dialog.card.info .ctext > * + *{margin-top:6px}
.dialog.card.info .ctext .cpara{font-size:14px;font-weight:700;line-height:1.4;color:#FFE9E4}
.dialog.card.info.t-purple .ctext{background:#4A2096}
.dialog.card.info.t-purple .dlg-body .ctext p{color:#EFE6FF}
.dialog.card.info.t-blue .ctext{background:#1F3A7A}
.dialog.card.info.t-blue .dlg-body .ctext p{color:#E6EEFF}

/* A portrait in a picture panel (Paused) is the same size as any picture. */
.cpanel.pic .masc,.cpanel.pic img{width:120px;height:120px}

/* The result's coin slot sits in the panel's text column. */
.cpanel .coinout{justify-self:start}

/* The booster row (level card and the lost result), v3.0. The saakh pill sits
   on the circle's bottom edge, centred, off the picture; the name sits clear
   below it, so it never touches the circle. */
.boost .freetag{left:50%;right:auto;top:auto;bottom:-8px;transform:translateX(-50%);padding:0 6px 1px;font-size:8.5px}
.boost .bname{bottom:-28px}
.boosts{margin-bottom:34px}
/* The lost result: the pills go one by one, last first, and each circle dulls
   with its pill. */
.saakhloss .boost{cursor:default}
.saakhloss .boosts.losing .freetag{animation:tagout .5s ease-in var(--d) both}
.saakhloss .boosts.losing .boost.on{animation:ringout .5s ease-in var(--d) both}
@keyframes tagout{0%{opacity:1;transform:translateX(-50%) scale(1)}35%{transform:translateX(-50%) scale(1.25)}100%{opacity:0;transform:translateX(-50%) scale(.4)}}
@keyframes ringout{to{box-shadow:0 0 0 3px #CFC6B3,0 4px 0 rgba(0,0,0,.3);filter:grayscale(.6)}}
@media (prefers-reduced-motion:reduce){ .saakhloss .boosts.losing .freetag{animation:none;opacity:0} .saakhloss .boosts.losing .boost.on{animation:none;filter:grayscale(.6)} }

/* The result panel's coin figure, at the panel's amount size (v3.1). */
.cpanel .coinout{font-size:30px}
/* The lost-saakh panel: label and name in the panel type, on the left like
   every number panel; circles not fronted are grey from the start. */
.saakhloss{text-align:left;padding:10px 12px}
.saakhloss .clabel,.saakhloss .cname{display:block}
.saakhloss .boosts{margin-top:8px}
.saakhloss .boost.off{filter:grayscale(.6);box-shadow:0 0 0 3px #CFC6B3,0 4px 0 rgba(0,0,0,.3)}
.saakhloss .cfoot{display:block}

/* Two buttons side by side, the in-game Repay / Borrow pair (v3.2): equal
   halves, a title and a small line under it. One button fills the row. */
.btnpair{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:10px;width:100%}
.btnpair .btn{display:flex;width:100%;min-width:0;}
.btnpair .btn small{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;font-size:11.5px}

/* ---------- the form windows (v3.3): profile, name, settings ---------- */
/* A number panel with a button on its right (Settings: Profile). */
.cpanel.num.aside{grid-template-columns:76px minmax(0,1fr) auto}
.cpanel.num .cart .masc{width:76px;height:76px;border-radius:50%;object-fit:cover}
/* The small pill beside a name (Edit, Roll), the gameplay's Cheap / Fair tag.
   A real button, unlike the tags it looks like: .btn.tiny lets taps fall
   through, so this takes them back (the Monkey bot found both dead, v3.20). */
.editpill{display:inline-block;vertical-align:middle;margin-left:6px;cursor:pointer;font-family:var(--body)}
.btn.tiny.editpill{pointer-events:auto}
.cpanel .clabel .editpill{font-size:11px}
.cpanel .nameinput{width:100%;box-sizing:border-box;margin:4px 0 2px}
/* What you have done: three, each with its picture. */
.pstats.three{grid-template-columns:repeat(3,1fr);gap:8px}
.pstats.three li{display:grid;justify-items:center;gap:2px;padding:8px 4px}
.pstats.three .ico{width:34px;height:34px}
.pstats.three b{font-size:20px}
.pstats.three small{font-size:11px}
/* The two traders: one size, smaller, whichever is chosen. */
.avatars.two{grid-template-columns:repeat(2,minmax(0,140px));justify-content:center;gap:14px}
.avatars.two .avatar{border:3px solid rgba(255,255,255,.35);border-radius:16px;padding:0;overflow:hidden}
.avatars.two .avatar.on{border-color:var(--gold2)}
.avatars.two .avatar img,.avatars.two .avatar .ico{width:100%;height:130px;object-fit:cover;object-position:top;border-radius:0}
.avatars.two .avatar small{height:20px;line-height:20px;padding:0 2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Settings: four switches, and the dev pair while it lasts. */
.dialog.card.info .stack{display:grid;gap:8px;margin:0 0 10px}
.toggle span small{font-family:var(--body);font-size:11px;font-weight:800;color:var(--muted)}
.devpair{margin:0 0 4px}
.devpair .btn{min-height:40px}
.btnpair .btn{white-space:nowrap;border-width:12px 24px;border-image-width:12px 24px;font-size:15px}
.cpanel.num.aside .cname{font-size:18px}

/* Portraits are taller than wide with the head at the top: in a round or
   square frame they sit from the top, so the face is never cut (v3.4). */
.cpanel .cart .masc,.cpanel.pic .masc,.avatars .avatar img,.emblem .masc,.pchip .masc{object-fit:cover;object-position:50% 0}
/* A link in a panel's small line: same face, same colour, underlined. */
.clink{display:inline;padding:0;border:0;background:none;font:inherit;color:inherit;text-decoration:underline;cursor:pointer}

/* ================= the list row (v3.5, docs/WINDOWS.md) =================
   One row for every list window, from the Trophies ladder. Written last, and
   scoped to the card, so it is the row whatever older rules said:
   picture 52px (no arch) | title, line, meter, count | one button, one size. */
:is(.dialog.card.info,.page) .livelist{display:grid;gap:8px;margin:0 0 10px;padding:0;list-style:none}
:is(.dialog.card.info,.stdlist) .liverow,:is(.dialog.card.info,.stdlist) .eventcard{display:grid;grid-template-columns:56px minmax(0,1fr) auto;gap:10px;align-items:center;
  min-height:72px;padding:8px 10px;box-sizing:border-box;border-radius:14px;background:#FFFDF6;border:2.5px solid var(--cream3);
  box-shadow:0 2px 0 rgba(0,0,0,.16);text-align:left;color:var(--ink)}
:is(.dialog.card.info,.stdlist) .liverow::after,:is(.dialog.card.info,.stdlist) .eventcard::after{display:none}
:is(.dialog.card.info,.stdlist) .liverow.done,:is(.dialog.card.info,.stdlist) .eventcard.done{background:#E3F4D2;border-color:#A9D98A}
:is(.dialog.card.info,.stdlist) .liverow.here{border-color:var(--gold2);box-shadow:0 0 0 2px rgba(243,182,52,.55)}
:is(.dialog.card.info,.stdlist) .liverow.shut,:is(.dialog.card.info,.stdlist) .eventcard.shut{opacity:.6}
/* the picture */
.emblem.rowpic,:is(.dialog.card.info,.stdlist) .liverow > .emblem,:is(.dialog.card.info,.stdlist) .eventcard > .emblem{position:relative;display:grid;place-items:center;width:52px;height:52px;margin:0 auto}
.emblem.rowpic > .ico,:is(.dialog.card.info,.stdlist) .liverow > .emblem > .ico,:is(.dialog.card.info,.stdlist) .eventcard > .emblem > .ico{width:52px!important;height:52px!important;margin:0!important;filter:drop-shadow(0 2px 2px rgba(0,0,0,.2))}
.emblem.rowpic > .tick,.emblem.rowpic > .badge{position:absolute;right:-4px;top:-4px}
/* the words */
:is(.dialog.card.info,.stdlist) .liverow > div,:is(.dialog.card.info,.stdlist) .eventcard > .ename{display:grid;gap:2px;min-width:0}
:is(.dialog.card.info,.stdlist) .liverow > div > b,:is(.dialog.card.info,.stdlist) .eventcard .ename > b,:is(.dialog.card.info,.stdlist) .liverow .tctitle{display:block;
  font-family:var(--display);font-weight:400;font-size:16px;line-height:1.15;color:var(--ink)}
:is(.dialog.card.info,.stdlist) .liverow > div > small,:is(.dialog.card.info,.stdlist) .eventcard .ename > small,:is(.dialog.card.info,.stdlist) .liverow .tchint{display:block;
  font-family:var(--body);font-size:12px;font-weight:800;line-height:1.3;color:#9A6B3F}
:is(.dialog.card.info,.stdlist) .liverow .rowcount{font-size:11.5px;color:#7A441C}
/* the meter: the panel's, thinner */
:is(.dialog.card.info,.stdlist) .liverow .lbar,:is(.dialog.card.info,.stdlist) .eventcard .lbar{display:block;height:6px;margin:3px 0 1px;border-radius:9px;background:#E3D7BC;overflow:hidden}
:is(.dialog.card.info,.stdlist) .liverow .lbar b,:is(.dialog.card.info,.stdlist) .eventcard .lbar b{display:block;height:100%;border-radius:9px;background:linear-gradient(#14690C,#39A81B)}
/* the button: one size */
:is(.dialog.card.info,.stdlist) .liverow .evbtn,:is(.dialog.card.info,.stdlist) .eventcard .evbtn{width:92px;min-width:92px;min-height:40px;box-sizing:border-box;font-size:14px;padding:0 4px}
.dialog.card.info p.listlabel{margin:12px 0 7px;font-family:var(--display);font-weight:400;font-size:19px;line-height:1.2;color:#FFF3D2;text-align:center}

/* The shop's rows are the standard row; the tag sits on the top edge. */
.stdlist .shoprow{position:relative}
.stdlist .shoprow .rowtag{position:absolute;top:-9px;right:12px;z-index:1}
/* A tag sits half above its row: room for it, so the list's top edge never cuts
   the first one ("5.1× value" on the Starter Pack, the author, 2026-10-18). */
.stdlist .shoprow:has(.rowtag){margin-top:6px}
.stdlist .shoprow:first-child:has(.rowtag){margin-top:12px}
.stdlist .shoprow .evbtn{flex-direction:row;align-items:center;justify-content:center;gap:4px;white-space:nowrap}
.stdlist .shoprow .evbtn .ico.inl{width:16px;height:16px}

/* Panels and rows on a page (Ranks, Team): the card's spacing. */
.page .cpanel{margin:0 0 10px}
.page .btnpair{margin:0 0 6px}
.stdlist .liverow{position:relative}
.stdlist .ownpill{display:inline-flex;align-items:center;gap:3px;white-space:nowrap}

/* ================= buttons (v3.10, docs/WINDOWS.md) =================
   Every full-width button in a window is one size and one face, whatever its
   colour; a button with a price has the words left and the price right. */
.dialog.card .btn.wide,.dialog.card .btn.xl{display:flex;width:100%;box-sizing:border-box;min-height:54px;
  border-width:14px 32px;border-image-width:14px 32px;padding:2px 8px 4px;font-size:18px!important;line-height:1.1}
.dialog.card .btn.buyrow{flex-direction:row!important;justify-content:space-between!important;align-items:center;gap:10px;font-size:18px!important}
.dialog.card .btn.buyrow .cost{display:inline-flex;align-items:center;gap:4px;font-size:16px;background:rgba(0,0,0,.2);border-radius:999px;padding:2px 12px 2px 6px}
.dialog.card .btn.buyrow .cost .inl{width:20px;height:20px}
.dialog.card.info .evbtn{white-space:nowrap;font-size:13.5px}

/* Veer or Devi's line on the result (v3.15): the chat bubble, in the card. */
.resultsay{margin:0 0 10px}
.resultsay .csay{display:flex;align-items:center;gap:8px}
.resultsay .masc{width:44px;height:44px;flex:none}
.resultsay .cbub{flex:1;text-align:left;font-size:13px;font-weight:800;line-height:1.3}

/* a claim answers the tap at once, before the server does */
.evbtn.busy{filter:brightness(.85);transform:translateY(2px);pointer-events:none}
.toggle span:has(small.under){text-align:left}
.toggle span small.under{display:block;margin-top:1px}
/* Google's own sign-in button (web version, testing only) */
.gsi-slot{display:flex;justify-content:center;align-items:center;min-height:44px}
.btnpair .gsi-slot{min-width:0}
.btn[data-act="signin"][hidden]{display:none!important}

/* v3.48 — flights: only transform and opacity move */
.flycoin,.flyreward{will-change:transform,opacity}
.flyreward{display:grid;justify-items:center}
.flyreward b{margin-top:-8px;font-family:var(--display);font-size:20px;color:#FFF3D2;
  text-shadow:0 2px 0 var(--ink),0 0 6px rgba(0,0,0,.5)}
.gatherglow{position:absolute;left:0;top:0;z-index:9998;pointer-events:none;width:0;height:0}
.gatherglow::before{content:"";position:absolute;left:-180px;top:-110px;width:360px;height:220px;border-radius:50%;
  background:radial-gradient(closest-side,rgba(255,226,138,.55),rgba(255,226,138,0))}
/* the profit and its coins in one spot (result.js) */
.cswap{display:grid;align-items:center;justify-items:start}
.cswap > *{grid-area:1/1}
.cpanel .cswap .coinout{font-size:30px;line-height:1.05;justify-content:flex-start}
.cpanel .cswap .coinout .ico{width:34px;height:34px}

/* Not open yet: the real picture, greyed (v3.50). Boosters on the level card and
   the result, the boosters and saakh windows, the shop's booster and tool rows. */
.boost.locked .ico,.liverow.shut .emblem .ico,.shoprow.locked .rowpic .ico{filter:grayscale(1);opacity:.6}
