/* ===========================================================
   SWAP — one centred card: You pay / You receive

   Everything structural (nav, modal shell, wallet rows, confirm steps)
   comes from exchange.css; the asset badge from screener.css. This file
   owns only the card itself. Tokens only — no literal colours, so both
   themes come for free.
   =========================================================== */

.sw-body { min-height: 100vh; display: flex; flex-direction: column; background: var(--bg-base); }

.sw-main {
  flex: 1 0 auto; width: 100%;
  display: flex; flex-direction: column; align-items: center;
  padding: var(--s10) var(--s4) var(--s12);
}

.sw-card {
  width: 100%; max-width: 440px;
  background: var(--bg-surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--s5);
  display: flex; flex-direction: column; gap: var(--s2);
  box-shadow: var(--shadow-sm);
}

.sw-head { margin-bottom: var(--s3); }
.sw-title { font-size: var(--fs-xl); font-weight: var(--fw-head); line-height: 1.2; }
.sw-sub { margin-top: var(--s1); font-size: var(--fs-sm); line-height: 1.5; color: var(--text-3); }

/* ---- Amount boxes ---- */
.sw-box {
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: var(--s3) var(--s4);
  transition: border-color var(--t-fast);
}
.sw-box:focus-within { border-color: var(--border-bright); }
.sw-box-top {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  font-size: var(--fs-sm); line-height: 18px; margin-bottom: var(--s2);
}
.sw-lbl { color: var(--text-3); font-weight: var(--fw-label); }
.sw-bal { color: var(--text-2); display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.sw-bal .num { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-max {
  color: var(--accent); font-size: var(--fs-xs); font-weight: var(--fw-head);
  padding: 2px 6px; border-radius: var(--r-sm); margin-left: 2px;
  transition: background var(--t-fast);
}
.sw-max:hover { background: var(--accent-dim); }
.sw-max[hidden] { display: none; }

.sw-box-row { display: flex; align-items: center; gap: var(--s3); height: 44px; }
.sw-amt {
  flex: 1 1 auto; min-width: 0; height: 44px;
  background: transparent; border: none; outline: none; padding: 0;
  font-size: 28px; font-weight: var(--fw-head); line-height: 44px;
  color: var(--text); letter-spacing: -0.01em;
}
.sw-amt::placeholder { color: var(--text-4); font-weight: var(--fw-label); }
.sw-amt:focus { outline: none; }
.sw-amt-ro { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-amt-ro.is-empty { color: var(--text-4); }
.sw-amt-ro.is-stale { color: var(--text-3); }

/* Asset picker button */
.sw-pick {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--s2);
  height: 36px; padding: 0 var(--s2) 0 6px;
  background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: 999px; font-size: var(--fs-md); font-weight: var(--fw-head);
  color: var(--text); transition: background var(--t-fast), border-color var(--t-fast);
}
.sw-pick:hover { background: var(--bg-hover); border-color: var(--border-bright); }
.sw-pick:active { transform: scale(.98); }
.sw-pick-badge { display: inline-flex; line-height: 0; }
.sw-pick-code { white-space: nowrap; }
.sw-pick-chev { width: 14px; height: 14px; color: var(--text-3); flex-shrink: 0; }

/* Badge: the homepage's .tk-logo, plus the inline Stellar mark for XLM. */
.tk-logo svg { position: relative; width: 100%; height: 100%; display: block; border-radius: 50%; }
.tk-letter { font-size: 9px; }

/* ---- Flip ---- */
.sw-flip-row { display: flex; justify-content: center; height: 0; position: relative; z-index: 1; }
.sw-flip {
  position: absolute; top: -18px;
  width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--bg-elevated); border: 1px solid var(--border);
  box-shadow: 0 0 0 4px var(--bg-surface);
  color: var(--text-2);
  transition: background var(--t-fast), color var(--t-fast), transform var(--t-base);
}
.sw-flip svg { width: 18px; height: 18px; }
.sw-flip:hover { background: var(--bg-hover); color: var(--text); }
.sw-flip:active { transform: rotate(180deg); }
.sw-flip.is-flipped svg { transform: rotate(180deg); }
.sw-flip svg { transition: transform var(--t-base); }

/* ---- Quote block ---- */
.sw-quote {
  margin-top: var(--s2); padding: var(--s1) var(--s1) 0;
  display: flex; flex-direction: column; gap: 0;
  font-size: var(--fs-sm); line-height: 18px;
}
.sw-qrow {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: 7px 0; border-bottom: 1px solid var(--border-soft);
}
.sw-qrow:last-child { border-bottom: none; }
.sw-qk { color: var(--text-3); white-space: nowrap; }
.sw-qk[title] { cursor: help; text-decoration: underline dotted var(--text-4); text-underline-offset: 3px; }
.sw-qv { color: var(--text); font-weight: var(--fw-label); text-align: right; min-width: 0;
         overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-qv.dim { color: var(--text-3); font-weight: var(--fw-body); }
.sw-qv.down { color: var(--down-text); }
.sw-qrate .sw-qv { cursor: pointer; }
.sw-qrate .sw-qv:hover { color: var(--accent); }

.sw-slip { display: inline-flex; gap: 4px; }
.sw-slip-b {
  height: 24px; padding: 0 9px; border-radius: 999px;
  font-size: var(--fs-xs); font-weight: var(--fw-label);
  color: var(--text-3); background: var(--bg-elevated); border: 1px solid var(--border);
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.sw-slip-b:not(:disabled):hover { color: var(--text); border-color: var(--border-bright); }
.sw-slip-b.active { color: var(--accent); background: var(--accent-dim); border-color: var(--accent-line); }
/* Frozen while a plan is being built or signed — the review's figures belong
   to the tolerance captured when Swap was pressed (swap.js freezeSlip). With
   no rule of its own a disabled chip looked and lit on hover exactly like a
   live one for the whole multi-round-trip "Checking route…", so a click that
   correctly did nothing read as the page ignoring it. */
.sw-slip-b:disabled, .sw-slip-c:disabled { opacity: .45; cursor: default; }

/* ---- Primary action ---- */
.sw-go {
  margin-top: var(--s3); height: 48px; font-size: var(--fs-lg); font-weight: var(--fw-head);
  border-radius: var(--r-md);
}
.sw-go:disabled { opacity: .7; }
.sw-go.is-busy { pointer-events: none; }

.sw-status {
  margin-top: var(--s1); padding: var(--s3) var(--s3);
  border-radius: var(--r-md); font-size: var(--fs-sm); line-height: 1.5;
  border: 1px solid var(--border); background: var(--bg-input); color: var(--text-2);
  overflow-wrap: anywhere;
}
/* Empty status: out of sight and out of the card's flex gap, but still in
   the accessibility tree, so its next message is announced. */
.sw-status.is-idle {
  position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* Where focus lands when a closed dialog's opener is disabled and there is
   no status to read (swap.js closeModal); a programmatic target, not a control. */
/* No outline:none here: closeModal can hand focus to the card, and base.css
   already hides the ring for mouse focus via :focus:not(:focus-visible). */
.sw-card:focus { box-shadow: var(--shadow-sm); }
.sw-status.ok  { border-color: rgba(46,189,133,.35); background: var(--up-dim); }
.sw-status.err { border-color: rgba(246,70,93,.35); background: var(--down-dim); }
.sw-status a { color: var(--accent); font-weight: var(--fw-label); text-decoration: underline; text-underline-offset: 2px; }
.sw-status code { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-3); }

.sw-foot {
  max-width: 440px; margin-top: var(--s4); text-align: center;
  font-size: var(--fs-xs); line-height: 1.55; color: var(--text-4);
}

/* ---- Asset picker (inside the shared modal) ---- */
.sw-search {
  width: 100%; height: 40px; padding: 0 var(--s3);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--r-md);
  font-size: var(--fs-md); color: var(--text); outline: none;
}
.sw-search:focus { border-color: var(--accent); }
.sw-search::placeholder { color: var(--text-4); }
.sw-alist { display: flex; flex-direction: column; gap: 4px; max-height: 52vh; overflow-y: auto;
            margin: 0 -4px; padding: 0 4px; }
.sw-arow {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: 8px 10px; border-radius: var(--r-md); text-align: left;
  border: 1px solid transparent; transition: background var(--t-fast), border-color var(--t-fast);
}
.sw-arow:hover { background: var(--bg-elevated); }
.sw-arow.is-on { border-color: var(--accent-line); background: var(--accent-dim); }
.sw-arow:disabled { opacity: .7; cursor: default; }
.sw-aname { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.sw-aname b { font-size: var(--fs-md); font-weight: var(--fw-head); color: var(--text); }
.sw-aname span { font-size: var(--fs-xs); color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-abal { flex: 0 0 auto; font-size: var(--fs-sm); color: var(--text-2); text-align: right; }
.sw-empty { padding: var(--s6) 0; text-align: center; color: var(--text-4); font-size: var(--fs-sm); }

/* Confirm dialog: neutral head, accent action. */
.cf-head.swap { background: var(--accent-dim); border-color: var(--accent-line); }
.cf-head.swap .cf-get { color: var(--text); }
.cf-go.swap { background: var(--accent-fill); color: var(--on-accent-fill); }
/* The figures are wrapped in #cfFig so a re-price can repaint them, which
   made Route the last div in its box: exchange.css's .crow:last-of-type took
   its divider off, and the rows lost the body's gap between them.
   display: contents puts them back in the body's column. */
#cfFig { display: contents; }
#cfFig .crow:last-of-type { border-bottom: 1px solid var(--border-soft); }

/* ---- Phone ---- */
@media (max-width: 480px) {
  .sw-main { padding: var(--s5) var(--s3) var(--s10); }
  .sw-card { padding: var(--s4); border-radius: var(--r-lg); }
  .sw-amt { font-size: 26px; }
  /* Real text inputs stay at 16px or more so iOS does not zoom the page. */
  .sw-search { font-size: 16px; }
  .sw-slip-b { height: 26px; }
}

/* ---------- Advanced quote surface ---------- */

/* What each leg is worth, when XLM has a dollar mark to convert through.
   Empty string when it does not, so the line simply is not there — an
   unknown rate prints nothing rather than $0.00. */
.sw-fiat {
  min-height: 16px;
  padding: 2px 2px 0;
  font-size: var(--fs-sm);
  line-height: 16px;
  color: var(--text-4);
}

/* Price impact. Three states, and a fourth that says there is no reference —
   which is not the same as an impact of zero. */
.sw-imp-ok { color: var(--text); }
.sw-imp-warn { color: var(--warn); }
.sw-imp-bad { color: var(--down-text); font-weight: var(--fw-label); }

/* The route, named rather than counted. "via 2 hops" hides the only
   interesting part: which assets the payment passes through. */
.sw-route { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }
.sw-hop {
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  font-size: var(--fs-sm);
  line-height: 17px;
  color: var(--text-2);
  white-space: nowrap;
}
.sw-arrow { color: var(--text-4); font-size: var(--fs-sm); }

/* Custom slippage sits in the same group as the presets, so choosing one
   clears the other and there is never a doubt which is in force. */
.sw-slip-c {
  width: 62px;
  height: 26px;
  padding: 0 6px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--bg-input);
  color: var(--text);
  font: var(--fw-body) var(--fs-sm)/1 inherit;
  text-align: right;
}
.sw-slip-c:focus { outline: none; border-color: var(--accent); }
.sw-slip-c::placeholder { color: var(--text-4); }

/* The receive box is an input now, not an output. */
.sw-amt.is-stale { opacity: .5; }
.sw-amt.is-empty { color: var(--text-4); }

@media (max-width: 560px) {
  .sw-slip-c { width: 56px; }
  .sw-route { gap: 4px; }
}

/* A number wider than its box shrinks rather than sliding under the picker.
   Stellar amounts span twelve orders of magnitude, so no single size fits. */
.sw-amt { min-width: 0; text-overflow: ellipsis; }
.sw-box-row { gap: var(--s2); }

/* ---------- Unlisted assets ----------
   An asset the registry does not list is named with its issuer everywhere
   it appears. A code is not an identity — two hundred accounts issue a
   "USDC" — so the bare code alone let a shared link pass a counterfeit off
   as the listed asset. */

/* Picker button: the issuer goes on a second line under the code, so the
   button grows taller by nothing and wider by little. */
.sw-pick-code.is-unlisted {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  line-height: 15px;
}
.sw-pick-iss {
  font-size: var(--fs-2xs); line-height: 12px; font-weight: var(--fw-label);
  color: var(--warn); font-variant-numeric: tabular-nums; letter-spacing: .01em;
}

/* The notice under the card and in the review. Not dismissable: it is about
   what is being bought, not about a moment in the flow. */
.sw-unlisted { display: flex; flex-direction: column; gap: var(--s2); }
.sw-unlisted[hidden] { display: none; }
.sw-warn {
  padding: var(--s2) var(--s3);
  border-radius: var(--r-md); border: 1px solid var(--warn-line);
  background: var(--warn-dim); color: var(--text-2);
  font-size: var(--fs-sm); line-height: 1.5; overflow-wrap: anywhere;
}
.sw-warn b { color: var(--warn); font-weight: var(--fw-head); }
.sw-warn code {
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text);
  overflow-wrap: anywhere; word-break: break-all;
}
.sw-warn-leg {
  display: block; margin-bottom: 2px;
  font-size: var(--fs-2xs); font-weight: var(--fw-label); letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-3);
}
/* A listed code under a different issuer — the phishing case — is stated as
   a warning, not a caution. */
.sw-warn.is-lookalike { border-color: rgba(246,70,93,.35); background: var(--down-dim); }
.sw-warn.is-lookalike b { color: var(--down-text); }

/* Labels that now carry an issuer can outgrow one line of the button. */
.sw-go { white-space: normal; line-height: 1.2; text-align: center; }

/* Review: the acknowledgement a lookalike needs before it can be signed. */
.sw-ack {
  display: flex; align-items: flex-start; gap: var(--s2);
  font-size: var(--fs-sm); line-height: 1.45; color: var(--text); cursor: pointer;
}
.sw-ack input { margin-top: 2px; flex-shrink: 0; accent-color: var(--accent); }
.cstep-t { min-width: 0; overflow-wrap: anywhere; }
/* .cf-go.swap outranks .btn:disabled, so a held button still looked live. */
.cf-go.swap:disabled { background: var(--bg-hover); color: var(--text-4); }

/* While a signature or a ledger check is in progress the review cannot be
   dismissed, so it stops offering to be. */
.modal-host.is-locked .modal-x { visibility: hidden; }
.modal-host.is-locked .modal-backdrop { cursor: default; }

/* ---------- Watch-only ----------
   A session that cannot sign looked exactly like one that can: every control
   live, the quote arriving, and a three-letter "watch" tag on the address
   chip in the far corner carrying the whole message. Stated on the card, next
   to the button it limits. Not an alarm — nothing has gone wrong — so it is
   the surface's own border and input fill rather than the warn palette the
   counterfeit notice uses. */
/* No margin of its own: .sw-card is a flex column with its own gap, and a
   margin on top of that reads as a stray line. */
.sw-mode {
  padding: var(--s2) var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--bg-input); color: var(--text-2);
  font-size: var(--fs-sm); line-height: 1.5;
}
.sw-mode b { color: var(--text); font-weight: var(--fw-head); }
#swMode[hidden] { display: none; }

/* ---------- Quote age ----------
   The card re-prices every ten seconds; this says so, and says when the
   figures on screen were taken. Quiet by design: it is reassurance, not a
   warning, and it must not compete with the rate above it. */
.sw-fresh {
  padding: 4px 2px 0;
  font-size: var(--fs-2xs); line-height: 15px;
  color: var(--text-4); text-align: right;
}
.sw-fresh[hidden] { display: none; }

/* The same fact in the review, where it decides whether to sign. The idle
   re-price stands down while a dialog is open, so past AGE_STALE this stops
   being a footnote and says what an old quote does and does not still
   guarantee. */
.cf-age { font-size: var(--fs-xs); line-height: 1.5; color: var(--text-4); }
.cf-age.is-stale {
  padding: var(--s2) var(--s3);
  border: 1px solid var(--warn-line); border-radius: var(--r-md);
  background: var(--warn-dim); color: var(--text-2);
}

/* The two rows that answer "and then what": what the swap can take out of the
   XLM balance, and what is left. They close the list, so they carry the
   weight of a total rather than the weight of a detail. */
.cf-total span { color: var(--text-2); }
.cf-total b { color: var(--text); }

/* ---------- Review actions ----------
   Leaving was a 20-pixel x in the corner of the head while continuing was a
   full-width button at the foot. Before anything is signed those are the same
   size of decision. Cancel keeps to its content width so the primary action
   is still plainly the primary one. */
.cf-actions { display: flex; align-items: stretch; gap: var(--s2); margin-top: 4px; }
.cf-actions .cf-go { flex: 1 1 auto; margin-top: 0; }
.cf-cancel {
  flex: 0 0 auto; height: 42px; padding: 0 var(--s4);
  font-size: var(--fs-sm); font-weight: var(--fw-label); border-radius: var(--r-sm);
}

/* ---------- Wallet panel ----------
   The address is middle-truncated now, so it holds one line and both ends —
   the part anyone checks against their wallet — stay readable. Monospaced so
   the characters line up against the wallet's own rendering of them. */
.wm-addr-t {
  flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere;
  font-family: var(--font-mono); letter-spacing: .01em; color: var(--text);
}
/* Copy that still says "Copy" afterwards is a button nobody can tell worked. */
.wm-copy.is-done { color: var(--accent); border-color: var(--accent); }
/* The explorer belongs beside the address it opens, not in the stack of
   actions at the foot where it read as a peer of Disconnect. */
.wm-exp { display: inline-flex; align-items: center; text-decoration: none; }

/* Disconnect ends the session. It was the third of three identical ghost
   blocks; it now reads as the one that undoes something, and the extra margin
   on top of the body's own gap sets it apart from the rest of the panel. */
.wm-disc {
  margin-top: var(--s2);
  background: var(--bg-elevated); border: 1px solid var(--border);
  color: var(--down-text); font-weight: var(--fw-label);
}
.wm-disc:hover { background: var(--down-dim); border-color: var(--down); }
