/* Phone history — reached from the profile menu's Histories ▸ Phone
   history link. Same page chrome/palette as transfer-money.css. */
:root{
  --blue-dark:#0f3d28;
  --blue-mid:#1f7a52;
  --blue-bright:#27935f;
  --accent-orange:#f39c1f;
  --header-blue:#0d3322;
}

html,body{height:100%;}
body{background:#eef5f2;display:flex;flex-direction:column;min-height:100vh;}

.ph-layout{
  flex:1 0 auto;
  max-width:1560px;
  margin:0 auto;
  padding:32px 16px 60px;
  width:100%;
  display:flex;
  align-items:flex-start;
  gap:24px;
  flex-wrap:wrap;
}

/* Match the header's edge-to-edge horizontal inset on mobile (see
   header.css .site-header) so the page content lines up flush with it
   instead of sitting inset relative to it. Also covers mail-history.html,
   which reuses this file/class. */
@media (max-width:860px){
  .ph-layout{padding-left:4px;padding-right:4px;}
  .ph-filter-grid--4{grid-template-columns:repeat(2, 1fr);}
  /* .ph-layout is a wrapping flex row: .service-panel (Numbers/E-mail's +
     Select service/country) comes first in the DOM, .ph-content (the
     "Phone history activations" title/tabs/subnav) second — fine side by
     side on desktop, but once they stack into one column on mobile that
     puts the page's own title and status tabs below the entire service
     picker. Flex `order` swaps the visual stacking without touching the
     DOM/source order (so screen readers etc. are unaffected), and only
     inside this breakpoint — desktop's side-by-side layout never sees it. */
  .ph-content{order:1;}
  .service-panel{order:2;}
}

.ph-content{flex:1 1 600px;min-width:0;}

.breadcrumb{
  font-size:13px;
  font-weight:500;
  color:#9fc7b4;
  margin:0 0 10px;
}
.breadcrumb a{color:#9fc7b4;text-decoration:none;}
.breadcrumb a:hover{color:var(--blue-mid);}

.ph-title-row{
  display:flex;
  align-items:center;
  gap:12px;
  margin:0 0 26px;
}
.ph-title-row svg{width:34px;height:34px;flex-shrink:0;color:var(--accent-orange);}
.ph-title{
  margin:0;
  font-family:var(--font-heading);
  font-size:32px;
  font-weight:700;
  letter-spacing:.3px;
  text-transform:uppercase;
  color:var(--blue-dark);
}

.ph-tabs{
  display:flex;
  gap:10px;
  margin:0 0 22px;
}
.ph-tab{
  position:relative;
  padding:11px 26px;
  border-radius:999px;
  font-weight:500;
  font-size:14px;
  font-family:inherit;
  cursor:pointer;
  text-decoration:none;
  transition:background .16s ease, color .16s ease, border-color .16s ease;
}
.ph-tab-badge{
  position:absolute;
  top:-6px;
  right:-6px;
  min-width:18px;
  height:18px;
  padding:0 4px;
  border-radius:999px;
  background:#e6462f;
  color:#fff;
  font-size:11px;
  font-weight:700;
  line-height:18px;
  text-align:center;
  box-shadow:0 0 0 2px #fff;
}
.ph-tab--solid{
  border:1.5px solid var(--blue-mid);
  background:var(--blue-mid);
  color:#fff;
}
.ph-tab--outline{
  border:1.5px solid #cfe9dc;
  background:#fff;
  color:var(--blue-mid);
}
.ph-tab--outline:hover{background:#eafaf2;}

.ph-subnav{
  display:flex;
  gap:26px;
  border-bottom:1.5px solid #cfe9dc;
  margin:0 0 30px;
}
.ph-subnav-item{
  position:relative;
  padding:0 2px 12px;
  border:none;
  background:none;
  font-family:inherit;
  font-weight:500;
  font-size:13.5px;
  color:var(--blue-mid);
  cursor:pointer;
}
.ph-subnav-item::after{
  content:'';
  position:absolute;
  left:0;right:0;bottom:-1.5px;
  height:2.5px;
  background:transparent;
  border-radius:2px;
}
.ph-subnav-item.active{color:var(--accent-orange);}
.ph-subnav-item.active::after{background:var(--accent-orange);}
.ph-subnav-item:not(.active):hover{color:var(--blue-dark);}

.ph-status-wrap:not([hidden]){display:flex;justify-content:center;margin-bottom:22px;}
.ph-status{
  padding:14px 26px;
  border:1.5px solid #cfe9dc;
  border-radius:14px;
  background:#fff;
  color:var(--blue-dark);
  font-weight:400;
  font-size:13px;
  letter-spacing:.3px;
  text-transform:uppercase;
  text-align:center;
}

/* ============ Order cards (Waiting/Paid/Canceled single-status views) ============ */
.ph-orders{display:flex;flex-direction:column;gap:18px;margin-bottom:26px;}
/* JS sets the `hidden` property when switching to "All phone activations",
   but an element's own `display:flex` always beats the browser's default
   [hidden]{display:none} rule (author CSS outranks the user-agent
   stylesheet regardless of specificity) — without this override, the
   previous tab's card stays stuck on screen, stacked above the table. */
.ph-orders[hidden]{display:none;}

.ph-order-card{
  background:#d7ede6;
  border:1.5px solid #a7dcc4;
  border-radius:20px;
  overflow:hidden;
  box-shadow:0 16px 36px -22px rgba(0,27,92,.4), 0 2px 10px -6px rgba(0,0,0,.06);
}

/* A two-row CSS Grid forms the card's main frame: service+number and
   Cancel each span both rows (full-height dividers on either side), while
   Status/Time share row 1 (a divider between just the two of them) and
   Price spans both their columns in row 2 — centered between them, with
   no vertical divider running through it. All real cell borders, not
   hand-drawn lines. */
.ph-order-grid{
  display:grid;
  grid-template-columns:1.7fr 1fr 1fr auto;
  grid-template-rows:auto auto;
  background:#d7ede6;
  border:1.5px solid #a7dcc4;
  border-top-left-radius:19px;
  border-top-right-radius:19px;
}
.ph-order-cell{
  padding:16px 20px;
  display:flex;
  flex-direction:column;
  justify-content:center;
}

.ph-order-cell--info{
  grid-column:1;
  grid-row:1 / 3;
  border-right:1px solid #a7dcc4;
  flex-direction:row;
  align-items:stretch;
  padding:0;
  gap:0;
}
/* Shared with mail-history.js's card head, which has no flag/connector —
   just wraps its single icon span. */
.ph-order-icons-col{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
  flex-shrink:0;
}
/* A "ticket stub" shape (rectangle + arrow notch cut into its right edge)
   that holds the service icon — ~30% of the card's width and the cell's
   full height, so it reads as its own independent zone (Telegram as the
   "source" of the connection), distinct from the plain rounded-square
   tile used elsewhere (e.g. mail-history's cards, which keep .ph-order-icon). */
.ph-order-chevron{
  position:relative;
  flex:0 0 30%;
  display:flex;
  align-items:center;
  justify-content:center;
  clip-path:polygon(0 0, 78% 0, 100% 50%, 78% 100%, 0 100%);
  box-shadow:2px 0 8px -3px rgba(0,0,0,.25);
}
/* Same "logo mark directly on its own brand-color tile" treatment as the
   Select service grid's .service-tile-icon — no extra ring/circle around
   it, just the icon at a size close to that grid's icon-to-tile ratio. */
.ph-order-chevron-icon{
  width:40px;height:40px;
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
}
.ph-order-chevron-icon svg,.ph-order-chevron-icon img{width:65%;height:65%;object-fit:contain;}
/* The "Content Area" — everything to the right of the chevron: name,
   number, the country divider, and the flag. Owns the padding the info
   cell lost when the chevron took over bleeding to its edges. */
.ph-order-info-content{
  display:flex;
  align-items:center;
  gap:12px;
  flex:1 1 auto;
  min-width:0;
  padding:16px 20px 16px 18px;
}
.ph-order-text-col{
  display:flex;
  flex-direction:column;
  justify-content:center;
  gap:10px;
  flex:1 1 auto;
  min-width:0;
}
.ph-order-divider{
  align-self:stretch;
  width:1px;
  flex-shrink:0;
  background:#68b39f;
}
.ph-order-icon{
  width:34px;height:34px;
  border-radius:9px;
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
  box-shadow:0 1px 4px rgba(0,0,0,.18);
}
.ph-order-icon svg,.ph-order-icon img{width:70%;height:70%;object-fit:contain;}
.ph-order-name{font-weight:700;font-size:15px;color:#44b48f;}

.ph-order-country-col{
  display:flex;
  align-items:center;
  gap:5px;
  min-width:0;
}

.ph-order-cell--status{
  grid-column:2;
  grid-row:1;
  border-right:1px solid #a7dcc4;
  align-items:center;
  text-align:center;
}
.ph-order-cell--time{
  grid-column:3;
  grid-row:1;
  align-items:center;
  text-align:center;
}
.ph-order-cell--time .ph-order-field-value{color:#5ead99;}
.ph-order-cell--cancel{
  grid-column:4;
  grid-row:1 / 3;
  align-items:center;
  border-left:1px solid #a7dcc4;
}
/* Non-waiting orders render this cell with no Cancel button inside it
   (see orderCardHtml) — without this it still keeps its own padding and
   reserves a blank, borderless strip of height between Time and Price,
   most obvious on mobile where every cell stacks into its own row. */
.ph-order-cell--cancel:empty{display:none;}
.ph-order-cell--price{
  grid-column:2 / 4;
  grid-row:2;
  align-items:center;
  justify-content:flex-start;
  text-align:center;
  border-top:1px solid #a7dcc4;
}
.ph-order-cell--price .ph-order-field-value{color:#5ead99;}
/* Waiting cards' Code cell only exists for the mobile 2x2 Status/Time/
   Price/Code grid below — desktop has no slot for it in its 4-column
   grid, so it stays hidden there (the code itself shows via
   .ph-code-reveal-held in .ph-order-help further down the card instead). */
.ph-order-cell--code{display:none;}
.ph-order-code-placeholder{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  color:#9aa5b1;
  font-family:var(--font-heading);
  font-weight:700;
  letter-spacing:3px;
  font-size:16px;
  margin-top:2px;
  width:fit-content;
}

/* A just-arrived SMS/mail code: one box per digit plus a "Received X ago"
   confirmation line, instead of a plain text string — used both inside
   the mobile 2x2 grid's Code cell and in .ph-order-help (desktop's
   .ph-code-reveal-held, and the Paid tab's resolved-order view). */
.ph-code-reveal{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
}
.ph-code-reveal-label{
  font-family:var(--font-heading);
  font-size:10px;
  font-weight:600;
  letter-spacing:.4px;
  text-transform:uppercase;
  color:#9aa5b1;
}
.ph-code-reveal-digits{
  display:flex;
  gap:7px;
  flex-wrap:wrap;
  justify-content:center;
}
.ph-code-digit{
  min-width:32px;
  height:40px;
  padding:0 5px;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius:10px;
  background:#eafaf2;
  border:1.5px solid #bfe6d3;
  font-family:var(--font-heading);
  font-size:19px;
  font-weight:700;
  color:var(--blue-mid);
  animation:phCodeDigitReveal .3s ease backwards;
}
@keyframes phCodeDigitReveal{
  0%{opacity:0;transform:scale(.8);}
  100%{opacity:1;transform:scale(1);}
}
.ph-code-reveal-received{
  display:flex;
  align-items:center;
  gap:6px;
  font-size:12.5px;
  font-weight:600;
  color:#1f9d55;
}
.ph-code-reveal-check{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  color:#1f9d55;
  flex-shrink:0;
}
.ph-code-reveal-check svg{width:15px;height:15px;}
@media (prefers-reduced-motion: reduce){
  .ph-code-digit{animation:none;}
}
/* Desktop-only twin of the mobile 2x2 grid's Code cell above — hidden on
   mobile so a held (arrived-but-not-yet-off-Waiting) order's code, or a
   genuinely Paid order's code, shows exactly once per breakpoint, never
   both. */
@media (max-width:680px){
  .ph-code-reveal-held{display:none;}
}

.ph-order-flag{width:48px;height:48px;border-radius:12px;object-fit:cover;box-shadow:0 0 0 1px rgba(0,0,0,.08);flex-shrink:0;}
/* Mobile-only country row (flag + name, under the phone number) — hidden
   on desktop, which keeps showing the existing side flag instead. */
.ph-order-country-row{display:none;}
.ph-order-number{
  font-weight:600;font-size:14.5px;color:#5ead99;letter-spacing:.2px;
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.ph-order-copy{
  position:relative;
  flex-shrink:0;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding:4px;
  margin-left:2px;
  border:none;
  background:none;
  color:var(--blue-mid);
  cursor:pointer;
  transition:color .15s ease;
}
.ph-order-copy:hover{color:var(--blue-dark);}
.ph-order-copy svg{width:15px;height:15px;}
.ph-copy-tooltip{
  position:absolute;
  bottom:100%;
  left:50%;
  transform:translate(-50%, 4px);
  margin-bottom:6px;
  padding:4px 10px;
  border-radius:6px;
  background:var(--blue-dark);
  color:#fff;
  font-size:11px;
  font-weight:600;
  letter-spacing:.2px;
  white-space:nowrap;
  line-height:normal;
  opacity:0;
  pointer-events:none;
  transition:opacity .18s ease, transform .18s ease;
  z-index:5;
}
.ph-copy-tooltip::after{
  content:'';
  position:absolute;
  top:100%;
  left:50%;
  transform:translateX(-50%);
  border:5px solid transparent;
  border-top-color:var(--blue-dark);
}
.ph-copy-tooltip.is-visible{opacity:1;transform:translate(-50%, 0);}

.ph-order-field-label{
  font-family:var(--font-heading);
  font-size:10px;
  font-weight:600;
  letter-spacing:.4px;
  text-transform:uppercase;
  color:#44b48f;
  margin-bottom:4px;
}
.ph-order-field-value{font-size:13.5px;font-weight:600;color:var(--blue-dark);}
.ph-order-field-value.is-waiting{color:#44b48f;}
.ph-order-field-value.is-paid{color:var(--blue-mid);}
.ph-order-field-value.is-canceled{color:#c94b4b;}

.ph-order-cancel{
  padding:9px 20px;
  border:none;
  border-radius:999px;
  background:var(--blue-mid);
  color:#fff;
  font-family:inherit;
  font-weight:600;
  font-size:11px;
  letter-spacing:.4px;
  text-transform:uppercase;
  cursor:pointer;
  white-space:nowrap;
  transition:background .16s ease;
}
.ph-order-cancel:hover{background:var(--blue-dark);}
.ph-order-cancel:disabled{opacity:.5;cursor:default;}

.ph-order-help{padding:16px 22px;background:#d7ede6;}
.ph-order-wait-row{
  display:flex;
  align-items:center;
  gap:10px;
  flex-wrap:wrap;
  font-size:12.5px;
  color:var(--blue-mid);
  margin-bottom:10px;
}
.ph-order-badge{
  width:18px;height:18px;
  border-radius:50%;
  background:var(--blue-mid);
  color:#fff;
  font-size:10px;
  font-weight:700;
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
}
.ph-order-spinner{
  width:16px;height:16px;
  border-radius:50%;
  border:2px solid #cfe9dc;
  border-top-color:var(--accent-orange);
  animation:ph-order-spin 0.8s linear infinite !important;
  flex-shrink:0;
}
@keyframes ph-order-spin{to{transform:rotate(360deg);}}
/* aspect-ratio reserves the image's real footprint before it loads —
   without it, height:auto collapses to 0px pre-load and the row jumps
   once the image pops in (visible on a slower mobile connection). */
.ph-order-code-arrow{width:48px;height:auto;aspect-ratio:577/433;flex-shrink:0;}
.ph-order-code-label{font-weight:600;color:var(--blue-dark);}
.ph-order-code-label.is-ready{color:var(--blue-mid);font-family:var(--font-heading);letter-spacing:.5px;}

.ph-order-note{font-size:12px;color:var(--blue-mid);line-height:1.5;margin:0 0 6px;}

.ph-btn.ph-order-buy{background:var(--blue-mid);}
.ph-btn.ph-order-buy:hover{background:var(--blue-dark);}
.ph-order-buy-row{
  display:flex;
  align-items:center;
  gap:10px;
  padding:4px 22px 18px;
}
.ph-order-buy-arrow{width:40px;height:auto;aspect-ratio:612/408;flex-shrink:0;}
.ph-order-buy-hint{font-size:12.5px;color:var(--blue-mid);}

.ph-order-empty{
  padding:30px 20px;
  text-align:center;
  color:var(--blue-mid);
  font-weight:400;
  font-size:13.5px;
  background:#fff;
  border:1px solid #e6e9ec;
  border-radius:20px;
}
/* Phone history's own empty state only (see orderCardHtml's caller in
   phone-history.js) — an icon tile centered above the message instead of
   plain centered text, so the "nothing here yet" moment reads as a
   designed state rather than a placeholder string. Mail history keeps
   the plain .ph-order-empty look untouched. */
.ph-order-empty--illustrated{
  display:flex;flex-direction:column;align-items:center;gap:16px;
  text-align:center;padding:36px 24px;
}
/* images/phone-history-empty-folder.png is a pre-cropped, true-alpha PNG
   (no black canvas baked in — see git history if regenerating), so it just
   sits directly on the card with no tile/background/blend trick needed. */
.ph-order-empty-img-wrap{
  width:64px;flex-shrink:0;
}
.ph-order-empty-img{
  width:100%;height:auto;display:block;
}
.ph-order-empty-text{margin:0;}
@media (max-width:480px){
  .ph-order-empty--illustrated{gap:12px;padding:28px 18px;}
  .ph-order-empty-img-wrap{width:52px;}
}

.ph-cards-pagination{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  margin:-8px 0 26px;
}
/* Same [hidden]-vs-display gotcha as .ph-orders above — without this,
   switching to a tab with 1 page (e.g. Waiting) leaves an empty flex
   container with its own negative margin sitting visible in the layout. */
.ph-cards-pagination[hidden]{display:none;}
/* Top up history's pagination sits below the bordered table card, not
   directly under a bare list of cards like phone-history's own — the
   negative top margin above was tuned for that second case and would
   crowd it up against the card's shadow here instead. */
#tuhPagination{margin:20px 0 0;}
.ph-cards-page{
  min-width:34px;
  height:34px;
  padding:0 4px;
  border:1.5px solid #cfe9dc;
  border-radius:999px;
  background:#fff;
  color:var(--blue-mid);
  font-weight:600;
  font-size:13px;
  font-family:inherit;
  cursor:pointer;
  transition:background .15s ease, color .15s ease, border-color .15s ease;
}
.ph-cards-page:hover{background:#eafaf2;}
.ph-cards-page.is-active{background:var(--blue-mid);border-color:var(--blue-mid);color:#fff;}
.ph-cards-page--nav{font-size:16px;line-height:1;}
.ph-cards-page--nav:disabled{opacity:.4;cursor:default;background:#fff;}
.ph-cards-page--nav:disabled:hover{background:#fff;}
/* Provider statistic's and Phone history's table pager use real chevron
   icons instead of the literal ‹ / › text glyphs the other card-view
   pagers still use. */
#statTablePagination .ph-cards-page--nav, #phTablePagination .ph-cards-page--nav{display:inline-flex;align-items:center;justify-content:center;}
#statTablePagination .ph-cards-page--nav svg, #phTablePagination .ph-cards-page--nav svg{width:14px;height:14px;}
/* Sits right after .ph-pagination (Number of rows per page) here, unlike
   the card-view layouts .ph-cards-pagination's shared -8px margin was
   tuned for — that negative top margin pulled it up into the row above. */
#statTablePagination, #phTablePagination{margin-top:16px;}

/* Paid/Canceled order cards' action button (replaces the Waiting card's
   "Buy" + curly-arrow hint) — .ph-order-action's rules are declared after
   .ph-btn above so they win any overlapping property regardless of
   selector specificity. */
.ph-order-actions{
  display:flex;
  gap:10px;
  padding:4px 22px 18px;
}
.ph-order-action{
  flex:1;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:6px;
  min-width:0;
  padding:11px 10px;
  border-radius:14px;
  border:none;
  margin:0;
  width:auto;
  text-align:center;
  line-height:1.25;
  font-family:var(--font-heading);
  font-weight:700;
  font-size:12px;
  letter-spacing:0;
  text-transform:none;
  text-decoration:none;
  cursor:pointer;
  transition:background .16s ease, border-color .16s ease;
}
.ph-order-action svg{width:16px;height:16px;flex-shrink:0;}
.ph-order-action--outline{
  background:#fff;
  border:1.5px solid var(--blue-mid);
  color:var(--blue-mid);
}
.ph-order-action--outline:hover{background:#eafaf2;}

@media (max-width:680px){
  /* Mobile card: white with a light gray/blue border instead of the
     desktop grid's mint-green fill — a real "card", not a scaled-down
     copy of the desktop table row. Inset from the screen edge by its own
     margin here rather than widening .ph-layout's shared 4px mobile
     padding (that padding is load-bearing for the header alignment and
     used by every other section on this page). */
  .ph-orders{padding:0 14px;}
  .ph-order-card{
    background:#fff;
    border-color:#e6e9ec;
    box-shadow:0 4px 16px -8px rgba(15,31,61,.14);
  }
  .ph-order-grid{background:#fff;border-color:#e6e9ec;}
  /* Thin #E5E7EB rules separate each stacked section (service info /
     status / time / price / buttons) now that they're full-width rows
     instead of the desktop grid's side-by-side columns. */
  .ph-order-help{background:#fff;border-top:1px solid #e5e7eb;}
  .ph-order-grid{grid-template-columns:1fr;grid-template-rows:none;}
  .ph-order-cell{
    grid-column:1;
    grid-row:auto;
    border-right:none;
    border-left:none;
    border-top:none;
    border-bottom:1px solid #e5e7eb;
  }
  .ph-order-cell--price{border-top:none;}
  .ph-order-cell--cancel{align-items:flex-start;border-bottom:none;}
  /* Status/Time/Price read as centered "stat" columns in the desktop
     grid, but once each becomes its own full-width row on mobile,
     centered text looks disconnected from the label above it — left
     align instead so label and value line up like every other row. */
  .ph-order-cell--status,
  .ph-order-cell--time,
  .ph-order-cell--price{
    align-items:flex-start;
    text-align:left;
  }
  /* Field labels (STATUS/TIME/PRICE) read as neutral gray captions here
     instead of the desktop's teal-green. */
  .ph-order-field-label{color:#9aa5b1;}
  /* Waiting cards only: Status/Time/Price/Code as a real 2x2 grid (info
     row and Cancel each spanning both columns above/below it) instead of
     the plain single-column stack every other status uses — a vertical
     rule down the middle (border-right on the left column) crossed with
     a horizontal one (border-bottom on the top row), matching the
     reference image's cross-divider exactly. Selectors here carry two
     classes vs. the generic single-class .ph-order-cell rules above, so
     they win regardless of source order. */
  .ph-order-grid--waiting{
    display:grid;
    grid-template-columns:1fr 1fr;
    grid-template-areas:
      "info info"
      "status time"
      "price code"
      "cancel cancel";
  }
  .ph-order-grid--waiting .ph-order-cell{grid-column:auto;grid-row:auto;}
  .ph-order-grid--waiting .ph-order-cell--info{grid-area:info;}
  .ph-order-grid--waiting .ph-order-cell--status{
    grid-area:status;
    border-right:1px solid #e5e7eb;
    border-bottom:1px solid #e5e7eb;
  }
  .ph-order-grid--waiting .ph-order-cell--time{
    grid-area:time;
    border-bottom:1px solid #e5e7eb;
  }
  .ph-order-grid--waiting .ph-order-cell--price{
    grid-area:price;
    border-right:1px solid #e5e7eb;
    border-bottom:none;
  }
  .ph-order-grid--waiting .ph-order-cell--code{
    grid-area:code;
    display:flex;
    align-items:center;
    text-align:center;
  }
  .ph-order-grid--waiting .ph-order-cell--code .ph-order-field-label{width:100%;}
  .ph-order-grid--waiting .ph-order-cell--cancel{
    grid-area:cancel;
    border-top:1px solid #e5e7eb;
    border-bottom:none;
    /* Overrides the generic .ph-order-cell--cancel's left alignment above
       (tuned for Paid/Canceled's plain single-column stack) — this cell
       spans the full "cancel cancel" row on its own here, so a centered
       button reads as balanced instead of stranded on the left edge. */
    align-items:center;
  }
  /* Status becomes a small tinted pill (dot + text) instead of the plain,
     roomy desktop text — the dot always matches the status color via
     currentColor, so is-waiting/is-paid/is-canceled need no dot-specific
     rules of their own. */
  .ph-order-cell--status .ph-order-field-value{
    display:inline-flex;
    align-items:center;
    gap:6px;
    padding:4px 10px;
    border-radius:999px;
    font-size:12.5px;
  }
  .ph-order-cell--status .ph-order-field-value::before{
    content:"";
    width:6px;height:6px;
    border-radius:50%;
    background:currentColor;
    flex-shrink:0;
  }
  .ph-order-cell--status .ph-order-field-value.is-waiting{background:#eafaf2;}
  .ph-order-cell--status .ph-order-field-value.is-paid{background:#eafaf2;}
  .ph-order-cell--status .ph-order-field-value.is-canceled{background:#fdecec;}
  /* Time value: a size step up from the desktop's 13.5px so it reads
     clearly as data, not a caption. */
  .ph-order-cell--time .ph-order-field-value{font-size:16px;}
  /* Price: legible but a notch below Time so it doesn't read as the
     loudest number on the card. */
  .ph-order-cell--price .ph-order-field-value{font-size:17px;}
  /* 2x2 grid's Status cell, per the reference: plain bold text (no
     pill/dot) instead of the generic badge treatment above — used by
     Waiting, held, Paid, and Canceled cards alike now (they all share
     .ph-order-grid--waiting), so the color has to key off the actual
     status class rather than a single blanket blue like before (that
     used to be safe when only Waiting cards carried this class, but was
     painting Paid/Canceled statuses blue too once they started reusing
     it). */
  .ph-order-grid--waiting .ph-order-cell--status .ph-order-field-value{
    display:block;
    background:none;
    padding:0;
    border-radius:0;
    font-size:16px;
    font-weight:700;
  }
  .ph-order-grid--waiting .ph-order-cell--status .ph-order-field-value.is-waiting{color:#2563eb;}
  .ph-order-grid--waiting .ph-order-cell--status .ph-order-field-value.is-paid{color:var(--blue-mid);}
  .ph-order-grid--waiting .ph-order-cell--status .ph-order-field-value.is-canceled{color:#c94b4b;}
  .ph-order-grid--waiting .ph-order-cell--status .ph-order-field-value::before{display:none;}
  .ph-order-grid--waiting .ph-order-cell--time .ph-order-field-value,
  .ph-order-grid--waiting .ph-order-cell--price .ph-order-field-value{
    color:#1f2937;
  }
  /* Brand block: a fixed 70–90px strip instead of 30% of the card's width
     (way too wide once the card itself is only ~380-430px), matching the
     info row's own height since .ph-order-cell--info is no longer forced
     to span the full card height here (grid-row:auto above already
     isolates it into its own row). */
  .ph-order-chevron{flex:0 0 80px;}
  /* Service name leads the info column instead of sitting vertically
     centered against the number/flag below it. */
  .ph-order-text-col{justify-content:flex-start;}
  .ph-order-name{font-size:21px;color:var(--blue-dark);}
  /* Phone number: dark and legible instead of the desktop's light teal,
     but a size step below the service name so the name still reads as
     the primary line. */
  .ph-order-number{font-size:18px;color:#37474f;}
  /* Copy-number button: bigger tap target, green instead of orange so it
     doesn't compete visually with the orange copy-code button elsewhere
     on the same card. */
  .ph-order-country-col .ph-order-copy{color:var(--blue-mid);}
  .ph-order-country-col .ph-order-copy:hover{color:var(--blue-dark);}
  .ph-order-country-col .ph-order-copy svg{width:19px;height:19px;}
  /* Country: a small flag + name row under the number, replacing the
     desktop's single large side flag (which, with the number, name and
     the shared divider, no longer fits the now much narrower content
     column next to the 80px brand block). */
  .ph-order-divider,
  .ph-order-info-content > .ph-order-flag{display:none;}
  .ph-order-country-row{
    display:flex;
    align-items:center;
    gap:6px;
    margin-top:4px;
  }
  .ph-order-flag-sm{width:28px;height:20px;border-radius:4px;object-fit:cover;flex-shrink:0;box-shadow:0 0 0 1px rgba(0,0,0,.08);}
  .ph-order-country-name{font-size:15px;color:#78909c;}
}

/* ============ Desktop version of the Waiting/Paid/Canceled card ========
   Reuses the exact same 2x2 Status/Time/Price/Code layout the mobile
   block above uses, sized up for a much wider card instead of copy-
   pasting mobile's own dimensions. Scoped to .ph-order-card--desktop2x2
   (Waiting, held, Paid, and Canceled cards all carry it now — see
   orderCardHtml in phone-history.js). Each rule below mirrors one from
   the mobile block, so compare against that if adjusting either. */
@media (min-width:681px){
  .ph-order-card--desktop2x2{
    background:#fff;
    border-color:#e6e9ec;
    box-shadow:0 4px 16px -8px rgba(15,31,61,.14);
  }
  .ph-order-card--desktop2x2 .ph-order-grid{
    background:#fff;
    border-color:#e6e9ec;
    display:grid;
    grid-template-columns:1fr 1fr;
    grid-template-rows:none;
    grid-template-areas:
      "info info"
      "status time"
      "price code"
      "cancel cancel";
  }
  .ph-order-card--desktop2x2 .ph-order-cell{
    grid-column:auto;
    grid-row:auto;
    border-right:none;
    border-left:none;
    border-top:none;
    border-bottom:1px solid #e5e7eb;
  }
  .ph-order-card--desktop2x2 .ph-order-cell--info{grid-area:info;}
  .ph-order-card--desktop2x2 .ph-order-cell--status,
  .ph-order-card--desktop2x2 .ph-order-cell--time,
  .ph-order-card--desktop2x2 .ph-order-cell--price{
    align-items:flex-start;
    text-align:left;
  }
  .ph-order-card--desktop2x2 .ph-order-cell--status{
    grid-area:status;
    border-right:1px solid #e5e7eb;
    border-bottom:1px solid #e5e7eb;
  }
  .ph-order-card--desktop2x2 .ph-order-cell--time{
    grid-area:time;
    border-bottom:1px solid #e5e7eb;
  }
  .ph-order-card--desktop2x2 .ph-order-cell--price{
    grid-area:price;
    border-right:1px solid #e5e7eb;
    border-bottom:none;
  }
  .ph-order-card--desktop2x2 .ph-order-cell--code{
    grid-area:code;
    display:flex;
    align-items:center;
    justify-content:center;
    text-align:center;
    border-bottom:none;
  }
  .ph-order-card--desktop2x2 .ph-order-cell--code .ph-order-field-label{width:100%;}
  .ph-order-card--desktop2x2 .ph-order-cell--cancel{
    grid-area:cancel;
    border-top:1px solid #e5e7eb;
    border-bottom:none;
    align-items:center;
  }
  .ph-order-card--desktop2x2 .ph-order-field-label{color:#9aa5b1;font-size:11px;}
  .ph-order-card--desktop2x2 .ph-order-cell--time .ph-order-field-value{font-size:18px;}
  .ph-order-card--desktop2x2 .ph-order-cell--price .ph-order-field-value{font-size:19px;}
  .ph-order-card--desktop2x2 .ph-order-cell--status .ph-order-field-value{
    display:block;
    background:none;
    padding:0;
    border-radius:0;
    font-size:19px;
    font-weight:700;
  }
  /* Color keys off the actual status class — a blanket blue here would be
     wrong now that Paid/Canceled cards share this layout too, not just
     Waiting. */
  .ph-order-card--desktop2x2 .ph-order-cell--status .ph-order-field-value.is-waiting{color:#2563eb;}
  .ph-order-card--desktop2x2 .ph-order-cell--status .ph-order-field-value.is-paid{color:var(--blue-mid);}
  .ph-order-card--desktop2x2 .ph-order-cell--status .ph-order-field-value.is-canceled{color:#c94b4b;}
  .ph-order-card--desktop2x2 .ph-order-cell--status .ph-order-field-value::before{display:none;}
  .ph-order-card--desktop2x2 .ph-order-cell--time .ph-order-field-value,
  .ph-order-card--desktop2x2 .ph-order-cell--price .ph-order-field-value{
    color:#1f2937;
  }
  .ph-order-card--desktop2x2 .ph-order-help{background:#fff;border-top:1px solid #e5e7eb;}
  /* The grid's own Code cell above is the single source of truth here
     (like mobile) — the help-section's .ph-code-reveal-held twin (built
     for the old desktop layout, which had no grid slot for Code) would
     otherwise duplicate it. */
  .ph-order-card--desktop2x2 .ph-code-reveal-held{display:none;}

  .ph-order-card--desktop2x2 .ph-order-chevron{flex:0 0 130px;}
  .ph-order-card--desktop2x2 .ph-order-chevron-icon{width:52px;height:52px;}
  .ph-order-card--desktop2x2 .ph-order-text-col{justify-content:flex-start;}
  .ph-order-card--desktop2x2 .ph-order-name{font-size:24px;color:var(--blue-dark);}
  .ph-order-card--desktop2x2 .ph-order-number{font-size:20px;color:#37474f;}
  .ph-order-card--desktop2x2 .ph-order-country-col .ph-order-copy{color:var(--blue-mid);}
  .ph-order-card--desktop2x2 .ph-order-country-col .ph-order-copy:hover{color:var(--blue-dark);}
  .ph-order-card--desktop2x2 .ph-order-country-col .ph-order-copy svg{width:20px;height:20px;}
  .ph-order-card--desktop2x2 .ph-order-divider,
  .ph-order-card--desktop2x2 .ph-order-info-content > .ph-order-flag{display:none;}
  .ph-order-card--desktop2x2 .ph-order-country-row{
    display:flex;
    align-items:center;
    gap:8px;
    margin-top:6px;
  }
  .ph-order-card--desktop2x2 .ph-order-flag-sm{width:34px;height:24px;border-radius:5px;object-fit:cover;flex-shrink:0;box-shadow:0 0 0 1px rgba(0,0,0,.08);}
  .ph-order-card--desktop2x2 .ph-order-country-name{font-size:16px;color:#78909c;}

  /* Code digit boxes read bigger here than the shared .ph-code-digit
     default, matching the extra room a desktop card has. */
  .ph-order-card--desktop2x2 .ph-order-cell--code .ph-code-digit{
    min-width:40px;
    height:50px;
    font-size:23px;
    border-radius:12px;
  }
  .ph-order-card--desktop2x2 .ph-order-cell--code .ph-code-reveal-received{font-size:13.5px;}
}

/* ============ "All phone activations" filter table ============ */
.ph-table-card{
  background:#fff;
  border:1px solid #e6e9ec;
  border-radius:20px;
  padding:22px 22px 26px;
  box-shadow:0 16px 36px -22px rgba(0,27,92,.4), 0 2px 10px -6px rgba(0,0,0,.06);
}

.ph-table-toolbar{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  margin-bottom:20px;
}
.ph-table-toolbar-actions{
  display:flex;
  align-items:center;
  gap:10px;
  flex-wrap:wrap;
  justify-content:flex-end;
}
.ph-btn{
  padding:10px 22px;
  border:none;
  border-radius:999px;
  background:var(--header-blue);
  color:#fff;
  font-family:inherit;
  font-weight:600;
  font-size:11.5px;
  letter-spacing:.5px;
  text-transform:uppercase;
  cursor:pointer;
  box-shadow:0 6px 14px -6px rgba(0,27,92,.55);
  transition:background .16s ease, box-shadow .16s ease, transform .1s ease;
}
.ph-btn:hover{background:var(--blue-dark);box-shadow:0 8px 18px -6px rgba(0,27,92,.6);}
/* Provider statistic's, Top up history's, and Email history's Hide/Show
   toggle — eye/eye-off swap instead of a plain text-only relabel, same
   two-icon pattern used elsewhere on the site (e.g. the FAQ +/- swap).
   Scoped to these buttons — #phHideBtn is shared with phone-history.html's
   own (differently-structured, [data-icon]-based) Hide button, but these
   .ph-btn-icon--eye/--eye-off classes don't exist there so they're inert
   on that page. */
#statHideBtn, #tuhHideBtn, #phHideBtn{display:inline-flex;align-items:center;gap:7px;}
#statHideBtn .ph-btn-icon, #tuhHideBtn .ph-btn-icon, #phHideBtn .ph-btn-icon{width:14px;height:14px;flex-shrink:0;}
#statHideBtn .ph-btn-icon--eye, #tuhHideBtn .ph-btn-icon--eye, #phHideBtn .ph-btn-icon--eye{display:none;}
#statHideBtn.is-collapsed .ph-btn-icon--eye-off, #tuhHideBtn.is-collapsed .ph-btn-icon--eye-off, #phHideBtn.is-collapsed .ph-btn-icon--eye-off{display:none;}
#statHideBtn.is-collapsed .ph-btn-icon--eye, #tuhHideBtn.is-collapsed .ph-btn-icon--eye, #phHideBtn.is-collapsed .ph-btn-icon--eye{display:inline-flex;}
#statSearchBtn, #tuhSearchBtn{display:inline-flex;align-items:center;gap:7px;}
#statSearchBtn .ph-btn-icon, #tuhSearchBtn .ph-btn-icon{width:14px;height:14px;flex-shrink:0;}
.ph-btn:active{transform:translateY(1px);box-shadow:0 3px 8px -4px rgba(0,27,92,.5);}
.ph-btn:disabled{opacity:.55;cursor:default;pointer-events:none;}

/* .ph-table-card's own background is white, so these need a visible
   border — with no shadow and a near-white fill they'd otherwise blend
   straight into the card and read as gone even while still in the DOM.
   Download CSV stays on the default dark .ph-btn look (a solid pill,
   same green as the header) since it's the primary action of the pair —
   Hide/Filter are secondary, so they get the flat light treatment. */
#phHideBtn,
#phFilterBtn{
  background:#f1f7f5;
  color:var(--blue-dark);
  border:1.5px solid #e2ece7;
  box-shadow:none;
}
#phHideBtn:hover,
#phFilterBtn:hover{
  background:#e8f1ec;
  box-shadow:none;
}
.ph-btn--with-icon{display:inline-flex;align-items:center;gap:7px;}
/* Same [hidden]-vs-display gotcha as .ph-orders/.ph-cards-pagination —
   without this, Download CSV stays visibly clickable even with zero
   rows to export (its own JS toggles `hidden` on the empty table). */
.ph-btn--with-icon[hidden]{display:none;}
.ph-btn-icon{width:14px;height:14px;flex-shrink:0;}

#phHideBtn:active,
#phFilterBtn:active{
  transform:none;
  box-shadow:none;
}

.ph-table-body.is-collapsed{display:none;}

.ph-filter-grid{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:16px;
  margin-bottom:16px;
}
/* Mail history has no Country field, so its filter row is two fields
   (Service / Status) instead of three. */
.ph-filter-grid--2{grid-template-columns:repeat(2, 1fr);}
.ph-filter-grid--4{grid-template-columns:repeat(4, 1fr);}
.ph-date-row{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:16px;
  margin-bottom:18px;
}
.ph-field label{
  display:block;
  font-family:var(--font-heading);
  margin-bottom:7px;
  font-size:10.5px;
  font-weight:600;
  letter-spacing:.4px;
  text-transform:uppercase;
  color:var(--accent-orange);
}
.ph-field-label-row{
  display:flex;
  align-items:center;
  gap:5px;
  margin-bottom:7px;
}
.ph-field-label-row label{margin-bottom:0;}
.ph-field-hint{
  display:inline-flex;
  width:13px;height:13px;
  color:var(--accent-orange);
  opacity:.85;
  cursor:help;
}
.ph-field-hint svg{width:100%;height:100%;}

/* Custom dropdown (Country / Service / Status) — same trigger look as a
   plain select, but the open panel is our own styled list instead of the
   browser's native popup, so hover/selected states use the site's green
   instead of the OS accent color. */
.ph-dd{position:relative;}
.ph-dd-trigger{
  width:100%;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:8px;
  padding:11px 14px;
  border:1.5px solid #e2ece7;
  border-radius:10px;
  background:#f2f7f5;
  color:var(--blue-dark);
  font-family:inherit;
  font-weight:600;
  font-size:12.5px;
  text-align:left;
  cursor:pointer;
  transition:background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.ph-dd-trigger:hover{background:#e8f1ec;border-color:#cfe0d8;}
.ph-dd-trigger-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.ph-dd-trigger svg{
  width:12px;height:12px;flex-shrink:0;
  color:var(--header-blue);
  transition:transform .15s ease;
}
.ph-dd.is-open .ph-dd-trigger{
  background:#fff;
  border-color:var(--header-blue);
  box-shadow:0 0 0 3px rgba(0,27,92,.16);
}
.ph-dd.is-open .ph-dd-trigger svg{transform:rotate(180deg);}

/* Small glyph in front of a trigger's label (Country's globe, Service's
   grid) — the chevron rule above rotates every svg in the trigger on
   open, and the generic trigger-svg rule sizes them all at 12px, so both
   need overriding here with the extra class for specificity instead of
   touching the shared dropdown styles used by Status/Rows too. */
.ph-dd-trigger--with-icon{justify-content:flex-start;}
.ph-dd-trigger--with-icon .ph-dd-trigger-icon{
  width:15px;height:15px;flex-shrink:0;
  color:var(--header-blue);
  opacity:.8;
}
.ph-dd.is-open .ph-dd-trigger--with-icon .ph-dd-trigger-icon{transform:none;}
.ph-dd-trigger--with-icon > svg:last-child{margin-left:auto;}

.ph-dd-panel{
  position:absolute;
  top:calc(100% + 8px);
  left:0;right:0;
  background:#fff;
  border-radius:14px;
  box-shadow:0 16px 32px -10px rgba(0,0,0,.28);
  padding:8px;
  z-index:60;
  opacity:0;
  visibility:hidden;
  transform:translateY(6px);
  transition:opacity .15s ease, transform .15s ease, visibility 0s linear .15s;
}
.ph-dd.is-open .ph-dd-panel{
  opacity:1;
  visibility:visible;
  transform:translateY(0);
  transition:opacity .15s ease, transform .15s ease, visibility 0s;
}

.ph-dd-search{
  display:flex;
  align-items:center;
  gap:7px;
  background:#f2f7f5;
  border:1.5px solid #e2ece7;
  border-radius:10px;
  padding:7px 12px;
  margin-bottom:6px;
}
.ph-dd-search svg{width:14px;height:14px;color:#7a9a8b;flex-shrink:0;}
.ph-dd-search-input{
  flex:1;min-width:0;border:none;background:none;outline:none;
  color:var(--blue-dark);font-weight:400;font-size:12.5px;font-family:inherit;
}
.ph-dd-search-input::placeholder{color:#7a9a8b;font-weight:400;}

.ph-dd-list{
  max-height:230px;
  overflow-y:auto;
  scrollbar-width:thin;
  scrollbar-color:#bcdccd transparent;
}
.ph-dd-list::-webkit-scrollbar{width:5px;}
.ph-dd-list::-webkit-scrollbar-track{background:transparent;}
.ph-dd-list::-webkit-scrollbar-thumb{background:#bcdccd;border-radius:999px;}
.ph-dd-item{
  padding:9px 10px;
  border-radius:8px;
  font-size:12.5px;
  font-weight:500;
  color:var(--blue-dark);
  cursor:pointer;
  transition:background .12s ease;
}
.ph-dd-item:hover, .ph-dd-item.is-active{background:rgba(15,44,92,.1);}
.ph-dd-item.is-selected{color:var(--header-blue);font-weight:700;}
.ph-dd-empty{padding:14px 10px;text-align:center;color:#5a7a6b;font-size:12.5px;}

/* Compact variant for the pagination dropdown — same look, tighter box. */
.ph-dd--compact{width:auto;min-width:76px;}
.ph-dd--compact .ph-dd-trigger{padding:7px 12px;font-size:12.5px;}
.ph-dd--compact .ph-dd-panel{min-width:100px;}

/* Custom calendar (Date from / Date to) — replaces the native date
   picker, whose popup (and the OS's blue "today" highlight) can't be
   restyled and clashed with the rest of the panel. */
.ph-cal-panel{
  left:0;
  right:auto;
  width:272px;
  padding:14px;
}
.ph-cal-header{
  display:flex;
  align-items:center;
  justify-content:space-between;
  margin-bottom:10px;
}
.ph-cal-month-label{font-family:var(--font-heading);font-size:13px;font-weight:600;color:var(--blue-dark);}
.ph-cal-nav{display:flex;gap:4px;}
.ph-cal-nav-btn{
  width:26px;height:26px;
  border:none;
  border-radius:8px;
  background:#f2f7f5;
  color:var(--header-blue);
  font-size:15px;
  font-weight:600;
  line-height:1;
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;
  transition:background .12s ease;
}
.ph-cal-nav-btn:hover{background:rgba(15,44,92,.14);}

.ph-cal-weekdays{
  display:grid;
  grid-template-columns:repeat(7, 1fr);
  text-align:center;
  margin-bottom:4px;
}
.ph-cal-weekdays span{
  font-size:9.5px;
  font-weight:400;
  letter-spacing:.2px;
  text-transform:uppercase;
  color:#8fb3a2;
}

.ph-cal-grid{
  display:grid;
  grid-template-columns:repeat(7, 1fr);
  gap:2px;
}
.ph-cal-day{
  aspect-ratio:1;
  display:flex;
  align-items:center;
  justify-content:center;
  border:none;
  border-radius:8px;
  background:none;
  font-family:inherit;
  font-size:12px;
  font-weight:600;
  color:var(--blue-dark);
  cursor:pointer;
  transition:background .12s ease, color .12s ease;
}
.ph-cal-day:hover{background:rgba(15,44,92,.1);}
.ph-cal-day.is-outside{color:#c7d0d9;}
.ph-cal-day.is-today{box-shadow:inset 0 0 0 1.5px var(--header-blue);}
.ph-cal-day.is-selected{
  background:var(--header-blue);
  color:#fff;
  font-weight:600;
}

.ph-cal-footer{
  display:flex;
  justify-content:space-between;
  margin-top:10px;
  padding-top:10px;
  border-top:1px solid #eaeef2;
}
.ph-cal-link{
  border:none;
  background:none;
  font-family:inherit;
  font-size:11.5px;
  font-weight:600;
  color:var(--header-blue);
  cursor:pointer;
  padding:2px;
}
.ph-cal-link:hover{text-decoration:underline;}

.ph-table-wrap{
  overflow-x:auto;
  border-radius:14px;
  background:#fff;
  border:1px solid #e6e9ec;
  box-shadow:0 1px 4px rgba(0,0,0,.04);
  scrollbar-width:none; /* Firefox */
  -ms-overflow-style:none; /* old Edge/IE */
  /* Reserves real trailing space inside the scroll area itself — relying
     on the last cell's own padding wasn't enough, since scrolling all the
     way right still lands the chip flush against this rounded edge. */
  padding-right:14px;
}
/* Table still scrolls fine with touch/trackpad/shift-wheel — this just
   hides the plain native scrollbar track in favor of the animated
   .ph-scroll-hint arrow below, which reads as a deliberate part of the
   design instead of a browser default. */
.ph-table-wrap::-webkit-scrollbar{display:none;}
.ph-table{width:100%;border-collapse:collapse;min-width:620px;}
.ph-table thead th{
  text-align:left;
  padding:13px 14px;
  font-family:var(--font-heading);
  font-size:10.5px;
  font-weight:600;
  letter-spacing:.3px;
  text-transform:uppercase;
  color:var(--header-blue);
  border-bottom:1.5px solid #eaf5f0;
  white-space:nowrap;
}
/* The last column's chip otherwise sits right up against the card's own
   rounded edge — extra breathing room here, not on every column. */
.ph-table thead th:last-child,
.ph-table tbody td:last-child{padding-right:22px;}
.ph-sort{
  display:inline-flex;
  vertical-align:middle;
  margin-left:4px;
  width:9px;height:9px;
  opacity:.5;
}
.ph-table tbody tr{transition:background .12s ease;}
.ph-table tbody tr:hover{background:#f4faf7;}
.ph-table tbody tr:not(.ph-table-empty):not(:last-child) td{border-bottom:1px solid #eef2f0;}
.ph-table tbody td{
  padding:13px 14px;
  font-size:13px;
  font-weight:500;
  color:var(--blue-dark);
  white-space:nowrap;
}
.ph-table-index{color:#9fc7b4;font-weight:600;}
.ph-table-accent{color:#44b48f;font-weight:600;}
.ph-table-price{color:#5ead99;font-weight:700;}

/* Country/Service/Status cells render as a small white "chip" (icon or
   dot + label) instead of bare text — reads as a proper data table
   instead of a plain CSV dump. */
.ph-table-chip{
  display:inline-flex;
  align-items:center;
  gap:6px;
  background:#fff;
  border:1px solid #eef2f0;
  border-radius:999px;
  padding:4px 12px 4px 4px;
  box-shadow:0 1px 3px rgba(0,0,0,.06);
  font-weight:600;
  color:var(--blue-dark);
}
/* Country/Service/Number/SMS drop the pill background — Status and Price
   keep it so the table still reads as data cells, not a flat text dump. */
.ph-table-chip--plain{
  background:transparent;
  border-color:transparent;
  box-shadow:none;
  padding:4px 0;
}
.ph-table-chip-flag{
  width:18px;height:18px;
  border-radius:50%;
  object-fit:cover;
  flex-shrink:0;
  box-shadow:0 0 0 1px rgba(0,0,0,.08);
}
.ph-table-chip-icon{
  width:18px;height:18px;
  border-radius:6px;
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
}
.ph-table-chip-icon svg,.ph-table-chip-icon img{width:70%;height:70%;object-fit:contain;}
.ph-table-chip-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;margin-left:3px;}
.ph-table-status.is-waiting{color:var(--accent-orange);}
.ph-table-status.is-paid{color:var(--blue-mid);}
.ph-table-status.is-canceled{color:#c94b4b;}
.ph-table-empty td{
  padding:16px;
  text-align:center;
  font-size:12.5px;
  font-weight:400;
  color:var(--header-blue);
  background:#eaf5f0;
}

/* Swipe hint under the table — only relevant once the table can
   actually scroll sideways (narrower than its min-width), which is
   also exactly when the wrapper's own horizontal scrollbar would have
   shown, so it's gated behind the same breakpoint that forces that
   scroll in the first place. */
.ph-scroll-hint{
  display:none;
  align-items:center;
  justify-content:center;
  gap:8px;
  margin-top:10px;
  color:#1f7a52;
  font-size:11px;
  font-weight:600;
  letter-spacing:.2px;
}
.ph-scroll-hint-icon{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  color:var(--blue-mid);
  flex-shrink:0;
}
.ph-scroll-hint-icon svg{width:14px;height:14px;animation:phScrollHintNudge 1.6s ease-in-out infinite;}
.ph-scroll-hint > svg{width:18px;height:18px;flex-shrink:0;animation:phScrollHintNudge 1.6s ease-in-out infinite;}
@keyframes phScrollHintNudge{
  0%,100%{transform:translateX(0);opacity:.55;}
  50%{transform:translateX(-5px);opacity:1;}
}
@media (max-width:680px){
  .ph-scroll-hint{display:flex;}
  /* Without this, the last visible column (e.g. a Status chip) gets
     sliced mid-word right at the card's edge — reads as broken rendering
     rather than "scroll for more". Fading it out instead signals there's
     more content that way, matching the arrow hint below. Scoped to the
     same breakpoint that actually forces the horizontal scroll. */
  .ph-table-wrap{
    -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
    mask-image:linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
  }
}
@media (prefers-reduced-motion: reduce){
  .ph-scroll-hint-icon svg, .ph-scroll-hint > svg{animation:none;}
}

.ph-pagination{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:10px;
  margin-top:20px;
  font-size:12.5px;
  font-weight:400;
  color:var(--blue-dark);
}

/* ============ TOP UP HISTORY — activity feed ============
   Grouped-by-day timeline (date header + a card of time-stamped rows)
   replacing the old plain table — one row per top-up, an icon/color
   that reads its outcome at a glance (confirmed/pending/rejected), and
   the amount right-aligned like a bank statement. */
.tuh-feed{display:flex;flex-direction:column;gap:20px;}
.tuh-day-label{
  font-size:13px;font-weight:700;color:var(--blue-mid);
  margin:0 0 10px 2px;
}
.tuh-day-card{
  background:#fff;border:1px solid #e6e9ec;border-radius:20px;
  overflow:hidden;
}
.tuh-row{
  display:flex;align-items:center;gap:14px;
  padding:16px 18px;
  border-bottom:1px solid #eef1ee;
}
.tuh-row:last-child{border-bottom:none;}
.tuh-row-time{flex-shrink:0;width:40px;font-size:12.5px;font-weight:400;color:#8ca1ac;}
.tuh-row-icon{
  flex-shrink:0;width:34px;height:34px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;color:#fff;
}
.tuh-row-icon svg{width:16px;height:16px;}
.tuh-row-icon--confirmed{background:#1f9d55;}
.tuh-row-icon--pending{background:#f39c1f;}
.tuh-row-icon--rejected{background:#c94b4b;}
.tuh-row-icon--refunded{background:#5a7a99;}
.tuh-row-text{flex:1;min-width:0;font-size:13.5px;font-weight:500;color:var(--blue-dark);line-height:1.45;}
.tuh-row-amount{flex-shrink:0;font-size:15px;font-weight:700;white-space:nowrap;color:var(--blue-dark);}
.tuh-row-amount--positive{color:#1f9d55;}
.tuh-row-amount--muted{color:#8ca1ac;}
.tuh-row-amount--negative{color:#c94b4b;}
.tuh-empty{
  padding:30px 20px;text-align:center;color:var(--blue-mid);font-weight:400;font-size:13.5px;
  background:#fff;border:1px solid #e6e9ec;border-radius:20px;
}
@media (max-width:560px){
  .ph-title{font-size:24px;}
  .ph-title-row svg{width:28px;height:28px;}
  .ph-subnav{gap:16px;flex-wrap:wrap;row-gap:10px;}
  .ph-filter-grid{grid-template-columns:1fr;}
  .ph-filter-grid--4{grid-template-columns:1fr;}
  .ph-date-row{grid-template-columns:1fr;}
  .tuh-row{padding:13px 14px;gap:10px;}
  .tuh-row-time{width:34px;font-size:11.5px;}
  .tuh-row-icon{width:28px;height:28px;}
  .tuh-row-icon svg{width:13px;height:13px;}
  .tuh-row-text{font-size:12.5px;}
  .tuh-row-amount{font-size:13px;}
}
