/* ============================================================================
   wallet.css — the sidebar wallet block, its menu and its connect dialog
   ----------------------------------------------------------------------------
   Loaded by marketplace.html only, AFTER tokens.css / tokens-dark.css and after
   marketplace.css. That order is the reason there is not one literal colour,
   blur or shadow below: every value resolves from src/shared/tokens.css, and
   tokens-dark.css re-points the same names, so the whole file themes itself
   with no [data-theme="dark"] block of its own. Unlike src/recall-drawer/,
   which ships a standalone demo page and therefore carries a literal fallback
   beside every var(), this module is page-scoped and never renders without the
   token sheets.

   VOCABULARY (docs/design/v2-pages.md, "Components and measurements"):
     · Primary action — 11px radius, 40px minimum height, orange fill,
       explicit foreground (--on-brand where it exists, else the --white
       surface token, which is what every other filled control here does).
     · Panel — 16px radius, 1px --brand-20, paper glass, --blur-panel,
       --sh-4-panel. The dialog is exactly that panel.
     · Data row — hairline divider, compact metadata, tabular numerals.
     · Identity tile — neutral token fill, derived from the real id.

   MOTION (the cast thesis, and the audit's rules):
     · ONE ease, --w-ease, on every transition in this file.
     · THREE durations: 180ms in, 120ms out, 140ms for hover/press feedback.
     · Opacity and transform only. Nothing here transitions a layout property,
       so nothing here can cause a reflow mid-animation.
     · The menu RISES: 6px of translate plus opacity over 180ms on the way in;
       on the way out the transform is not in the transition list at all, so it
       snaps and only the opacity fades, over 120ms.
     · Reduced motion collapses every duration; the block still opens, closes
       and reports, it simply does it instantly.
   ========================================================================== */

.wallet-slot,
.wallet-dialog {
  --w-ease: cubic-bezier(.23, 1, .32, 1);
  --w-in: 180ms;
  --w-out: 120ms;
  --w-hover: 140ms;
}

/* ── the slot ─────────────────────────────────────────────────────────────
   The sidebar is a fixed 296px flex column inset 12px from the viewport on
   every side. `.filters` takes the flex, `.count` and this block do not, so the
   slot is pinned to the foot with no absolute positioning and no height maths.

   THE PADDING, and the one number that is not the brief's. The brief asks for
   "12 px bottom inset, 14 px side padding, matching the head's rhythm". The
   head's rhythm is `padding:14px 16px 12px` — 14 top, 16 SIDES, 12 bottom — and
   `.count`, `.grp` and `.searchwrap` all inset 16 with it. At 14 the block's
   left edge lands 2px inside every other row in the column, which is visible
   as a stagger the moment the menu opens beside the search field (measured:
   row at 15px from the sidebar's inner edge, search at 17px). So the sides take
   the head's 16 and the block is the head's rhythm mirrored, 12 over 14, which
   is what the sentence asks for even though it is not the number it names.
   Revert with one line — `padding: 12px 14px` — if the 14 was meant literally.

   The hairline above is `.count`'s own border-top, restated so the last two
   rows read as one foot rather than as a foot and an appendix. */
.wallet-slot {
  flex: 0 0 auto;
  position: relative;
  padding: 12px 16px 14px;
  border-top: 1px solid var(--border);
}

/* Nothing in marketplace.css had to be overridden for this to work, and one
   near-miss is worth writing down. The sidebar is a flex column; on the phone
   `marketplace.css` (~L896) re-lays it as a centred box capped at
   `max-height:64vh` with `overflow:hidden`. A block appended after `.count`
   would be clipped clean off that sheet if `.filters` refused to shrink — and a
   flex item's default `min-height:auto` is exactly that refusal. It does not
   bite here because `.filters` already carries `overflow-y:auto`, which makes
   its automatic minimum size zero, so the list gives up its own height and this
   block stays inside the sheet. Measured at 390x844: sheet 151.9-692.1, slot
   630.1-691.1. If `.filters` ever loses that overflow, add `min-height:0`. */

/* ── disconnected: the one action ─────────────────────────────────────────
   Quest.Tech's rule, verbatim: disconnected, the whole block IS the action. */
.wallet-connect {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 40px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-11);
  background: var(--brand);
  color: var(--on-brand, var(--white));
  font-family: var(--font-body);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: opacity var(--w-hover) var(--w-ease),
              transform var(--w-hover) var(--w-ease);
}
.wallet-connect:hover { opacity: .9; }
.wallet-connect:active { transform: scale(.98); }
.wallet-connect:disabled { opacity: .6; cursor: default; transform: none; }
.wallet-connect:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ── connected: the glass row ─────────────────────────────────────────────── */
.wallet-account { position: relative; }

.wallet-row {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 9px;
  text-align: left;
  border: 1px solid var(--brand-20);
  border-radius: var(--r-11);
  background: var(--paper-93);
  -webkit-backdrop-filter: var(--blur-card);
  backdrop-filter: var(--blur-card);
  box-shadow: var(--sh-1-card);
  color: var(--ink);
  cursor: pointer;
  transition: border-color var(--w-hover) var(--w-ease),
              box-shadow var(--w-hover) var(--w-ease);
}
.wallet-row:hover { border-color: var(--brand-55); box-shadow: var(--sh-2); }
.wallet-row:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* the identity tile: a neutral plate, the mark inside it, 7px corners like
   every other small avatar on the page (.brandlogo, .influ-row .ip) */
.wallet-mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: var(--wm-size, 28px);
  height: var(--wm-size, 28px);
  border-radius: var(--r-7);
  overflow: hidden;
}
.wallet-mark svg { display: block; }

/* The address is the row's only text (user ruling on review: pfp and wallet,
   nothing else — the network line and status dot were removed). */
.wallet-addr {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-md);
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── the menu ─────────────────────────────────────────────────────────────
   It rises out of the row rather than dropping past the sidebar's foot, which
   is also what keeps it inside `.sidebar`'s `overflow:hidden`. The closed rule
   carries the exit transition and the open rule the entrance, which is how the
   entrance moves and the exit only fades. `visibility` keeps the closed items
   out of the tab ring; the row itself is what :focus-within catches. */
.wallet-menu {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 6px);
  z-index: 3;
  padding: 5px;
  /* The sidebar's OWN dropdown vocabulary, not the panel's: `.suggest`
     (marketplace.css L122) is the one surface that already floats over this
       column, and it is opaque `--white` with a `--border` hairline and
     `--sh-3-suggest`. A paper-glass plate over paper-glass reads as text with
     no plate under it, which is what the first pass looked like. */
  border: 1px solid var(--border);
  border-radius: var(--r-12);
  background: var(--white);
  box-shadow: var(--sh-3-suggest);
  transform-origin: bottom center;

  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--w-out) var(--w-ease),
              visibility 0s linear var(--w-out);
}
.wallet-account:hover > .wallet-menu,
.wallet-account:focus-within > .wallet-menu,
.wallet-account[data-open="true"] > .wallet-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity var(--w-in) var(--w-ease),
              transform var(--w-in) var(--w-ease),
              visibility 0s linear 0s;
}
/* the dismissal veto, and the reason it has to exist.
   Escape closes the menu and puts focus back on the row — which is INSIDE
   `.wallet-account`, so `:focus-within` would immediately re-open it and
   Escape would do nothing at all. The same is true of a second click on the
   row. wallet.js sets this attribute for exactly those two gestures and clears
   it the moment the pointer or the focus leaves and comes back. It carries the
   exit transition, so a dismissal fades out on opacity alone like every other
   close. */
.wallet-account[data-dismissed="true"] > .wallet-menu {
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--w-out) var(--w-ease),
              visibility 0s linear var(--w-out);
}

.wallet-menu-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.wallet-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 30px;
  padding: 5px 8px;
  text-align: left;
  border: 0;
  border-radius: var(--r-8);
  background: none;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  cursor: pointer;
  transition: background-color var(--w-hover) var(--w-ease),
              color var(--w-hover) var(--w-ease);
}
.wallet-item:hover { background: var(--brand-08); color: var(--brand); }
.wallet-item:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.wallet-item-label { flex: 1 1 auto; min-width: 0; }

/* ── the connect dialog ───────────────────────────────────────────────────
   The clone's panel, exactly: 16px radius, --paper-93, --blur-panel,
   --sh-4-panel, a --brand-20 hairline. A native <dialog>, so the top layer
   carries it out of the sidebar's overflow with no portal. */
.wallet-dialog {
  width: 356px;
  max-width: calc(100vw - 24px);
  padding: 16px;
  border: 1px solid var(--brand-20);
  border-radius: var(--r-16);
  background: var(--paper-93);
  -webkit-backdrop-filter: var(--blur-panel);
  backdrop-filter: var(--blur-panel);
  box-shadow: var(--sh-4-panel);
  color: var(--ink);
  font-family: var(--font-body);
}
.wallet-dialog::backdrop {
  background: var(--scrim-modal);
  -webkit-backdrop-filter: var(--blur-xs);
  backdrop-filter: var(--blur-xs);
}
.wallet-dialog[open] { animation: wallet-in var(--w-in) var(--w-ease); }
@keyframes wallet-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.wallet-dialog-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 12px;
}
.wallet-dialog-title {
  flex: 1 1 auto;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-17);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-tight);
}
.wallet-dialog-x {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-8);
  background: none;
  color: var(--graphite);
  font-size: var(--fs-base);
  cursor: pointer;
  transition: background-color var(--w-hover) var(--w-ease),
              color var(--w-hover) var(--w-ease);
}
.wallet-dialog-x:hover { background: var(--brand-08); color: var(--brand); }
.wallet-dialog-x:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.wallet-dialog-list { display: flex; flex-direction: column; gap: 8px; }
.wallet-conn-wrap { display: flex; flex-direction: column; gap: 4px; }

/* Quest.Tech's measured wallet row: 50px tall, 12px radius. */
.wallet-conn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 50px;
  padding: 0 11px;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--r-12);
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
  transition: border-color var(--w-hover) var(--w-ease),
              opacity var(--w-hover) var(--w-ease);
}
.wallet-conn:hover { border-color: var(--brand); }
.wallet-conn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.wallet-conn:disabled { cursor: default; opacity: .6; }

.wallet-conn-icon {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: var(--r-6);
  object-fit: contain;
}
.wallet-conn-icon-blank { background: var(--brand-14); }

.wallet-conn-label {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  flex: 1 1 auto;
}
.wallet-conn-label b {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wallet-conn-label small {
  font-size: var(--fs-sm-p);
  line-height: var(--lh-body);
  color: var(--graphite);
}

/* the DETECTED / PREVIEW pill — pump.fun's idea by way of Quest.Tech: the list
   is a report of what is on this machine, and the pill is what says so */
.wallet-tag {
  flex: 0 0 auto;
  padding: 2px 7px;
  border-radius: var(--r-20);
  background: var(--brand-14);
  color: var(--acc);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-10);
  text-transform: uppercase;
}

.wallet-conn-msg {
  margin: 0 2px;
  font-size: var(--fs-sm-p);
  line-height: var(--lh-body);
  color: var(--graphite);
}
.wallet-conn-msg.is-error { color: var(--danger); }

.wallet-dialog-empty {
  margin: 0 0 4px;
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  color: var(--graphite);
}

.wallet-dialog-note {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--divider-warm);
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  color: var(--graphite);
}

/* ── phone ───────────────────────────────────────────────────────────────
   At ≤560px the sidebar becomes a centred sheet (marketplace.css ~L896) capped
   at 64vh. The slot travels with it as the sheet's last flex child and stays
   reachable; only the paddings tighten. */
@media (max-width: 560px) {
  .wallet-slot { padding: 10px 12px; }
  .wallet-dialog { padding: 14px; }
  .wallet-conn { min-height: 46px; }
}

/* ── reduced motion ──────────────────────────────────────────────────────
   Every transition and the dialog's entrance collapse. The menu still opens,
   the dialog still appears; neither travels. */
@media (prefers-reduced-motion: reduce) {
  .wallet-slot,
  .wallet-dialog {
    --w-in: .01ms;
    --w-out: .01ms;
    --w-hover: .01ms;
  }
  .wallet-menu { transform: none; }
  .wallet-connect:active { transform: none; }
  .wallet-dialog[open] { animation: none; }
}
