/* ============================================================================
   panel.css — invoice, admin, brief result, error pages.

   Same tokens as the site. A client who gets an invoice link has already seen
   the storefront; a payment page in a different visual language is the moment
   they start wondering whether the link is genuine.

   Two surfaces only, as the system allows: paper for anything a client reads
   (the invoice), ink for anything Danil operates (the panel, the review page).
   ========================================================================== */

/* Ink on the body, the page surface on .page — see the overscroll note in
   base.css. Safari paints the rubber band past the top and bottom of the
   document with the BODY's background, so a paper body put a pale strip above
   the dark header here exactly as it did on the storefront. */
body.panel{background:var(--ink);color:var(--ink);min-height:100vh}
body.panel .page{background:var(--paper)}
body.panel-dark{background:var(--ink);color:var(--on-ink)}
body.panel-dark .page{background:var(--ink)}

/* --- Shell --------------------------------------------------------------- */
.p-top{background:var(--ink);color:var(--on-ink);position:sticky;top:0;z-index:20}
.p-top-in{max-width:900px;margin-inline:auto;padding:10px var(--gut);
  display:flex;align-items:center;justify-content:space-between;gap:14px}
.p-top-side{display:flex;align-items:center;gap:16px;justify-content:flex-end;flex-wrap:wrap}
.p-top-sub{font:400 11px/1 var(--ff-mono);letter-spacing:.18em;text-transform:uppercase;
  color:var(--on-ink-60);text-align:right}
/* NOTHING HERE FOR THE LANGUAGE SWITCH, ON PURPOSE.
   These pages render the storefront's own .langbtn — same markup, same class —
   so its size, its spacing and the two rules that light the current language
   all come from base.css. A second set of numbers in this file is exactly how
   the two drifted apart into a one-press toggle over there and a pair of
   separate word-sized links over here. The only thing left to say is that the
   anchor needs the hover the button gets for free. */
a.langbtn:hover .l-ru,a.langbtn:hover .l-en{color:var(--on-ink)}

/* The answer to "I paid" sits with the button, not at the top of the page. */
.inv-wait{margin-top:8px;font-size:12.5px;line-height:1.5;color:var(--ink-72)}
body.panel-dark .inv-wait{color:var(--on-ink-72)}
.p-wrap{max-width:900px;margin-inline:auto;padding:clamp(20px,5vw,38px) var(--gut) 72px}
.p-narrow{max-width:600px}
.p-h1{font:600 clamp(24px,6.4vw,34px)/1.08 var(--ff-display);letter-spacing:.015em;text-transform:uppercase}
.p-h2{font:600 17px/1.2 var(--ff-display);letter-spacing:.04em;text-transform:uppercase;
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.p-h2 i{font:400 11px/1 var(--ff-mono);letter-spacing:.14em;font-style:normal;opacity:.66}
.p-lead{margin-top:8px;font-size:14.5px;line-height:1.6}
body.panel .p-lead{color:var(--ink-72)}
body.panel-dark .p-lead{color:var(--on-ink-72)}
.p-actions{margin-top:14px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.p-back{margin-bottom:10px;font:400 11px/1 var(--ff-mono);letter-spacing:.14em;text-transform:uppercase}
.p-back a{color:var(--accent-on-ink)}
.p-mono{font-family:var(--ff-mono);font-size:13px;word-break:break-all}
.p-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.p-out{margin-top:36px}

/* --- Flash --------------------------------------------------------------- */
/* Waiting is its own state: not an error, not a confirmation. */
body.panel .flash-wait{border-color:var(--line);background:rgba(35,29,20,.03);color:var(--ink-72)}
body.panel-dark .flash-wait{border-color:var(--field-line);background:rgba(232,224,207,.04);color:var(--on-ink-72)}
.flash-a{color:inherit;text-decoration:underline;text-underline-offset:3px}

/* --- The invoice on one screen --------------------------------------------
   What is owed on the left, how to pay it on the right. Stacked, a desktop
   client scrolled past the amount to reach the methods and past the methods
   to reach the button. ---------------------------------------------------- */
.inv-grid{display:grid;gap:22px;margin-top:20px}
@media(min-width:820px){
  /* The bar has to be as wide as the page it heads. The invoice column opens
     out to 1080 here while the header stayed at 900, so the switch in its
     corner sat 90px inside the right edge of the invoice underneath it —
     which is what made it look like it was in a different place on every
     page. The review page already matched its own column; now this one does
     too, and RU/EN lands in the same corner throughout. */
  body.inv-body .p-top-in{max-width:1080px}
  .p-wrap.inv{max-width:1080px}
  .inv-grid{grid-template-columns:minmax(0,360px) minmax(0,1fr);gap:40px;align-items:start}
  .inv-a{position:sticky;top:78px}
}

/* --- Choosing how to pay -------------------------------------------------
   A row of chips, then one card. Not six cards. */
.rail-pick{margin:2px 0 12px;font-size:13px;line-height:1.55;color:var(--ink-72)}
body.panel-dark .rail-pick{color:var(--on-ink-72)}
.rail-tabs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px}
.rail-tab{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:9px 12px;
  border:1px solid var(--line);border-radius:var(--r1);background:none;color:inherit;
  cursor:pointer;transition:background .16s,border-color .16s}
.rail-tab img{width:18px;height:18px;object-fit:contain;border-radius:3px}
.rail-tab span{font:400 11.5px/1 var(--ff-mono);letter-spacing:.08em;text-transform:uppercase}
.rail-tab:hover{border-color:var(--line-hard)}
.rail-tab.is-on{border-color:var(--accent);background:rgba(168,50,30,.09)}
body.panel-dark .rail-tab{border-color:var(--field-line)}
body.panel-dark .rail-tab.is-on{border-color:var(--accent-on-ink);background:rgba(233,150,122,.14)}

/* What the money buys. */
.inv-for{margin:18px 0 22px;padding:13px 15px;border-radius:var(--r2);background:rgba(35,29,20,.05)}
body.panel-dark .inv-for{background:rgba(232,224,207,.06)}
.inv-for-b{margin-top:6px;font-size:14px;line-height:1.6}

/* THE BUTTON THE CLIENT CAME TO PRESS DOES NOT GO BELOW THE FOLD.
   A crypto card carries a network warning, an address, a copy button and a
   QR — comfortably taller than what is left of a laptop screen once the
   header and the amount have had their share. Stuck to the bottom of its own
   column it is reachable whatever method is open and however tall that
   method's card happens to be. */
/* THE FADE GOES ON THE WRAPPER, NOT ON THE BUTTON.
   This used to be #claimBtn::before with z-index:-1. A negative-z pseudo of a
   positioned element paints AFTER that element's own background and before
   its content — so the paper backdrop was drawn straight over the madder
   button, leaving the label floating on a pale rectangle. It looked like the
   button had failed to render, and it did it on every real invoice, not only
   in the panel's preview.

   On a wrapper the same pseudo-element lands behind the button, which is
   where a backdrop belongs. */
.claim-wrap{position:sticky;bottom:0;z-index:5;margin-top:14px}
.claim-wrap::before{content:"";position:absolute;left:-6px;right:-6px;bottom:-14px;top:-14px;
  z-index:-1;background:var(--paper);
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 14px);
  mask-image:linear-gradient(to bottom,transparent,#000 14px)}
body.panel-dark .claim-wrap::before{background:var(--ink)}
#claimBtn{width:100%}
.inv-claim,.inv-wait{position:relative;z-index:5}

/* The answer to "I paid". */
.inv-claim{margin-top:10px;padding:10px 12px;border-radius:var(--r1);
  border:1px solid var(--line);font-size:13.5px;line-height:1.55}
.inv-claim.is-ok{border-color:var(--accent);background:rgba(168,50,30,.08)}
body.panel-dark .inv-claim{border-color:var(--field-line)}
body.panel-dark .inv-claim.is-ok{border-color:var(--accent-on-ink);background:rgba(233,150,122,.14)}

/* The exact amount is the reference number. It reads as data, like the
   address under it, because that is what a client has to copy without a
   single digit going missing. */
.rail-x{margin:6px 0 8px;display:flex;flex-wrap:wrap;gap:6px 10px;align-items:baseline}
.rail-x .cap{flex:0 0 100%}
.rail-x b{font:600 17px/1.2 var(--ff-mono);letter-spacing:.02em;color:var(--accent-on-ink)}
body.panel .rail-x b{color:var(--accent)}
.btn-copy-sm{min-height:32px;padding:6px 10px;font-size:11px}
.rail-warn-x{margin-top:6px}

.flash{margin-bottom:18px;padding:12px 14px;border-radius:var(--r2);
  font-size:13.5px;line-height:1.55;border:1px solid}
.flash ul{margin-top:6px;padding-left:16px;list-style:disc}
body.panel .flash-ok{border-color:var(--line-hard);background:rgba(35,29,20,.05);color:var(--ink)}
body.panel .flash-bad{border-color:var(--accent);background:rgba(168,50,30,.08);color:var(--ink)}
body.panel-dark .flash-ok{border-color:var(--field-line);background:rgba(232,224,207,.08);color:var(--on-ink)}
body.panel-dark .flash-bad{border-color:var(--accent-on-ink);background:rgba(233,150,122,.12);color:var(--on-ink)}

/* --- Buttons ------------------------------------------------------------- */
.btn-dark{border-color:var(--field-line);color:var(--on-ink)}
.btn-dark:hover{background:rgba(232,224,207,.1)}
/* Dark pages carry BOTH classes — layout() emits `panel panel-dark` — and this
   pair has no `panel-dark` counterpart, so without the :not() it won an ink
   text colour on an ink background: every ghost button on the admin and review
   pages was rendering at roughly 1:1 contrast. */
body.panel:not(.panel-dark) .btn-ghost.btn-dark{border-color:var(--line-hard);color:var(--ink)}
body.panel:not(.panel-dark) .btn-ghost.btn-dark:hover{background:var(--ink-fill)}
.btn-mini{min-height:44px;padding:8px 12px;border-radius:var(--r1);
  border:1px solid var(--field-line);color:var(--on-ink);
  font:400 11px/1 var(--ff-mono);letter-spacing:.1em;text-transform:uppercase}
.btn-mini:hover{background:rgba(232,224,207,.1)}
.btn-danger{border-color:rgba(233,150,122,.5);color:var(--accent-on-ink)}
.btn-danger:hover{background:rgba(233,150,122,.14)}
.btn-copy{min-height:44px;padding:10px 14px;border-radius:var(--r1);
  border:1px solid var(--line-hard);color:var(--ink);
  font:400 11px/1 var(--ff-mono);letter-spacing:.12em;text-transform:uppercase}
.btn-copy:hover{background:var(--ink-fill)}
body.panel-dark .btn-copy{border-color:var(--field-line);color:var(--on-ink)}
body.panel-dark .btn-copy:hover{background:rgba(232,224,207,.1)}
.btn-copy[data-state=done]{border-color:var(--accent);color:var(--accent)}
body.panel-dark .btn-copy[data-state=done]{border-color:var(--accent-on-ink);color:var(--accent-on-ink)}

/* --- Forms on ink -------------------------------------------------------- */
.p-form{margin-top:18px;display:grid;gap:14px;max-width:520px}
.f-l-dark{color:var(--on-ink-60)}
.f-i-dark{border-color:var(--field-line);background:var(--field);color:var(--on-ink)}
.f-i-dark:hover{border-color:var(--on-ink-60)}
.f-h-dark{color:var(--on-ink-60)}
body.panel-dark select.f-i{
  background-image:linear-gradient(45deg,transparent 50%,var(--on-ink-60) 50%),
    linear-gradient(135deg,var(--on-ink-60) 50%,transparent 50%)}
input[type=file].f-i{padding:10px 12px;line-height:1.3}
input[type=file].f-i::file-selector-button{margin-right:10px;padding:7px 11px;border-radius:var(--r1);
  border:1px solid var(--field-line);background:none;color:var(--on-ink);
  font:400 11px/1 var(--ff-mono);letter-spacing:.1em;text-transform:uppercase;cursor:pointer}

/* --- Panels and rows ----------------------------------------------------- */
.p-tabs{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:20px;
  border-bottom:1px solid rgba(232,224,207,.16)}
.p-tab{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:11px 14px;
  font:400 11px/1 var(--ff-mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--on-ink-60);border-radius:var(--r2) var(--r2) 0 0;transition:color .18s,background .18s}
.p-tab:hover{color:var(--on-ink)}
.p-tab.is-on{color:var(--on-ink);background:rgba(232,224,207,.09)}
.tab-n{font-style:normal;min-width:18px;padding:2px 6px;border-radius:9px;
  background:var(--accent);color:var(--on-ink);font-size:11px;text-align:center}

.p-panel{margin-bottom:32px}
.p-panel + .p-panel{padding-top:26px;border-top:1px solid rgba(232,224,207,.14)}
.p-danger{border-top-color:rgba(233,150,122,.28)}

.rows{margin-top:14px;border:1px solid rgba(232,224,207,.18);border-radius:var(--r3);overflow:hidden}
.row{display:flex;gap:12px;align-items:flex-start;justify-content:space-between;flex-wrap:wrap;
  padding:13px 14px;border-bottom:1px solid rgba(232,224,207,.12)}
.row:last-child{border-bottom:0}
.row.is-new{background:rgba(233,150,122,.07)}
.row-main{display:grid;gap:3px;flex:1 1 240px;min-width:0;color:inherit}
a.row-main:hover .row-title{color:var(--accent-on-ink)}
.row-code{font:400 11px/1 var(--ff-mono);letter-spacing:.14em;color:var(--accent-on-ink)}
.row-title{font:600 15px/1.3 var(--ff-body);word-break:break-word}
.row-sub{font-size:12.5px;line-height:1.5;color:var(--on-ink-60)}
.row-err{font-size:12px;line-height:1.5;color:var(--accent-on-ink);word-break:break-word}
.lead-about{margin-top:5px;font-size:13.5px;line-height:1.55;color:var(--on-ink-72);
  padding-left:10px;border-left:2px solid rgba(232,224,207,.2)}
.row-side{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.row-side form{display:contents}
.pill{font:400 11px/1 var(--ff-mono);letter-spacing:.1em;text-transform:uppercase;font-style:normal;
  padding:5px 8px;border-radius:var(--r1);border:1px solid var(--field-line);color:var(--on-ink-60)}
.pill-warn{border-color:var(--accent-on-ink);color:var(--accent-on-ink)}

/* Empty states carry the next action, not just the absence of rows. */
.row-empty{display:block;padding:22px 16px;text-align:center}
.row-empty p{font-size:14px;line-height:1.55}
.row-empty-hint{margin-top:5px;font-size:12.5px;color:var(--on-ink-60);max-width:44ch;margin-inline:auto}

.p-new{margin-top:18px}
.p-new summary{display:inline-flex;align-items:center;min-height:44px;cursor:pointer;
  font:400 11px/1 var(--ff-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--on-ink-60)}
.p-new summary:hover{color:var(--on-ink)}
.p-new[open] summary{color:var(--on-ink)}

/* --- Comments in the panel ----------------------------------------------- */
.cmts{margin-top:14px;display:grid;gap:8px}
.cmt{padding:12px 14px;border:1px solid rgba(232,224,207,.18);border-radius:var(--r2)}
.cmt.is-done{opacity:.58}
.cmt-h{display:flex;gap:10px;align-items:baseline;justify-content:space-between}
.cmt-t{font:400 11px/1 var(--ff-mono);letter-spacing:.12em;color:var(--accent-on-ink)}
.cmt-a{font:400 11px/1 var(--ff-mono);letter-spacing:.12em;color:var(--on-ink-60)}
.cmt-b{margin:6px 0 8px;font-size:14px;line-height:1.55}

/* --- Upload -------------------------------------------------------------- */
.up{margin-top:18px;display:grid;gap:12px;max-width:520px}
.up-bar{height:6px;border-radius:3px;background:rgba(232,224,207,.14);overflow:hidden}
.up-bar i{display:block;height:100%;width:0;background:var(--accent);transition:width .25s}

/* --- Table --------------------------------------------------------------- */
.p-table{width:100%;border-collapse:collapse;font-size:13px;min-width:640px}
.p-table th,.p-table td{padding:9px 10px;text-align:right;border-bottom:1px solid rgba(232,224,207,.12);
  font-variant-numeric:tabular-nums}
.p-table thead th{font:400 11px/1.3 var(--ff-mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--on-ink-60);text-align:right;vertical-align:bottom}
.p-table th[scope=row],.p-table thead th:first-child{text-align:left}
.p-table th[scope=row]{font:400 11px/1 var(--ff-mono);letter-spacing:.12em;color:var(--accent-on-ink)}
.p-table tfoot th[scope=row]{color:var(--on-ink)}
.p-table .muted{color:var(--on-ink-60)}
.p-h3{margin-top:26px}
.p-stats{margin-top:12px;display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(132px,1fr))}
.p-stats li{padding:11px 12px;border:1px solid rgba(232,224,207,.18);border-radius:var(--r2)}
.p-stats b{display:block;font:600 24px/1 var(--ff-display);font-variant-numeric:tabular-nums}
.p-stats span{display:block;margin-top:4px;font:400 11px/1.4 var(--ff-mono);
  letter-spacing:.08em;text-transform:uppercase;color:var(--on-ink-60)}

/* ============================================================================
   INVOICE — the one page in this project where a client is about to move
   money. Everything on it is either the amount, a way to pay it, or who to
   ask. Nothing else.
   ========================================================================== */
.inv{max-width:620px}
.inv-head{padding-bottom:18px;border-bottom:1px solid var(--line)}
.inv-head .p-h1{margin-top:6px}
.inv-to{margin-top:10px;font-size:14px}
.inv-to .cap,.inv-project .cap{margin-right:6px}
.inv-project{margin-top:6px;font-size:14px}
/* The link to the review page is a real tap target, not a run of inline text. */
.inv-project a{display:inline-flex;align-items:center;min-height:44px;padding-block:4px}

.inv-sum{margin-top:22px;padding:16px 18px;border:1px solid var(--line-hard);border-radius:var(--r3);
  background:rgba(35,29,20,.04)}
.inv-sum-l{font:400 11px/1 var(--ff-mono);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-72)}
.inv-sum-n{margin-top:8px;font:600 clamp(32px,9vw,44px)/.95 var(--ff-display);
  font-variant-numeric:tabular-nums}
.inv-sum-t{margin-top:8px;font-size:13px;color:var(--ink-72)}
.inv-note{margin-top:14px;padding:12px 14px;border-left:2px solid var(--accent);
  background:rgba(35,29,20,.04);font-size:13.5px;line-height:1.55}

/* The card action. No panel, no fill, no border: it is one button and one
   line of explanation, and a box drawn around them would read as dirt on the
   paper rather than as structure. */
/* The final, on its own page. A plain video in a column that reads — no
   chrome to invent, because the only two things to do here are watch it and
   take it. */
.dl-stage{margin:18px 0;background:var(--ink);border-radius:var(--r3);overflow:hidden}
.dl-video{display:block;width:100%;max-height:70vh;background:var(--ink)}

.inv-final{margin-top:28px}
.inv-final .p-note{margin-top:10px;max-width:58ch}

.rail-card-pay{margin-top:30px}
.rail-card-pay .rail-hint{margin-top:10px;max-width:54ch}

.rail-group{margin-top:30px}
.rail-group > .cap{display:block;margin-bottom:10px}
.rail-card .rail-warn{margin:6px 0 10px;font-size:12px;line-height:1.5}
.rail-warn{margin-bottom:10px;font-size:13px;line-height:1.55;color:var(--ink);
  padding:10px 12px;border-left:2px solid var(--accent);background:rgba(168,50,30,.07)}
/* Two columns from narrow widths up: six rails stacked one per row meant a
   client had to scroll to discover the one they can actually use. */
.rail-list{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.rail-card{padding:14px;border:1px solid var(--line-hard);border-radius:var(--r3);
  background:rgba(35,29,20,.03)}
.rail-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font:600 14px/1.2 var(--ff-body)}
.rail-h i{font:400 11px/1 var(--ff-mono);letter-spacing:.1em;text-transform:uppercase;
  font-style:normal;color:var(--ink-72)}
.rail-ic{width:22px;height:22px;object-fit:contain;flex:0 0 auto}
.rail-v{margin-top:9px;font-family:var(--ff-mono);font-size:14px;line-height:1.5;
  word-break:break-all;-webkit-user-select:all;user-select:all}
.rail-card .btn-copy{margin-top:10px}
.rail-meta{margin-top:8px;font-size:12.5px;color:var(--ink-72)}
.rail-hint{margin-top:8px;font-size:12.5px;color:var(--ink-72)}
.qr-box{margin-top:12px;width:max-content;max-width:100%;padding:8px;
  background:#fff;border:1px solid var(--line);border-radius:var(--r2)}
.qr-box svg{display:block;width:140px;height:140px;max-width:100%}
.qr-small svg{width:118px;height:118px}
.rail-qr{text-align:left}

.inv-foot{margin-top:32px;padding-top:20px;border-top:1px solid var(--line)}
.inv-sign{margin-top:16px;font:400 11px/1.6 var(--ff-mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-72)}
.inv-contact{margin-top:4px;font-size:13px;color:var(--ink-72)}

@media(min-width:700px){
  .p-form,.up{max-width:560px}
}

/* --- The offer, at the bottom of every page -------------------------------
   Rendered by layout() in views.js, so it is the same line on an invoice, a
   review, a quote and a 404. Quiet on purpose: it is the document a client
   accepted, not a thing to press. One rule, mono caps, and a 44px target —
   the same furniture as the storefront's own footer. ---------------------- */
.p-foot{max-width:900px;margin-inline:auto;padding:0 var(--gut) 26px;
  font:400 11px/1 var(--ff-mono);letter-spacing:.14em;text-transform:uppercase}
/* The rule is a pseudo-element and not a border on the link, so it lines up
   with the column above it and so the click target is the word rather than
   the whole width of the page. */
.p-foot::before{content:"";display:block;height:1px;background:var(--line)}
.p-foot a{display:inline-flex;align-items:center;min-height:44px;
  color:var(--ink-72);transition:color .18s}
.p-foot a:hover{color:var(--ink)}
body.panel-dark .p-foot::before{background:var(--field-line)}
body.panel-dark .p-foot a{color:var(--on-ink-60)}
body.panel-dark .p-foot a:hover{color:var(--on-ink)}
/* The invoice column opens out to 1080 above 820px and its header follows it;
   the footer has to be the same width or the rule under the page stops short
   of the page. */
@media(min-width:820px){
  body.inv-body .p-foot{max-width:1080px}
}

/* Строка состояния под кнопкой карты. Пустая — её нет: место под сообщение,
   которого ещё не случилось, читается как пропущенная строка. */
.rail-card-status:empty { display: none; }

/* Виджет Продамуса вставляет свой iframe в <body> и стилизует его своим
   init.css с чужого домена. Если тот не доедет — а он с чужого домена и может
   не доехать, — iframe останется нестилизованным элементом в конце страницы.
   Эти правила делают его окном сами, чтобы оплата выглядела как оплата даже
   тогда. Класс задан виджетом, не нами. */
iframe.prodamus-payform-widget {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  z-index: 9999;
  background: rgba(20, 16, 11, .55);
}
