/* Auth and customer dashboard. Extends the tokens in ip2.css. */

/* --- shared form field --- */
.field { display: block; margin-bottom: 16px; }
.field > span {
  display: block; margin-bottom: 6px;
  font-size: 14px; font-weight: 700; color: var(--ink-strong);
}
.field input, .field select {
  width: 100%; height: 46px; padding: 0 13px;
  font: inherit; color: var(--ink);
  background: #fff; border: 2px solid #e2e8f5; border-radius: var(--r);
  transition: border-color .15s;
}
.field select { cursor: pointer; }
.field input:focus, .field select:focus { border-color: var(--blue); outline: none; }

/* --- login --- */
.auth {
  min-height: calc(100vh - var(--header-h) - 90px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 48px 20px; background: var(--bg-soft);
}
/* Sign-in sits beside a panel of what the account is actually for. A lone form
   on an empty page asks for an email without ever saying what it buys. */
.auth__grid {
  display: grid; grid-template-columns: 440px minmax(0, 1fr);
  gap: 44px; align-items: center; max-width: 980px;
}
.auth__card {
  width: 100%; max-width: 440px; background: #fff;
  border: 1px solid #e6eaf2; border-radius: var(--r-xl);
  box-shadow: var(--shadow); overflow: hidden;
}

.auth__offer {
  display: grid; grid-template-columns: auto 1fr; gap: 8px 18px;
  align-items: baseline; margin-bottom: 26px; padding: 20px 24px;
  border-radius: var(--r-xl); background: #eefaf1; border: 1px solid #c9ecd5;
}
.auth__offer-tag {
  grid-column: 1 / -1; font-size: 12px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: #157a37;
}
.auth__offer b {
  font-size: 46px; font-weight: 900; color: #157a37; line-height: 1;
  letter-spacing: -1.5px; white-space: nowrap;
}
.auth__offer span:last-child { font-size: 15px; line-height: 1.55; color: #1d5c33; }

.auth__list { list-style: none; margin: 0 0 22px; padding: 0; }
.auth__list li {
  position: relative; padding-left: 28px; margin-bottom: 12px;
  font-size: 15px; line-height: 1.5; color: var(--ink);
}
.auth__list li::before {
  content: "\2713"; position: absolute; left: 0; top: -1px;
  width: 19px; height: 19px; border-radius: 50%;
  background: var(--tint-2); color: var(--blue-ink);
  font-size: 11px; font-weight: 900; display: grid; place-items: center;
}
.auth__list b { font-weight: 800; color: var(--ink-strong); }
.auth__side-note { font-size: 14px; color: var(--muted); margin: 0; }

/* Passwords are easy to mistype and there is no reset link that works without
   mail configured, so let people read what they typed. */
.field--pw { position: relative; }
.field--pw input { padding-right: 66px; }
.field__eye {
  position: absolute; right: 10px; bottom: 9px;
  background: none; border: 0; cursor: pointer; padding: 6px 8px;
  font: inherit; font-size: 13px; font-weight: 800; color: var(--blue);
}
.field__eye:hover { color: var(--blue-ink); }
.auth__forgot { margin: -8px 0 18px; font-size: 13.5px; text-align: right; }

@media (max-width: 940px) {
  .auth__grid { grid-template-columns: 1fr; gap: 30px; justify-items: center; }
  .auth__side { max-width: 440px; }
}
.auth__tabs { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid #eaeef6; }
.auth__tab {
  padding: 15px 10px; font: inherit; font-weight: 700; color: var(--muted);
  background: #fafbfd; border: 0; border-bottom: 3px solid transparent; cursor: pointer;
}
.auth__tab.is-on { color: var(--blue-ink); background: #fff; border-bottom-color: var(--blue); }
.auth__card form { padding: 28px; }
.auth__title { font-size: 26px; margin-bottom: 6px; }
.auth__sub { font-size: 15px; color: var(--muted); margin-bottom: 22px; }
.auth__note { margin: 16px 0 0; font-size: 14px; color: var(--muted); text-align: center; }

/* The email-confirmation page has no form, so it needs the padding the form
   would otherwise carry. */
.auth__card > div { padding: 28px; }
.auth__alt { margin: 16px 0 0; font-size: 14px; color: var(--muted); }

.verify-banner {
  display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
  margin: 18px 0 0; padding: 15px 18px; border-radius: var(--r-lg);
  background: #fff6e6; border: 1px solid #ffe0ad; color: #6b3f05;
  font-size: 14.5px; line-height: 1.55;
}
.verify-banner > div { flex: 1 1 320px; }
.verify-banner b { color: #7a3d00; }

/* ---------- balance ---------- */
.bal {
  display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: baseline;
  margin: 0 0 26px; padding: 20px 22px; border-radius: var(--r-lg);
  background: linear-gradient(135deg, var(--blue-ink), var(--blue-600));
  color: #fff;
}
.bal__now { display: flex; flex-direction: column; gap: 4px; }
.bal__label { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; opacity: .78; }
.bal__now b { font-size: 38px; font-weight: 900; line-height: 1; }
.bal__hint { flex: 1 1 260px; margin: 0; font-size: 14px; line-height: 1.55; opacity: .9; }

.bal__steps { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 18px; }
.bal__step {
  min-width: 92px; height: 46px; padding: 0 20px; cursor: pointer;
  border: 2px solid var(--line); border-radius: var(--r);
  background: #fff; color: var(--ink);
  font: 700 17px/1 inherit;
  transition: border-color .12s, color .12s, transform .12s;
}
.bal__step:hover { border-color: var(--blue); color: var(--blue); transform: translateY(-1px); }

.bal__own { max-width: 420px; }
.bal__own label { display: block; margin: 0 0 7px; font-size: 14px; color: var(--muted); }
.bal__own-row { display: flex; align-items: center; gap: 9px; }
.bal__cur { font-size: 19px; font-weight: 700; color: var(--muted); }
.bal__own-row input {
  flex: 1 1 auto; min-width: 0; height: 46px; padding: 0 13px;
  border: 2px solid var(--line); border-radius: var(--r);
  font: 400 16px/1 inherit; color: var(--ink);
}
.bal__own-row input:focus { outline: none; border-color: var(--blue); }
.bal__note { margin: 9px 0 0; font-size: 13.5px; color: var(--muted); line-height: 1.5; }

/* The free gigabyte. Green rather than the amber of a warning, because this is
   something being offered, not something the customer has got wrong. */
.claim-box {
  display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
  margin: 18px 0 0; padding: 18px 20px; border-radius: var(--r-lg);
  background: linear-gradient(135deg, #eefaf1, #e3f4fb);
  border: 1px solid #c9ecd5; color: #1d5c33;
  font-size: 14.5px; line-height: 1.55;
}
.claim-box__text { flex: 1 1 340px; }
.claim-box b { color: #157a37; font-weight: 900; }
.claim-box__note {
  flex: 1 1 100%; margin: 2px 0 0; font-size: 13.5px;
  color: #2c6b45; line-height: 1.5;
}
.auth__gift {
  display: flex; gap: 12px; align-items: baseline; margin: 0 0 22px;
  padding: 16px 18px; border-radius: var(--r-lg);
  background: #eefaf1; border: 1px solid #c9ecd5; color: #1d5c33;
  font-size: 14.5px; line-height: 1.5;
}
.auth__gift b { font-size: 22px; font-weight: 900; color: #157a37; white-space: nowrap; }
.auth__help { margin-top: 22px; max-width: 440px; font-size: 14px; color: var(--muted); text-align: center; }
.auth__err, .pcard__err {
  margin: 0 0 16px; padding: 11px 13px; border-radius: var(--r);
  background: #fdeced; border: 1px solid #f3b9bb; color: #a32126;
  font-size: 14px; line-height: 1.45;
}

/* --- dashboard ---
   A left rail that stays put and one view at a time beside it, which is how
   the original account area was laid out. The rail carries the thing a
   customer opens this page to see -- how much traffic is left -- so it is
   answered before they have clicked anything. */
.dash { padding: 28px 0 64px; background: var(--bg-soft); min-height: 78vh; }
.dash__in { display: grid; grid-template-columns: 248px minmax(0, 1fr); gap: 28px; align-items: start; }

.dash__side {
  position: sticky; top: calc(var(--header-h) + 18px);
  background: #fff; border: 1px solid #e6eaf2; border-radius: var(--r-xl);
  padding: 20px 16px; box-shadow: var(--shadow);
}
.dash__me { display: flex; align-items: center; gap: 11px; margin-bottom: 18px; }
.dash__avatar {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  background: var(--blue); color: #fff; font-weight: 900; font-size: 17px;
  display: grid; place-items: center;
}
.dash__who { min-width: 0; }
.dash__who b {
  display: block; font-size: 13.5px; color: var(--ink-strong);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash__who small { font-size: 12px; color: var(--muted-2); }

.dash__balance {
  margin-bottom: 18px; padding: 14px 16px; border-radius: var(--r-lg);
  background: linear-gradient(135deg, #7b5cff, #4b3fca); color: #fff;
}
.dash__balance-l { display: block; font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; opacity: .75; }
.dash__balance b { font-size: 30px; font-weight: 900; letter-spacing: -1px; line-height: 1.15; }
.dash__balance-u { font-size: 14px; font-weight: 700; opacity: .8; margin-left: 4px; }

.dash__nav { display: flex; flex-direction: column; gap: 2px; margin-bottom: 18px; }
.dash__nav a {
  padding: 9px 12px; border-radius: var(--r); font-size: 14.5px; font-weight: 600;
  color: var(--ink); text-decoration: none; transition: background .12s, color .12s;
}
.dash__nav a:hover { background: var(--tint-2); }
.dash__nav a.is-on { background: var(--tint-2); color: var(--blue-ink); font-weight: 800; }
.dash__ops { margin-top: 8px; border-top: 1px solid #eef1f7; padding-top: 14px !important; color: var(--muted) !important; }

.dash__out {
  width: 100%; padding: 9px 12px; font: inherit; font-size: 14px; font-weight: 700;
  color: var(--muted); background: none; border: 1px solid #e6eaf2;
  border-radius: var(--r); cursor: pointer;
}
.dash__out:hover { color: #a32126; border-color: #f3b9bb; }

/* One view is visible at a time; the rest are simply not rendered. */
.view { display: none; }
.view.is-on { display: block; }
.view__head { margin-bottom: 22px; }
.view__head h1 { font-size: clamp(24px, 2.6vw, 32px); margin-bottom: 6px; }
.view__head p { color: var(--muted); margin: 0; max-width: 60ch; }

/* The console strip.
   Modelled on their own desktop manager, which put three things across the top
   and nothing else: what you have left, what state you are in, and the button
   that turns one into the other. Four plain equal tiles read as a report; this
   reads as a control panel, which is what the page is. */
.console {
  display: grid; grid-template-columns: 1.15fr 1fr .85fr 1.1fr; gap: 14px;
  margin-bottom: 22px;
}
.console__tile {
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid #e6eaf2; border-radius: var(--r-xl);
  padding: 16px 18px 15px; box-shadow: var(--shadow);
}
.console__l {
  font-size: 11.5px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted-2); margin-bottom: 8px;
}
.console__v {
  font-size: 30px; font-weight: 900; line-height: 1; letter-spacing: -1px;
  color: var(--blue-ink); font-variant-numeric: tabular-nums;
}
.console__u { font-size: 13px; font-weight: 800; color: var(--muted-2); margin-left: 4px; }
.console__note { margin-top: 7px; font-size: 12px; line-height: 1.4; color: var(--muted-2); }
.console__tile .btn { margin-top: 13px; align-self: flex-start; }

/* The balance wears the brand colour on purpose: it is the number people open
   this page to read, and the only one that costs money to change. */
.console__tile--balance { background: var(--blue-ink); border-color: var(--blue-ink); }
.console__tile--balance .console__l { color: rgba(255, 255, 255, .6); }
.console__tile--balance .console__v { color: #fff; }
.console__tile--balance .console__u,
.console__tile--balance .console__note { color: rgba(255, 255, 255, .72); }
.console__tile--balance .btn { background: #fff; color: var(--blue-ink); border-color: #fff; }
.console__tile--balance .btn:hover { background: #eaf1ff; border-color: #eaf1ff; }

.console__meter {
  height: 5px; margin-top: 11px; border-radius: 99px;
  background: #eef1f7; overflow: hidden;
}
.console__meter i { display: block; height: 100%; background: var(--blue); border-radius: 99px; }

/* The primary action, sized so it is never the thing you have to hunt for. */
.console__go {
  display: flex; flex-direction: column; justify-content: center;
  padding: 16px 20px; border-radius: var(--r-xl); text-decoration: none;
  background: var(--blue); color: #fff; border: 1px solid var(--blue);
  box-shadow: 0 8px 20px rgba(60, 127, 255, .26);
  transition: transform .15s, box-shadow .15s;
}
.console__go:hover { transform: translateY(-1px); box-shadow: 0 12px 26px rgba(60, 127, 255, .34); }
.console__go b { font-size: 19px; font-weight: 900; letter-spacing: -.3px; }
.console__go small { margin-top: 5px; font-size: 12.5px; color: rgba(255, 255, 255, .82); }

/* the running bonus, only rendered when one is genuinely running */
/* A standing offer stated once, in the house blue. The orange countdown that
   used to sit here shouted at the customer every time they came for proxies. */
.note {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px;
  margin-bottom: 22px; padding: 12px 16px; border-radius: var(--r-lg);
  background: #eef4ff; border: 1px solid #d3e2fb; color: #1b3a6b;
}
.note__txt { flex: 1 1 280px; font-size: 14.5px; line-height: 1.5; }
.note__txt b { font-weight: 800; color: var(--blue); }
.note__go { font-size: 14px; font-weight: 700; white-space: nowrap; }

/* The generator stays usable with an empty balance: the controls work and the
   output shows the shape of a real line, so a new customer can see what they
   are buying before they buy it. */
.gen__go { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 16px; }
.gen__locked { font-size: 14px; color: var(--muted); line-height: 1.5; }
.gen__locked a { font-weight: 700; }
.gen__sample {
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #9aa4b8;
}
.gen__out:has(.gen__sample:not([hidden])) textarea { color: #8e99ad; }

.panel__h2 { font-size: 20px; margin: 0 0 14px; }

.pcard {
  background: #fff; border: 1px solid #e6eaf2; border-radius: var(--r-xl);
  padding: 24px; box-shadow: var(--shadow); margin-bottom: 22px;
}
.pcard h2 { font-size: 20px; margin-bottom: 8px; }
.pcard__lead { color: var(--muted); font-size: 15px; margin-bottom: 18px; }
.pcard--empty { text-align: center; padding: 44px 26px; }
.pcard__ok {
  margin: 0 0 16px; padding: 11px 13px; border-radius: var(--r);
  background: var(--green-tint); border: 1px solid #c9ecd5; color: #1d5c33;
  font-size: 14px;
}

/* plan cards */
.plans-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: 16px; margin-bottom: 22px; }
.plan-card {
  background: #fff; border: 1px solid #e6eaf2; border-radius: var(--r-xl);
  padding: 18px 20px; box-shadow: var(--shadow);
}
.plan-card.is-low { border-color: #ffd8a8; }
.plan-card__top { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.plan-card__top h3 { font-size: 15.5px; margin: 0; }
.plan-card__id { font-size: 12px; color: var(--muted-2); font-family: ui-monospace, Menlo, Consolas, monospace; }
.plan-card__gb { margin: 12px 0 8px; font-size: 14px; color: var(--muted); }
.plan-card__gb b { font-size: 26px; font-weight: 900; color: var(--blue-ink); letter-spacing: -.6px; }
.plan-card__gb span { font-size: 13px; }
.plan-card__foot { display: flex; justify-content: space-between; margin-top: 10px; font-size: 12.5px; color: var(--muted-2); }
.plan-card__warn { margin: 10px 0 0; font-size: 13px; color: #c2410c; font-weight: 700; }

.meter { height: 8px; background: #eef1f7; border-radius: 99px; overflow: hidden; }
.meter i { display: block; height: 100%; background: var(--green); border-radius: 99px; }
.meter i.is-low { background: var(--amber); }

/* generator */
.gen__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0 16px; margin-bottom: 8px; }
.gen__out { margin-top: 22px; }
.gen__bar { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 10px; font-weight: 700; color: var(--ink-strong); }
.gen__actions { display: flex; gap: 8px; }
.gen__out textarea {
  width: 100%; padding: 14px; resize: vertical;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px; line-height: 1.65;
  color: var(--ink-strong); background: #fafbfd;
  border: 2px solid #e2e8f5; border-radius: var(--r);
}
.gen__out textarea:focus { border-color: var(--blue); outline: none; }
.gen__hint { margin: 10px 0 0; font-size: 13px; color: var(--muted); }
.gen__hint code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; background: var(--tint-2); padding: 2px 6px; border-radius: var(--r-sm); }

/* tables */
.table-wrap {
  background: #fff; border: 1px solid #e6eaf2; border-radius: var(--r-xl);
  box-shadow: var(--shadow); overflow-x: auto;
}
.ptable { width: 100%; border-collapse: collapse; min-width: 520px; }
.ptable th, .ptable td { padding: 12px 18px; text-align: left; font-size: 14.5px; }
.ptable th {
  font-size: 12px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--muted-2); background: #fafbfd; border-bottom: 1px solid #eaeef6;
}
.ptable td { border-bottom: 1px solid #f2f4f9; }
.ptable tr:last-child td { border-bottom: 0; }
.ptable .plus { color: #0a7a34; font-weight: 800; }
.ptable .minus { color: #a32126; font-weight: 800; }
.ptable .muted { color: var(--muted-2); }

.deflist { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 12px 18px; margin: 0; }
.deflist dt { font-size: 13px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--muted-2); }
.deflist dd { margin: 0; font-size: 15px; color: var(--ink-strong); }

/* help */
.help-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; margin-bottom: 22px; }
.help-card {
  display: block; padding: 18px 20px; text-decoration: none; color: inherit;
  background: #fff; border: 1px solid #e6eaf2; border-radius: var(--r-xl);
  box-shadow: var(--shadow); transition: border-color .15s, transform .15s;
}
.help-card:hover { border-color: var(--blue); transform: translateY(-2px); }
.help-card h3 { font-size: 15.5px; margin: 0 0 6px; color: var(--blue-ink); }
.help-card p { margin: 0; font-size: 13.5px; color: var(--muted); line-height: 1.5; }

.badge { display: inline-block; padding: 3px 10px; border-radius: 99px; font-size: 13px; font-weight: 700; }
.badge.is-ok { background: var(--green-tint); color: #3f7f02; }
.badge.is-wait { background: #fff7e8; color: #a3690b; }
.badge.is-bad { background: #fdeced; color: #a32126; }

/* slim footer for logged-in pages */
.ftr--slim { padding: 22px 0; background: var(--blue-ink); }
.ftr--slim .ftr__bottom { margin: 0; padding: 0; border: 0; }

.has-dash .burger { display: none; }

/* --- redeeming a prepaid key --- */
.redeem__row { display: flex; gap: 10px; flex-wrap: wrap; }
.redeem__row input {
  flex: 1 1 300px; min-width: 0;
  /* keys get read off screenshots and retyped, so even spacing earns its keep */
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 15px; letter-spacing: .06em; text-transform: uppercase;
  padding: 12px 14px; border: 1px solid #d9e0ec; border-radius: var(--r);
  background: #fff; color: var(--ink);
}
.redeem__row input:focus {
  outline: none; border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(60, 127, 255, .16);
}
.redeem__row input::placeholder {
  letter-spacing: .04em; opacity: .45; text-transform: none;
}
.redeem__msg {
  margin: 12px 0 0; padding: 11px 13px; border-radius: var(--r);
  font-size: 14px; line-height: 1.45;
}
.redeem__msg.is-ok {
  background: #eef8e6; color: #3f7f02; border: 1px solid #cfe8ab;
}
.redeem__msg.is-bad {
  background: #fdeced; color: #a32126; border: 1px solid #f3b9bb;
}


@media (max-width: 1000px) {
  /* Two across, with the action tile dropping under the numbers rather than
     being squeezed to a strip too narrow to read. */
  .console { grid-template-columns: repeat(2, 1fr); }
  .console__go { grid-column: span 2; }
}
@media (max-width: 860px) {
  .dash__in { grid-template-columns: 1fr; }
  /* On a phone the rail becomes a drawer behind the burger, so the content
     starts at the top of the screen instead of below a column of links. */
  .has-dash .burger { display: block; }
  .dash__side { position: static; display: none; }
  .dash-open .dash__side { display: block; }
}
@media (max-width: 620px) {
  .console { grid-template-columns: 1fr 1fr; gap: 10px; }
  .console__tile { padding: 13px 14px; }
  .console__v { font-size: 24px; }
  .gen__bar { flex-direction: column; align-items: flex-start; }
  .deflist { grid-template-columns: 1fr; gap: 4px 0; }
  .deflist dd { margin-bottom: 10px; }
}


/* ------------------------------------------------------- support threads
   A conversation reads better than a table of tickets, so it is laid out like
   one: our answers on the left in our blue, the customer's own words on the
   right, oldest first. */
.ask--panel { background: transparent; border: 0; padding: 0; margin: 18px 0 0; }
.ask--panel .ask__row { margin: 0 0 14px; }
.ask--panel label {
  display: block; margin: 0 0 6px;
  font-size: 13px; font-weight: 700; color: var(--ink-strong);
}
.ask--panel select, .ask--panel textarea {
  width: 100%; padding: 11px 13px; font: inherit; font-size: 15px;
  color: var(--ink-strong); background: #fff;
  border: 1px solid var(--line); border-radius: 9px; outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.ask--panel select:focus, .ask--panel textarea:focus {
  border-color: var(--blue); box-shadow: 0 0 0 3px rgba(60,127,255,.15);
}
.ask--panel textarea { resize: vertical; min-height: 110px; line-height: 1.6; }
.ask__end { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; }
.ask__msg { font-size: 14px; color: var(--muted); }
.ask__msg.is-ok { color: #2f7d18; }
.ask__msg.is-bad { color: #c0392b; }

.threads { display: grid; gap: 12px; }
.thread {
  border: 1px solid var(--line); border-radius: 12px;
  background: #fff; overflow: hidden;
}
.thread > summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 16px; cursor: pointer; list-style: none;
  font-size: 15px; color: var(--ink-strong);
}
.thread > summary::-webkit-details-marker { display: none; }
.thread > summary em {
  margin-left: auto; font-style: normal;
  font-size: 13px; color: var(--muted);
}
.thread__st {
  padding: 2px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .04em;
}
.thread__st--open { background: #fff4e2; color: #9a6100; }
.thread__st--answered { background: #eaf7e2; color: #2f7d18; }
.thread__st--closed { background: var(--bg-soft); color: var(--muted); }

.thread__msgs {
  display: grid; gap: 10px;
  padding: 4px 16px 14px; border-top: 1px solid var(--line);
}
.msg { max-width: 82%; padding: 11px 14px; border-radius: 12px; }
.msg__who {
  display: flex; gap: 8px; align-items: baseline;
  margin: 0 0 4px; font-size: 12px; font-weight: 800;
}
.msg__who span { font-weight: 400; opacity: .7; }
.msg__body { font-size: 15px; line-height: 1.6; white-space: pre-wrap; }
.msg--them { background: var(--bg-soft); color: var(--ink-strong); }
.msg--mine {
  margin-left: auto; background: var(--blue); color: #fff;
}

.thread__reply { display: flex; gap: 10px; padding: 0 16px 16px; }
.thread__reply textarea {
  flex: 1; padding: 10px 13px; font: inherit; font-size: 15px;
  border: 1px solid var(--line); border-radius: 9px;
  resize: vertical; outline: none;
}
.thread__reply textarea:focus { border-color: var(--blue); }

@media (max-width: 700px) {
  .msg { max-width: 100%; }
  .thread__reply { flex-direction: column; }
}


/* ------------------------------------------------------- reseller keys
   Three numbers at the top, because those are what a reseller checks before
   deciding anything: what is left to sell, what is out there unsold, and what
   their customers have actually taken. */
.rk-top {
  display: grid; gap: 14px; margin-bottom: 20px;
  grid-template-columns: 1.3fr 1fr 1fr;
}
.rk-tile {
  padding: 18px 20px; background: #fff;
  border: 1px solid var(--line); border-radius: 14px;
}
.rk-tile--main {
  color: #fff; border-color: transparent;
  background: linear-gradient(135deg, #5a4bdf 0%, #4b3fca 100%);
}
.rk-tile__l {
  display: block; margin-bottom: 8px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; opacity: .75;
}
.rk-tile__v {
  display: block; font-size: 30px; font-weight: 900; line-height: 1.1;
  letter-spacing: -.02em; color: var(--ink-strong);
}
.rk-tile--main .rk-tile__v { color: #fff; }
.rk-tile__v i { font-size: 15px; font-weight: 700; font-style: normal; margin-left: 5px; opacity: .8; }
.rk-tile__n { display: block; margin-top: 6px; font-size: 12.5px; color: var(--muted); }
.rk-tile--main .rk-tile__n { color: rgba(255,255,255,.75); }

/* Generating is two numbers and a button; anything more would be a form. */
.rk-form {
  display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap;
  margin-top: 18px;
}
.rk-form label {
  display: block; font-size: 12px; font-weight: 800;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
.rk-form input {
  display: block; width: 130px; margin-top: 7px; padding: 11px 13px;
  font: inherit; font-size: 17px; font-weight: 700; letter-spacing: 0;
  text-transform: none; color: var(--ink-strong);
  border: 1px solid var(--line); border-radius: 9px; background: #fff;
}
.rk-form input:focus { border-color: var(--blue); outline: none; }
.rk-unit { position: relative; display: block; }
.rk-unit i {
  position: absolute; right: 13px; bottom: 12px;
  font-style: normal; font-size: 13px; font-weight: 700; color: var(--muted);
}
.rk-form__go { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* The running total is the guard rail: it says what this will cost before the
   button is pressed, so being short is never a surprise. */
.rk-cost { font-size: 13.5px; color: var(--muted); }
.rk-cost.is-bad { color: #c0392b; font-weight: 700; }

.rk-msg { margin: 14px 0 0; font-size: 14px; color: var(--muted); }
.rk-msg.is-ok { color: #2f7d18; }
.rk-msg.is-bad { color: #c0392b; }

.rk-out { margin-top: 18px; }
.rk-out__head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; margin-bottom: 9px; font-size: 14.5px;
}
.rk-out__head span { display: flex; gap: 8px; }
.rk-out textarea {
  width: 100%; padding: 13px 15px; resize: vertical;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px; line-height: 1.8; letter-spacing: .05em; color: var(--ink-strong);
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 10px;
}

.rk-filters { display: flex; gap: 10px; margin: 4px 0 14px; flex-wrap: wrap; }
.rk-filters select, .rk-filters input {
  font: inherit; font-size: 14px; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: 9px; background: #fff;
}
.rk-filters input { flex: 1; min-width: 200px; }

.rk-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px; letter-spacing: .04em; white-space: nowrap;
}
.rk-acts { display: flex; gap: 6px; white-space: nowrap; }
.rk-note { margin: 14px 0 0; font-size: 13px; line-height: 1.6; color: var(--muted); max-width: 72ch; }

.ptag {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
}
.ptag--unused { background: #fdf3e3; color: #8a5a11; }
.ptag--redeemed { background: #e8f6ec; color: #1c6b33; }
.ptag--revoked { background: var(--bg-soft); color: var(--muted); }
.pempty { padding: 22px 18px; color: var(--muted); font-size: 14.5px; }

@media (max-width: 900px) {
  .rk-top { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .rk-form { gap: 12px; }
  .rk-form input { width: 100%; }
  .rk-form label, .rk-form__go { width: 100%; }
  .rk-form__go .btn { width: 100%; }
}


/* Two thousand keys is a legitimate amount to be holding and an illegitimate
   amount to scroll past, so the list gets its own window. */
.rk-scroll { max-height: 520px; overflow-y: auto; }
.rk-scroll thead th { position: sticky; top: 0; z-index: 1; }
.rk-count { margin: 10px 0 0; font-size: 13px; color: var(--muted); }


/* Forwarding is optional, so it sits on its own row under the two numbers that
   actually decide the batch, and says out loud that it can be left alone. */
.rk-form__wide { grid-column: 1 / -1; }
.rk-form__wide i {
  font-style: normal; font-weight: 600; font-size: 12px; color: #9aa4b8;
  text-transform: uppercase; letter-spacing: .05em; margin-left: 6px;
}
.rk-form__wide input { width: 100%; max-width: 420px; }
.rk-form__wide small {
  display: block; margin-top: 7px; max-width: 520px;
  font-size: 13px; line-height: 1.55; color: var(--muted);
  font-weight: 400; text-transform: none; letter-spacing: 0;
}


/* ============================================================ dashboard skin

   Set at the size someone actually reads at. The panel is a working screen,
   used daily, often quickly — so the numbers are large, the labels are dark
   enough to read, and there is exactly one thing on the page that looks like
   the main button. */

.panel, .dash { background: #f2f5fa; }

/* --- headings --- */
.view__head { margin-bottom: 22px; }
.view__head h1 {
  font-size: clamp(30px, 3.4vw, 40px); font-weight: 900;
  letter-spacing: -1px; color: #241f47; margin-bottom: 7px;
}
.view__head p { font-size: 16px; line-height: 1.55; color: #5a6a85; margin: 0; }
.panel__h2 {
  font-size: 22px; font-weight: 900; letter-spacing: -.4px;
  color: #241f47; margin: 0 0 14px;
}

/* --- the rail --- */
.dash__side {
  background: #241f47; border: 0; box-shadow: none;
  padding: 20px 14px 16px; border-radius: 14px;
}
.dash__me { align-items: center; }
.dash__who b { color: #fff; font-size: 14.5px; }
.dash__who small { color: #8ba1c4; font-size: 12.5px; }
.dash__avatar {
  background: #5a4bdf; color: #fff; font-weight: 900; font-size: 17px;
}

.dash__balance {
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .1); border-radius: 11px;
  padding: 14px 16px;
}
.dash__balance-l {
  color: #8ba1c4; opacity: 1; font-size: 11.5px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase;
}
.dash__balance b {
  color: #fff; font-size: 34px; font-weight: 900; letter-spacing: -1.2px;
}
.dash__balance-u { color: #8ba1c4; opacity: 1; font-weight: 700; }

.dash__nav { gap: 2px; }
.dash__nav a {
  padding: 11px 14px; border-radius: 9px;
  font-size: 15px; font-weight: 700; color: #c2d2ea; border-left: 3px solid transparent;
}
.dash__nav a:hover { background: rgba(255, 255, 255, .07); color: #fff; }
.dash__nav a.is-on {
  background: #5a4bdf; color: #fff; font-weight: 800; border-left-color: #b9a9ff;
}

/* The link to the proxies is not one of seven equals. It is the reason the
   account exists, so it is marked as such before anything is clicked. */
.dash__nav a.dash__nav--main {
  background: rgba(90, 75, 223, .16); color: #fff; font-weight: 800;
  border-left-color: #5a4bdf;
}
.dash__nav a.dash__nav--main:hover { background: rgba(90, 75, 223, .3); }
.dash__nav a.dash__nav--main.is-on { background: #5a4bdf; }

.dash__ops {
  margin-top: 8px; padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, .12) !important;
  color: #8ba1c4 !important; font-size: 13.5px !important;
}
.dash__out {
  background: transparent; color: #8ba1c4; font-weight: 700;
  border: 1px solid rgba(255, 255, 255, .14); border-radius: 9px; padding: 11px;
}
.dash__out:hover { color: #ff9095; border-color: rgba(255, 144, 149, .45); }

/* --- the one action --- */
.usebar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; margin-bottom: 22px; padding: 24px 26px;
  border-radius: 14px; text-decoration: none;
  background: #241f47; box-shadow: none;
  border: 0; transition: background .12s;
}
.usebar:hover { background: #2c2456; transform: none; }
.usebar__l b {
  display: block; margin-bottom: 6px;
  font-size: 24px; font-weight: 900; letter-spacing: -.6px; color: #fff;
}
.usebar__l small {
  display: block; max-width: 580px;
  font-size: 15px; line-height: 1.55; color: #b3c7e8;
}
.usebar__go {
  flex: none; padding: 15px 30px; border-radius: 10px;
  background: #5a4bdf; color: #fff; font-size: 17px; font-weight: 900;
  letter-spacing: -.2px; white-space: nowrap;
}
.usebar:hover .usebar__go { background: #6f4fdf; }

/* --- the numbers --- */
.console { grid-template-columns: repeat(3, 1fr); gap: 14px; }
.console__tile {
  background: #fff; border: 1px solid #dbe3f0; border-radius: 13px;
  padding: 20px 22px; box-shadow: none;
}
/* The balance stops wearing the brand colour here: the rail already shows it
   in navy, and the text rules written for that dark tile were still in force,
   which is what made the number disappear against a white background. */
.console__tile--balance { background: #fff; border-color: #b9cdf5; }
.console__tile--balance .console__l,
.console__tile--balance .console__u,
.console__tile--balance .console__note { color: #6b7c99; }
.console__tile--balance .console__v { color: #241f47; }
.console__tile--balance .btn {
  background: #5a4bdf; border-color: #5a4bdf; color: #fff;
}
.console__tile--balance .btn:hover { background: #6f4fdf; border-color: #6f4fdf; }
.console__l {
  font-size: 11.5px; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: #6b7c99;
}
.console__v {
  font-size: 42px; font-weight: 900; letter-spacing: -1.8px; color: #241f47;
  line-height: 1.05;
}
.console__u { font-size: 17px; font-weight: 800; color: #6b7c99; margin-left: 5px; }
.console__note { font-size: 13.5px; color: #6b7c99; }
.console__meter { background: #e6ebf4; }

/* --- cards --- */
.pcard {
  background: #fff; border: 1px solid #dbe3f0; border-radius: 13px;
  padding: 24px 26px; box-shadow: none; margin-bottom: 20px;
}
.pcard h2 {
  font-size: 21px; font-weight: 900; letter-spacing: -.4px;
  color: #241f47; margin-bottom: 8px;
}
.pcard__lead { font-size: 15.5px; line-height: 1.6; color: #5a6a85; margin-bottom: 18px; }

.plan-card {
  background: #fff; border: 1px solid #dbe3f0; border-radius: 13px;
  padding: 20px 22px; box-shadow: none;
}
.plan-card__top h3 { font-size: 16.5px; font-weight: 800; color: #241f47; }
.plan-card__gb { font-size: 15px; color: #5a6a85; }
.plan-card__gb b { font-size: 34px; font-weight: 900; letter-spacing: -1.4px; color: #241f47; }
.plan-card__foot { font-size: 13px; color: #6b7c99; }

/* --- the standing offer --- */
/* A pale strip with small print reads as filler. If it is worth saying at all
   it is worth saying in a line that can be read at a glance. */
.note {
  background: #fff5e6; border: 1px solid #ffd79b; border-radius: 12px;
  padding: 15px 20px;
}
.note__txt { font-size: 15px; line-height: 1.55; color: #6b4405; }
.note__txt b { color: #9a5c00; font-weight: 900; }
.note__go { font-size: 15px; font-weight: 800; color: #9a5c00; }

/* --- tables --- */
.table-wrap { border: 1px solid #dbe3f0; border-radius: 13px; box-shadow: none; }
.ptable th, .ptable td { padding: 14px 20px; font-size: 15px; }
.ptable th {
  font-size: 11.5px; font-weight: 800; letter-spacing: .08em;
  color: #6b7c99; background: #f7f9fc;
}
.ptable td { color: #29364d; }

/* --- forms --- */
.field > span { font-size: 13px; font-weight: 800; color: #29364d; }
.field input, .field select {
  height: 48px; font-size: 15.5px; border: 1px solid #cfd9ea; border-radius: 10px;
}
.field input:focus, .field select:focus {
  border-color: #5a4bdf; box-shadow: 0 0 0 3px rgba(90, 75, 223, .14);
}

/* --- reseller tiles, matched to the rest --- */
.rk-tile { border: 1px solid #dbe3f0; border-radius: 13px; padding: 20px 22px; }
.rk-tile--main { background: #241f47; border-color: transparent; }
.rk-tile__v { font-size: 36px; letter-spacing: -1.4px; color: #241f47; }
.rk-tile--main .rk-tile__v { color: #fff; }
.rk-tile__l { font-size: 11.5px; letter-spacing: .08em; }

.view__tag {
  display: inline-block; vertical-align: middle; margin-left: 10px;
  padding: 5px 11px; border-radius: 99px;
  background: #e7efff; border: 1px solid #c3d8fb;
  font-size: 12px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: #1a4b99;
}

@media (max-width: 900px) {
  .usebar { flex-direction: column; align-items: flex-start; gap: 16px; }
  .usebar__go { width: 100%; text-align: center; }
}
@media (max-width: 620px) {
  .console__v { font-size: 32px; }
  .usebar__l b { font-size: 20px; }
}

/* ============================================================ country picker

   Drawn rather than borrowed from the operating system, so the flag and the
   country code can sit next to the name and the list can be searched. The
   native control is still underneath, holding the value. */

.pick { position: relative; }
/* Written specifically enough to beat ".field select", which sets the width
   of every dropdown on the page and was keeping this one at full size. */
.field select.pick__native, .pick__native {
  position: absolute; width: 1px; height: 1px; min-height: 0; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0; opacity: 0; pointer-events: none;
}

.pick__btn {
  display: flex; align-items: center; gap: 10px;
  width: 100%; height: 48px; padding: 0 13px;
  font: inherit; font-size: 15.5px; color: #241f47; text-align: left;
  background: #fff; border: 1px solid #cfd9ea; border-radius: 10px;
  cursor: pointer; transition: border-color .12s, box-shadow .12s;
}
.pick__btn:hover { border-color: #a9bcdc; }
.pick__btn[aria-expanded="true"] {
  border-color: #5a4bdf; box-shadow: 0 0 0 3px rgba(90, 75, 223, .14);
}
.pick__btn > span {
  flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; font-weight: 600;
}
.pick__caret {
  flex: none; width: 9px; height: 9px; margin-right: 2px;
  border-right: 2px solid #7c8ca8; border-bottom: 2px solid #7c8ca8;
  transform: rotate(45deg) translate(-2px, -2px);
}

.pick__pop {
  position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; right: 0;
  background: #fff; border: 1px solid #cfd9ea; border-radius: 12px;
  box-shadow: 0 18px 40px rgba(13, 31, 60, .18); overflow: hidden;
}
.pick__search {
  display: block; width: 100%; padding: 13px 15px;
  font: inherit; font-size: 15px; color: #241f47;
  border: 0; border-bottom: 1px solid #e6ecf6; outline: none;
}
.pick__search::placeholder { color: #93a2bb; }

/* Tall enough to show that the list is long, short enough to stay on screen. */
.pick__list { max-height: 300px; overflow-y: auto; padding: 6px; }
.pick__opt {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; border-radius: 8px; cursor: pointer;
  font-size: 15px; color: #29364d;
}
.pick__opt > span {
  flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
/* The two-letter code is what goes into the proxy line, so it is worth
   showing next to the name people search by. */
.pick__opt > em {
  font-style: normal; font-size: 12px; font-weight: 800; letter-spacing: .06em;
  color: #93a2bb;
}
.pick__opt:hover, .pick__opt.is-active { background: #f0f5ff; }
.pick__opt.is-on { background: #e7efff; color: #123a78; font-weight: 700; }
.pick__opt.is-on > em { color: #4d7dc9; }
.pick__none { margin: 0; padding: 18px 12px; font-size: 14.5px; color: #7c8ca8; }

/* ---------------------------------------------------------- the generator */

/* Six controls in a row of equal grey boxes gave no clue which one mattered.
   They are grouped now: what you are buying from, then where it comes out,
   then how many lines. */
.gen__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 16px 18px; margin-bottom: 20px;
}
.gen__grid .field { margin-bottom: 0; }
.gen__grid .field > span {
  font-size: 11.5px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: #6b7c99; margin-bottom: 7px;
}

#genBox { padding: 26px 28px; }
#genBtn { font-size: 16px; font-weight: 800; padding: 14px 32px; }

.gen__bar {
  font-size: 15px; color: #241f47; font-weight: 800;
  padding-bottom: 12px; border-bottom: 1px solid #e6ecf6;
}
.gen__out textarea {
  border: 1px solid #cfd9ea; border-radius: 11px; background: #f7f9fc;
  font-size: 13.5px; line-height: 1.75; padding: 15px;
}
.gen__hint { font-size: 13.5px; color: #5a6a85; line-height: 1.6; }

@media (max-width: 620px) {
  .pick__pop { left: -4px; right: -4px; }
}

/* ======================================================= generator controls

   The dropdowns are drawn in the picker rules above. These are the two
   controls left: how many lines, and the button that asks for them. */

/* Options that exist so people can see what is coming, but cannot be picked
   yet. Greyed rather than hidden, and marked so it is clear why. */
.pick__opt.is-off {
  color: #a3aec2; cursor: not-allowed;
}
.pick__opt.is-off:hover, .pick__opt.is-off.is-active { background: transparent; }
/* No "soon" badge here: the option text already ends in the word, and adding
   a second one reads like a bug. */

/* Short lists have no search box, so the panel should not leave a gap for one. */
.pick__pop--plain .pick__list { padding: 6px; }

/* Matches the height and the border of the dropdowns beside it, so the row
   reads as one set of controls rather than a form and a stray box. */
#genCount {
  height: 48px; font-size: 16px; font-weight: 700; color: #241f47;
  border: 1px solid #cfd9ea; border-radius: 10px;
}
#genCount:focus {
  border-color: #5a4bdf; box-shadow: 0 0 0 3px rgba(90, 75, 223, .14);
  outline: none;
}

/* What the selected product actually gives you, sitting between the controls
   and the button. Five products were on sale and nothing in the account said
   how any of them behaved, so people bought by name and hoped. */
.gen__facts {
  border: 1px solid #e2e9f4; border-radius: 12px; background: #f8fafd;
  padding: 4px 18px; margin: 0 0 20px;
}
.facts__row {
  display: grid; grid-template-columns: 190px 1fr; gap: 6px 20px;
  padding: 12px 0; border-top: 1px solid #e9eef7;
  font-size: 14px; line-height: 1.6;
}
.facts__row:first-child { border-top: 0; }
.facts__row b {
  font-size: 11.5px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: #6b7c99; padding-top: 2px;
}
.facts__row span { color: #2b3b57; }
/* The limits of a pool live in the same block as its selling points. */
.facts__row--limit span { color: #7a5a2a; }
.facts__row--limit b { color: #a8792f; }
@media (max-width: 620px) {
  .facts__row { grid-template-columns: 1fr; gap: 2px; padding: 11px 0; }
}

/* Said where a pool cannot hold an address, so the empty session dropdown
   beside it does not read as something that failed to load. */
.field__note {
  display: block; margin-top: 7px; font-size: 12.5px; font-style: normal;
  color: #7a889f; line-height: 1.5;
}

.pick.is-off { opacity: .62; }
.pick.is-off .pick__btn { cursor: not-allowed; background: #f4f7fb; }

.gen__go { margin-top: 4px; }
#genBtn {
  height: 52px; padding: 0 34px; border-radius: 11px;
  font-size: 16.5px; font-weight: 900; letter-spacing: -.2px;
  box-shadow: 0 6px 16px rgba(90, 75, 223, .28);
}
#genBtn:hover { box-shadow: 0 8px 20px rgba(90, 75, 223, .34); }
#genBtn:disabled { box-shadow: none; }

/* The copy and download controls sit above the output, where they read as
   part of the result rather than more form. */
.gen__actions .btn { height: 38px; padding: 0 16px; font-weight: 800; }

/* --- reseller API keys ---------------------------------------------------- */

/* The label and the button sit on one line at desk width and stack on a phone,
   which is where a key gets revoked in a hurry. */
.rk-api__new {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin: 14px 0 0;
}
.rk-api__new label {
  flex: 1 1 260px;
  display: grid;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2, #4a5568);
}
.rk-api__new label i {
  font-style: normal;
  font-weight: 400;
  opacity: .65;
}
.rk-api__new input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line, #dfe3ea);
  border-radius: 10px;
  font: inherit;
}
#rkApiKeys tr.is-dim { opacity: .5; }
#rkApiGw {
  margin-top: 10px;
  font-size: 13px;
  opacity: .8;
}
