/* ============ xcxc app shell (auth + LK) — matches the landing design system ============
   Theme: system by default, html[data-theme] wins (same contract as the landing).       */

:root{
  --bg:#f5f5f7; --bg-card:#ffffff; --panel:rgba(255,255,255,.72); --panel-border:rgba(0,0,0,.08);
  --ink:#1d1d1f; --ink-soft:#6e6e73; --ink-faint:#86868b; --hair:#d2d2d7;
  --accent:#0071e3; --accent-ink:#0067d6; --ok:#30a46c; --warn:#b7791f; --danger:#e5484d;
  --a-blue:#0a84ff; --a-indigo:#5e5ce6; --a-purple:#bf5af2; --a-pink:#ff375f; --a-cyan:#64d2ff;
  --grad:linear-gradient(90deg,var(--a-indigo),var(--a-purple) 40%,var(--a-pink));
  --shadow:0 8px 40px rgba(0,0,0,.06); --shadow-lg:0 20px 70px rgba(0,0,0,.10);
  --radius:20px; --radius-sm:12px;
  --font:-apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text","Segoe UI",system-ui,Roboto,Helvetica,Arial,sans-serif;
  --e:cubic-bezier(.22,.61,.36,1); --e-spring:cubic-bezier(.34,1.4,.5,1);
}
@media (prefers-color-scheme:dark){
  :root{
    --bg:#000; --bg-card:#101012; --panel:rgba(28,28,30,.62); --panel-border:rgba(255,255,255,.10);
    --ink:#f5f5f7; --ink-soft:#a1a1a6; --ink-faint:#86868b; --hair:#2a2a2c;
    --accent:#2997ff; --accent-ink:#2997ff; --danger:#ff6369;
    --a-blue:#409cff; --a-indigo:#7d7aff; --a-purple:#da8fff; --a-pink:#ff6482; --a-cyan:#70d7ff;
    --grad:linear-gradient(90deg,var(--a-cyan),var(--a-purple) 45%,var(--a-pink));
    --shadow:0 8px 40px rgba(0,0,0,.5); --shadow-lg:0 24px 80px rgba(0,0,0,.6);
  }
}
:root[data-theme="light"]{
  --bg:#f5f5f7; --bg-card:#ffffff; --panel:rgba(255,255,255,.72); --panel-border:rgba(0,0,0,.08);
  --ink:#1d1d1f; --ink-soft:#6e6e73; --ink-faint:#86868b; --hair:#d2d2d7;
  --accent:#0071e3; --accent-ink:#0067d6; --danger:#e5484d;
  --a-blue:#0a84ff; --a-indigo:#5e5ce6; --a-purple:#bf5af2; --a-pink:#ff375f; --a-cyan:#64d2ff;
  --grad:linear-gradient(90deg,var(--a-indigo),var(--a-purple) 40%,var(--a-pink));
  --shadow:0 8px 40px rgba(0,0,0,.06); --shadow-lg:0 20px 70px rgba(0,0,0,.10);
}
:root[data-theme="dark"]{
  --bg:#000; --bg-card:#101012; --panel:rgba(28,28,30,.62); --panel-border:rgba(255,255,255,.10);
  --ink:#f5f5f7; --ink-soft:#a1a1a6; --ink-faint:#86868b; --hair:#2a2a2c;
  --accent:#2997ff; --accent-ink:#2997ff; --danger:#ff6369;
  --a-blue:#409cff; --a-indigo:#7d7aff; --a-purple:#da8fff; --a-pink:#ff6482; --a-cyan:#70d7ff;
  --grad:linear-gradient(90deg,var(--a-cyan),var(--a-purple) 45%,var(--a-pink));
  --shadow:0 8px 40px rgba(0,0,0,.5); --shadow-lg:0 24px 80px rgba(0,0,0,.6);
}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{font-family:var(--font);background:var(--bg);color:var(--ink);line-height:1.5;
  -webkit-font-smoothing:antialiased;min-height:100vh;min-height:100dvh}
a{color:var(--accent-ink);text-decoration:none}
a:hover{text-decoration:underline}
::selection{background:var(--accent);color:#fff}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
[hidden]{display:none !important}

/* ---------- shared chrome ---------- */
.logo{display:inline-flex;align-items:center;gap:9px;font-weight:700;font-size:17px;
  letter-spacing:.04em;color:var(--ink);text-transform:uppercase}
.logo:hover{text-decoration:none}
.logo svg{width:26px;height:26px;border-radius:7px;flex:0 0 auto}

.iconbtn{width:40px;height:40px;border-radius:50%;border:1px solid var(--hair);background:transparent;
  color:var(--ink-soft);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  flex:0 0 auto;transition:color .2s,border-color .2s,transform .2s var(--e-spring);position:relative;overflow:hidden}
.iconbtn:hover{color:var(--ink);border-color:var(--accent)}
.iconbtn:active{transform:scale(.9)}
.iconbtn svg{width:17px;height:17px;position:absolute;transition:opacity .3s var(--e),transform .45s var(--e-spring)}
.iconbtn .ic-sun{opacity:0;transform:rotate(-90deg) scale(.4)}
.iconbtn .ic-moon{opacity:1}
:root[data-theme="dark"] .iconbtn .ic-sun{opacity:1;transform:none}
:root[data-theme="dark"] .iconbtn .ic-moon{opacity:0;transform:rotate(90deg) scale(.4)}

.langpill{font-size:12px;color:var(--ink-soft);border:1px solid var(--hair);border-radius:999px;
  padding:8px 12px;display:inline-flex;gap:4px;align-items:center;cursor:pointer;background:transparent;
  font-family:inherit;min-height:38px}
.langpill b{color:var(--ink);font-weight:600}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:inherit;
  font-size:15px;font-weight:600;letter-spacing:-.01em;border-radius:999px;padding:11px 20px;
  min-height:44px;cursor:pointer;border:1px solid transparent;white-space:nowrap;
  transition:transform .15s var(--e),background .2s,opacity .2s,border-color .2s}
.btn:active{transform:scale(.97)}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none}
.btn-primary{background:var(--accent);color:#fff}
.btn-primary:hover{background:color-mix(in srgb,var(--accent) 88%,#000)}
.btn-ghost{background:transparent;color:var(--accent-ink);border-color:var(--hair)}
.btn-ghost:hover{border-color:var(--accent)}
.btn-danger{background:transparent;color:var(--danger);border-color:var(--hair)}
.btn-danger:hover{border-color:var(--danger)}
.btn-sm{font-size:13px;padding:7px 14px;min-height:36px}
.btn-block{width:100%}
.btn .spinner{width:16px;height:16px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;
  animation:spin .7s linear infinite;display:none}
.btn.loading .spinner{display:inline-block}
.btn.loading .btn-label{opacity:.7}
@keyframes spin{to{transform:rotate(360deg)}}

/* Touch input: nothing tappable below the 44px guideline. Keyed on pointer:coarse
   so desktop keeps its tighter density. This app is the base for a mobile app,
   so touch ergonomics are a first-class requirement, not a small-screen fallback. */
@media (pointer:coarse){
  .btn-sm{min-height:44px;padding:10px 16px}
  .iconbtn{width:44px;height:44px}
  .langpill{min-height:44px;padding:10px 14px}
  .pw-toggle{min-height:44px;display:inline-flex;align-items:center}
}

/* Honeypot: must be reachable in the DOM (so a bot fills it) but never seen by a
   human or announced by a screen reader. Positioned off-screen rather than
   display:none, which naive bots know to skip. */
.hp-field{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}

/* ---------- forms ---------- */
.field{margin-bottom:16px;text-align:left}
.field label{display:block;font-size:13px;font-weight:600;color:var(--ink-soft);margin-bottom:6px}
.input{width:100%;font:inherit;font-size:16px;padding:12px 14px;min-height:48px;border:1px solid var(--hair);
  border-radius:var(--radius-sm);background:transparent;color:var(--ink);transition:border-color .2s}
.input:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent}
.input[aria-invalid="true"]{border-color:var(--danger)}
.field .hint{font-size:12px;color:var(--ink-faint);margin-top:5px}
.field .field-err{font-size:12.5px;color:var(--danger);margin-top:5px;display:none}
.field.invalid .field-err{display:block}
.pw-wrap{position:relative}
.pw-wrap .input{padding-right:74px}
.pw-toggle{position:absolute;right:6px;top:50%;transform:translateY(-50%);border:0;background:transparent;
  color:var(--accent-ink);font:inherit;font-size:12.5px;font-weight:600;cursor:pointer;padding:8px 10px;border-radius:8px}
.choice{display:flex;gap:8px}
.choice input{position:absolute;opacity:0;pointer-events:none}
.choice label{flex:1;border:1px solid var(--hair);border-radius:var(--radius-sm);padding:10px 12px;
  font-size:13.5px;color:var(--ink-soft);cursor:pointer;text-align:center;transition:border-color .2s,color .2s;margin:0;font-weight:500}
.choice input:checked+label{border-color:var(--accent);color:var(--ink);box-shadow:inset 0 0 0 1px var(--accent)}
.choice input:focus-visible+label{outline:2px solid var(--accent);outline-offset:2px}

.form-msg{border-radius:var(--radius-sm);padding:11px 14px;font-size:13.5px;margin-bottom:16px;display:none;text-align:left}
.form-msg.show{display:block}
.form-msg.error{background:color-mix(in srgb,var(--danger) 10%,transparent);color:var(--danger)}
.form-msg.ok{background:color-mix(in srgb,var(--ok) 12%,transparent);color:var(--ok)}

/* ---------- auth page ---------- */
.auth-body{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;gap:22px}
.auth-top{position:fixed;top:14px;right:14px;display:flex;gap:10px;align-items:center}
.auth-card{background:var(--bg-card);border:1px solid var(--hair);border-radius:22px;max-width:410px;width:100%;
  padding:36px 30px;box-shadow:var(--shadow-lg);text-align:center;animation:cardIn .5s var(--e) both}
@keyframes cardIn{from{opacity:0;transform:translateY(14px) scale(.99)}to{opacity:1;transform:none}}
.auth-card h1{font-size:25px;font-weight:650;letter-spacing:-.02em;margin:16px 0 6px}
.auth-card .lead{color:var(--ink-soft);font-size:14.5px;margin-bottom:22px}
.auth-card .alt{font-size:13.5px;color:var(--ink-soft);margin-top:18px}
.auth-card .back{margin-top:14px;font-size:13px}
.plan-note{font-size:13px;color:var(--ink-soft);background:color-mix(in srgb,var(--accent) 8%,transparent);
  border-radius:10px;padding:8px 12px;margin-bottom:16px}
.plan-note b{color:var(--ink)}
@media (max-width:480px){
  .auth-body{justify-content:flex-start;padding-top:76px}
  .auth-card{padding:28px 20px;border-radius:18px}
}
@media (prefers-reduced-motion:reduce){.auth-card{animation:none}}

/* ---------- LK shell ---------- */
.lk-nav{position:sticky;top:0;z-index:50;background:var(--panel);backdrop-filter:saturate(180%) blur(20px);
  -webkit-backdrop-filter:saturate(180%) blur(20px);border-bottom:1px solid var(--panel-border)}
.lk-nav-in{max-width:1080px;margin:0 auto;padding:0 16px;height:56px;display:flex;align-items:center;gap:12px}
.lk-nav .grow{flex:1}
.balance-chip{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--hair);border-radius:999px;
  padding:8px 14px;font-size:13.5px;font-variant-numeric:tabular-nums;color:var(--ink);min-height:38px;white-space:nowrap}
.balance-chip b{font-weight:650}
.balance-chip .dot{width:7px;height:7px;border-radius:50%;background:var(--ok)}

/* below 560px the balance chip crowds the nav and duplicates the balance card — drop it */
@media (max-width:560px){
  .lk-nav-in{gap:9px;padding:0 12px}
  .balance-chip{display:none}
  .langpill{padding:6px 9px}
}

.lk-main{max-width:1080px;margin:0 auto;padding:26px 16px 80px}
.lk-hello{margin:6px 0 22px}
.lk-hello h1{font-size:clamp(22px,4.5vw,30px);font-weight:650;letter-spacing:-.02em}
.lk-hello p{color:var(--ink-soft);font-size:14px;margin-top:2px;overflow-wrap:anywhere}
.lk-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.lk-grid .wide{grid-column:1/-1}
@media (max-width:760px){.lk-grid{grid-template-columns:1fr}}

/* Unverified-email reminder. Informational, not an error: the account works — so it
   uses the warm accent tone rather than the danger red. */
.verify-banner{display:flex;align-items:center;gap:14px;margin-bottom:16px;padding:14px 16px;
  border:1px solid color-mix(in srgb,var(--warn) 40%,var(--hair));border-radius:var(--radius-sm);
  background:color-mix(in srgb,var(--warn) 8%,transparent);flex-wrap:wrap}
/* SVG rather than an emoji: emoji coverage varies by platform and this icon is
   always on screen for unverified accounts — it must never render as a tofu box. */
.verify-banner .vb-ic{width:22px;height:22px;flex:0 0 auto;color:var(--warn)}
.verify-banner b{font-size:14.5px;display:block}
.verify-banner .sub{font-size:13px;color:var(--ink-soft);margin-top:2px}
.verify-banner .grow{flex:1;min-width:190px}

.card{background:var(--bg-card);border:1px solid var(--hair);border-radius:var(--radius);
  padding:22px;box-shadow:var(--shadow)}
.card h2{font-size:16px;font-weight:650;letter-spacing:-.01em;display:flex;align-items:center;gap:8px;margin-bottom:14px}
.card h2 .grow{flex:1}
.card h2 svg{width:18px;height:18px;color:var(--accent-ink);flex:0 0 auto}

.balance-big{font-size:34px;font-weight:650;letter-spacing:-.02em;font-variant-numeric:tabular-nums;margin:2px 0 14px}
.balance-big small{font-size:15px;color:var(--ink-faint);font-weight:500}

/* plans inside LK */
.plan-row{display:flex;align-items:center;gap:14px;padding:13px 4px;border-top:1px solid var(--hair);flex-wrap:wrap}
.plan-row:first-of-type{border-top:0}
.plan-row .nm{font-weight:650;font-size:15px;min-width:86px}
.plan-row .specs{color:var(--ink-soft);font-size:13px;flex:1;min-width:180px}
.plan-row .pr{font-variant-numeric:tabular-nums;font-weight:650;white-space:nowrap}
.plan-row .pr small{color:var(--ink-faint);font-weight:400}
.plan-row.hot{background:color-mix(in srgb,var(--accent) 6%,transparent);border-radius:var(--radius-sm);border-top:0;padding:13px 12px}

/* On narrow phones the 4 children wrap raggedly (name/specs/price/button land on
   three lines with mismatched alignment). Lay them out explicitly instead:
   name, then specs, then price + action on one baseline. */
@media (max-width:430px){
  .plan-row{
    display:grid;grid-template-columns:1fr auto;
    grid-template-areas:"nm nm" "specs specs" "pr btn";
    gap:4px 10px;align-items:center;padding:14px 4px;
  }
  .plan-row.hot{padding:14px 12px}
  .plan-row .nm{grid-area:nm;min-width:0}
  .plan-row .specs{grid-area:specs;min-width:0}
  .plan-row .pr{grid-area:pr;margin-top:2px}
  .plan-row .btn{grid-area:btn;justify-self:end}
}

/* generic list rows (orders / ledger / sessions) */
.row{display:flex;align-items:center;gap:12px;padding:12px 4px;border-top:1px solid var(--hair);font-size:14px;flex-wrap:wrap}
.row:first-child{border-top:0}
.row .grow{flex:1;min-width:120px}
.row .sub{color:var(--ink-faint);font-size:12.5px;overflow-wrap:anywhere}
.row .num{font-variant-numeric:tabular-nums;white-space:nowrap}
.amount-pos{color:var(--ok)}.amount-neg{color:var(--ink)}
/* A server row opens its detail view. Signal it's tappable and keep the focus ring. */
.row-tappable{cursor:pointer;border-radius:8px;transition:background .15s}
.row-tappable:hover{background:color-mix(in srgb,var(--ink) 4%,transparent)}
.row-tappable:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* service detail dialog */
.svc-detail{display:flex;flex-direction:column;gap:2px;margin:4px 0 2px}
.svc-row{display:flex;gap:12px;align-items:center;padding:9px 0;border-top:1px solid var(--hair);font-size:14px}
.svc-row:first-child{border-top:0}
.svc-k{color:var(--ink-soft);font-size:13px;flex:0 0 40%;max-width:150px}
.svc-v{flex:1;text-align:right;overflow-wrap:anywhere}
.svc-v.mono,.svc-copy .mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}
.svc-copy{display:inline-flex;align-items:center;gap:8px;justify-content:flex-end;flex-wrap:wrap}
.copybtn{font:inherit;font-size:12px;font-weight:600;color:var(--accent-ink);background:transparent;
  border:1px solid var(--hair);border-radius:7px;padding:4px 9px;cursor:pointer;min-height:30px}
.copybtn:hover{background:color-mix(in srgb,var(--accent) 10%,transparent)}
.copybtn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.svc-note{text-align:center;padding:14px 4px 6px;color:var(--ink-faint)}
.svc-note .art{font-size:30px;margin-bottom:8px}
@media (pointer:coarse){.copybtn{min-height:40px;padding:8px 14px}}

.status{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;border-radius:999px;
  padding:4px 10px;white-space:nowrap}
.status::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}
.status.provisioning{background:color-mix(in srgb,var(--warn) 14%,transparent);color:var(--warn)}
.status.active{background:color-mix(in srgb,var(--ok) 14%,transparent);color:var(--ok)}
.status.pending_payment{background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent-ink)}
.status.canceled,.status.failed,.status.suspended{background:color-mix(in srgb,var(--danger) 12%,transparent);color:var(--danger)}

/* empty states + skeletons */
.empty{padding:26px 10px;text-align:center;color:var(--ink-soft)}
.empty .art{font-size:34px;margin-bottom:8px;filter:grayscale(.2)}
.empty p{font-size:13.5px;max-width:36ch;margin:0 auto 14px}
.skel{position:relative;overflow:hidden;background:color-mix(in srgb,var(--ink) 6%,transparent);
  border-radius:8px;height:14px;margin:10px 0}
.skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--ink) 5%,transparent),transparent);
  animation:shimmer 1.4s infinite}
@keyframes shimmer{to{transform:translateX(100%)}}
@media (prefers-reduced-motion:reduce){.skel::after{animation:none}}

/* ---------- dialogs ---------- */
dialog{border:1px solid var(--hair);border-radius:var(--radius);background:var(--bg-card);color:var(--ink);
  padding:24px;max-width:430px;width:calc(100vw - 32px);box-shadow:var(--shadow-lg);
  margin:auto}  /* the global *{margin:0} reset kills native <dialog> centering — restore it */
dialog[open]{animation:cardIn .3s var(--e) both}
@media (prefers-reduced-motion:reduce){dialog[open]{animation:none}}
dialog::backdrop{background:rgba(0,0,0,.45);backdrop-filter:blur(4px)}
dialog h3{font-size:18px;font-weight:650;margin-bottom:6px;letter-spacing:-.01em}
dialog .dlg-sub{color:var(--ink-soft);font-size:13.5px;margin-bottom:18px}
dialog .dlg-actions{display:flex;gap:10px;margin-top:20px}
dialog .dlg-actions .btn{flex:1}
.provider-list{display:flex;flex-direction:column;gap:8px;margin-bottom:6px}
.provider{display:flex;align-items:center;gap:12px;border:1px solid var(--hair);border-radius:var(--radius-sm);
  padding:12px 14px;cursor:pointer;transition:border-color .2s;font-size:14px;background:transparent;
  color:var(--ink);font-family:inherit;width:100%;text-align:left;min-height:48px}
.provider:hover:not(:disabled){border-color:var(--accent)}
.provider:disabled{opacity:.55;cursor:not-allowed}
.provider .p-ic{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;
  background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent-ink);flex:0 0 auto;font-size:15px}
.provider .grow{flex:1}
.provider .soon{font-size:11px;font-weight:600;color:var(--warn);border:1px solid currentColor;
  border-radius:999px;padding:2px 8px}
.term-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:8px 0 4px}
@media (max-width:400px){.term-grid{grid-template-columns:repeat(2,1fr)}}
.order-total{display:flex;justify-content:space-between;align-items:baseline;border-top:1px solid var(--hair);
  padding-top:14px;margin-top:14px;font-size:14px}
.order-total b{font-size:20px;font-variant-numeric:tabular-nums}

/* Where a rouble price comes from — shown only to customers billed in RUB. */
.fx-note{font-size:12px;color:var(--ink-faint);margin-top:12px;line-height:1.45}

.prof-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.prof-actions .btn{flex:1 1 auto}

/* ---------- support threads ---------- */
.thread{max-height:340px;overflow-y:auto;margin-bottom:14px;display:flex;flex-direction:column;gap:8px}
.msg{padding:10px 12px;border-radius:12px;font-size:14px;line-height:1.45;overflow-wrap:anywhere;
  background:color-mix(in srgb,var(--ink) 5%,transparent);max-width:88%}
/* Staff answers are visually distinct so an official reply is never mistaken for
   the customer's own words in a long thread. */
.msg.staff{align-self:flex-end;background:color-mix(in srgb,var(--accent) 14%,transparent)}
.msg .who{display:block;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-faint);margin-bottom:3px}
textarea.input{min-height:80px;resize:vertical;font-family:inherit}
#threadDlg,#ticketDlg{max-width:540px}

/* ---------- 2FA ---------- */
.totp-qr{display:flex;justify-content:center;margin:4px 0 12px}
.totp-qr svg{width:180px;height:180px;background:#fff;border-radius:10px;padding:8px}
.totp-secret{font-size:12.5px;color:var(--ink-soft);text-align:center;margin-bottom:14px}
.totp-secret code{display:block;margin-top:4px;font-size:13px;color:var(--ink);
  letter-spacing:.08em;overflow-wrap:anywhere}
.codes-list{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:0 0 4px}
@media (max-width:420px){.codes-list{grid-template-columns:1fr}}
.codes-list li{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:14px;
  background:color-mix(in srgb,var(--ink) 5%,transparent);border-radius:8px;padding:8px 10px;text-align:center}
.sec-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.sec-row .grow{flex:1;min-width:170px}
.sec-row .sub{font-size:12.5px;color:var(--ink-soft);margin-top:2px}

/* ---------- admin panel ---------- */
.admin-badge{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--danger);border:1px solid currentColor;border-radius:999px;padding:2px 8px;flex:0 0 auto}
.admin-who{font-size:13px;color:var(--ink-soft);overflow-wrap:anywhere}
.admin-search{max-width:240px;min-height:38px;font-size:14px;padding:8px 12px}
.stat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media (max-width:760px){.stat-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:420px){.admin-search{max-width:100%}}
@media (max-width:330px){.stat-grid{grid-template-columns:1fr}}
.stat{background:var(--bg-card);border:1px solid var(--hair);border-radius:var(--radius-sm);
  padding:16px 18px;box-shadow:var(--shadow)}
.stat.warn{border-color:color-mix(in srgb,var(--warn) 50%,var(--hair))}
.stat-v{font-size:26px;font-weight:650;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.stat-l{font-size:12.5px;color:var(--ink-soft);margin-top:2px}
@media (max-width:560px){.admin-who{display:none}}

.cust-block{margin-bottom:14px}
.cust-h{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-faint);margin-bottom:6px}
.cust-block .row{padding:8px 2px;font-size:13.5px}
.cust-line{display:flex;justify-content:space-between;gap:10px;padding:6px 2px;font-size:14px;
  border-top:1px solid var(--hair)}
.cust-line:first-child{border-top:0}
.cust-line .num{font-variant-numeric:tabular-nums}
#custDlg{max-width:520px}
.row.clickable{cursor:pointer;border-radius:8px}
.row.clickable:hover{background:color-mix(in srgb,var(--ink) 4%,transparent)}

.health-v{font-variant-numeric:tabular-nums;font-size:13.5px}
.health-v.ok{color:var(--ok)}
.health-v.warn{color:var(--warn)}
.health-v.bad{color:var(--danger);font-weight:600}

/* ---------- toast ---------- */
.toast-wrap{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:400;display:flex;
  flex-direction:column;gap:8px;width:min(420px,calc(100vw - 24px))}
.toast{background:var(--bg-card);border:1px solid var(--hair);border-radius:14px;box-shadow:var(--shadow-lg);
  padding:13px 16px;font-size:14px;display:flex;gap:10px;align-items:flex-start;animation:toastIn .35s var(--e-spring) both}
.toast.err{border-color:color-mix(in srgb,var(--danger) 45%,var(--hair))}
.toast.ok{border-color:color-mix(in srgb,var(--ok) 45%,var(--hair))}
@keyframes toastIn{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:none}}
.toast.out{transition:opacity .3s,transform .3s;opacity:0;transform:translateY(8px)}

/* ---------- onboarding tour ---------- */
.tour-hole{position:absolute;z-index:300;border-radius:14px;pointer-events:none;
  box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 70%,transparent),0 0 0 9999px rgba(0,0,0,.55);
  transition:all .45s var(--e)}
.tour-tip{position:absolute;z-index:310;background:var(--bg-card);border:1px solid var(--hair);border-radius:16px;
  box-shadow:var(--shadow-lg);padding:18px;width:min(340px,calc(100vw - 24px));animation:toastIn .4s var(--e-spring) both}
.tour-tip .t-step{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;margin-bottom:6px}
.tour-tip h4{font-size:16px;font-weight:650;margin-bottom:6px;letter-spacing:-.01em}
.tour-tip p{font-size:13.5px;color:var(--ink-soft);margin-bottom:14px}
.tour-tip .t-act{font-size:12.5px;color:var(--accent-ink);font-weight:600;margin:-6px 0 12px}
.tour-tip .t-nav{display:flex;align-items:center;gap:10px}
.tour-tip .t-dots{display:flex;gap:5px;flex:1}
.tour-tip .t-dots i{width:6px;height:6px;border-radius:50%;background:var(--hair);transition:background .3s,transform .3s}
.tour-tip .t-dots i.on{background:var(--accent);transform:scale(1.25)}
.tour-skip{position:fixed;top:14px;right:14px;z-index:320}
@media (max-width:480px){
  .tour-tip{left:12px !important;right:12px;width:auto}
}

/* ---------- operation confirmation (receipt) ---------- */
.receipt-body{background:var(--bg);min-height:100vh;display:flex;justify-content:center;
  padding:32px 16px}
.receipt{width:100%;max-width:520px;background:var(--bg-card);border:1px solid var(--hair);
  border-radius:var(--radius);padding:28px 26px;box-shadow:var(--shadow);align-self:flex-start}
.rcpt-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding-bottom:16px;border-bottom:1px solid var(--hair);margin-bottom:20px;flex-wrap:wrap}
.rcpt-doctype{font-size:12px;font-weight:600;color:var(--ink-soft);text-align:right;
  text-transform:uppercase;letter-spacing:.03em}
.rcpt-amount{font-size:34px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.rcpt-amount.pos{color:var(--ok)}
.rcpt-kind{font-size:14px;color:var(--ink-soft);margin-bottom:22px}
.rcpt-rows{display:grid;grid-template-columns:auto 1fr;gap:10px 18px;font-size:14px;margin:0 0 22px}
.rcpt-rows dt{color:var(--ink-soft);white-space:nowrap}
.rcpt-rows dd{margin:0;text-align:right;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}
.rcpt-note{font-size:12px;color:var(--ink-faint);line-height:1.5;padding-top:16px;
  border-top:1px solid var(--hair)}
.rcpt-actions{display:flex;gap:10px;margin-top:22px;flex-wrap:wrap}

@media print{
  /* Two things were wrong here, and the first hid the second.
     1. The theme toggle stamps data-theme on <html>, and :root[data-theme="dark"] out-ranks
        a plain :root — so this whole block was dead for anyone who had chosen a theme.
        Measured in the browser: with the attribute set, a plain :root override left --bg
        at #000. The selector has to match that specificity to have any effect at all.
     2. Only the background was restated. Print the receipt from the dark theme and the
        text stays #f5f5f7 — white ink on white paper, i.e. a blank sheet. The whole
        palette has to come with it, not just the backdrop.
     Greys are darkened relative to the light theme because light grey prints fainter than
     it looks on screen. */
  :root,
  :root[data-theme="dark"],
  :root[data-theme="light"]{
    --bg:#fff; --bg-card:#fff; --panel:#fff; --panel-border:#c7c7cc;
    --ink:#1d1d1f; --ink-soft:#48484d; --ink-faint:#6e6e73; --hair:#c7c7cc;
    --accent:#0057b8; --accent-ink:#0057b8;
    --ok:#1a7f4b; --warn:#8a5a00; --danger:#b3242a;
    --shadow:none; --shadow-lg:none;
  }
  .receipt-body{padding:0;background:#fff;color:var(--ink)}
  .receipt{border:0;box-shadow:none;max-width:none;padding:0}
  .no-print{display:none !important}
  .toast-wrap{display:none !important}
}
.rcpt-link{font-size:12px;font-weight:600;color:var(--accent-ink);white-space:nowrap;
  padding:4px 8px;border-radius:7px;border:1px solid transparent}
.rcpt-link:hover{text-decoration:none;border-color:var(--hair)}
.rcpt-link:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
@media (pointer:coarse){.rcpt-link{padding:8px 10px}}

/* Visually hidden but available to screen readers — for labels that would be redundant
   on screen (e.g. a search field under an obvious heading) but must still name the field
   for assistive tech. The clip/1px pattern, not display:none, which would hide it from AT. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ---------- public status page ---------- */
.status-overall{display:flex;align-items:center;gap:12px;font-size:18px;font-weight:650;
  padding:16px;border:1px solid var(--hair);border-radius:var(--radius);margin-bottom:18px}
.status-dot{width:12px;height:12px;border-radius:50%;flex:0 0 auto;background:var(--ink-faint)}
.status-dot.up{background:var(--ok)}
.status-dot.warn{background:var(--warn)}
.status-dot.down{background:var(--danger)}
.status-list{display:flex;flex-direction:column;gap:2px;margin-bottom:16px}
.status-row{display:flex;align-items:center;gap:12px;padding:12px 4px;border-top:1px solid var(--hair);font-size:14px}
.status-row:first-child{border-top:0}
/* .grow is scoped per container elsewhere in this file, so it does nothing here without
   its own rule — without this the badges hug the label instead of lining up right. */
.status-row .grow{flex:1}
.status-badge{font-size:12px;font-weight:600;border-radius:999px;padding:4px 10px;white-space:nowrap}
.status-badge.up{color:var(--ok);background:color-mix(in srgb,var(--ok) 14%,transparent)}
.status-badge.warn{color:var(--warn);background:color-mix(in srgb,var(--warn) 16%,transparent)}
.status-badge.down{color:var(--danger);background:color-mix(in srgb,var(--danger) 14%,transparent)}
.status-meta{font-size:12px;color:var(--ink-faint);text-align:center;margin-bottom:14px}
