/* ==========================================================================
   88M — desktop build (/web)
   ========================================================================== */

body { padding-top: var(--header-h); }

/* **This build states its own field widths; it does not inherit them.**
   `.form-control` and `.form-select` are Bootstrap's class names, and Bootstrap
   is what sets `display: block; width: 100%` on them — so every form on the
   site depended on a vendor stylesheet arriving. When it does not, an `<input>`
   falls back to its intrinsic 20-character width and a `<select>` to whatever
   its longest option happens to be, and a form comes out as a column of boxes
   at four different widths. That is what /m's registration page did on
   production on 16 Sep 2026; this is the same hole in the desktop build,
   closed at the same time rather than left for the day it shows.

   `box-sizing` is restated for the same reason: it is Bootstrap's reboot that
   sets it globally, and without it `width: 100%` plus a field's own padding
   overflows the row it is meant to fill. Both declarations are exactly what
   Bootstrap declares, so nothing moves while that file is there. */
.form-control,
.form-select {
  display: block;
  width: 100%;
  box-sizing: border-box;
}

.container-x {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 16px;
}

/* --- Header -------------------------------------------------------------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--header-h);
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(6px);
  z-index: 50;
  display: flex;
  align-items: center;
}
.site-header .hdr-inner {
  width: 100%;
  padding-inline: 28px;
  display: flex;
  align-items: center;
  gap: 18px;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: 26px;
  margin-left: 8px;
}
.main-nav a {
  position: relative;
  font-size: 14px;
  color: var(--c-ink);
  white-space: nowrap;
  padding: 6px 0;
}
.main-nav a:hover { color: var(--c-orange); }
.main-nav a.active { color: var(--c-orange); }
.main-nav a.hovering { color: var(--c-orange); }
.main-nav a .tag-new {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--c-red-badge);
  color: #fff;
  font-size: 9px;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 3px;
}

/* Clock stacks above the controls in normal flow — absolutely positioning it
   over the header made it collide with the buttons at some widths. */
.hdr-right {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
.hdr-clock {
  font-size: 11px;
  color: var(--c-ink);
  white-space: nowrap;
  line-height: 1;
}
.hdr-controls { display: flex; align-items: center; gap: 16px; }

/* Join and Login as a matched pair in the logo's own two colours, the same
   way the mobile build paints them: green to join, orange to sign in. */
/* --- The site's buttons ---------------------------------------------------
   The header's Login/Join pair was the only button drawn off the logo; every
   other one had picked up its own fill somewhere down the file. They are one
   family now, so a member coming off the header onto a cashier page is still
   pressing the same button.

   **The three colours mean something.** Orange is the mark's own and says
   "this is the thing you came here to do" — Login, Submit, Save, Claim,
   Confirm. Blue is the route *to* one of those, never the doing of it —
   Deposit, Add Bank, Upload Receipt, More Info. Green is the logo's other
   half, kept for Join Now alone so that registering never looks like anything
   else on the page.

   Written here and not in theme.css: that file is shared with /m, which has
   its own `--m-*` look and is not part of this.

   **Only the look is shared — the sizes are not.** A header button is 32px
   tall and a cashier Submit is 283px wide because of where each one sits, and
   each keeps its own line further down the file. What is unified is the
   shape, the weight, the fill and the way it lifts under the cursor. */
.hdr-cta,
.btn-deposit,
.btn-orange,
.btn-info-blue,
.btn-upload,
.btn-addbank,
.acc-submit,
.vf-ghost {
  /* The fill rides on variables, so a colour below is three lines instead of
     a repeat of this whole rule. Unset it is the logo orange — which makes
     every confirm button right by default and leaves only the exceptions with
     anything to say. */
  --cta-a: var(--c-logo-orange-lit);
  --cta-b: var(--c-logo-orange-deep);
  --cta-glow: rgba(182, 72, 55, .26);

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 0;
  border-radius: var(--radius);
  background: linear-gradient(135deg, var(--cta-a), var(--cta-b));
  box-shadow: 0 4px 10px var(--cta-glow);
  color: #fff;
  font-weight: 600;
  letter-spacing: .03em;
  text-align: center;
  transition: filter .15s ease, box-shadow .15s ease;
}

.hdr-cta:hover,
.btn-deposit:hover,
.btn-orange:hover,
.btn-info-blue:hover,
.btn-upload:hover,
.btn-addbank:hover,
.acc-submit:hover,
.vf-ghost:hover {
  /* Restated, because theme.css's own `.btn-orange:hover` still sets the flat
     `--c-orange` it used to be and nothing above would replace it — the fill
     would snap back to the old colour under the cursor. */
  background: linear-gradient(135deg, var(--cta-a), var(--cta-b));
  color: #fff;
  filter: brightness(1.07);
}

/* A button that cannot be pressed still has to read as a button. Bootstrap's
   `.btn:disabled` sets its own grey background, so the fill is restated here
   and the *opacity* is what says it is locked. */
.hdr-cta:disabled,
.btn-deposit:disabled,
.btn-orange:disabled,
.btn-info-blue:disabled,
.btn-upload:disabled,
.btn-addbank:disabled,
.acc-submit:disabled,
.vf-ghost:disabled {
  background: linear-gradient(135deg, var(--cta-a), var(--cta-b));
  color: #fff;
  opacity: .45;
  box-shadow: none;
  filter: none;
  cursor: not-allowed;
}

/* Blue — the routes to money, never the confirming of it. */
.btn-deposit,
.btn-info-blue,
.btn-upload,
.btn-addbank {
  --cta-a: var(--c-blue-light);
  --cta-b: var(--c-blue);
  --cta-glow: rgba(10, 78, 162, .26);
}

/* The header pair's own height, and the general-purpose orange button's own
   padding — theme.css still sizes `.btn-orange` for /m, and /web wants it a
   little taller now that it has a shadow under it. */
.hdr-cta { height: 32px; padding: 0 16px; font-size: 14px; }
.btn-orange { padding: 9px 20px; font-size: 15px; }

/* Green — Join Now, and nothing else. */
.hdr-cta.join {
  --cta-a: var(--c-logo-green-lit);
  --cta-b: var(--c-logo-green-deep);
  --cta-glow: rgba(63, 139, 104, .26);
}

/* Cancel, standing beside a confirm. Flat and quiet on purpose: two filled
   buttons side by side are two things asking to be pressed. */
.vf-ghost, .vf-ghost:disabled {
  background: var(--c-soft);
  border: 1px solid var(--c-line);
  color: var(--c-body);
  box-shadow: none;
}
.vf-ghost:hover { background: var(--c-soft-2); color: var(--c-body); filter: none; }

/* Language switcher ------------------------------------------------------- */
.lang-pick {
  display: flex;
  align-items: center;
  background: #f3f5f6;
  border: 0;
  border-radius: var(--radius-pill);
  padding: 5px 8px;
  height: 32px;
  color: var(--c-muted);
}
.lang-pick .flag { width: 25px; height: 25px; flex-basis: 25px; }
.lang-pick .flag > i { font-size: 15px; }
.lang-pick .caret { font-size: 11px; margin-left: 4px; transition: transform .18s ease; }
.lang-pick[aria-expanded="true"] .caret { transform: rotate(180deg); }

.lang-panel {
  position: absolute;
  top: 68px;
  /* Right edge lines up with the trigger button, i.e. the header's own
     inline padding — keep in sync with .site-header .hdr-inner. */
  right: 28px;
  width: 320px;
  background: #fff;
  border-radius: var(--radius-sm);
  box-shadow: rgba(0, 0, 0, .2) 5px 5px 5px -2px;
  padding: 26px 24px 0;
  display: none;
  z-index: 51;
}
.lang-panel.open { display: block; }
.lang-panel .lang-head {
  display: flex;
  align-items: center;
  padding-bottom: 15px;
  border-bottom: 2px solid #f7f7f7;
  margin-bottom: 15px;
}
.lang-panel .lang-head .globe { font-size: 26px; color: var(--c-blue-light); line-height: 1; }
.lang-panel .lang-head p { font-size: 14px; color: var(--c-ink); margin: 0 0 0 20px; }
.lang-panel .region-row:last-child { padding-bottom: 26px; }

/* --- Product submenu -----------------------------------------------------
   Measured off the reference: a full-bleed translucent navy bar hanging from
   the header, its contents centred in a 1000px six-column grid, 45px rows.
   The header is fixed, so `top: 100%` pins the bar to its lower edge. */
.submenu-bar {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: rgba(0, 15, 76, .8);
  backdrop-filter: blur(6px);
  padding: 20px 0 0;
  display: none;
}
.submenu-bar.open { display: block; }
/* A product with a lot of cards would otherwise run off the screen. */
.submenu-bar { max-height: 78vh; overflow-y: auto; }

.submenu-panel { display: none; width: 1000px; margin-inline: auto; }
.submenu-panel.on { display: block; }

.submenu-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.submenu-item {
  position: relative;
  padding-bottom: 30px;
  text-align: center;
  transition: opacity .15s;
}
/* Like the reference: the logo is an image at 70% of the column, its height
   left to the artwork. The image is whatever was uploaded against the platform
   row in /admin → 平台设定; a row with none gets the plate below. */
.submenu-item .logo {
  display: inline-block;
  width: 70%;
  height: auto;
  vertical-align: middle;
}
/* Fallback when a provider has no file yet. */
.submenu-item .logo.plate {
  aspect-ratio: 2 / 1;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  font-size: 11px;
  font-weight: 500;
  color: #fff;
  line-height: 1.25;
}
/* Platform tiles: seven across, as the artwork sheets are laid out.
   Named "tile" because Bootstrap owns .card — using that class here painted a
   white panel and a border behind every picture. */
.submenu-grid.tiles { grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 10px; padding-bottom: 20px; }
.submenu-item.tile { padding-bottom: 0; }
.submenu-item.tile img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius);
  transition: transform .15s;
}
.submenu-item.tile:hover img { transform: translateY(-3px); }

/* Hovering one entry dims the rest, exactly as the reference does. */
.submenu-grid:hover .submenu-item { opacity: .5; }
.submenu-grid .submenu-item:hover { opacity: 1; }

.submenu-item .pill-hot,
.submenu-item .pill-new {
  position: absolute;
  top: -5px;
  right: 12%;
  font-style: normal;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  line-height: normal;
}
.submenu-item .pill-hot { background: #ff650f; color: #fff; }
.submenu-item .pill-new { background: #e0092c; color: #fff; }

/* Mega menu behind the burger. One column since the secondary list came out
   of it, so the panel is half the width it used to be. */
.mega {
  position: fixed;
  top: var(--header-h);
  left: 18px;
  width: 258px;
  background: #fff;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  padding: 22px 26px 20px;
  display: none;
  z-index: 49;
}
.mega.open { display: block; }
.mega-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 9px 4px;
  font-size: 15px;
  font-weight: 500;
  color: var(--c-ink);
  border-radius: var(--radius-sm);
}
.mega-item:hover { background: var(--c-soft); color: var(--c-blue-mid); }
.mega-item .ico {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  color: var(--c-blue-mid);
  font-size: 18px;
}
/* The traced product marks. They are drawings, not glyphs, so they take their
   size here rather than from the icon font's font-size above. */
.mega-item .ico .ic-svg { width: 21px; height: 21px; }
/* The drawer's own Login / Log Out, drawn as the header pair are — left
   aligned at its own width under the list, not stretched across it. */
.mega .hdr-cta { margin: 14px 0 0 4px; }

/* --- Hero ---------------------------------------------------------------- */
.hero {
  position: relative;
  /* Follows the slideshow slot's shape (1920×430) instead of a fixed height,
     so an uploaded banner fills it edge to edge at every width and is never
     cropped. At 1920px wide this is the reference's 430px exactly. */
  aspect-ratio: 1920 / 430;
  height: auto;
  background: #000;
  overflow: hidden;
  /* Let the page still scroll vertically when a drag starts on the hero. */
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
  outline: none;
}
.hero:active { cursor: grabbing; }
.hero-track {
  display: flex;
  height: 100%;
  will-change: transform;
}
.hero-slide {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.hero-slide img { pointer-events: none; }
.hero-copy {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 60px;
  position: relative;
  z-index: 2;
  color: #fff;
}
.hero-copy .kicker { font-size: 18px; font-weight: 600; }
.hero-copy h1 { font-size: 40px; font-weight: 700; line-height: 1.15; margin: 6px 0 10px; }
.hero-copy p { font-size: 14px; opacity: .85; max-width: 420px; }

.hero-dots {
  position: absolute;
  left: 50%;
  bottom: 52px;
  transform: translateX(-670px);
  display: flex;
  gap: 8px;
  z-index: 3;
}
.hero-dots button {
  width: 8px;
  height: 8px;
  border-radius: 8px;
  border: 0;
  background: #fff;
  opacity: .75;
  padding: 0;
  transition: width .2s ease;
}
.hero-dots button.active { width: 26px; background: var(--c-orange); opacity: 1; }

/* --- Promo strip --------------------------------------------------------- */
.promo-strip { padding: 26px 0 0; }
.promo-strip .rail-wrap { position: relative; }
.promo-strip .rail-btn { position: absolute; top: 50%; transform: translateY(-50%); }
.promo-strip .rail-btn.prev { left: -6px; }
.promo-strip .rail-btn.next { right: -6px; }
/* --- Uploaded artwork ----------------------------------------------------
   Managed pictures arrive pre-padded to the exact box, so they only ever need
   to fill it. */
/* contain, not cover: the whole banner shows. The padding baked into the file
   and this background are the same colour, so the seam is invisible. */
.hero-img { width: 100%; height: 100%; object-fit: contain; display: block; background: #000; }
.hero-link { position: absolute; inset: 0; }
.promo-card.img { padding: 0; background: var(--c-soft); }
.promo-card.img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.promo-item .thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius); display: block; }
.auth-side img.banner { width: 100%; height: 320px; object-fit: cover; display: block; }

/* --- Scrolling notice ----------------------------------------------------- */
.ticker-bar { background: #fff; border-bottom: 1px solid var(--c-line); }
.ticker-bar .container-x { display: flex; align-items: center; gap: 12px; height: 44px; }
.ticker-bar .ico { color: var(--c-red-badge); font-size: 15px; flex: 0 0 auto; }
.ticker-view { flex: 1; overflow: hidden; }
.ticker-track {
  display: inline-flex;
  gap: 70px;
  white-space: nowrap;
  will-change: transform;
  animation: ticker-scroll 34s linear infinite;
}
.ticker-view:hover .ticker-track { animation-play-state: paused; }
.ticker-msg { font-size: 13px; color: var(--c-body); }
.ticker-msg a { color: var(--c-blue-mid); text-decoration: underline; margin-left: 8px; }
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .ticker-track { animation: none; }
}

/* --- Promotion detail ----------------------------------------------------- */
.promo-detail { max-width: 860px; }
.promo-detail .back-link { font-size: 13px; color: var(--c-muted); }
.promo-detail-img { width: 100%; border-radius: var(--radius-lg); margin: 16px 0 22px; display: block; }
.promo-detail h1 { font-size: 30px; font-weight: 600; margin-bottom: 12px; }
.promo-detail .lead { font-size: 15px; color: var(--c-body); margin-bottom: 20px; }
.rich { font-size: 14px; line-height: 1.75; color: var(--c-body); }
.rich table { border-collapse: collapse; margin: 14px 0; width: 100%; }
.rich table td, .rich table th { border: 1px solid var(--c-line); padding: 8px 12px; }
.rich img { max-width: 100%; height: auto; }
.rich ul, .rich ol { padding-left: 22px; margin: 10px 0; }

.promo-card {
  width: 268px;
  height: 84px;
  border-radius: var(--radius);
  padding: 12px 14px;
  color: #fff;
  position: relative;
  overflow: hidden;
}
.promo-card b { display: block; font-size: 14px; font-weight: 600; }
.promo-card span { font-size: 11px; opacity: .85; line-height: 1.3; display: block; }

/* --- Section scaffolding ------------------------------------------------- */
.sec { padding: 26px 0; }
.sec-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.sec-head h2 {
  font-size: var(--fs-section);
  font-weight: 600;
  color: var(--c-ink);
  margin: 0;
}
.sec-head .see-all { font-size: 16px; text-decoration: underline; }

.tab-pills { display: flex; align-items: center; gap: 8px; }
.tab-pill {
  border: 0;
  background: none;
  font-size: 14px;
  color: var(--c-muted);
  padding: 4px 18px;
  border-radius: var(--radius-pill);
  height: 28px;
  line-height: 20px;
}
.tab-pill.active { background: var(--c-orange); color: #fff; }

/* --- Live matches -------------------------------------------------------- */
.matches-panel {
  background: var(--c-soft);
  border-radius: var(--radius-lg);
  padding: 24px;
}
.match-hero { display: grid; grid-template-columns: 1fr 340px; gap: 16px; }
.match-hero .banner {
  height: 200px;
  border-radius: var(--radius);
  position: relative;
  padding: 22px 26px;
  color: #fff;
}
.match-hero .banner h3 { font-size: 18px; font-weight: 600; margin: 34px 0 12px; }
.match-hero .video {
  height: 200px;
  border-radius: var(--radius);
  display: grid;
  place-items: center;
}
.match-hero .video .play {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .85);
  color: #222;
  display: grid;
  place-items: center;
  font-size: 20px;
}

.match-rail { margin-top: 14px; position: relative; }
.match-card {
  width: 330px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #fff;
  box-shadow: var(--shadow-card);
}
.match-card .mc-head {
  background: linear-gradient(to right, var(--c-purple-1), var(--c-purple-2));
  color: #fff;
  font-size: 13px;
  padding: 9px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.match-card .mc-body { padding: 12px; display: flex; align-items: center; justify-content: space-between; }
.mc-odds { display: flex; gap: 8px; padding: 0 12px 12px; }
.mc-odds div {
  flex: 1;
  background: var(--c-soft);
  border-radius: 4px;
  padding: 6px 8px;
  display: flex;
  justify-content: space-between;
  font-size: 12px;
}
.mc-odds div span { color: var(--c-muted); }

/* --- How to register -----------------------------------------------------
   Four cards read left to right with a chevron between them. The icon sits in
   a white disc that overhangs the top edge of its card, which is what stops
   the row reading as four boxes of text. */
.howto { text-align: center; padding: 54px 0 40px; }
.howto .eyebrow { font-size: 14px; font-weight: 600; color: var(--c-ink); }
.howto h2 { font-size: 34px; font-weight: 700; color: #14307d; margin: 4px 0 46px; }

.howto-steps {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 6px;
  max-width: 1100px;
  margin-inline: auto;
}
.howto-arrow { align-self: center; font-size: 15px; color: #c9a45a; flex: 0 0 auto; }

.howto-step {
  /* minmax(0,…) in flex terms: the copy is translated and must be allowed to
     wrap rather than push its neighbours out of the row. */
  flex: 1 1 0;
  min-width: 0;
  position: relative;
  margin-top: 22px;
  padding: 34px 16px 22px;
  border: 1px solid #eceff5;
  border-radius: 14px;
  background: linear-gradient(#fbfcfe, #f7f9fc);
}
/* The disc straddles the card's top border, so the card's own background
   would show through the gap without a solid fill of its own. */
.howto-step .ico {
  position: absolute;
  top: -22px;
  left: 50%;
  transform: translateX(-50%);
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 1px #eef1f7, 0 4px 14px rgba(23, 43, 87, .07);
  display: grid;
  place-items: center;
}
.howto-step .ico .ic-svg { width: 27px; height: 27px; }
.howto-step b { display: block; font-size: 19px; font-weight: 600; letter-spacing: .01em; }
.howto-step p { margin: 7px 0 0; font-size: 13px; color: var(--c-body); line-height: 1.55; }

/* --- Feature row ---------------------------------------------------------
   One wide dark band under the steps, carrying the artwork uploaded in /admin
   and, over its right-hand side, the match card typed there. More than one
   entry runs it on the hero's carousel script, so the shapes match: a flex
   track of full-width slides that the script translates by whole percentages
   of the band. */
.feature-row { padding: 18px 0 6px; }
.fr-band {
  position: relative;
  /* Follows the upload slot's shape (2000×620) rather than a fixed height, so
     an uploaded banner fills it edge to edge at every width. */
  aspect-ratio: 2000 / 620;
  border-radius: var(--radius);
  overflow: hidden;
  background: #0a1730;
  touch-action: pan-y;
  user-select: none;
}
.fr-track { display: flex; height: 100%; will-change: transform; }
.fr-slide { position: relative; flex: 0 0 100%; height: 100%; overflow: hidden; }

.fr-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
/* Covers the whole slide so the banner is clickable anywhere the card is not;
   the card sits above it on z-index and keeps its own links. */
.fr-link { position: absolute; inset: 0; z-index: 2; }

/* Drawn only when this language has no artwork. */
.fr-plate {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 140% at 78% 30%, rgba(56, 108, 205, .55), transparent 60%),
    linear-gradient(115deg, #071129 0%, #0d2148 52%, #14315f 100%);
}
.fr-copy {
  position: relative;
  z-index: 3;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 46px;
  color: #fff;
}
.fr-copy .kicker { font-size: 15px; font-weight: 600; color: #f3cf86; }
.fr-copy h2 {
  font-size: 42px;
  font-weight: 800;
  line-height: 1.1;
  margin: 8px 0 6px;
  background: linear-gradient(#fbeec4, #d8ab52);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.fr-copy p { font-size: 14px; color: rgba(255, 255, 255, .82); margin: 0 0 16px; }

.fr-chips { display: flex; gap: 22px; flex-wrap: wrap; margin-bottom: 18px; }
.fr-chips span {
  display: grid;
  grid-template-columns: 30px auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 9px;
  font-size: 12.5px;
}
.fr-chips i {
  grid-row: 1 / 3;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .35);
  display: grid;
  place-items: center;
  font-size: 13px;
  color: #cfe0ff;
}
.fr-chips b { font-weight: 600; color: #fff; }
.fr-chips em { font-style: normal; color: rgba(255, 255, 255, .68); }

.fr-cta {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 11px 34px;
  border-radius: var(--radius-pill);
  background: linear-gradient(#f6d999, #d2a34c);
  color: #2a1c05;
  font-size: 16px;
  font-weight: 700;
}
.fr-cta:hover { color: #2a1c05; filter: brightness(1.05); }

.fr-dots {
  position: absolute;
  z-index: 5;
  left: 50%;
  transform: translateX(-50%);
  bottom: 14px;
  display: flex;
  gap: 7px;
}
.fr-dots button {
  width: 7px;
  height: 7px;
  border: 0;
  border-radius: 50%;
  padding: 0;
  background: rgba(255, 255, 255, .55);
}
.fr-dots button.active { background: var(--c-orange); }

/* A narrow desktop window: the banner's own copy is what has to give. */
@media (max-width: 1000px) {
  .fr-copy { padding: 0 26px; }
  .fr-copy h2 { font-size: 30px; }
  .fr-chips { display: none; }
  .fr-dots { left: 26px; }
}

/* --- Best Sports Games ---------------------------------------------------
   对战卡 — the match cards under the banner. Until 17 Sep 2026 one of these was
   glass over the artwork, pinned to the right-hand third of a feature slide;
   they are a row of their own now, so the card carries its own dark plate and
   the strip is the same sideways rail the game sections use. The card itself is
   unchanged inside — the `fm-` rules below are the ones it always had. */
.sport-rail-wrap { position: relative; }
.sport-rail-wrap .rail-btn { position: absolute; top: 50%; transform: translateY(-50%); }
.sport-rail-wrap .rail-btn.prev { left: -10px; }
.sport-rail-wrap .rail-btn.next { right: -10px; }

.sport-card {
  /* Wide enough for two team names side by side without either wrapping to
     three lines, which is what 290px did on the banner. */
  width: 320px;
  padding: 16px 18px 14px;
  border-radius: var(--radius-lg);
  border: 1px solid rgba(255, 255, 255, .1);
  background: linear-gradient(150deg, #14315f, #0a1730 72%);
  box-shadow: var(--shadow-card);
  color: #fff;
  /* The rail gives every card the height of the tallest, so the prices are
     pushed to the floor of the card instead of floating wherever that card's
     content happened to end — one card carries a "Bet now" button and the
     next does not, and the tiles read across the row. */
  display: flex;
  flex-direction: column;
}
.sport-card .fm-odds { margin-top: auto; padding-top: 12px; }
/* A flex child is as wide as its content unless it is told otherwise, and
   the button's `max-width: 60%` alone left it a small pill in the middle of
   the card. */
.sport-card .fm-bet { align-self: center; width: 60%; }
.fm-head { text-align: center; font-size: 16px; font-weight: 700; margin-bottom: 12px; }

.fm-vs { display: grid; grid-template-columns: 1fr auto 1fr; align-items: start; gap: 10px; }
.fm-side { text-align: center; min-width: 0; }
.fm-side .logo {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  max-width: 76px;
  margin: 0 auto 6px;
  border-radius: 10px;
  background: #fff;
  color: var(--c-muted);
  font-size: 22px;
  overflow: hidden;
}
.fm-side .logo img { width: 100%; height: 100%; object-fit: contain; }
.fm-side b { display: block; font-size: 12px; font-weight: 500; line-height: 1.3; }

.fm-mid { text-align: center; padding-top: 12px; }
.fm-mid .vs { display: block; font-size: 22px; font-weight: 800; }
.fm-mid time { display: block; margin-top: 4px; font-size: 13px; line-height: 1.35; }

.fm-bet {
  display: block;
  margin: 12px auto 0;
  max-width: 60%;
  padding: 7px 0;
  border-radius: 7px;
  background: var(--c-red, #d8342c);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  text-align: center;
}
.fm-bet:hover { color: #fff; filter: brightness(1.08); }

.fm-odds { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; margin-top: 12px; }
.fm-odds span {
  border-radius: 8px;
  padding: 7px 4px;
  text-align: center;
  background: rgba(255, 255, 255, .9);
  color: #17325e;
}
.fm-odds .o-a { background: linear-gradient(#dbe9ff, #c3d9fb); }
.fm-odds .o-b { background: linear-gradient(#fbe0e0, #f4cccc); }
.fm-odds b { display: block; font-size: 12.5px; font-weight: 600; }
.fm-odds em { display: block; font-style: normal; font-size: 14px; margin-top: 2px; }

/* --- Game cards ---------------------------------------------------------- */
.game-rail-wrap { position: relative; }
.game-rail-wrap .rail-btn { position: absolute; top: 96px; }
.game-rail-wrap .rail-btn.prev { left: -10px; }
.game-rail-wrap .rail-btn.next { right: -10px; }

.game-card { width: 186px; }
.game-card .thumb {
  width: 186px;
  height: 140px;
  border-radius: var(--radius);
  position: relative;
}
.game-card .name {
  font-size: 13px;
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.game-card .name b { font-weight: 400; overflow: hidden; text-overflow: ellipsis; }
.game-card .prov { font-size: 12px; color: var(--c-muted); }
.game-card .pill-rtp { margin-top: 6px; }
.game-card .badge-corner { position: absolute; top: 8px; left: 8px; }

/* --- Partners / testimonials / news -------------------------------------- */
.partner-strip {
  background: var(--c-soft);
  border-radius: var(--radius-lg);
  padding: 16px;
  overflow: hidden;
}
/* The track holds the list twice and slides exactly one pass to the left, so
   the second copy is standing where the first started when the animation
   restarts and the loop has no seam. `--partner-n` comes from the markup and
   ties the duration to the length, so the marks travel at the same speed
   whether a country sells eight platforms or thirty. */
.partner-track {
  display: flex;
  width: max-content;
  animation: partner-slide calc(var(--partner-n, 10) * 2.6s) linear infinite;
}
.partner-strip:hover .partner-track { animation-play-state: paused; }
@keyframes partner-slide { to { transform: translateX(-50%); } }
.partner-strip .p-logo {
  /* A margin, not `gap` on the track: a gap would sit between the two passes as
     well as inside them, so half of it would be left over and the loop would
     jump by that much every time round. */
  flex: 0 0 auto;
  /* 2:1 — the shape /admin stores a logo at (PLATFORM_LOGO_BOX, 240×120), so
     the cell is the upload's own proportion and the artwork lands in it at the
     size it was saved, neither cropped nor letterboxed. **No card behind it**:
     the logo keeps the transparent background it was uploaded with, and a white
     rectangle would put one back. */
  width: 140px;
  height: 70px;
  margin-right: 12px;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-body);
  text-align: center;
}
.partner-strip .p-logo img { width: 100%; height: 100%; object-fit: contain; }
@media (prefers-reduced-motion: reduce) { .partner-track { animation: none; } }

/* --- Footer -------------------------------------------------------------- */
.site-footer { border-top: 1px solid var(--c-line); padding: 34px 0 0; }
/* Two columns since the Information list came out: a narrow menu of the five
   products, then the region picker and the licence. `minmax(0, …)` on both so
   a long translated product name shortens the link rather than widening the
   column past the container. */
.foot-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px; }
.foot-grid h5 { font-size: 13px; font-weight: 500; color: var(--c-ink); margin-bottom: 14px; }
.foot-grid ul { list-style: none; padding: 0; margin: 0; }
.foot-grid li { margin-bottom: 10px; }
.foot-grid li a,
.foot-grid li span { font-size: 13px; color: var(--c-muted); }
.foot-grid li a:hover { color: var(--c-blue-mid); }
.foot-licence img { height: 46px; width: auto; display: block; }
.foot-icons { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 30px; padding: 30px 0; }
.foot-icons h5 { font-size: 12px; color: var(--c-body); margin-bottom: 14px; }

.seo-panel {
  background: var(--c-soft);
  border-radius: var(--radius-lg);
  padding: 22px 26px 26px;
  margin-bottom: 40px;
}
.seo-panel h6 { font-size: 14px; font-weight: 500; margin-bottom: 10px; }
.seo-panel p { font-size: 12px; color: var(--c-body); line-height: 1.7; margin: 0; }
.seo-panel a { color: var(--c-blue-light); }

/* --- Inner page furniture ------------------------------------------------ */
/* **The height follows the banner's shape, it is not a number.** The five
   product banners are 1600×370, and at 1600px wide this rule is that 370px
   exactly — the height the page has always had. Wider or narrower, the hero
   grows and shrinks with the artwork so it is never cropped.

   A fixed 370px with `object-fit: cover` was the obvious alternative and it
   is wrong here: on a 2560px screen the banner would be scaled to 592px tall
   and 111px taken off the top, which is where the faces are. Same reasoning,
   and the same ratio trick, as `.hero` on the home page.

   It is set on `.page-hero` itself and not only on the ones that have a
   banner, so Esports and 4D & Lottery — which keep their gradient plate —
   stay the same height as their five neighbours. A hero that changes size
   as you move along the product menu reads as a bug. */
.page-hero {
  position: relative;
  aspect-ratio: 1600 / 370;
  height: auto;
  display: flex;
  align-items: center;
  overflow: hidden;
  color: #fff;
}
.page-hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* The section is the image's own ratio, so cover crops nothing; it is here
     for the one pixel rounding leaves behind. */
  object-fit: cover;
  object-position: center;
  display: block;
  /* Under the wash below, which is a sibling ::before: at equal z-index the
     later element in the DOM wins, and the picture is the later one. */
  z-index: 0;
}
/* Every banner leaves its left third quiet for exactly this, but the copy is
   white and the artwork is not ours to re-cut — a soft wash guarantees the
   contrast without touching the picture on the right. */
/* And a ground under the picture, so white copy on a banner that has not
   loaded — or never will — is still legible. */
.page-hero.has-banner { background: #061024; }
.page-hero.has-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(90deg, rgba(3, 8, 26, .55) 0%, rgba(3, 8, 26, .28) 34%, rgba(3, 8, 26, 0) 58%);
  pointer-events: none;
}
.page-hero h1 { font-size: 46px; font-weight: 700; margin-bottom: 6px; }
.page-hero .sub { font-size: 18px; font-weight: 500; line-height: 1.3; }
.page-hero .sub small { display: block; font-size: 13px; font-weight: 400; opacity: .85; margin-top: 8px; }

/* Equal cells, not a wrapping row of pills: a chip sized to its own text gives
   every row a different rhythm, and the logos need a box of a fixed shape to
   line up in. `minmax(150px, 1fr)` rather than a fixed count so the bar fills
   whatever width it is given. */
.provider-bar {
  background: var(--c-soft);
  border-radius: var(--radius-lg);
  padding: 12px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
  margin-top: 26px;
}
.provider-chip {
  border: 1px solid transparent;
  background: #fff0;
  border-radius: var(--radius);
  padding: 8px 12px;
  min-height: 64px;
  min-width: 0;                 /* or a long name widens its own column */
  font-size: 13px;
  line-height: 1.3;
  color: var(--c-muted);
  display: grid;
  place-items: center;
  text-align: center;
  overflow-wrap: anywhere;
  position: relative;
}
.provider-chip img { max-width: 100%; max-height: 46px; object-fit: contain; }
.provider-chip.active { background: #fff; border-color: var(--c-orange); color: var(--c-ink); }
/* All three tags sit in the cell's own top-right corner. They used to hang
   outside it, which a wrapping row of pills had room for; a tight grid does
   not — the tag would land on the row above. */
.provider-chip .pill-hot,
.provider-chip .pill-new,
.provider-chip.maint .pill-maint { position: absolute; top: 4px; right: 4px; font-size: 9px; padding: 3px 5px; }

.filter-row { display: flex; align-items: center; justify-content: space-between; margin: 22px 0 18px; gap: 16px; }
.filter-row .text-muted-2 { white-space: nowrap; }
.search-box {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-pill);
  padding: 6px 16px;
  min-width: 180px;
  color: var(--c-muted);
}
.search-box input { border: 0; outline: none; font-size: 13px; width: 100%; }
.sort-select {
  border: 1px solid var(--c-line);
  border-radius: var(--radius-pill);
  font-size: 13px;
  padding: 6px 14px;
  color: var(--c-muted);
  min-width: 150px;
}

/* minmax(0,…), not 1fr: the auto minimum of a grid item is its min-content
   width, and for a game card that is the game's own name — so one long name
   from a synced catalogue widens its column at the others' expense. */
.game-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 20px; }
.game-grid .game-card, .game-grid .game-card .thumb { width: 100%; }
/* **A ratio, not a height.** The column is a fraction of the container, so a
   fixed 150px made the box's shape drift with the window — 1.22:1 at 1440px,
   nearer square on a laptop — and the artwork's letterboxing drifted with it.
   4:3 is the vendors' own shape (480x360), so their pictures fill this exactly
   and only an operator's square upload leaves a band. */
.game-grid .game-card .thumb { aspect-ratio: 4 / 3; height: auto; }

.tile-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 22px; }
.tile-card .thumb {
  aspect-ratio: 1;
  border-radius: 22px;
  position: relative;
}
.tile-card .thumb .pill-new { position: absolute; top: 8px; left: 8px; }
.tile-card .name { font-size: 13px; margin-top: 10px; }
.tile-card .prov { font-size: 12px; color: var(--c-muted); }

/* Promotions */
.promo-item { display: grid; grid-template-columns: 430px 1fr; gap: 40px; padding: 22px 0; }
.promo-item .thumb { height: 140px; border-radius: var(--radius); }
.promo-item h3 { font-size: 20px; font-weight: 600; margin-bottom: 10px; }
.promo-item p { font-size: 13px; color: var(--c-body); max-width: 380px; }
.promo-item .acts { display: flex; gap: 12px; margin-top: 30px; }
/* Size only — the blue fill and the shape come from the button family. */
.btn-info-blue { font-size: 14px; padding: 9px 22px; }

/* Auth pages */
.auth-wrap { background: var(--c-soft); min-height: calc(100vh - var(--header-h)); padding: 40px 0 70px; }
.auth-title { font-size: 22px; font-weight: 500; margin-bottom: 22px; }
.auth-grid { display: grid; grid-template-columns: 345px 1fr; gap: 18px; align-items: start; }
.auth-card { background: #fff; border-radius: var(--radius-lg); padding: 26px; }
.auth-card label { font-size: 13px; color: var(--c-body); margin-bottom: 5px; display: block; }
.auth-card label i { color: var(--c-red); font-style: normal; }
.auth-card .form-control, .auth-card .form-select {
  border: 1px solid var(--c-line);
  border-radius: var(--radius-sm);
  height: 38px;
  font-size: 14px;
}
/* The dial code and the number are one row, stated here rather than borrowed
   from `d-flex`/`gap-2` for the reason in the note at the top of this file —
   those are Bootstrap's utilities too. The code keeps its own width; the number
   takes the rest. `min-width: 0` is what lets it shrink: a flex item's floor is
   otherwise its content. */
.auth-card .field .d-flex { display: flex; gap: 8px; }
.auth-card .field .d-flex .form-select { flex: 0 0 100px; }
.auth-card .field .d-flex .form-control { flex: 1 1 auto; min-width: 0; }

.auth-card .field { margin-bottom: 14px; }
.auth-submit { width: 100%; height: 40px; font-size: 15px; margin-top: 16px; }
.auth-meta { text-align: center; font-size: 13px; color: var(--c-body); margin-top: 12px; }
.auth-meta a { color: var(--c-blue-light); text-decoration: underline; }
.auth-meta .create { color: var(--c-orange); text-decoration: none; }
.auth-note { text-align: center; font-size: 13px; color: var(--c-body); line-height: 1.6; border-top: 1px solid var(--c-line); margin-top: 20px; padding-top: 18px; }
/* Stands in for the login or registration form while that switch is off. */
.service-closed {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--c-soft);
  border: 1px dashed var(--c-line);
  border-radius: var(--radius);
  padding: 22px;
  margin: 10px 0 4px;
}
.service-closed i { font-size: 24px; color: var(--c-muted); }
.service-closed p { margin: 0; font-size: 14px; color: var(--c-body); line-height: 1.6; }

.auth-side { background: #fff; border-radius: var(--radius-lg); padding: 26px; text-align: center; }
.auth-side .banner { height: 260px; border-radius: var(--radius); }
.auth-side h3 { font-size: 26px; font-weight: 600; margin: 26px 0 22px; }

/* --- Logged-in header ---------------------------------------------------- */
.hdr-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--c-orange);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 17px;
}
.hdr-avatar:hover { color: #fff; }
.hdr-mail { position: relative; color: var(--c-blue-mid); font-size: 22px; line-height: 1; }
.hdr-mail:hover { color: var(--c-blue-mid); }
.hdr-mail .dot {
  position: absolute;
  top: -7px;
  right: -9px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--c-red-badge);
  color: #fff;
  font-size: 10px;
  line-height: 17px;
  text-align: center;
}
.hdr-wallet { line-height: 1.2; }
.hdr-wallet .lbl { display: block; font-size: 12px; color: #0071e3; }
.hdr-wallet .amt { display: block; font-size: 17px; color: var(--c-ink); }
.hdr-wallet .amt i { font-size: 13px; color: var(--c-blue-light); margin-left: 2px; cursor: pointer; }
/* The header pair sets the height, so Deposit matches it rather than sitting
   a few pixels proud of Login beside it. */
.btn-deposit { height: 32px; padding: 0 18px; font-size: 15px; }

/* --- Header hover panels -------------------------------------------------
   The panel is padded away from the trigger by a transparent strip so the
   pointer can travel into it without the hover dropping. */
.hdr-item { position: relative; }
.hdr-pop {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 9px;
  background: #fff;
  border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(15, 22, 31, .16);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity .15s ease, transform .15s ease, visibility .15s;
  z-index: 55;
}
.hdr-pop::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -13px;
  height: 13px;
}
.hdr-item:hover .hdr-pop,
.hdr-item:focus-within .hdr-pop {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* Message counts */
.pop-mail { width: 172px; padding: 10px 0; }
.pop-mail a {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 7px 18px;
  font-size: 13px;
  color: var(--c-muted);
}
.pop-mail a:hover { background: var(--c-soft); color: var(--c-blue-mid); }
.pop-mail em { font-style: normal; }

/* Cashier shortcuts */
.pop-cashier { width: 200px; padding: 13px; display: grid; gap: 8px; }
.pop-cashier a {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--c-soft);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 14px;
  color: var(--c-ink);
}
.pop-cashier a:hover { background: var(--c-soft-2); color: var(--c-blue-mid); }
.pop-cashier i { font-size: 18px; color: var(--c-blue-mid); }

/* Account summary */
.pop-account { width: 245px; padding: 18px 16px 10px; }
.pa-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.pa-head .hi { font-size: 14px; color: var(--c-ink); margin-bottom: 8px; }
.tier-pill {
  display: inline-block;
  background: var(--c-blue-mid);
  color: #fff;
  font-size: 11px;
  border-radius: var(--radius-pill);
  padding: 3px 14px;
}
.pa-head .vip { font-size: 10px; color: var(--c-muted); text-align: right; line-height: 1.5; }
.pa-head .vip b { display: block; font-size: 14px; font-weight: 400; color: var(--c-blue-light); }

.pa-progress {
  margin-top: 14px;
  background: #1b2430;
  border-radius: 6px;
  padding: 14px 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: #8f98a3;
}
.pa-progress a { color: #fff; font-size: 13px; white-space: nowrap; }

.pa-nav { padding-top: 6px; }
.pa-nav details { border-bottom: 1px solid var(--c-line); }
.pa-nav details:last-child { border-bottom: 0; }
.pa-nav summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 4px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.pa-nav summary::-webkit-details-marker { display: none; }
.pa-nav summary > .bi:first-child { color: var(--c-blue-mid); font-size: 15px; }
.pa-nav summary .chev { margin-left: auto; font-size: 10px; color: var(--c-muted); font-weight: 400; }
.pa-nav details[open] summary .chev { transform: rotate(180deg); }
.pa-nav ul { list-style: none; margin: 0; padding: 0 0 8px; }
.pa-nav li a { display: block; padding: 7px 16px; font-size: 13px; color: var(--c-muted); border-radius: var(--radius-sm); }
.pa-nav li a:hover { background: var(--c-soft); color: var(--c-blue-mid); }

/* --- Member area --------------------------------------------------------- */
.acc-wrap { background: var(--c-soft); min-height: 70vh; padding: 30px 0 60px; }
.acc-grid { display: grid; grid-template-columns: 220px 1fr; gap: 14px; align-items: start; }

/* Every group is open at once and every item wears its glyph — the supplied
   screen shows the whole menu, and eleven items over four headings do not need
   folding away. */
.acc-side { background: #fff; border-radius: var(--radius); padding: 10px 0 6px; }
.acc-group + .acc-group { border-top: 1px solid var(--c-line); margin-top: 6px; padding-top: 8px; }
.acc-group-hd {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 0;
  padding: 8px 18px 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--c-ink);
}
.acc-group-hd .bi { font-size: 16px; color: var(--c-blue-mid); }
.acc-group ul { list-style: none; margin: 0; padding: 0 10px 6px; }
.acc-group li a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 8px;
  font-size: 14px;
  color: var(--c-body);
  border-radius: var(--radius-sm);
}
.acc-group li a .bi { flex: 0 0 18px; font-size: 15px; color: var(--c-muted); text-align: center; }
.acc-group li a:hover { background: var(--c-soft); color: var(--c-blue-mid); }
.acc-group li a:hover .bi { color: var(--c-blue-mid); }
.acc-group li a.active { background: #e7effc; color: var(--c-blue-mid); font-weight: 600; }
.acc-group li a.active .bi { color: var(--c-blue-mid); }

.acc-referral {
  margin-top: 14px;
  border-radius: var(--radius);
  padding: 22px 24px 30px;
  background: linear-gradient(160deg, #cfe2fb, #e5eeff 60%, #dfeafd);
  position: relative;
  overflow: hidden;
}
.acc-referral h4 { font-size: 17px; font-weight: 600; line-height: 1.3; margin-bottom: 12px; }
.acc-referral p { font-size: 13px; color: var(--c-body); line-height: 1.5; }
.acc-referral .code {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  margin-top: 16px;
  background: #fff;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 14px;
  letter-spacing: .04em;
  color: var(--c-ink);
}
.acc-referral .code i { color: var(--c-blue-mid); }

/* --- Member area: the head of every page --------------------------------
   Who is signed in, when they last were, and the two balances beside the way
   to top one of them up. */
.acc-welcome { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.acc-welcome h1 { font-size: 22px; font-weight: 600; margin: 0; display: flex; align-items: center; gap: 10px; }
.acc-welcome h1 b { font-weight: 600; }
.acc-welcome h1 .ok {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--c-blue-mid);
  background: #e7effc;
  border-radius: var(--radius-pill);
  padding: 3px 11px;
}
.acc-welcome p { margin: 0 0 0 auto; font-size: 12.5px; color: var(--c-muted); }

.acc-cards {
  display: grid;
  /* minmax(0,…) so a long currency + balance cannot push the promo card out
     of the row. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin-bottom: 14px;
}
.acc-bal {
  position: relative;
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  padding: 20px 22px 22px;
}
.acc-bal .lbl { font-size: 14px; font-weight: 600; color: var(--c-ink); }
.acc-bal .lbl .bi { font-size: 13px; color: var(--c-faint); }
.acc-bal .amt { font-size: 30px; font-weight: 700; color: var(--c-blue-mid); margin: 14px 0 18px; }
.acc-bal .amt span { font-size: 14px; font-weight: 500; color: var(--c-muted); }
.acc-bal .amt i { font-size: 15px; color: var(--c-blue-mid); cursor: pointer; }
.acc-bal .go {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--c-blue-mid);
  color: #fff;
  border-radius: var(--radius-sm);
  padding: 11px 0;
  font-size: 15px;
  font-weight: 600;
}
.acc-bal .go:hover { color: #fff; filter: brightness(1.08); }
.acc-bal .tag {
  display: inline-block;
  background: var(--c-soft);
  color: var(--c-faint);
  border-radius: var(--radius-pill);
  padding: 7px 14px;
  font-size: 12.5px;
}
/* The glyph is decoration, not a control: it sits behind the copy at low
   contrast so it never competes with the figure. */
.acc-bal .deco {
  position: absolute;
  right: 18px;
  top: 40px;
  font-size: 46px;
  color: #dbe6f8;
  pointer-events: none;
}
/* 禮碼錢包 — the second card. Ink rather than blue for the figure, because it
   is not money the member can take out, and the coin glyph in the logo's gold
   so the card reads as a different kind of wallet at a glance. */
.acc-bal.chip { border-color: transparent; }
.acc-bal.chip .amt { color: var(--c-ink); }
.acc-bal.chip .deco { color: #f1e3b6; }

.acc-promo {
  position: relative;
  overflow: hidden;
  display: block;
  border-radius: var(--radius);
  padding: 22px 24px;
  background: linear-gradient(140deg, #14459c, #0e3178 70%);
  color: #fff;
}
.acc-promo:hover { color: #fff; }
.acc-promo b { display: block; font-size: 18px; font-weight: 700; }
.acc-promo span { display: block; margin-top: 6px; font-size: 13px; color: rgba(255, 255, 255, .82); }
.acc-promo em {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 20px;
  font-style: normal;
  font-size: 14px;
  font-weight: 700;
  color: #2a1c05;
  background: linear-gradient(#f6d999, #e6c076);
  border-radius: var(--radius-sm);
  padding: 9px 20px;
}
.acc-promo .deco { position: absolute; right: 16px; bottom: 12px; font-size: 62px; color: rgba(255, 255, 255, .14); }

/* --- Member area: cards --------------------------------------------------- */
.acc-card { background: #fff; border-radius: var(--radius); padding: 26px 30px 34px; }
.acc-card + .acc-card { margin-top: 14px; }
.acc-card h3 { font-size: 16px; font-weight: 600; margin-bottom: 20px; }
.acc-card h3.acc-hd { display: flex; align-items: center; gap: 12px; font-size: 19px; }
.acc-hd .ic {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  border-radius: 8px;
  background: #e7effc;
  color: var(--c-blue-mid);
  display: grid;
  place-items: center;
  font-size: 15px;
}

/* The security note above the first card. */
.acc-tip {
  display: flex;
  align-items: center;
  gap: 12px;
  background: #eef4fd;
  border: 1px solid #d7e5fa;
  border-radius: var(--radius);
  padding: 13px 16px;
  margin-bottom: 14px;
}
.acc-tip > .bi { font-size: 18px; color: var(--c-blue-mid); }
.acc-tip p { margin: 0; flex: 1; font-size: 13.5px; color: var(--c-body); }
.acc-tip button { border: 0; background: none; color: var(--c-faint); font-size: 13px; }

/* Two columns of read-only fields, each a label over its value with a hairline
   under it — the shape the supplied screen uses in place of the old table. */
.acc-split { display: grid; grid-template-columns: 1fr 268px; gap: 26px; align-items: start; }
.acc-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 40px; }
.acc-fields .f { padding: 14px 0 13px; border-bottom: 1px solid var(--c-line); min-width: 0; }
.acc-fields .f:first-child, .acc-fields .f:nth-child(2) { padding-top: 0; }
.acc-fields .k { display: block; font-size: 13px; color: var(--c-muted); }
.acc-fields .v {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 7px;
  font-size: 15px;
  color: var(--c-ink);
  min-width: 0;
}
.acc-fields .v > .edit, .acc-fields .v > .acc-pill { margin-left: auto; }

.acc-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border-radius: var(--radius-pill);
  padding: 3px 10px;
  font-size: 12px;
  white-space: nowrap;
}
.acc-pill.ok { background: #e7f7ec; color: #1e9e50; }
.acc-pill.star { background: #fdf3dd; color: #c08b16; }
/* The pill as a *call to action*: 資料已驗證 is an answer and only appears
   once the bank account is saved, so the unverified state needs something in
   its place that says what to do about it. */
.acc-pill.todo {
  border: 0;
  cursor: pointer;
  background: #fdf3dd;
  color: #c08b16;
}
.acc-pill.todo:hover { background: #fbe9c0; }

/* Bank accounts as cards, with the "add" tile last. */
.acc-banks { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.acc-banks .bk {
  border-radius: var(--radius);
  background: var(--c-soft);
  padding: 16px 18px 18px;
  min-width: 0;
}
.acc-banks .bk-top { display: flex; align-items: center; gap: 10px; }
.acc-banks .bk-top b { font-size: 15px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acc-banks .bk-top .acc-pill { margin-left: auto; }
.acc-banks .bk-top .flag, .acc-banks .bk-top .bank-logo { flex: 0 0 26px; width: 26px; height: 26px; }
.acc-banks .bk-no { margin: 14px 0 16px; font-size: 15px; letter-spacing: .04em; color: var(--c-ink); }
.acc-banks .bk .k { font-size: 12.5px; color: var(--c-muted); }
.acc-banks .bk-foot { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.acc-banks .bk-foot .v { font-size: 14px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acc-banks .bk-foot .acc-pill { margin-left: auto; }
.acc-banks .bk.add {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-size: 14px;
  color: var(--c-blue-mid);
  background: #fafbfd;
  border: 1px dashed var(--c-line);
}
.acc-banks .bk.add .plus {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #e7effc;
  display: grid;
  place-items: center;
  font-size: 17px;
}

/* Two-tab switcher used by Profile / Referral */
/* The strip is drawn to sit **on** the card: the tabs are square-bottomed and
   the card under them carries a square top-left corner to meet the active one.
   A `margin-bottom: 14px` here undid all of that — the active tab floated
   above a card it is supposed to be part of, with the two square corners left
   pointing at each other across the gap. */
.acc-tabs { display: flex; gap: 4px; }
/* 提款帳戶 can put a saved/removed notice between the strip and the card, and
   it needs the gap the strip no longer carries. */
.acc-tabs + .acc-note { margin-top: 14px; }
.acc-tabs a {
  min-width: 116px;
  text-align: center;
  padding: 12px 22px;
  font-size: 14px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: #b9bfc6;
  color: #fff;
}
.acc-tabs a.active { background: linear-gradient(to right, #095ebd, #04a9c2); }

/* Definition rows */
.acc-fields .edit {
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 6px;
  background: var(--c-soft);
  color: var(--c-body);
  display: grid;
  place-items: center;
  font-size: 13px;
  cursor: pointer;
}
.acc-fields .edit:hover { color: var(--c-blue-mid); }
/* Sits where the pencil would be on a field that can no longer be changed.
   Same box as .edit so the column does not shift between rows. */
.acc-fields .acc-locked {
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  font-size: 12px;
  color: var(--c-faint);
}

/* Sits in the second column of .acc-split, so it takes that column's width
   rather than a fixed one. */
.verify-card {
  background: var(--c-soft);
  border-radius: var(--radius);
  padding: 18px 20px 20px;
}
.verify-card h5 { font-size: 14px; font-weight: 600; margin-bottom: 16px; }
.verify-card .icons { display: flex; gap: 18px; margin-bottom: 18px; }
.verify-card .acc-pill { font-size: 13px; padding: 5px 12px; }
/* Buttons where there is still something to ask, a plain span where there is
   not: the bank mark stops being pressable once an account is on file. Both
   have to look the same, so both are styled here. */
.verify-card .icons button,
.verify-card .icons > span {
  position: relative;
  font-size: 19px;
  color: var(--c-blue-mid);
  background: none;
  border: 0;
  padding: 0;
  line-height: 1;
  cursor: pointer;
}
.verify-card .icons button:hover { color: var(--c-blue-light); }
.verify-card .icons .done::after {
  content: '\f26e';
  font-family: 'bootstrap-icons';
  position: absolute;
  right: -5px;
  bottom: -3px;
  font-size: 11px;
  color: var(--c-green);
  background: #fff;
  border-radius: 50%;
  line-height: 1;
}

/* Option pickers (deposit / withdraw) */
.opt-grid { display: flex; flex-wrap: wrap; gap: 14px; }
.opt-card {
  width: 128px;
  min-height: 88px;
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  background: var(--c-soft);
  display: grid;
  place-items: center;
  align-content: center;
  gap: 6px;
  padding: 10px 6px;
  font-size: 13px;
  color: var(--c-body);
  text-align: center;
  line-height: 1.25;
  position: relative;
  cursor: pointer;
}
.opt-card:hover { color: var(--c-body); }
.opt-card i { font-size: 24px; color: var(--c-blue-mid); }
.opt-card.active { border-color: var(--c-orange); border-width: 2px; background: #fff; }
.opt-card.dim { opacity: .45; }
.opt-card .ribbon {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--c-orange);
  color: #fff;
  font-size: 10px;
  padding: 3px 8px;
  border-radius: 3px;
  white-space: nowrap;
}
/* Green availability dot on the Normal Deposit bank tiles */
.opt-card .dot-online {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #29c76f;
}
/* Crypto network tiles carry two lines of meta, so they run taller */
.opt-card.net { width: 148px; min-height: 104px; gap: 2px; }
.opt-card.net b { font-size: 13px; font-weight: 400; margin-top: 2px; }
.opt-card.net small { font-size: 10px; color: var(--c-faint); }

.field-label { font-size: 13px; color: var(--c-muted); margin: 24px 0 10px; }
.field-label i { color: var(--c-red); font-style: normal; }
.need-help { float: right; font-size: 13px; color: var(--c-blue-light); }

.card-links { float: right; display: flex; gap: 22px; font-size: 13px; }
.card-links a { color: var(--c-blue-light); }
.card-links .offline-status { position: relative; color: var(--c-muted); }
.card-links .offline-status::after {
  content: '';
  position: absolute;
  top: -2px;
  left: 9px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-red);
}

/* Amount input + its limit note */
.acc-input { max-width: 283px; border: 1px solid var(--c-line); border-radius: var(--radius-sm); height: 40px; font-size: 14px; }
.amount-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.amount-input { position: relative; width: 283px; }
.amount-input .form-control { border: 1px solid var(--c-line); border-radius: var(--radius-sm); height: 40px; font-size: 14px; padding-right: 38px; }
.amount-input .clear {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  border: 0;
  background: none;
  color: var(--c-body);
  font-size: 13px;
}
.limit-note { font-size: 13px; color: var(--c-body); display: flex; align-items: center; gap: 7px; }
.limit-note i { color: var(--c-faint); }
.limit-note.warn { color: var(--c-red); max-width: 270px; line-height: 1.4; }

.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; max-width: 460px; }
.amt-chip {
  border: 0;
  background: var(--c-soft);
  border-radius: var(--radius-sm);
  color: var(--c-muted);
  font-size: 14px;
  padding: 9px 0;
  width: 84px;
}
.amt-chip:hover { background: var(--c-soft-2); }

.withdrawable { font-size: 14px; color: var(--c-body); margin-top: 12px; }
.withdrawable b { color: var(--c-blue-light); font-weight: 400; }

.upload-note { font-size: 13px; color: var(--c-body); margin: 26px 0 12px; display: flex; align-items: center; gap: 8px; }
.upload-note i { color: var(--c-faint); }
.btn-upload { height: 40px; width: 258px; font-size: 15px; }
/* Was a pale blue of its own, which read as disabled next to a real button. */
.btn-addbank { width: 283px; height: 38px; font-size: 14px; margin-top: 16px; }
.add-round {
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  border: 0;
  border-radius: 50%;
  background: #b9bfc6;
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 13px;
}

/* Crypto exchange-rate block on the withdraw page */
.rate-box { margin-top: 22px; }
.rate-box .lbl { font-size: 12px; color: var(--c-muted); letter-spacing: .02em; margin-bottom: 12px; }
.rate-box .grid { display: flex; align-items: center; gap: 60px; }
.rate-box .k { display: block; font-size: 13px; color: var(--c-muted); margin-bottom: 6px; }
.rate-box .v { font-size: 13px; color: var(--c-ink); }
.rate-refresh { border: 0; background: none; color: var(--c-faint); font-size: 16px; }

/* Saved-account tables and their inline add form */
.acc-tabs.three a { min-width: 148px; }
.acc-table.saved thead th { text-align: left; padding-left: 18px; }
.acc-table.saved td { text-align: left; padding-left: 18px; border-bottom: 0; color: var(--c-muted); }
.acc-table.saved td.lead { display: flex; align-items: center; gap: 12px; color: var(--c-muted); }
.row-del { border: 0; background: none; color: var(--c-faint); font-size: 15px; }
.row-del:hover { color: var(--c-red); }

.side-form { display: grid; gap: 14px; max-width: 620px; }
.side-form > div { display: grid; grid-template-columns: 170px 283px; align-items: center; gap: 12px; }
.side-form label { font-size: 13px; color: var(--c-muted); margin: 0; }
.side-form label i { color: var(--c-red); font-style: normal; }
.side-form .form-control, .side-form .form-select {
  border: 1px solid var(--c-line);
  border-radius: var(--radius-sm);
  height: 40px;
  font-size: 14px;
}


/* Deposit speed tabs */
.speed-tabs { display: flex; gap: 4px; margin-bottom: 0; }
.speed-tabs a {
  flex: 0 0 138px;
  text-align: center;
  padding: 10px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: #b9bfc6;
  color: #fff;
  font-size: 14px;
  line-height: 1.3;
}
.speed-tabs a small { display: block; font-size: 11px; opacity: .9; }
.speed-tabs a.active { background: linear-gradient(to right, #095ebd, #04a9c2); }

/* Stat pair on the withdraw page */
.stat-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.stat-box { background: var(--c-soft); border-radius: var(--radius); padding: 18px 22px; }
.stat-box .t { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--c-body); }
.stat-box .t i { font-size: 16px; }
.stat-box .n { font-size: 22px; color: var(--c-blue-light); margin-top: 8px; }
.stat-box .n span { font-size: 12px; color: var(--c-muted); }

/* Tables */
.acc-table { width: 100%; border-collapse: collapse; }
.acc-table thead th {
  background: var(--c-soft);
  font-size: 13px;
  font-weight: 400;
  color: var(--c-body);
  padding: 12px 10px;
  text-align: center;
}
.acc-table thead th:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.acc-table thead th:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.acc-table td { padding: 13px 10px; font-size: 13px; text-align: center; border-bottom: 1px solid var(--c-line); }
.acc-table .ok { color: var(--c-blue-light); }
.acc-empty { text-align: center; color: var(--c-muted); font-size: 13px; padding: 34px 0; }
.acc-count { text-align: center; font-size: 13px; color: var(--c-body); padding: 16px 0; }
.pager { display: flex; justify-content: center; gap: 6px; }
.pager a, .pager span {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 13px;
  color: var(--c-muted);
}
.pager .on { background: var(--c-soft); color: var(--c-ink); }

/* Filter form */
.acc-filter { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 22px; max-width: 600px; }
.acc-filter label { font-size: 13px; color: var(--c-muted); display: block; margin-bottom: 6px; }
.acc-filter label i { color: var(--c-red); font-style: normal; }
.acc-filter .form-control, .acc-filter .form-select {
  border: 1px solid var(--c-line);
  border-radius: var(--radius-sm);
  height: 40px;
  font-size: 14px;
  color: var(--c-body);
}
.acc-submit { height: 40px; width: 283px; font-size: 15px; margin-top: 20px; }

/* Messaging */
.msg-tabs { display: flex; gap: 4px; }
.msg-tabs a {
  min-width: 132px;
  text-align: center;
  padding: 12px 18px;
  font-size: 14px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: #b9bfc6;
  color: #fff;
}
.msg-tabs a.active { background: linear-gradient(to right, #095ebd, #04a9c2); }
.msg-toolbar { display: flex; align-items: center; gap: 14px; font-size: 14px; color: var(--c-body); padding: 6px 0 20px; }
.msg-toolbar .right { margin-left: auto; display: flex; gap: 22px; }
.msg-toolbar .right span { display: flex; align-items: center; gap: 7px; color: var(--c-muted); cursor: pointer; }
.acc-table td.subj { text-align: left; font-size: 14px; line-height: 1.4; }
.acc-table td.subj.unread { font-weight: 600; }
.acc-table td.subj.read { color: var(--c-faint); }
.acc-table .row-acts { display: flex; gap: 16px; justify-content: center; color: var(--c-faint); }

/* Transfer wallets */
.turnover-bar {
  background: var(--c-soft);
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  color: var(--c-body);
  margin-bottom: 18px;
}
.turnover-bar b { color: var(--c-blue-light); font-weight: 400; }
.turnover-bar i { color: var(--c-orange); cursor: pointer; }
.wallet-group { font-size: 14px; color: var(--c-body); margin: 22px 0 12px; }
.wallet-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.wallet-card { background: var(--c-soft); border-radius: var(--radius); padding: 14px; position: relative; }
.wallet-card .top { display: flex; align-items: center; gap: 10px; }
.wallet-card .logo { width: 34px; height: 34px; border-radius: 8px; flex: 0 0 34px; }
.wallet-card .nm { font-size: 13px; }
.wallet-card .bal { font-size: 13px; color: var(--c-blue-light); }
.wallet-card .plus {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: #b9bfc6;
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 11px;
}
.wallet-card .to {
  display: flex;
  justify-content: space-between;
  background: #fff;
  border-radius: 4px;
  padding: 6px 9px;
  font-size: 12px;
  color: var(--c-muted);
  margin-top: 12px;
}
.wallet-card .allin {
  display: block;
  text-align: center;
  background: #9aa3ad;
  color: #fff;
  border-radius: var(--radius-pill);
  font-size: 12px;
  padding: 4px;
  margin-top: 8px;
}

/* Referral */
.ref-status { background: var(--c-soft); border-radius: var(--radius-sm); padding: 6px 16px; max-width: 270px; }
/* The two ladders, side by side when the card is wide enough for both.
   `auto-fit` rather than a count so a narrow window stacks them instead of
   squeezing four columns of money into 260px. */
.ref-ladder { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; align-items: start; }
.ref-note { font-size: 12px; color: var(--c-muted); line-height: 1.7; margin: 14px 0 0; }
/* The one line on the page that is a *condition* rather than an invitation, so
   it is set apart from the prose above it instead of being a third sentence of
   it. Flex, not a bullet, so the second line wraps under the text and not
   under the icon. */
.ref-limit {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 8px;
  padding: 10px 13px;
  border-radius: var(--radius-sm);
  background: var(--c-soft);
  color: var(--c-body);
}
.ref-limit i { color: var(--c-blue-mid); font-size: 13px; line-height: 1.6; }
/* 推薦首充彩金 — the rule in one line, and the 領取 button beside it while a
   friend's first deposit is waiting. Wraps under the text on a narrow card. */
.ref-first {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--c-soft);
}
.ref-first > i { color: var(--c-orange); font-size: 20px; }
.ref-first .rf-txt { flex: 1 1 180px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ref-first .rf-txt b { font-size: 13px; color: var(--c-body); }
.ref-first .rf-txt span { font-size: 12px; color: var(--c-muted); line-height: 1.6; }
.ref-first form { margin: 0; }
.ref-first .btn { white-space: nowrap; padding: 7px 16px; font-size: 13px; }
.ref-status div { display: flex; justify-content: space-between; padding: 7px 0; font-size: 13px; color: var(--c-muted); }
/* The agent level: a badge, the rate it earns, and what the next one takes.
   The badge colours follow the level names — plain, silver, gold, diamond —
   so the word and the colour say the same thing. */
.ref-level { display: flex; flex-direction: column; gap: 6px; margin: 0 0 14px; }
.ref-level b { font-size: 15px; color: var(--c-ink); }
.ref-level > span:last-child { font-size: 12.5px; color: var(--c-muted); }
.ref-badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
  background: var(--c-soft);
  color: var(--c-body);
}
.ref-badge.lv2 { background: #eceff3; color: #5b6673; }
.ref-badge.lv3 { background: #fbf1d6; color: #96702a; }
.ref-badge.lv4 { background: #e4f0ff; color: #1d5fbf; }
/* 超級代理 — the level that is given, not climbed, so it is the one badge that
   does not sit on the same pale ground as the other four. Dark with gold on
   it: the ladder's colours run soft grey → gold → blue, and a fifth pale pill
   would read as another rung rather than as something off the ladder. */
.ref-badge.lv5 { background: linear-gradient(135deg, #1c2533, #33405a); color: #f0d9a0; }
/* Their one figure, where the two ladder tables would have been. */
.ref-super {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 18px 20px;
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  background: linear-gradient(135deg, #f7f9fc, #eef2f8);
}
.ref-super em { font-style: normal; font-size: 13px; color: var(--c-muted); }
.ref-super b { font-size: 34px; line-height: 1.1; color: var(--c-blue-mid); }
.ref-super > span:last-child { font-size: 12.5px; color: var(--c-muted); }
/* The wallet a payout landed in, on the row that says which one — every other
   row on the table is chips, so only the odd one out is marked. */
.ref-wallet {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  background: #e7effc;
  font-style: normal;
  font-size: 11px;
  font-weight: 600;
  color: var(--c-blue-mid);
}
/* The member's own row of the ladder, and the milestones they have passed. */
.ref-ladder tr.is-me td { background: #eef4ff; color: var(--c-ink); font-weight: 600; }
.ref-ladder tr.is-done td { color: var(--c-faint); text-decoration: line-through; }
/* 推薦詞 — the invitation as one copyable block. The wording, then the link on
   a line of its own so the member can see the thing they are sending is whole,
   and one button that takes both. `pre-wrap` because the operator's own
   wording in /admin may carry line breaks and they are part of the message. */
.ref-msg-box {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  background: var(--c-soft);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
}
.ref-msg-box .rmb-text {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.75;
  color: var(--c-body);
  white-space: pre-wrap;
}
/* The link is its own line and wraps anywhere: a referral link is one long
   unbroken word, and left to itself it would push the button off the box. */
.ref-msg-box .rmb-link {
  display: block;
  margin-top: 8px;
  color: var(--c-blue-light);
  overflow-wrap: anywhere;
}
.ref-msg-box .rmb-copy {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--c-line);
  background: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 18px;
  font-size: 13px;
  color: var(--c-body);
  cursor: pointer;
}
.ref-msg-box .rmb-copy:hover { border-color: var(--c-blue-light); color: var(--c-blue-mid); }
/* The same tick the clipboard buttons give, so a silent write is visibly one. */
.ref-msg-box .rmb-copy.copied { border-color: var(--c-green); background: #e8f6ed; color: #1b7a42; }
.ref-msg-box .rmb-copy.copied i::before { content: '\f26e'; }
/* Narrow: the button goes under the message rather than squeezing it. */
@media (max-width: 575.98px) {
  .ref-msg-box { flex-direction: column; gap: 12px; }
  .ref-msg-box .rmb-copy { width: 100%; justify-content: center; }
}
/* My Bonus: what has been earned in all beside what is in the wallet now. */
.ref-earned-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }
.copy-field { display: flex; align-items: center; gap: 10px; background: var(--c-soft); border-radius: var(--radius-sm); padding: 9px 14px; }
.copy-field input { border: 0; background: none; outline: none; flex: 1; font-size: 13px; color: var(--c-body); }
/* The clipboard is a real button — it is the only thing on the row that does
   anything, so it has to be reachable by keyboard and hit like a button. The
   old rule dressed a bare <i> in a pointer cursor and nothing happened. */
.copy-field .cf-copy {
  border: 0;
  background: none;
  padding: 0;
  line-height: 1;
  font-size: 15px;
  color: var(--c-blue-light);
  cursor: pointer;
}
.copy-field .cf-copy:hover { color: var(--c-blue-mid); }
/* A tick for a moment, so a silent clipboard write is visibly a write. */
.copy-field .cf-copy.copied { color: var(--c-green); }
.copy-field .cf-copy.copied i::before { content: '\f26e'; }
.offer-card {
  border: 2px solid var(--c-orange);
  border-radius: var(--radius);
  width: 283px;
  overflow: hidden;
  text-align: center;
}
.offer-card .hd { font-size: 15px; color: var(--c-blue-light); padding: 12px; background: var(--c-soft); }
.offer-card div + div { border-top: 1px solid var(--c-line); }
.offer-card .ln { font-size: 13px; color: var(--c-body); padding: 8px; background: #fff; }

/* Notice / recent panels */
.acc-panel { background: #fff; border-radius: var(--radius); padding: 20px 26px 24px; margin-top: 14px; }
.acc-panel > .hd { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--c-body); margin-bottom: 14px; }
.acc-panel > .hd i.warn { color: var(--c-red); }
.acc-panel > .hd .chev { margin-left: auto; color: var(--c-muted); font-size: 12px; }
.acc-panel ul { padding-left: 18px; margin: 0; }
.acc-panel li { font-size: 13px; color: var(--c-muted); line-height: 1.7; }
.acc-more { display: block; text-align: center; font-size: 13px; text-decoration: underline; margin-top: 14px; }

/* --- VIP page -------------------------------------------------------------
   Drawn on the same white ground as every other page: the shell is the shell,
   and only the gold accent and the medals say this is the VIP one. A tier's
   colour arrives per element as `--c`, so the medal and its column share one
   accent without a class per tier. The names themselves print in ink — those
   colours are picked in /admin for a medal, and a pale one (silver, diamond)
   would be unreadable as text on white.

   Gold is the accent, but #c8a256 as text on white is too pale to read, so
   headings and bands use a darker draw of the same colour. */
.vip-page { --c-gold-ink: #96702a; }

.btn-gold {
  background: linear-gradient(135deg, #d4ac63, #b8893c);
  color: #1a1206;
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: 600;
  padding: 7px 26px;
}
.btn-gold:hover { color: #1a1206; filter: brightness(1.08); }

/* Hero. The banner is 1280×256 and the section is that ratio, the same rule
   `.page-hero` follows: on a wide screen the picture grows rather than being
   cropped, and the couple never loses their heads to `cover`.

   The floor is there for the narrow end — below about 1100px the ratio alone
   would give the copy less height than it needs — and it is only then that
   `cover` crops anything. It crops from the left, where the artwork is empty
   marble, which is why the picture sits `right`. */
.vip-hero {
  position: relative;
  aspect-ratio: 2069 / 760;
  min-height: 268px;
  height: auto;
  display: flex;
  align-items: center;
  overflow: hidden;
  background: #f7f2e9;
  border-bottom: 1px solid var(--c-line);
}
.vip-hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right center;
  display: block;
  z-index: 0;
}
/* Not `.container-x`: the copy has to line up with what is behind it, and the
   marble the banner leaves clear is a share of the picture, not a fixed
   column. Inset and width are both percentages of the section for that reason
   — on a 2560px screen the swirl and the headline move out together. */
.vip-hero-in {
  position: relative;
  z-index: 1;
  width: 100%;
  padding-inline: 16.5% 0;
}
/* A share of the banner, but a line of body text stops being readable long
   before a 2560px screen runs out of marble. */
.vip-hero-copy { width: 32%; min-width: 290px; max-width: 620px; }
.vip-eyebrow {
  display: inline-block;
  font-size: 12px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--c-gold-ink);
  margin-bottom: 10px;
}
.vip-hero h1 {
  font-size: 38px;
  font-weight: 700;
  letter-spacing: -.5px;
  line-height: 1.1;
  margin: 0 0 12px;
  color: var(--c-ink);
}
.vip-hero-copy p {
  font-size: 14px;
  line-height: 1.75;
  color: var(--c-body);
  margin: 0 0 18px;
}
.vip-hero .btn-orange { font-size: 14px; padding: 8px 26px; }

/* Tab strip. The tabs are anchors down the page, so the strip has to stay
   reachable after the jump — hence sticky, under the header. */
.vip-tabbar {
  position: sticky;
  top: var(--header-h);
  z-index: 20;
  background: rgba(255, 255, 255, .93);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--c-line);
}
.vip-tabs { display: flex; gap: 6px; padding: 12px 0; }
.vip-tab {
  border-radius: var(--radius-pill);
  padding: 8px 22px;
  font-size: 14px;
  color: var(--c-muted);
  transition: background .15s, color .15s;
}
.vip-tab:hover { background: rgba(200, 162, 86, .14); color: var(--c-gold-ink); }

.vip-sec { padding: 62px 0 0; scroll-margin-top: calc(var(--header-h) + 60px); }
.vip-h2 { font-size: 26px; font-weight: 600; margin: 0 0 26px; color: var(--c-ink); }

/* About */
/* The picture is flush with the card — no gap, and no padding on its side — so
   the diagonal it is cut on lands on the card's own white and the two read as
   one shape. That is why the padding sits on the copy and not on the card. */
.vip-about {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: stretch;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.vip-about > div { align-self: center; padding: 32px 0 32px 44px; }
.vip-about h2 { font-size: 24px; font-weight: 600; color: var(--c-gold-ink); margin: 0 0 12px; }
.vip-about p { font-size: 14.5px; line-height: 1.8; color: var(--c-body); margin: 0 0 20px; }
/* The lean is drawn rather than cut into the file: the card is as tall as its
   own copy, which is taller than the 150px the reference happened to be, and a
   baked wedge is the first thing `cover` would crop away. */
.vip-about-art {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 190px;
  object-fit: cover;
  object-position: center;
  clip-path: polygon(11% 0, 100% 0, 100% 100%, 0 100%);
}

/* Medal strip */
.vip-strip-sec {
  background: radial-gradient(ellipse 760px 300px at 50% 30%, rgba(17, 99, 207, .07), transparent 72%);
}
.vip-strip-title {
  text-align: center;
  font-size: 22px;
  font-weight: 500;
  color: var(--c-gold-ink);
  margin: 0 0 42px;
}
.vip-strip-title small {
  display: block;
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin-top: 8px;
}
/* minmax(0, 1fr) rather than 1fr: a tier name is typed in /admin, and a long
   one must wrap inside its column instead of widening the strip. */
.vip-medals {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(var(--n, 5), minmax(0, 1fr));
  gap: 18px;
  align-items: end;
  text-align: center;
}
.vip-medals li { display: grid; justify-items: center; gap: 10px; }
/* Grows with the tier, from `--i` on the item. Raising the middle one instead
   would say the middle tier is the best, which it is not. The hairline ring is
   what stops a pale tier dissolving into the white behind it. */
.vip-medal {
  width: calc(86px + var(--i, 0) * 9px);
  height: calc(86px + var(--i, 0) * 9px);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 34px;
  color: rgba(0, 0, 0, .3);
  background:
    radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .45) 0%, transparent 46%),
    conic-gradient(from 210deg, var(--c), rgba(255, 255, 255, .5), var(--c), rgba(0, 0, 0, .22), var(--c));
  box-shadow:
    0 6px 18px rgba(15, 22, 31, .16),
    inset 0 0 0 5px rgba(255, 255, 255, .35),
    0 0 0 1px rgba(15, 22, 31, .08);
  object-fit: contain;
}
.vip-medal.sm {
  width: 52px;
  height: 52px;
  font-size: 18px;
  box-shadow: 0 3px 8px rgba(15, 22, 31, .14), 0 0 0 1px rgba(15, 22, 31, .08);
}
/* Real artwork brings its own rim and its own shine, so the plate above has to
   get out of the way — a ring drawn over a medal that already has one reads as
   a mistake. The shadow moves to `filter`, which follows the cut-out circle
   instead of the element's box. Only the drawn plate keeps the CSS version. */
img.vip-medal {
  background: none;
  box-shadow: none;
  /* The artwork is a badge, not a disc — the wreath, the crown and the
     ribbon all stand outside the circle the plate is, and the round clip
     would take them off. */
  border-radius: 0;
  object-fit: contain;
  filter: drop-shadow(0 5px 12px rgba(15, 22, 31, .28));
}
img.vip-medal.sm { filter: drop-shadow(0 2px 5px rgba(15, 22, 31, .25)); }
.vip-medals b { font-size: 15px; font-weight: 500; color: var(--c-ink); }
.vip-medals em {
  font-style: normal;
  font-size: 20px;
  font-weight: 600;
  color: var(--c-ink);
  line-height: 1.3;
}

/* How it works */
.vip-journey { max-width: 900px; margin: 58px 0 0; }
.vip-journey h3 { font-size: 20px; font-weight: 600; margin: 0 0 18px; color: var(--c-ink); }
.vip-journey ol { margin: 0; padding-left: 20px; }
.vip-journey li { font-size: 14px; line-height: 2; color: var(--c-body); }
.vip-fine { font-size: 12.5px; line-height: 1.9; color: var(--c-muted); margin: 18px 0 0; }

/* Comparison table */
.vip-table-wrap { overflow-x: auto; }
.vip-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  min-width: 900px;
}
.vip-table th, .vip-table td { padding: 11px 14px; text-align: center; }
.vip-table thead th { padding: 6px 14px 20px; border-bottom: 1px solid var(--c-line); }
.vip-table thead th b { display: block; margin-top: 10px; font-size: 15px; font-weight: 600; color: var(--c-ink); }
.vip-table thead th .vip-medal { margin: 0 auto; }
.vip-table .lbl {
  text-align: left;
  font-weight: 400;
  color: var(--c-body);
  width: 32%;
  min-width: 260px;
}
.vip-table .lbl small { display: block; font-size: 12px; color: var(--c-muted); margin-top: 2px; }
.vip-table .lbl.sub { padding-left: 30px; color: var(--c-muted); }
.vip-table .lbl.sub::before { content: "–"; margin-left: -14px; padding-right: 6px; color: var(--c-faint); }
.vip-table tbody tr:nth-child(even) { background: var(--c-soft); }
.vip-table tbody tr.band { background: none; }
.vip-table tbody tr.band td {
  text-align: left;
  padding: 30px 14px 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--c-gold-ink);
}
.vip-table td { color: var(--c-ink); }
.vip-table td.off { color: var(--c-faint); }
.vip-table td .bi-check-lg { color: var(--c-green); font-size: 19px; }
/* The renewal row is the last thing read before committing, so it is the one
   the eye should land on as the table ends. */
.vip-table tbody tr:last-child { background: rgba(200, 162, 86, .14); }

/* FAQ, referral and the rewards teaser */
.vip-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
.vip-card {
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 30px 32px;
  scroll-margin-top: calc(var(--header-h) + 70px);
}
.vip-card:target { box-shadow: 0 0 0 1px rgba(200, 162, 86, .55), var(--shadow-card); }
.vip-card h3 { font-size: 19px; font-weight: 600; color: var(--c-gold-ink); margin: 0 0 18px; }
.vip-card details { border-bottom: 1px solid var(--c-line); }
.vip-card details:last-of-type { border-bottom: 0; }
.vip-card summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--c-ink);
}
.vip-card summary::-webkit-details-marker { display: none; }
.vip-card summary .chev { margin-left: auto; font-size: 12px; color: var(--c-muted); transition: transform .18s; }
.vip-card details[open] summary .chev { transform: rotate(180deg); }
.vip-card details p { font-size: 13.5px; line-height: 1.85; color: var(--c-body); margin: 0 0 16px; }
.vip-refer p { font-size: 14.5px; line-height: 1.85; color: var(--c-body); margin: 0 0 14px; }
.vip-refer .btn { margin-top: 10px; }

/* Closing call */
.vip-cta {
  margin-top: 70px;
  padding: 62px 0;
  text-align: center;
  background:
    radial-gradient(ellipse 700px 260px at 50% 100%, rgba(200, 162, 86, .22), transparent 70%),
    var(--c-soft);
  border-top: 1px solid var(--c-line);
}
.vip-cta h2 { font-size: 28px; font-weight: 600; margin: 0 0 12px; color: var(--c-ink); }
.vip-cta p { font-size: 15px; color: var(--c-body); margin: 0 0 24px; }

.acc-signout {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
  background: #fff;
  border-radius: var(--radius);
  padding: 13px;
  font-size: 14px;
  color: var(--c-body);
}
.acc-signout:hover { color: var(--c-red); }

/* --- Verification popups --------------------------------------------------
   Native <dialog>: the backdrop, Esc and focus trapping are the browser's job,
   so this file only has to dress the box. */
.vf {
  border: 0;
  padding: 0;
  border-radius: var(--radius-lg);
  width: min(420px, calc(100vw - 32px));
  box-shadow: 0 24px 60px rgba(9, 30, 66, .25);
}
.vf::backdrop { background: rgba(6, 20, 44, .55); }
.vf-box { padding: 26px 24px 22px; position: relative; }
.vf-box h3 { font-size: 18px; font-weight: 600; margin: 0 0 6px; padding-right: 24px; }
.vf-lead { font-size: 13px; color: var(--c-muted); line-height: 1.6; margin: 0 0 18px; }

.vf-x {
  position: absolute;
  top: 16px;
  right: 16px;
  border: 0;
  background: none;
  font-size: 15px;
  color: var(--c-muted);
  cursor: pointer;
  line-height: 1;
}
.vf-x:hover { color: var(--c-ink); }

.vf-lbl { display: block; font-size: 13px; color: var(--c-body); margin: 0 0 6px; }
.vf-box input, .vf-box select {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  background: #fff;
  font-size: 14px;
  margin-bottom: 16px;
}
.vf-box input[readonly] { background: var(--c-soft); color: var(--c-muted); }
.vf-row { display: flex; gap: 8px; align-items: start; }
.vf-row input, .vf-row select { flex: 1; margin-bottom: 0; }
.vf-row { margin-bottom: 16px; }
.vf-send {
  flex: 0 0 auto;
  padding: 9px 20px;
  border: 0;
  border-radius: var(--radius);
  background: var(--c-blue-mid);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.vf-help { font-size: 12px; color: var(--c-muted); margin: -6px 0 16px; line-height: 1.6; }
.vf-help a { color: var(--c-orange); }

/* Says why the buttons do nothing. Without it a dead Submit reads as a bug. */
.vf-locked {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 12px;
  line-height: 1.6;
  color: #8a6d1f;
  background: #fdf6e3;
  border-radius: var(--radius);
  padding: 10px 12px;
  margin: 0 0 18px;
}
.vf-locked i { margin-top: 2px; }

.vf-acts { display: flex; gap: 10px; }
.vf-acts .btn { flex: 1; justify-content: center; padding: 10px; font-size: 14px; }
/* Bootstrap ships `.btn:disabled { background-color: var(--bs-btn-disabled-bg) }`,
   which outranks `.btn-orange` and leaves a locked Submit with no fill at all.
   Restate the colour so a disabled button still reads as a button. */
.vf-acts .btn-orange,
.vf-acts .btn-orange:disabled {
  background: linear-gradient(135deg, var(--c-logo-orange-lit), var(--c-logo-orange-deep));
  color: #fff;
}
.vf-acts .btn:disabled, .vf-send:disabled { opacity: .5; cursor: not-allowed; }

/* Date-of-birth popup ------------------------------------------------------ */
.vf-dob { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 10px; }
.vf-dob select { margin-bottom: 18px; }
.vf-err {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 13px;
  line-height: 1.6;
  color: var(--c-red);
  background: #fdecec;
  border-radius: var(--radius);
  padding: 10px 12px;
  margin: 0 0 16px;
}

/* What finishing the bank popup is worth, said inside the popup. The same
   shape as .vf-err and .vf-locked beside it, in the colour of a reward rather
   than a warning. */
.vf-prize {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 12.5px;
  line-height: 1.6;
  color: #1b7a42;
  background: #e8f6ed;
  border-radius: var(--radius);
  padding: 10px 12px;
  margin: 0 0 18px;
}
.vf-prize i { margin-top: 2px; }

/* --- 實名認證彩金 popup ------------------------------------------------------
   The free 18: offered, then paid. The same <dialog> furniture as the
   verification popups above, arranged differently because this one is an offer
   rather than a form — centred, the figure first, and it opens itself. */
.vb {
  border: 0;
  padding: 0;
  border-radius: var(--radius-lg);
  width: min(360px, calc(100vw - 32px));
  box-shadow: 0 24px 60px rgba(9, 30, 66, .25);
}
.vb::backdrop { background: rgba(6, 20, 44, .6); }
.vb-box { position: relative; padding: 30px 24px 22px; text-align: center; }
.vb-box h3 { font-size: 17px; font-weight: 600; margin: 0 0 8px; padding: 0 14px; }
.vb-lead { font-size: 13px; color: var(--c-muted); line-height: 1.65; margin: 0 0 20px; }

.vb-x {
  position: absolute;
  top: 14px;
  right: 14px;
  border: 0;
  background: none;
  font-size: 14px;
  color: var(--c-muted);
  cursor: pointer;
  line-height: 1;
}
.vb-x:hover { color: var(--c-ink); }

/* The mark, and the figure under it. A bonus is a number before it is a
   sentence, so the number is the biggest thing in the box. */
.vb-mark {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  margin: 0 auto 14px;
  font-size: 24px;
  color: #fff;
}
.vb-mark.bad { background: var(--c-red); }

.vb-amt {
  font-size: 30px;
  font-weight: 700;
  line-height: 1.15;
  margin: 0 0 10px;
}

.vb-acts { display: flex; gap: 10px; margin: 0; }
.vb-acts .btn { flex: 1; justify-content: center; padding: 11px; font-size: 14px; }
.vb-mark { background: linear-gradient(135deg, var(--c-logo-orange-lit), var(--c-logo-orange-deep)); }
.vb-amt {
  background: linear-gradient(135deg, var(--c-logo-orange-lit), var(--c-logo-orange-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Bootstrap's `.btn:disabled` rule outranks `.btn-orange`, exactly as it does
   in .vf-acts — restate the fill so the button always reads as one. */
.vb-acts .btn-orange {
  background: linear-gradient(135deg, var(--c-logo-orange-lit), var(--c-logo-orange-deep));
  color: #fff;
}
/* Confirmation above the profile card after a save. */
.acc-note {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  border-radius: var(--radius);
  padding: 11px 15px;
  margin-bottom: 14px;
}
.acc-note.ok  { background: #e8f6ed; color: #1b7a42; }
.acc-note.err { background: #fdecec; color: #b3243d; }

/* Deposit: the steps that only appear once something is chosen ------------- */
.dep-hint {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--c-muted);
  background: var(--c-soft);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 16px 0 0;
}
.dep-hint i { font-size: 18px; }
.dep-amount-hint { font-size: 12px; color: var(--c-red); margin: 6px 0 0; }
/* IDR: the box is typed in thousands — "1 = 1,000 IDR" beside the label. */
.dep-unit { display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; font-style: normal; color: var(--c-orange, #f5a623); border: 1px solid currentColor; vertical-align: middle; }
/* The tiles are labels now, so the radio inside must not take up space. */
.opt-card { cursor: pointer; }
.opt-card .bank-logo, .m-opt .bank-logo { width: 48px; height: 48px; object-fit: contain; }
.dep-sender { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.dep-add {
  width: 44px;
  height: 44px;
  border: 1px dashed var(--c-line);
  border-radius: var(--radius);
  display: grid;
  place-items: center;
  font-size: 20px;
  color: var(--c-muted);
}
.dep-add:hover { border-color: var(--c-blue-mid); color: var(--c-blue-mid); }
/* Without scripting the whole form is shown rather than a dead end. */

/* Deposit Bank Account — the account a Bank Transfer is paid into ---------- */
.pay-to { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 4px; }
.pay-field { position: relative; }
.pay-field .form-control { padding-right: 44px; background: var(--c-soft); }
.pay-copy {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: var(--c-blue-mid);
  font-size: 16px;
  cursor: pointer;
}
.pay-copy:hover { color: var(--c-blue-light); }
/* A tick for a moment, so a silent clipboard write is visibly a write. */
.pay-copy.copied { color: var(--c-green); }
.pay-copy.copied i::before { content: '\f26e'; }

/* A readonly field on the withdrawal form: it looks filled in rather than
   typed into, and says why underneath. */
.side-form input[readonly] { background: var(--c-soft); color: var(--c-muted); }
/* .side-form > div is a two-column grid (label | field), so a third child
   would land back under the label. Put the note in the field column. */
.side-note {
  grid-column: 2;
  display: block;
  font-size: 12px;
  color: var(--c-muted);
  margin-top: -4px;
  line-height: 1.5;
}

/* --- Confirm dialog -------------------------------------------------------
   Replaces the browser's confirm(): that one cannot be styled, announces the
   origin, and reads like a security warning rather than a question about the
   thing the reader just clicked. */
.cf {
  border: 0;
  padding: 0;
  border-radius: var(--radius-lg);
  width: min(380px, calc(100vw - 32px));
  box-shadow: 0 24px 60px rgba(9, 30, 66, .28);
}
.cf::backdrop { background: rgba(6, 20, 44, .55); }
.cf-box { padding: 28px 26px 22px; text-align: center; }
.cf-icon {
  width: 54px;
  height: 54px;
  margin: 0 auto 16px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 26px;
  background: #fff4e5;
  color: var(--c-orange);
}
.cf-box h3 { font-size: 17px; font-weight: 600; margin: 0 0 8px; }
.cf-box p { font-size: 14px; color: var(--c-muted); line-height: 1.6; margin: 0 0 22px; }
.cf-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cf-btn {
  padding: 11px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
.cf-btn.ghost { background: #fff; border-color: var(--c-line); color: var(--c-body); }
.cf-btn.ghost:hover { border-color: var(--c-muted); }
.cf-btn.go { background: var(--c-orange); color: #fff; }
.cf-btn.go:hover { filter: brightness(1.06); }
/* Destructive actions say so in the button, not just in the sentence. */
.cf-btn.go.danger { background: var(--c-red); }

/* Withdraw: a saved account tile carries its number under the bank name. */
.opt-card .wd-acct { display: block; font-size: 11px; color: var(--c-faint); margin-top: 2px; }
/* The two filled-in fields are shown, not typed into. */
.acc-filter input[readonly] { background: var(--c-soft); color: var(--c-muted); }
/* The saved-account table's logo, at row height. */
.bank-logo.sm { width: 26px; height: 26px; object-fit: contain; vertical-align: middle; margin-right: 8px; }

/* Receipt upload — optional, and the chosen filename is echoed by hand
   because the real input is hidden inside a label. */
.upload-note .opt, .text-muted-2 .opt { color: var(--c-faint); }
.dep-file { font-size: 12px; color: var(--c-muted); word-break: break-all; }

/* Referral invitation popup ------------------------------------------------
   Opened by the code chip on the referral card. Wide and quiet: the whole
   point is a block of text somebody is about to copy into a chat. */
.rf {
  border: 0;
  padding: 0;
  border-radius: var(--radius-lg);
  width: min(620px, calc(100vw - 60px));
  box-shadow: 0 24px 60px rgba(9, 30, 66, .25);
  /* The close button hangs off the corner, and a dialog scrolls by default —
     without this it earns a scrollbar instead of letting the button out. */
  overflow: visible;
}
.rf::backdrop { background: rgba(6, 20, 44, .55); }
.rf-box { padding: 40px 38px 30px; position: relative; text-align: center; }
.rf-x {
  position: absolute;
  top: -14px;
  right: -14px;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: #fff;
  color: var(--c-muted);
  box-shadow: 0 4px 14px rgba(9, 30, 66, .18);
}
.rf-msg { font-size: 16px; color: var(--c-ink); line-height: 1.7; margin: 0 0 22px; }
/* The link wraps rather than stretching the dialog — a referral code is short
   but the host in front of it does not have to be. */
.rf-link {
  display: block;
  font-size: 15px;
  color: var(--c-blue-light);
  word-break: break-all;
  margin-bottom: 26px;
}
.rf-acts { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; }
.rf-copy, .rf-ok {
  border: 0;
  border-radius: var(--radius-sm);
  height: 44px;
  padding: 0 34px;
  font-size: 15px;
}
.rf-copy { background: var(--c-soft); color: var(--c-body); }
.rf-copy.copied { background: #e8f6ed; color: #1b7a42; }
.rf-ok { background: var(--c-blue-mid); color: #fff; }

/* The code chip is a button now, so it has to give back what a <button>
   takes away — it was an <a> when the card only linked somewhere. */
.acc-referral .code, .m-referral .code { width: 100%; border: 0; text-align: left; font: inherit; cursor: pointer; }

/* Message reader ------------------------------------------------------------
   Wide and plain: the body is written by an operator and can be long, so the
   dialog gets out of its way and scrolls rather than clipping. */
.msgv {
  border: 0;
  padding: 0;
  border-radius: var(--radius-lg);
  width: min(760px, calc(100vw - 32px));
  max-height: calc(100vh - 60px);
  box-shadow: 0 24px 60px rgba(9, 30, 66, .25);
  overflow: visible;
}
.msgv::backdrop { background: rgba(6, 20, 44, .55); }
.msgv-box {
  position: relative;
  padding: 28px 32px 30px;
  max-height: calc(100vh - 60px);
  overflow-y: auto;
  border-radius: var(--radius-lg);
}
.msgv-x {
  position: absolute;
  top: -14px;
  right: -14px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #fff;
  color: var(--c-muted);
  box-shadow: 0 4px 14px rgba(9, 30, 66, .18);
  display: grid;
  place-items: center;
  /* The scrolling box is painted after it in the DOM and would swallow the
     clicks otherwise. */
  z-index: 1;
}
.msgv-box h3 { font-size: 18px; font-weight: 600; line-height: 1.5; margin: 0 0 6px; padding-right: 20px; }
.msgv-date { font-size: 12px; color: var(--c-faint); padding-bottom: 16px; border-bottom: 1px solid var(--c-line); }
/* The body is the operator's own markup, so it is given room rather than a
   house style — only the things that would break the dialog are constrained. */
.msgv-body { font-size: 15px; line-height: 1.75; color: var(--c-ink); padding-top: 20px; }
.msgv-body p { margin: 0 0 14px; }
.msgv-body a { color: var(--c-blue-light); text-decoration: underline; }
.msgv-body img { max-width: 100%; height: auto; }
.msgv-body table { width: 100%; border-collapse: collapse; }
.msgv-body td, .msgv-body th { border: 1px solid var(--c-line); padding: 6px 10px; }
.msgv-body hr { border: 0; border-top: 1px solid var(--c-line); margin: 22px 0; }
/* The toolbar's two actions post now; they were styled as <span>s. */
.msg-toolbar .right button {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--c-muted);
  cursor: pointer;
}
.msg-toolbar .right button:hover { color: var(--c-blue-mid); }
.acc-table td.subj a { color: inherit; }
.acc-table td.subj a:hover { color: var(--c-blue-mid); }
.acc-table .row-acts button { border: 0; background: none; padding: 0; color: inherit; cursor: pointer; }
.acc-table .row-acts button:hover { color: var(--c-red); }

/* Game cards that enter a game are links, and must not read as one. The
   provider bar and the category tabs above them only filter this grid. */
.game-card.play { display: block; text-decoration: none; color: inherit; }
.game-card.play:hover .thumb { filter: brightness(1.06); }
.game-card.play:hover .name b { color: var(--c-orange); }

/* A card with the platform's own picture instead of a gradient plate.

   **`contain`, not `cover`: a game's artwork is never cropped.** The two
   shapes in the catalogue are the vendors' 4:3 (480x360, what
   GAME_IMAGE_BOX still names) and square — an operator's own upload is kept
   at whatever size it arrived, so both are in the same grid. `cover` filled
   the box by cutting the picture, and what it cut off a live-casino photo
   was the dealer's head.

   **No ground of its own**, so a picture with transparency keeps it and the
   band a mismatched shape leaves is the card's own background rather than a
   plate drawn behind the artwork. */
.thumb.has-img { overflow: hidden; }
.thumb.has-img img { width: 100%; height: 100%; object-fit: contain; display: block; border-radius: inherit; }

/* Filtered out by the provider bar or the category tabs. */
[data-game-grid] > [hidden], [data-top-rail] > [hidden] { display: none; }
.grid-empty { padding: 60px 0; }

/* The chip of a platform under maintenance reads as unavailable without
   disappearing — hiding it is what the Hidden switch is for. */
.provider-chip.maint { opacity: .6; }

/* A tile that enters a game is a link, same as a game card. */
.tile-card.play { display: block; text-decoration: none; color: inherit; }
.tile-card.play:hover .thumb { filter: brightness(1.06); }
.tile-card.play:hover .name { color: var(--c-orange); }

/* Balance refresh ----------------------------------------------------------
   The button drops in wherever a balance is printed — the header strip, the
   two account cards, the withdraw tiles, the line under the amount box — so it
   carries no look of its own. It strips the browser's button furniture and
   inherits, which leaves the rules already written for `.amt i`, `.n i` and
   the rest to size and colour the icon exactly as they did when it was a bare
   <i> with nothing behind it. */
.bal-sync {
  border: 0;
  background: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  line-height: 1;
  vertical-align: baseline;
  cursor: pointer;
}

/* The figure's wrapper is only somewhere for the script to write. `<b>` is
   what it is — a wrapper that cannot be confused with the `<span>` these
   layouts already use for the currency code — and this takes the bold back
   off, so the number weighs what the plain text it replaced weighed. Any card
   that means its figure to be bold says so in its own rule, which is more
   specific than this one and wins. */
b[data-bal] { font-weight: inherit; }

/* Turning while the request is in flight, dimmed while the cooldown runs.
   Both are on the button rather than a wrapper so the mobile card's own
   refresh button gets them without inheriting anything else. */
[data-bal-sync][data-busy] i { display: inline-block; animation: bal-spin .8s linear infinite; }
[data-bal-sync]:disabled { opacity: .4; cursor: default; }
@keyframes bal-spin { to { transform: rotate(360deg); } }

/* Opening a game -----------------------------------------------------------
   Covers the gap between tapping a card and the platform handing back a URL —
   see the handler in the script for why that gap is half a second to a second
   before the game's own domain even starts loading.

   **It has to actually block.** A translucent sheet that let taps through
   would look like feedback and change nothing, which was the whole complaint:
   the second tap starts a second launch. `inset: 0` over everything, and the
   body loses its scroll so the list underneath cannot be moved either. */
.game-loading {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: grid;
  place-items: center;
  background: rgba(8, 16, 30, .72);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  /* The one thing a player may still do is leave. */
  cursor: wait;
}
.game-loading[hidden] { display: none; }
body.game-loading-on { overflow: hidden; }

.game-loading .gl-box {
  text-align: center;
  padding: 0 28px;
  max-width: 320px;
}

/* A ring rather than a graphic: no image to load at the exact moment the
   network is already busy fetching a game. */
.game-loading .gl-spin {
  width: 46px;
  height: 46px;
  margin: 0 auto 18px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .22);
  border-top-color: #fff;
  animation: gl-spin .8s linear infinite;
}
@keyframes gl-spin { to { transform: rotate(360deg); } }

.game-loading .gl-name {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 600;
  color: #fff;
  line-height: 1.35;
}
/* No game name on the card — the hint carries it alone rather than leaving a
   gap where a title would have been. */
.game-loading .gl-name:empty { display: none; }

.game-loading .gl-hint {
  margin: 0;
  font-size: 13px;
  color: rgba(255, 255, 255, .72);
  line-height: 1.5;
}

/* A player who has asked their browser not to animate still needs to see that
   something is happening, so the ring stays and only stops turning. */
@media (prefers-reduced-motion: reduce) {
  .game-loading .gl-spin { animation: none; border-top-color: rgba(255, 255, 255, .8); }
}

/* --- Play or Demo ---------------------------------------------------------
   The same ground as the loading overlay above and deliberately so: they are
   two steps of one action, and a player who has just tapped a card should see
   the page dim once, not twice in two different colours. The cursor is the
   difference — this one is asking a question, so it is not `wait`. */
.game-pick {
  position: fixed;
  inset: 0;
  z-index: 3010;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(8, 16, 30, .72);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
.game-pick[hidden] { display: none; }
body.game-pick-on { overflow: hidden; }

.game-pick .gp-box {
  position: relative;
  width: 100%;
  max-width: 330px;
  padding: 22px 22px 22px;
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: 0 24px 60px rgba(6, 12, 24, .4);
  text-align: center;
}
/* The game's own picture, at the shape the grids draw it. `object-fit`
   rather than a fixed height: the catalogue's artwork is 4:3 from some
   vendors and square from others, and a letterboxed tile reads as a
   loading error. */
.game-pick .gp-art {
  width: 100%;
  aspect-ratio: 4 / 3;
  margin: 0 0 20px;
  border-radius: var(--radius);
  overflow: hidden;
}
/* The ground shows only while the picture loads — and **not** when the
   plate is on, or this rule's two classes would out-specify `.art`'s one
   and every game with no artwork would be a grey box. */
.game-pick .gp-art:not(.art) { background: var(--c-soft); }
.game-pick .gp-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* A game with no artwork keeps the plate its card wears — see gpPaint(). */
.game-pick .gp-art.art::after { font-size: 13px; }

/* Two equal buttons, side by side: neither choice is the small print. Play
   carries the site's own call-to-action colour and Demo is the quiet one — the
   difference in weight is the only thing saying which is the real game. */
.game-pick .gp-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.game-pick .gp-btn {
  display: block;
  padding: 12px 10px;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  transition: filter .15s, background .15s, color .15s;
}
/* The logo's own orange, declared here the way every other confirm button
   on this site declares it — the `--cta-*` pair is set on the rule that
   uses it, not inherited from :root. */
.game-pick .gp-play {
  --cta-a: var(--c-logo-orange-lit);
  --cta-b: var(--c-logo-orange-deep);
  background: linear-gradient(135deg, var(--cta-a), var(--cta-b));
  box-shadow: 0 4px 10px rgba(182, 72, 55, .26);
  color: #fff;
}
.game-pick .gp-play:hover { color: #fff; filter: brightness(1.08); }
.game-pick .gp-demo {
  background: var(--c-soft);
  color: var(--c-ink);
  box-shadow: inset 0 0 0 1px var(--c-line);
}
.game-pick .gp-demo:hover { background: #e9edf3; color: var(--c-ink); }

/* The X sits **on** the picture, so it cannot be a grey glyph on white — the
   artwork behind it is a different colour on every game. A dark disc reads
   over all of them. */
.game-pick .gp-x {
  position: absolute;
  top: 30px;
  right: 30px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(10, 16, 28, .55);
  color: #fff;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  transition: background .15s;
}
.game-pick .gp-x:hover { background: rgba(10, 16, 28, .8); color: #fff; }

/* --- Registration, in two steps --------------------------------------------
   The account is not created until the second panel has been filled in, so the
   two are one form and one POST — see inc/register-post.php. The panels are
   plain divs the script toggles with `hidden`; **without JavaScript both are
   visible and the single Create Account button submits all of it**, which is
   the whole reason nothing here hides a panel by class.

   `[hidden]` is spelled out because a `display` rule further up the file would
   otherwise win against the browser's own default for the attribute. */
[data-reg-panel][hidden] { display: none; }

.reg-steps {
  display: flex;
  gap: 10px;
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  counter-reset: none;
}
.reg-steps li {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--c-muted);
  padding-top: 9px;
  border-top: 3px solid var(--c-line);
}
.reg-steps li em {
  flex: none;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--c-line);
  color: #fff;
  font-style: normal;
  font-size: 11px;
  font-weight: 600;
}
/* Both dots are lit on the second panel — the first step is done, not
   abandoned. `.now` is the one being filled in. */
.reg-steps li.on { border-top-color: var(--c-orange); color: var(--c-body); }
.reg-steps li.on em { background: var(--c-orange); }
.reg-steps li.now { font-weight: 600; }

/* 實名制. Amber rather than red: it is a condition of the form, not an error
   in it, and the member has not done anything wrong yet. */
.reg-note {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin: 4px 0 0;
  padding: 11px 12px;
  border: 1px solid #f0c98a;
  border-radius: var(--radius-sm, 6px);
  background: #fff8ec;
  color: #7a4c07;
  font-size: 12.5px;
  line-height: 1.65;
}
.reg-note i { flex: none; font-size: 14px; line-height: 1.35; }

/* 上一步 is a way back, not a second thing to press — it reads as text under
   the button that finishes the form. */
.reg-back {
  display: block;
  width: 100%;
  margin-top: 10px;
  background: none;
  border: 0;
  color: var(--c-muted);
  font-size: 13px;
  text-decoration: underline;
}
.reg-back:hover { color: var(--c-body); }

/* The registration account on Withdrawal Details: a lock where the 移除 button
   is on every other row. 實名制 — see sql/migrate-member-bank-locked.sql. */
.bank-locked { color: var(--c-muted); font-size: 14px; display: inline-block; padding: 4px; }

/* --- 分享邀請詞 --------------------------------------------------------------
   The 分享 button beside Copy on the referral page and inside the invite
   popup, and the menu it opens: Copy, then the six networks.

   **A menu rather than a row of six icons.** The invitation is sent once, to
   one friend, in one app — six always-on buttons would be five wrong answers
   sitting next to the right one, in exactly the place the member is trying to
   do one thing. It is what the reference does, for the same reason. */
.rmb-acts { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.shr { position: relative; }
.shr-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--c-line);
  background: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 18px;
  font-size: 13px;
  color: var(--c-body);
  cursor: pointer;
  white-space: nowrap;
}
.shr-toggle:hover { border-color: var(--c-blue-light); color: var(--c-blue-mid); }
/* Open reads as pressed, so it is obvious which button the menu belongs to. */
.shr.open .shr-toggle { border-color: var(--c-blue-light); color: var(--c-blue-mid); background: var(--c-soft); }

/* Closed by `display:none` rather than `hidden` on the element, so one class on
   `.shr` opens and closes it and the script never touches the menu itself. */
.shr-menu {
  display: none;
  position: absolute;
  z-index: 40;
  top: calc(100% + 8px);
  right: 0;
  min-width: 190px;
  padding: 6px;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: 12px;
  box-shadow: 0 12px 30px rgba(23, 43, 77, .16);
  text-align: left;
}
.shr.open .shr-menu { display: block; }

.shr-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  font-size: 13.5px;
  color: var(--c-ink);
  text-decoration: none;
  cursor: pointer;
  text-align: left;
}
.shr-item:hover { background: var(--c-soft); color: var(--c-ink); }
/* One column of icons: the labels have to start on the same x or the menu
   reads as a pile rather than a list. */
.shr-ico { flex: none; width: 18px; font-size: 16px; text-align: center; }
/* The tick `[data-copy]` gives every other copy on the site. */
.shr-item.copied { background: #e8f6ed; color: #1b7a42; }
.shr-item.copied .shr-ico { color: #1b7a42; }
.shr-item.copied .shr-ico::before { content: '\f26e'; }

/* Inside the invite popup the menu opens **upwards**: the dialog ends a few
   pixels under the button row, and a menu dropping out of the bottom of it
   would be cut off or push the page behind it around. */
.rf-acts .shr-menu { top: auto; bottom: calc(100% + 8px); right: auto; left: 50%; transform: translateX(-50%); }
.rf-acts .shr-toggle { height: 44px; border-radius: var(--radius-sm); padding: 0 22px; }

/* Narrow: Copy and 分享 sit side by side under the message and share the row,
   which is the same rule `.ref-msg-box` already follows at this width. */
@media (max-width: 575.98px) {
  .ref-msg-box .rmb-acts { width: 100%; }
  .ref-msg-box .rmb-acts .rmb-copy,
  .ref-msg-box .rmb-acts .shr { flex: 1 1 0; }
  .ref-msg-box .rmb-acts .shr-toggle { width: 100%; justify-content: center; }
}

/* --- 首頁彈窗 -----------------------------------------------------------
   The operator's popup over the home page: artwork, a line or two under it,
   and a cross. Managed per country and per language — see admin/home-popup.php.

   The <dialog> itself is only the frame: .hp-box is the white card and the
   cross sits *under* it on the backdrop, so nothing is ever drawn over the
   artwork. That is why the dialog has no background and `overflow: visible`. */
.hp {
  border: 0;
  padding: 0;
  background: none;
  overflow: visible;
  width: min(560px, calc(100vw - 32px));
}
.hp::backdrop { background: rgba(6, 20, 44, .68); }

/* **The frame.** The artwork does not bleed to the card's edge — it sits inset
   in white, which is what makes the popup read as a mounted picture rather than
   a banner with a caption bolted under it. The padding is the frame, and it is
   why the picture carries a radius of its own below. */
.hp-box {
  background: #fff;
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px rgba(9, 30, 66, .3);
  padding: 16px;
}

/* **The slideshow.** One entry draws no track worth the name and no dots; two
   or more rotate on the same script the hero uses, and the wording rides inside
   its own slide so picture and words can never come apart.

   `.hp-view` is the window the track slides behind, and it carries the picture's
   radius because it is now the thing doing the clipping. The dots sit *outside*
   it, in the flow under the card's contents — over the artwork they would be a
   corner the operator's designer has to leave free, which is the same reason
   the cross is on the backdrop. */
.hp-slider { position: relative; }
.hp-view { overflow: hidden; border-radius: 9px; }
.hp-track { display: flex; will-change: transform; }
/* `min-width: 0` beside the basis: a bare `flex: 0 0 100%` still floors at the
   content width, and one long unbroken line of wording would push its slide
   wider than the card. */
.hp-slide { flex: 0 0 100%; min-width: 0; }

.hp-dots {
  display: flex;
  justify-content: center;
  gap: 7px;
  margin: 14px 0 2px;
}
.hp-dots button {
  width: 7px;
  height: 7px;
  border: 0;
  border-radius: 7px;
  padding: 0;
  cursor: pointer;
  background: rgba(9, 30, 66, .22);
  transition: width .2s ease;
}
.hp-dots button.active { width: 20px; background: var(--c-orange); }

/* **The whole picture, always.** The upload was already scaled to fit its
   1800×760 box and padded by media_store(), so `height: auto` here draws every
   pixel of it at whatever width the card has. There is deliberately no
   `object-fit: cover` on this: nothing may be cropped.

   `overflow: hidden` is on this box and not on the card: the radius that has to
   clip something is the picture's — and with a slideshow it is `.hp-view` above
   that does the clipping, so this radius only has to match it. */
.hp-art { display: block; border-radius: 9px; overflow: hidden; }
.hp-art img { display: block; width: 100%; height: auto; }

/* The wording is a statement, not small print — dark and semi-bold, the way the
   client's reference has it. `margin` rather than padding so that a popup with
   no wording at all closes up to an even frame on all four sides. */
.hp-text {
  margin: 22px 6px 8px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.6;
  color: var(--c-ink);
  text-align: center;
}

.hp-x {
  display: block;
  margin: 16px auto 0;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .45);
  background: rgba(255, 255, 255, .12);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.hp-x:hover { background: rgba(255, 255, 255, .26); }

/* --- Referral QR ---------------------------------------------------------
   The referral link as a QR with the site favicon on the middle. The box is
   set from the caller (`--qr-size` on the wrapper) so the canvas, the CSS
   frame and the downloaded PNG are the same figure. Level H reserves ~30% of
   the code, and the logo covers ~22% of the width — inside the reserve, so
   the code still scans.
--- */
.ref-qr-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-top: 18px; }
.ref-qr-hint { font-size: 12px; color: var(--c-body); margin: 0; text-align: center; }
.ref-qr { display: inline-flex; flex-direction: column; align-items: center; gap: 10px; }
.ref-qr-box { position: relative; width: var(--qr-size, 200px); height: var(--qr-size, 200px);
  background: #fff; border-radius: 14px; padding: 10px; box-sizing: border-box;
  box-shadow: 0 4px 18px rgba(15, 23, 42, .10); border: 1px solid var(--c-line, #e5eaf1); }
.ref-qr-box canvas { width: 100% !important; height: 100% !important; display: block; border-radius: 8px; background: #fff; }
.ref-qr-logo { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 22%; height: 22%; padding: 4px; background: #fff; border-radius: 10px;
  box-shadow: 0 1px 4px rgba(15, 23, 42, .18); box-sizing: border-box; object-fit: contain; }
.ref-qr-dl { display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: var(--radius-pill, 999px);
  border: 1px solid var(--c-line, #e5eaf1); background: #fff; color: var(--c-body, #475569);
  font-size: 12px; cursor: pointer; }
.ref-qr-dl:hover { border-color: var(--c-blue-light, #93c5fd); color: var(--c-blue-mid, #2563eb); }
/* Inside the invite popup the QR sits above the link. */
.rf-qr { display: flex; justify-content: center; margin: 0 0 18px; }
.rf-qr .ref-qr-box { --qr-size: 180px; width: 180px; height: 180px; }
