/* ============================================================
   APP UI — pola aplikasi dompet (GoPay/Gojek): kartu saldo,
   ikon pintasan, daftar menu, navigasi bawah. Dipakai bersama
   oleh account / topup / swap / login / register.
   Tujuannya: langsung dikenali dan mudah dipahami.
   ============================================================ */
:root{
  /* Neutrals are the DESIGN.md global tokens verbatim. The app shell is a layout
     sub-system, not a visual one, so it owns no private palette — every value
     below names the DESIGN.md token it mirrors. */
  --a-bg-deep:#03070a;  /* colors.bg-deep     */
  --a-bg:#050d09;       /* colors.bg          */
  --a-card:#08160e;     /* colors.surface     */
  --a-input:#04100a;    /* colors.surface-input — darker than the card, reads inset */
  /* Back-compat alias: swap.html still says --a-bg2. Retire the name the next
     time that file is edited; this issue is scoped to app.css only. */
  --a-bg2:var(--a-input);
  --a-line:#1f5f3a;     /* colors.border      */
  --a-text:#d7f7e3;     /* colors.text        */
  --a-mut:#9ccfb0;      /* colors.text-muted  */
  --a-dim:#6f9a82;      /* colors.text-dim    */
  --a-ink:#06120b;      /* colors.text-inverse — text sitting on a green fill */

  --a-green:#4dff8c;      /* colors.primary       */
  --a-green-lt:#b7ffd4;   /* colors.primary-soft  */
  --a-green-soft:rgba(77,255,140,.12);
  --a-line2:rgba(77,255,140,.3);
  /* Press feedback. Accent-tinted, not white — a white wash on a green-dark
     surface renders grey and pulls the app shell off the product hue. */
  --a-press:rgba(77,255,140,.06);
  --a-amber:#ffc94d; --a-red:#ff7b7b;
  --a-font:"JetBrains Mono",ui-monospace,Consolas,monospace;
  --a-r:0;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{max-width:100%;overflow-x:hidden}
/* The terminal WINDOW (.win/.winbar/.winbody) + the page background come from
   terminal.css — the SAME shell the landing page uses. Nothing here redefines it;
   app.css only styles what goes INSIDE the window. */
body{
  color:var(--a-text);
  font-family:var(--a-font);font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased;
}
/* app content sits inside the window body.
   NOTE: only centring here — width belongs to `.app` and its responsive rules.
   A `width` on this (0,2,0) selector outranks the (0,1,0) `.app` media queries
   (media queries add no specificity), which silently disabled the whole desktop
   block: the page stayed 620px wide while .app-grid still split into two columns,
   so it got NARROWER as the viewport got wider. */
.winbody{padding:18px 0 26px}
.winbody > .app{margin:0 auto}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--a-green);outline-offset:2px}
img{display:block;max-width:100%}
button{font-family:inherit}

/* kolom aplikasi */
.app{width:min(560px,100%);margin:0 auto;padding:0 16px}

/* ---- HEADER bernuansa terminal ---- */
.appbar{position:sticky;top:0;z-index:30;background:rgba(5,13,9,.94);backdrop-filter:blur(10px);
  border-bottom:1px solid rgba(77,255,140,.22)}
.appbar .in{width:min(560px,100%);margin:0 auto;padding:9px 16px;display:flex;align-items:center;gap:10px;
  font-family:var(--a-font)}
/* tiga titik jendela terminal */
.appbar .dots{flex:0 0 auto;display:flex;gap:5px}
.appbar .dots i{width:9px;height:9px;border-radius:50%;background:var(--a-line);display:block}
.appbar .dots i:last-child{background:var(--a-green)}
/* path seperti prompt shell */
.appbar .name{font-weight:500;font-size:12px;color:var(--a-mut);letter-spacing:.01em}
.appbar .name b{color:var(--a-green);font-weight:700}
.appbar .act{margin-left:auto;display:flex;align-items:center;gap:16px}
.appbar .act a,.appbar .act button{display:inline-flex;align-items:center;min-height:44px;
  color:var(--a-mut);font-family:inherit;font-size:12px;
  background:none;border:0;cursor:pointer;padding:4px 0}
.appbar .act a:hover,.appbar .act button:hover{color:var(--a-green)}
.appbar .act a::before,.appbar .act button::before{content:"$ ";color:var(--a-line)}
.appbar .back{display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;margin-left:-12px;
  font-size:20px;color:var(--a-mut);text-decoration:none}
.appbar .back:hover{color:var(--a-green)}
.appbar .back::before{content:none}

/* ---- KARTU SALDO ---- */
.balance-card{margin-top:14px;border-radius:0;padding:18px;
  background:linear-gradient(150deg,#15412c,#0e2a1e 55%,#101a17);
  border:1px solid var(--a-line2);box-shadow:0 8px 26px rgba(0,0,0,.35)}
.balance-card .lbl{color:var(--a-green-lt);font-size:12px}
.balance-card .amt{display:flex;align-items:baseline;gap:7px;margin-top:3px}
.balance-card .amt b{font-size:32px;font-weight:700;letter-spacing:-.02em}
.balance-card .amt span{color:var(--a-green-lt);font-size:14px;font-weight:600}
.balance-card .row{display:flex;gap:12px;margin-top:16px}
.balance-card .btn{flex:1;display:flex;align-items:center;justify-content:center;gap:7px;
  min-height:44px;padding:12px;border-radius:0;font-weight:700;font-size:13px}
.btn-solid{background:var(--a-green);color:var(--a-ink)}
.btn-solid:active{filter:brightness(.95)}
/* Secondary actions are OUTLINED, so the page keeps exactly one solid green fill. */
.btn-ghost{background:var(--a-green-soft);border:1px solid var(--a-line2);color:var(--a-text)}
/* A quiet rule line under the figure — states the balance's one rule where it is raised. */
.balance-card .foot{margin-top:16px;padding-top:12px;border-top:1px solid rgba(255,255,255,.09);
  color:var(--a-green-lt);font-size:12px;line-height:1.6}

/* The .shortcuts tile row is gone: the winbar icon nav already owns Play / Top up /
   Cash out / Help, so the row repeated three of its own destinations one line below.
   What survives is a single labelled Play anchor (.btn-lg.btn-out) in the markup. */


/* ---- SEKSI ---- */
.sec{margin-top:22px}
/* Fixed height so section headings sit on the SAME line across the grid gutter. */
.sec-t{display:flex;align-items:center;justify-content:space-between;height:22px;margin-bottom:10px}
.sec-t h2{font-size:15px;font-weight:700}
.sec-t a{color:var(--a-green);font-size:12px;font-weight:600}

/* kartu umum */
.card{background:var(--a-card);border:1px solid var(--a-line);border-radius:0;overflow:hidden}
.card-pad{padding:16px}

/* ---- DESKTOP COMPOSITION ----
   One rule holds the wallet page together: every column is ONE heading + ONE card,
   the headings share a fixed-height box so they align across the gutter, and the
   cards stretch to a common bottom edge. Each card ENDS on a control rather than
   trailing off, so no column leaves a ragged void under it. */
.card-fill{display:flex;flex-direction:column;height:100%}
.card-note{padding:15px 15px 0;color:var(--a-dim);font-size:12px;line-height:1.6}
/* the action pinned to a card's foot, flush, separated by the card's own rule */
.card-act{margin-top:auto;display:flex;align-items:center;justify-content:center;gap:9px;
  min-height:48px;padding:12px;border-top:1px solid var(--a-line);
  background:var(--a-green-soft);color:var(--a-text);font-weight:700;font-size:13px}
.card-act:hover{background:rgba(77,255,140,.18)}
.card-act.is-disabled{opacity:.4;cursor:not-allowed;pointer-events:none}
.li-foot{margin-top:auto;border-bottom:0;border-top:1px solid var(--a-line)}

/* ============================================================
   INSTRUMENT PANEL — the wallet reads as one calibrated instrument
   instead of a stack of paragraphs. Every quantity is drawn on the SAME
   kind of track, so 0xT, room capacity and earned tokens are all read the
   same way, and three of the four "How it works" sentences become the axis
   of a chart instead of prose. Everything is scoped under .inst.
   ============================================================ */
.inst{display:flex;flex-direction:column;gap:18px;margin-top:18px}
.inst *{box-sizing:border-box}
.inst .pan{border:1px solid var(--a-line);background:var(--a-card)}
.inst .num{font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.inst .lab{font-size:10px;letter-spacing:.17em;text-transform:uppercase;color:var(--a-dim);white-space:nowrap}
.inst .lab-m{font-size:10px;letter-spacing:.17em;text-transform:uppercase;color:var(--a-mut);white-space:nowrap}
.inst .r{text-align:right}
/* The display figure. 92px is the desktop reading; anything narrower scales down.
   It scales off its OWN COLUMN (cqi), not the viewport. Sizing it with vw was the bug
   behind the balance colliding with the CAPACITY column: at a 930px viewport the left
   column is only 290px wide, but 13vw still clamped to the full 92px, so "12,480"
   measured 326px and ran 58px past the divider. A viewport unit cannot know how wide
   the column it lives in ended up. 19cqi leaves room for the "0xT" unit beside it. */
.inst .figcol{container-type:inline-size}
/* Two caps, whichever is smaller: the column's share (19cqi), and what actually FITS
   given the digit count. JetBrains Mono advances 0.6em per character, so a --fig-len
   digit string needs len*0.6*font-size; the 86px allowance is the column padding plus
   the "0xT" unit sitting beside it. Without the second cap a seven-digit balance
   wrapped onto a second line. --fig-len is set by account-page.js when it renders. */
.inst .fig{font-weight:700;line-height:1;color:var(--a-text);white-space:nowrap;min-width:0;
  font-size:min(clamp(38px,19cqi,92px), calc((100cqi - 86px) / (var(--fig-len,6) * 0.6)))}

/* the one track every quantity is drawn on */
.inst .trk{display:block;position:relative;height:11px;border:1px solid var(--a-hair,#123a24);background:var(--a-input)}
.inst .fil{display:block;height:100%;background:rgba(77,255,140,.2);border-right:2px solid var(--a-green)}
.inst .trk.free{border-style:dashed;border-color:var(--a-line);background:rgba(77,255,140,.06)}
.inst .trk.zero{border-style:dotted;border-color:#123a24}

/* fixed instrument columns — grid, so a label can never be squeezed into its meter */
.inst .row-cap{display:grid;grid-template-columns:92px minmax(0,1fr) 58px;gap:14px;align-items:center}
.inst .row-tok{display:grid;grid-template-columns:42px 40px minmax(0,1fr) 88px;gap:16px;align-items:center}
.inst .row-rate{display:grid;grid-template-columns:38px minmax(0,1fr) 120px;gap:12px;align-items:center}

/* ruled key/value block — a tick mark instead of an icon chip */
.inst .kv{position:relative;display:flex;align-items:center;gap:14px;padding:12px 0 12px 16px;border-bottom:1px solid #123a24}
.inst .kv:last-child{border-bottom:0}
/* display:flex above beats the UA's [hidden]{display:none}, so restore it — the verify
   row is hidden outright when no mail provider is configured. */
.inst .kv[hidden]{display:none}
.inst .kv::before{content:"";position:absolute;left:0;top:50%;width:8px;height:1px;background:var(--a-line)}
.inst .kv .v{margin-left:auto;font-size:12px;color:var(--a-mut);text-align:right;white-space:nowrap}

/* controls */
.inst .ibtn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:46px;padding:0 20px;
  font-size:12.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;font-family:inherit;cursor:pointer}
.inst .ibtn.solid{background:var(--a-green);color:var(--a-ink);border:1px solid var(--a-green)}
.inst .ibtn.out{background:rgba(77,255,140,.1);border:1px solid var(--a-line);color:var(--a-text)}
.inst .ibtn.out:hover{background:rgba(77,255,140,.18)}
.inst .ibtn.is-disabled{opacity:.32;cursor:not-allowed;pointer-events:none}
.inst .ilink{border:1px solid var(--a-line);padding:6px 10px;font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--a-green);white-space:nowrap;background:none;font-family:inherit;cursor:pointer}
.inst .stamp{display:inline-flex;align-items:center;gap:8px;border:1px solid #123a24;padding:6px 11px;
  font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--a-mut);white-space:nowrap}
.inst .tick{width:1px;height:5px;background:var(--a-line)}
.inst .lamp{display:block;width:9px;height:9px}

/* top-up history: a real bar series, drawn from /api/game/topups */
.inst .spark{margin-left:auto;display:flex;align-items:flex-end;gap:5px;height:30px}
.inst .spark i{display:block;width:9px;border:1px solid var(--a-line);background:rgba(77,255,140,.14)}
.inst .spark i.nil{border:0;background:#123a24;height:2px}

/* annunciator — what still works while cash-out is held */
.inst .lamps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.inst .lamps span{border:1px solid var(--a-line);padding:11px 12px;display:flex;align-items:center;gap:10px}
.inst .lamps span.held{border-color:rgba(255,201,77,.45);background:rgba(255,201,77,.07)}

/* Hiding a whole instrument panel. Must beat BOTH the inline `display:flex` that
   #real-earned-pan carries in the markup and the `display:grid` that .band1 gets
   here, so it is the one !important in this file. Panels are hidden with this class
   (plus the `hidden` attribute for assistive tech), never by writing an inline
   display — writing one destroys .band1's grid and collapses the wallet layout. */
.inst .is-off{display:none!important}

/* the two instrument bands */
.inst .band1{display:grid;grid-template-columns:minmax(0,1fr)}
.inst .band2{display:grid;grid-template-columns:minmax(0,1fr);gap:18px}
/* Two columns only once there is genuinely room for both. At the old 900px breakpoint
   the fixed 560px right column left the left one just 290px — narrower than it is on a
   phone — which is what starved the balance. The right column is now allowed to shrink
   too, so it can never do that again. */
@media (min-width:1120px){
  .inst .band1{grid-template-columns:minmax(320px,1fr) minmax(0,560px)}
  .inst .band2{grid-template-columns:minmax(320px,1fr) minmax(0,428px)}
  /* One of band2's two panels is mode-specific: #real-earned-pan is hidden in DEMO.
     The track it leaves behind is still reserved, so the Account card sat in the left
     column with 428px of empty page beside it. When the pair is down to one panel the
     band is a single column and that panel takes the full width. Scoped to this
     breakpoint because below it the band is already one column. */
  .inst .band2.is-solo{grid-template-columns:minmax(0,1fr)}
}

/* reference strip: four identical three-line cells */
.refs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.ref{background:var(--a-card);border:1px solid var(--a-line);padding:13px 14px}
.ref .k{color:var(--a-dim);font-size:11px}
.ref .v{font-weight:700;font-size:13px;margin-top:4px}
.ref .v.ok{color:var(--a-green)}
.ref .s{color:var(--a-dim);font-size:11px;margin-top:3px}

/* hero band: figure left, actions right (side by side from 900px) */
.balance-card.hero .row{margin-top:16px}
@media (min-width:900px){
  .balance-card.hero{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:24px;align-items:center}
  .balance-card.hero .row{margin-top:0}
  .refs{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
}

/* daftar baris */
.li{display:flex;align-items:center;gap:12px;padding:14px 16px;border-bottom:1px solid var(--a-line)}
.li:last-child{border-bottom:0}
/* Inert list rows get a QUIET icon: the filled green chip is reserved for rows that
   actually do something, so "How it works" stops competing with real controls. */
.li .ic{width:36px;height:36px;flex:0 0 auto;border-radius:0;background:none;
  display:flex;align-items:center;justify-content:center;color:var(--a-dim);font-size:15px}
.li.tap .ic,.li a .ic,.li button .ic{background:var(--a-green-soft);color:var(--a-green)}
.li .tx{min-width:0;flex:1}
.li .tx b{display:block;font-size:13px;font-weight:600}
.li .tx span{display:block;color:var(--a-mut);font-size:12px}
.li .v{margin-left:auto;text-align:right;font-size:13px;font-weight:600;word-break:break-all}
.li .v.ok{color:var(--a-green)}
.li .v.mut{color:var(--a-mut);font-weight:500}
.li .chev{color:var(--a-dim);font-size:17px;flex:0 0 auto}
.li.tap:active{background:var(--a-press)}

/* token kecil */
.tokens{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px}
/* inside a card the tiles need the card's own inset */
.card-fill .tokens{padding:13px 15px 15px}
.tok{background:var(--a-card);border:1px solid var(--a-line);border-radius:0;padding:12px;text-align:center}
.tok img{width:24px;height:24px;margin:0 auto 6px}
.tok .n{color:var(--a-mut);font-size:11px}
.tok .v{font-size:17px;font-weight:700;margin-top:1px}

/* form */
.field{margin-bottom:14px}
.field label{display:block;font-size:12px;color:var(--a-mut);margin-bottom:7px;font-weight:600}
.inp{width:100%;min-height:48px;padding:12px 16px;border-radius:0;border:1px solid var(--a-line);
  background:var(--a-input);color:var(--a-text);font-family:inherit;font-size:14px}
.inp:focus{outline:none;border-color:var(--a-green);box-shadow:0 0 0 3px rgba(77,255,140,.14)}
.err{min-height:18px;font-size:12px;color:var(--a-red);margin-bottom:6px}
.btn-lg{width:100%;min-height:48px;padding:14px;border-radius:0;border:0;background:var(--a-green);
  color:var(--a-ink);font-size:14px;font-weight:700;cursor:pointer}
/* The anchor flavour ("Go to sign in", "Go to my account") is an <a>, which is inline by
   default: width:100% is ignored and the 14px padding rides up over the paragraph above it.
   Make it lay out like the <button> flavour. */
a.btn-lg{display:block;box-sizing:border-box;margin-top:16px;text-align:center;text-decoration:none}
/* Outlined flavour — secondary full-width actions (Play, Cash out) so `+ Top up`
   stays the page's ONLY solid green fill. Declared AFTER .btn-lg and with a higher
   specificity (.btn-lg.btn-out) so it actually beats the solid background above,
   and it restores the border .btn-lg zeroes out. */
.btn-lg.btn-out{background:var(--a-green-soft);border:1px solid var(--a-line2);color:var(--a-text)}
a.btn-lg.btn-out{display:flex;align-items:center;justify-content:center;gap:9px}
.btn-lg:disabled{opacity:.4;cursor:not-allowed}
/* Anchor flavour cannot use :disabled — the href is removed and this class applied. */
a.btn-lg.is-disabled{opacity:.4;cursor:not-allowed;pointer-events:none}
.btn-lg:not(:disabled):active{filter:brightness(.95)}

.note{color:var(--a-dim);font-size:12px;line-height:1.6;margin-top:16px}

/* Advisory: fakta produk yang harus dibaca SEBELUM bertindak, bukan pesan error.
   Amber, bukan merah — ini bukan kesalahan pemain. Dipakai di /register untuk
   memberi tahu bahwa password belum bisa dipulihkan. */
.advisory{margin:0 0 14px;padding:12px 14px;border-radius:0;
  border:1px solid rgba(255,201,77,.28);background:rgba(255,201,77,.07);
  color:var(--a-mut);font-size:12px;line-height:1.65}
.advisory b{color:var(--a-amber);font-weight:700}
.alt{text-align:center;color:var(--a-mut);font-size:13px;margin-top:16px}
.alt a{color:var(--a-green);font-weight:700}

/* ---- NAVIGASI BAWAH ---- */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:40;background:rgba(5,13,9,.96);
  backdrop-filter:blur(10px);border-top:1px solid var(--a-line);
  padding-bottom:env(safe-area-inset-bottom,0px)}
.tabbar .in{width:min(560px,100%);margin:0 auto;display:grid;grid-template-columns:repeat(4,1fr)}
.tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  min-height:56px;padding:8px 0;color:var(--a-dim);font-size:11px}
.tab .ic{font-size:18px;line-height:1}
.tab.on{color:var(--a-green)}

/* ============================================================
   SPLASH TERMINAL — perintah diketik huruf demi huruf, lalu
   baris [ ok ] muncul seperti server booting, sebelum halaman tampil.
   Muncul juga saat berpindah halaman.
   ============================================================ */
.splash{
  /* Sebagian halaman menyembunyikan <html> sampai datanya siap (account-page.js).
     visibility diwariskan, jadi splash harus memaksa terlihat agar tidak ikut hilang. */
  visibility:visible;
  position:fixed;inset:0;z-index:2000;display:flex;flex-direction:column;
  justify-content:center;padding:24px;
  background:var(--a-bg-deep);
  font-family:"JetBrains Mono",ui-monospace,Consolas,monospace;
  font-size:13px;line-height:1.9;color:var(--a-mut);
  transition:opacity .3s ease, visibility .3s ease;
}
.splash.is-gone{opacity:0;visibility:hidden;pointer-events:none}
.splash-in{width:min(620px,100%);margin:0 auto;position:relative;z-index:1}
.splash-brand{color:var(--a-green);font-size:11px;letter-spacing:.2em;text-transform:uppercase;margin-bottom:14px}
.splash-row{color:var(--a-green);white-space:pre-wrap;word-break:break-word}
.splash-row .p{color:var(--a-dim)}
/* kursor berkedip mengikuti akhir teks yang diketik */
.splash-line::after{content:"";display:inline-block;width:8px;height:14px;background:var(--a-green);
  vertical-align:-2px;margin-left:3px;animation:splashBlink 1s steps(1) infinite}
@keyframes splashBlink{50%{opacity:0}}
.splash-log{margin-top:6px}
.splash-log div{color:var(--a-mut);opacity:0;animation:splashFade .18s ease forwards}
.splash-log .ok{color:var(--a-green)}
@keyframes splashFade{to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .splash-line::after{animation:none}
  .splash-log div{animation:none;opacity:1}
}


/* ============================================================
   RESPONSIF DESKTOP
   Di layar lebar kolom 560px membuat sisi kiri-kanan kosong.
   Mulai 900px halaman melebar dan isinya dibagi dua kolom
   (dashboard), 1200px+ proporsinya disesuaikan lagi.
   Di bawah 900px semuanya tetap satu kolom seperti di ponsel.
   ============================================================ */
.app-grid{display:grid;grid-template-columns:1fr;gap:0}
.app-grid > .colA,
.app-grid > .colB{min-width:0}

@media (min-width:900px){
  .app{width:min(1080px,100%);padding:0 24px}
  .appbar .in{width:min(1080px,100%);padding-left:24px;padding-right:24px}
  .tabbar .in{width:min(1080px,100%)}
  /* EQUAL columns, stretched: unequal tracks (1.05fr/.95fr) plus align-items:start
     were what made the two sides read as unrelated stacks with a ragged bottom. */
  .app-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px;align-items:stretch;margin-top:18px}
  .app-grid > .colA,
  .app-grid > .colB{display:flex;flex-direction:column}
  .app-grid > .colA > .sec,
  .app-grid > .colB > .sec{flex:1;display:flex;flex-direction:column;margin-top:0}
}
@media (min-width:1280px){
  .app{width:min(1200px,100%)}
  .appbar .in,.tabbar .in{width:min(1200px,100%)}
  .app-grid{gap:32px}
}

/* Auth forms must not stretch to the full dashboard width on a wide screen —
   DESIGN.md caps a form column at ~380px. */
@media (min-width:900px){
  .app-narrow{width:min(420px,100%)}
  .app-narrow .card-pad{padding:24px}
}

/* Judul halaman di atas isi — memberi konteks selain path di top bar. */
.page-h{padding:18px 0 4px}
.page-h h1{font-size:20px;font-weight:700;letter-spacing:-.01em}
.page-h p{color:var(--a-mut);font-size:13px;margin-top:3px}
@media (min-width:900px){ .page-h{padding:22px 0 6px} .page-h h1{font-size:23px} }

/* Baris status verifikasi email di kartu Account. Aksen tunggal (hijau) dipakai hanya
   untuk keadaan "verified"; keadaan "belum" memakai warna muted, bukan warna baru.
   Tombolnya tetap 44px agar nyaman disentuh di mobile. */
.li .v .st{display:block;font-weight:600}
.li .v .st.ok{color:var(--a-green)}
.li .v .st.mut{color:var(--a-mut);font-weight:500}
.li .v button.li-act{display:block;margin-left:auto;min-height:44px;padding:0;border:0;background:none;
  color:var(--a-green);font-family:inherit;font-size:12px;font-weight:700;text-align:right;cursor:pointer}
.li .v button.li-act:disabled{color:var(--a-mut);cursor:not-allowed}
.li .v button.li-act:hover:not(:disabled){text-decoration:underline}


/* Swap-history pager. Sits in the section header beside "Your swaps" rather than under
   the list, so the card keeps a fixed height and the page does not grow a row of
   controls that shifts everything below it. */
/* .sec-t is pinned to height:22px, which would clip the buttons; let a header that
   carries a pager grow to fit it. */
.sec-t:has(.sw-pager) { height: auto; min-height: 22px; }
.sw-pager {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.sw-page {
  font-family: inherit;
  font-size: 13px;
  line-height: 1;
  color: var(--a-text);
  background: var(--a-input);
  border: 1px solid var(--a-line);
  border-radius: 0;
  padding: 4px 9px;
  cursor: pointer;
}
.sw-page:hover:not([disabled]) { border-color: var(--a-green); color: var(--a-green); }
.sw-page[disabled] { opacity: 0.3; cursor: not-allowed; }
.sw-page-label {
  font-size: 11px;
  color: var(--a-mut);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ============================================================
   PRACTICE PANEL (wallet) — the free arena's score, kept visibly apart.
   Practice points are NOT 0xT and can never be swapped, so this panel gets
   its own band, its own "not a balance" stamp, and a hairline-amber-free,
   deliberately quieter treatment than the balance instruments above: its
   figures are muted, never the bright --a-text used for real money, and no
   practice number ever shares a row or a meter with a real one.
   ============================================================ */
.inst .band3{display:flex;flex-direction:column;border-style:dashed}
.inst .pr-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:14px 20px 11px;border-bottom:1px solid #123a24}
.inst .pr-body{display:grid;grid-template-columns:minmax(0,1fr);gap:0}
.inst .pr-tot{container-type:inline-size;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 18px;
  padding:16px 20px 18px;align-content:start}
/* Points is the headline and can run to five or six digits, so it gets its own row
   rather than a third of the width — that truncation is how a figure lies about itself. */
.inst .pr-stat.wide{grid-column:1 / -1}
.inst .pr-stat{display:flex;flex-direction:column;gap:6px;min-width:0}
.inst .pr-fig{font-size:28px;font-weight:700;line-height:1;color:var(--a-mut);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.inst .pr-fig.sm{font-size:19px}
.inst .pr-note{grid-column:1 / -1;display:flex;flex-direction:column;gap:9px;
  margin-top:2px;padding-top:14px;border-top:1px solid #123a24}
.inst .pr-note .stamp{align-self:flex-start}
.inst .pr-p{font-size:11.5px;line-height:1.5;color:var(--a-dim);margin:0}

.inst .pr-hist{padding:14px 20px 18px;border-top:1px solid #123a24}
.inst .pr-hist-h{display:flex;align-items:baseline;gap:12px;padding-bottom:9px;
  border-bottom:1px solid #123a24}
/* label column can shrink; the meter and the figure keep their width, so a long
   date can never squeeze the number it belongs to */
.inst .row-prc{display:grid;grid-template-columns:minmax(0,1fr) minmax(48px,1.1fr) 62px;
  gap:12px;align-items:center;padding:11px 0;border-bottom:1px solid #123a24}
.inst .row-prc:last-child{border-bottom:0}
.inst .row-prc .when{font-size:11.5px;color:var(--a-mut);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.inst .row-prc .tag{font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--a-dim);margin-top:3px;display:block}
.inst .row-prc .tag.alive{color:var(--a-green)}
.inst .row-prc .pts{font-size:14px;line-height:1;color:var(--a-mut)}
.inst .pr-empty{padding:26px 0 22px;text-align:center}
.inst .pr-empty .t{font-size:12.5px;color:var(--a-mut)}
.inst .pr-empty .s{font-size:11.5px;color:var(--a-dim);margin-top:6px}
/* the pager lives in the panel header, so the card keeps a fixed height */
.inst .pr-head .sw-pager{margin-left:auto}

@media (min-width:1120px){
  .inst .pr-body{grid-template-columns:minmax(0,300px) minmax(0,1fr)}
  .inst .pr-hist{border-top:0;border-left:1px solid #123a24}
  .inst .pr-tot{align-content:start}
}
/* Same track as every other quantity, deliberately dimmer fill: a practice meter must
   not read as brightly as a real balance meter. */
.inst .row-prc .fil{background:rgba(77,255,140,.10);border-right:2px solid var(--a-mut)}

/* Narrow: the three-column practice row cannot hold a date, a meter and a figure at
   390px without either wrapping the tag under itself or crushing the meter. Drop the
   meter onto its own full-width line instead, so every row stays two lines tall. */
@media (max-width:520px){
  .inst .row-prc{grid-template-columns:minmax(0,1fr) 62px;gap:8px 12px}
  .inst .row-prc>*:nth-child(1){grid-column:1;grid-row:1}
  .inst .row-prc>*:nth-child(3){grid-column:2;grid-row:1;align-self:center}
  .inst .row-prc>.trk{grid-column:1 / -1;grid-row:2}
  .inst .row-prc .tag{white-space:nowrap}
}

/* ---- REAL / DEMO wallet switch ------------------------------------------
   Top-right of the wallet page. Square by house style (see CLAUDE.md) — the
   two buttons share one border so they read as a single control, not as two
   loose actions. The active side is the only one that is filled, because the
   whole point is knowing at a glance which book you are looking at. */
.wmode {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 10px auto;
  width: max-content;
  border: 1px solid var(--a-line, #1f5f3a);
}
.wmode-btn {
  padding: 5px 14px;
  background: none;
  border: 0;
  color: var(--a-dim, #6f9a80);
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
}
.wmode-btn + .wmode-btn { border-left: 1px solid var(--a-line, #1f5f3a); }
.wmode-btn:hover { color: var(--a-green, #5aff96); }
.wmode-btn.is-on { background: rgba(90, 255, 150, 0.12); color: var(--a-green, #5aff96); }
/* DEMO is not money. When it is the active side the control says so in colour,
   so the page never looks like a second real balance. */
#wmode-demo.is-on { background: rgba(255, 200, 90, 0.12); color: #ffc85a; }

/* ---- DEMO wallet: same shape as real, deliberately different colour -------
   The demo balance sits in the same place and at the same size as the real one
   so a player can compare them. That makes colour the ONLY thing carrying the
   difference, so it has to be unmissable: real money is green everywhere in this
   product, and the demo book is amber and never green. */
.demo-fig { padding: 18px 22px 4px; }
.demo-fig-top { display: flex; align-items: baseline; gap: 12px; }
.demo-fig-row { display: flex; align-items: baseline; gap: 12px; margin-top: 4px; }
.demo-fig .num.fig { color: #ffc85a; }
.demo-unit { font-size: 17px; font-weight: 700; color: rgba(255, 200, 90, 0.6); }
.demo-tag {
  margin-left: auto;
  padding: 2px 8px;
  border: 1px solid rgba(255, 200, 90, 0.5);
  color: #ffc85a;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
}
/* The whole demo panel takes the amber edge, so it never reads as a second
   green (= real) card even when glanced at from the side of the screen. */
#practice-pan { border-color: rgba(255, 200, 90, 0.45); }
#practice-pan .lab-m { color: #ffc85a; }

/* Demo token rows: identical geometry to the real .row-tok list so the two
   wallets can be read against each other, amber instead of green so they are
   never mistaken for one another. */
.demo-toks { padding: 4px 20px 6px; }
.demo-row { padding: 13px 0; border-bottom: 1px solid rgba(255, 200, 90, 0.22); }
.demo-row.last { border-bottom: 0; }
.demo-row img { width: 42px; height: 42px; }
.demo-row .lab { color: #ffc85a; letter-spacing: .1em; }
.demo-row .num.r { font-size: 19px; font-weight: 700; color: #ffc85a; }
.demo-row .fil { background: #ffc85a; width: 0; }
.demo-noswap {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  padding: 11px 0 2px;
  border-top: 1px solid rgba(255, 200, 90, 0.22);
  color: rgba(255, 200, 90, 0.75);
  font-size: 11px;
  letter-spacing: .04em;
}

.demo-refill { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.demo-refill .ibtn {
  border: 1px solid rgba(255, 200, 90, 0.5);
  background: rgba(255, 200, 90, 0.1);
  color: #ffc85a;
  padding: 7px 14px;
  font-size: 11.5px;
  letter-spacing: .04em;
}
.demo-refill .ibtn:disabled { opacity: .45; cursor: default; }
.demo-refill .lab { color: rgba(255, 200, 90, 0.7); }
