/* ═══ the browser view ══════════════════════════════════════════════════════
   Loaded ONLY by the /web shell. /app — the surface Telegram opens as a Mini
   App — never requests this file, so the phone column stands there at any
   window width, which is what a Mini App is supposed to look like even when
   Telegram Desktop gives it a wide one.

   That is also why these rules live in their own file rather than behind an
   `html[data-surface="web"]` prefix on every selector: the split is then a
   fact of the network (one surface downloads it, the other does not) instead
   of a specificity contest, and nothing here can leak into the Mini App by
   somebody forgetting the prefix on a rule added later.

   Under 1000px nothing here applies and /web is byte-for-byte the /app layout
   — deliberately, so landing on the wrong door costs a phone user nothing.
   Above it, each screen gets the width it can actually use — which is NOT the
   same width for all of them: a login form 1180px wide is worse than one at
   460px. */
@media (min-width:1000px){
  /* No wrapper element exists inside #hdr, so the bar is centred with padding
     instead of markup — max() keeps a sane gutter on a narrow desktop. */
  #hdr{padding:16px max(24px,calc((100% - 1180px) / 2));height:76px}
  .logo{font-size:22px;gap:11px}
  .logo-img{height:34px;width:auto}

  #app{max-width:620px;padding:38px 24px 80px}
  h2{font-size:34px;margin-bottom:26px}

  /* The sign-in window floats in the middle of the page instead of sitting at
     the top of a column. 76px is the sticky header. */
  body[data-screen="auth"] #app{max-width:none;padding:0;
    min-height:calc(100vh - 76px);display:flex;align-items:center;justify-content:center}
  body[data-screen="auth"] .authwin{padding:34px 32px 28px}
  body[data-screen="auth"] .authwin-t{font-size:26px}

  /* Screens that earn the full page. */
  body[data-screen="home"] #app,
  body[data-screen="pointsScreen"] #app{max-width:1180px;padding-left:34px;padding-right:34px}
  /* Rates sits just inside the others. A rate row is one short line of text and
     one price: at the full 1180 the carrier name and the amount end up at
     opposite edges of the screen and the eye has to travel the whole width to
     pair them. Narrower reads as a list of comparable things. */
  body[data-screen="ratesScreen"] #app{max-width:1040px;padding-left:34px;padding-right:34px}
  /* Saved labels for exactly the same reason, and it used to sit at the full
     1180: a label card is a carrier, a price and two buttons, so the wider the
     page the further the price drifts from the name it belongs to and the more
     empty floor sits under the buttons. */
  body[data-screen="labelsScreen"] #app{max-width:940px;padding-left:34px;padding-right:34px}
  /* Forms are wide enough for two columns, and no wider. */
  body[data-screen="shipFrom"] #app,
  body[data-screen="details"] #app,
  body[data-screen="smartLabel"] #app,
  body[data-screen="settings"] #app{max-width:940px;padding-left:34px;padding-right:34px}

  /* ── home ── */
  .dash-mark{display:none}          /* the 104px hero mark is a phone device */
  #svhost:empty{display:none}
  .dbal{display:grid;grid-template-columns:1.5fr 1fr 1fr;align-items:end;gap:28px;
    padding:26px 30px;margin-bottom:16px}
  .dbal .balance{font-size:52px}
  .dstat{margin-top:0}

  /* Twelve tracks, so the two rows can have different rhythms.
     Row one is what people come for: buy a label, put money in. Row two is
     everything a customer touches once a month at most. Equal tiles would have
     claimed all six were equally likely. Sized by padding and never by a
     min-height — forcing them taller only put empty floor under one word. */
  .dgrid{display:grid;grid-template-columns:repeat(12,1fr);gap:14px}
  .dgrid .dtile{margin-top:0;padding:26px 24px;text-align:left;font-size:19px;grid-column:span 3}
  .dgrid .dtile--pri{grid-column:span 8;font-size:26px;padding:34px 28px}
  .dgrid .dtile--alt{grid-column:span 4;font-size:26px;padding:34px 28px}
  .dgrid .dtile--sm{font-size:17px;padding:22px 22px}
  .drow{padding:15px 20px;gap:20px}

  /* ── the quote form ──
     From and To are the same question asked twice, so they sit side by side
     and the parcel spans both. Stacked, the customer scrolls past the origin
     to reach the destination and cannot see the corridor they are pricing. */
  body[data-screen="shipFrom"] #app > .card:nth-of-type(1),
  body[data-screen="shipFrom"] #app > .card:nth-of-type(2){
    display:inline-block;width:calc(50% - 7px);vertical-align:top;margin-bottom:14px}
  body[data-screen="shipFrom"] #app > .card:nth-of-type(1){margin-right:12px}

  /* ── rates ──
     The price set like the prices on the public page, in a row kept deliberately
     tight: a rate list is scanned, not read, and every millimetre of row height
     is one fewer option visible without scrolling. */
  body[data-screen="ratesScreen"] .rate{padding:13px 20px;margin-bottom:7px}
  body[data-screen="ratesScreen"] .rate .price{font-size:26px}

  /* ── details ──
     Sender and recipient in two columns: they are filled in one after the
     other and constantly compared. */
  body[data-screen="details"] #app{column-gap:0}
  body[data-screen="details"] .dcols{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}

  /* ── saved labels ── */
  body[data-screen="labelsScreen"] .lbl{padding:16px 20px}
}

/* ═══ Bulk Paste ════════════════════════════════════════════════════════════
   Browser-only by construction: the screen is reached from a tile that only
   /web paints, and these rules only exist in the file only /web downloads. The
   markup degrades to a readable stack without them, which is what a phone
   arriving through a shared link would get. */
@media (min-width:1000px){
  /* The batch screens need the page, not the 620px column: a review table has
     ten columns and a paste screen has two boxes side by side. */
  body[data-screen="bulkPaste"] #app,
  body[data-screen="bulkReview"] #app,
  body[data-screen="bulkRates"] #app,
  body[data-screen="bulkRun"] #app,
  body[data-screen="bulkDone"] #app{max-width:1180px;padding-left:34px;padding-right:34px}
  body[data-screen="bulkConfirm"] #app{max-width:620px}

  /* Sender on the left, its recipients on the right — the shape of the thing
     being described, so no label has to explain which box is which. */
  .bk-group{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-bottom:16px}
}
.bk-group{display:grid;gap:14px;margin-bottom:14px}
.bk-col{display:flex;flex-direction:column;min-width:0}
.bk-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px;min-height:24px}
.bk-head small{color:var(--muted);font-weight:700;letter-spacing:.04em;text-transform:uppercase;font-size:11px}
.bk-group textarea{width:100%;box-sizing:border-box;font-family:ui-monospace,"SFMono-Regular",Menlo,monospace;font-size:13px;line-height:1.5}
.bk-x{background:none;border:1px solid var(--line);color:var(--muted);border-radius:6px;
  font-size:12px;line-height:1;padding:4px 8px;cursor:pointer}
.bk-x:hover{border-color:var(--danger);color:var(--danger)}
.bk-add{margin:0 0 18px}
.bk-help{font-size:13px;line-height:1.55;margin-bottom:16px}
.bk-count{font-size:13px;color:var(--muted);margin:10px 0 4px;text-align:right}
.bk-count.over{color:var(--danger);font-weight:700}

/* An amber note, not an error: everything it reports is something the customer
   can still fix on this screen. */
.bk-warn{background:rgba(251,191,36,.1);border:1px solid rgba(251,191,36,.32);color:#fbbf24;
  padding:9px 12px;border-radius:10px;font-size:13px;line-height:1.5;margin:10px 0}

.bk-senders{display:grid;gap:12px;margin-bottom:14px}
@media (min-width:1000px){.bk-senders{grid-template-columns:repeat(auto-fit,minmax(340px,1fr))}}
.bk-sender{border:1px solid var(--line);border-radius:var(--r);padding:12px;background:var(--card)}
.bk-sender.warn{border-color:rgba(251,191,36,.45)}
.bk-sgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:6px}
.bk-book{font-size:12px;padding:3px 6px;max-width:52%}

.bk-fill{display:flex;gap:8px;align-items:center;margin:0 0 12px;flex-wrap:wrap}
.bk-fill .bk-in{flex:1;min-width:150px}
.bk-fill .btn{margin:0;width:auto;padding:8px 14px;flex:none}

/* The table scrolls inside itself. The page must not scroll sideways — a
   horizontal scrollbar on the whole document loses the buttons under it. */
.bk-tablewrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r);margin-bottom:14px}
.bk-table{border-collapse:collapse;width:100%;font-size:13px}
.bk-table th{text-align:left;font-size:11px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);font-weight:700;padding:8px 6px;border-bottom:1px solid var(--line);white-space:nowrap}
.bk-table td{padding:4px 6px;vertical-align:middle;border-bottom:1px solid var(--line)}
.bk-table tr:last-child td{border-bottom:none}
.bk-table tr.bk-out{background:rgba(239,68,68,.06)}
.bk-num{color:var(--muted);font-variant-numeric:tabular-nums;width:26px;text-align:right}
.bk-from .pill{max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bk-st input{width:52px}
.bk-cc input{width:44px;text-transform:uppercase}

/* Inputs inside the table are quiet until they need attention: a grid of ten
   bordered boxes across is a wall, and the red ones stop standing out. */
.bk-in{width:100%;box-sizing:border-box;background:var(--inset);border:1px solid transparent;
  color:var(--text);border-radius:7px;padding:6px 8px;font-size:13px;min-width:90px}
.bk-in:focus{border-color:var(--accent);outline:none}
.bk-in.bad{border-color:var(--danger);background:rgba(239,68,68,.08)}
.bk-table td .bk-in + .bk-in{margin-top:4px}

.bk-actions{display:flex;gap:10px;align-items:stretch}
/* The base .btn is width:100%, so without pinning the secondary one it eats
   the row and the primary gets squeezed into three lines of text. */
.bk-actions .btn{margin:0;width:auto}
.bk-actions .btn-ghost{flex:none;padding-left:22px;padding-right:22px;white-space:nowrap}
.bk-actions .btn-primary{flex:1;white-space:nowrap}

/* A partial-coverage row is dimmed but never hidden: it is a real offer, just
   not for every parcel, and the row says which ones it drops. */
.bk-rate.partial{opacity:.82}
.bk-miss{font-size:12px;color:#fbbf24;margin-top:4px;line-height:1.4}
.bk-each{font-size:11.5px;color:var(--muted);font-weight:600;text-align:right;margin-top:2px}

.bk-progress{height:6px;border-radius:99px;background:var(--inset);overflow:hidden;margin:12px 0 16px}
.bk-progress i{display:block;height:100%;background:var(--accent);transition:width .3s ease}
.bk-lines{display:flex;flex-direction:column;gap:2px;margin-bottom:16px}
.bk-line{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:9px;
  background:var(--card);border:1px solid var(--line);font-size:13px}
.bk-line.fail{border-color:rgba(239,68,68,.35)}
.bk-who{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.bk-line .bk-dl{margin:0;width:auto;padding:5px 12px;font-size:12px;flex:none}
.err-inline{color:#fca5a5;font-size:12.5px}

/* A count, not a message box: .ok in the theme is a bordered panel with
   padding, which around a single digit reads as a stray green rectangle. */
.bk-ok{color:var(--accent);font-weight:700}
