/* Ported from wallet_mini_app's inline <style> blocks (wallet busimatch.js lines 28-94, 98-162). */
/* Branding colors are applied at runtime via CSS custom properties set from sys_options - see js/wallet-bootstrap.js. */
body { font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; }
#wkn-wallet-fullpage-root { background: var(--wkn-bg, #fff); min-height: 100%; }
.glass { background: rgba(255,255,255,0.6); backdrop-filter: blur(6px); }
.dark .glass { background: rgba(15,23,42,0.6); }
.balance-large { font-weight:700; font-size:1.35rem; position: relative; transition: all 0.2s ease-in-out; }
.token-card { transition: transform .15s, box-shadow .15s; }
.token-card:active { transform: translateY(1px); }
.token-card:hover { background-color: rgba(0,0,0,0.03); }
.refresh-price-btn .fa-sync-alt { transition: transform 0.3s ease; }
.refresh-price-btn:hover .fa-sync-alt { transform: rotate(90deg); }
.spinner { width: 16px; height: 16px; display: inline-block; }
.token-img { width:36px; height:36px; border-radius:999px; object-fit:cover; }
.clickable { cursor:pointer; }
#modalRoot > *, #customDialogRoot > * { align-items:center; justify-content:center; }
.modal-backdrop-layout{position:fixed;inset:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:999999;display:flex;align-items:center;justify-content:center}
.modal-backdrop-layout>.modal-backdrop{max-width:600px;width:100%;margin:0 16px;box-sizing:border-box}
.modal-backdrop-layout>.modal-token-backdrop{max-width:800px;width:100%;margin:0 16px;box-sizing:border-box}

/* ---- Modal consistency + mobile-first layout (Session 12) ----
   Every dynamically-built dialog in this file wraps itself in
   `.modal-backdrop-layout` (confirmed by search - no other ad-hoc
   fixed-position dialog pattern exists), then usually - but not always
   - an inner `.modal-backdrop`/`.modal-token-backdrop` wrapper before
   its own hand-written content div. Because that inner wrapper class
   was sometimes skipped, and its own box (shadow/radius/background) was
   never centrally defined - only max-width/margin - the actual visible
   box was left entirely to each individual call site's own Tailwind
   classes, which is why some ended up too narrow/plain and others
   stretched edge-to-edge. This gives EVERY modal's direct content a
   sane, consistent default box, whether or not that specific call site
   remembered `.modal-backdrop`, and without touching any of the ~12
   individual call sites. */
.modal-backdrop-layout { padding: 16px; }
.modal-backdrop-layout > div {
  width: 100%;
  max-width: 460px;
  margin: 0 auto;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  border-radius: var(--wkn-radius-lg);
  box-shadow: var(--wkn-shadow-lg);
  animation: wknScaleIn .25s cubic-bezier(.34,1.56,.64,1);
}
.modal-backdrop-layout > .modal-backdrop, .modal-backdrop-layout > .modal-token-backdrop { box-shadow: none; } /* the shadow belongs on the visible box one level in, not this sizing wrapper - avoids a doubled/offset shadow where a call site DOES nest both */
.modal-backdrop-layout > .modal-token-backdrop { max-width: 800px; }
/* the actual visible card is usually one level further in (each call
   site's own `bg-white dark:bg-gray-800 rounded-lg ...` div) - give
   THAT the real shadow/radius when it's a direct child of the sizing
   wrapper above, so nesting depth doesn't create a doubled box. */
.modal-backdrop-layout > div > div:first-child { border-radius: inherit; }

/* Mobile: full-screen, no backdrop margin/space, per instruction -
   EXCEPT compact utility dialogs (numeric password entry, and any
   future delete/simple-confirm dialog) opted out via
   `.wkn-modal-compact`, which stay centered with full WIDTH but not
   full height, matching "alert/prompt/confirm/password" being called
   out as the deliberate exception. */
@media (max-width: 640px) {
  .modal-backdrop-layout { padding: 0; }
  .modal-backdrop-layout > div:not(.wkn-modal-compact) {
    max-width: 100%;
    width: 100%;
    height: 100%;
    max-height: 100%;
    margin: 0;
    border-radius: 0;
  }
  .modal-backdrop-layout > .wkn-modal-compact {
    width: calc(100% - 24px);
    max-width: 440px;
    margin: 0 auto;
    border-radius: var(--wkn-radius-lg);
  }
}
.fade-in {
  animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: translateY(0); }
}
button i {
  transition: transform 0.2s ease, color 0.2s ease;
}
button:hover i {
  transform: translateY(-2px);
  color: #4338ca;
}
/* This unscoped rule's background-color is the confirmed root cause of
   Session 27's colored-action-button hover bug ("#doTransferMain
   white-on-white on hover") - its specificity (element + pseudo-class)
   beats a bare Tailwind bg-color utility class, so it silently
   overrode the background on hover for every colored button sitewide.
   Left in place (still the intended subtle hover for plain, uncolored
   buttons), but the `!important` rule added for
   `button[class*="bg-"][class*="text-white"]:hover` further down this
   file now reliably overrides it for colored action buttons specifically. */
button:hover {
  border-color: #4338ca;
  background-color: rgba(67, 56, 202, 0.05);
}
#toggleUsdInput:checked + div {
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
}
/* keep the mobile tweak */
@media (max-width: 640px) {
  #connectedInfo { display: none; }
  #profileQuickActions { width: 100% !important; }
}
#doAddTokenHome, #addTokenAddrHome, #doTransferMain { width: 100%; }
.ui-widget, .ui-widget-content, .ui-autocomplete, #ui-id-4.ui-menu-item-wrapper { 
  color: transparent !important;
  font-size: 0 !important;
  display: none !important;
}
/* REMOVE BLUR / WHITE LAYERS from selects and wallet button */
select,
.web3-toggle-btn {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    filter: none !important;
    background: none !important;
    background-color: transparent !important;
    opacity: 1 !important;
    box-shadow: none !important;
}
select,
.web3-toggle-btn {
    background-color: #fff !important;   /* light mode */
}
.dark select,
.dark .web3-toggle-btn {
    background-color: #1f2937 !important; /* dark mode */
}
/* BUG FIXED (Session 18): the home/close icon (a Font Awesome glyph,
   `color: inherit` by default - not an inline SVG with its own
   explicit stroke) had no color of its own at all, so it silently rode
   on whatever an ancestor's `color` happened to be - correct only by
   accident, and easily broken by any future change up the chain (as
   nearly happened with this very session's own background/color
   fixes). Set explicitly and unconditionally here instead: dark icon
   on the light background, light icon on the dark background, matching
   the button's own background toggle one rule above. */
.web3-toggle-btn { color: #111827 !important; }
.dark .web3-toggle-btn, html[data-wkn-theme="dark"] .web3-toggle-btn { color: #e6eef8 !important; }
#web3WalletInstanceMiniModal {
  position: relative;
  width: 100%;
  /* BUG FIXED (Session 18): was a rigid `height: 100%` - together with
     #wkn-wallet-fullpage-root having no explicit height of its own,
     this could compute against an indeterminate/viewport-only ancestor
     height rather than truly growing with content, reported as "fixed
     page height and not adjust according to content". `min-height`
     lets this - and everything under it - grow past one viewport's
     worth of content when a page genuinely needs more room, while
     .modal-panel's own internal `overflow:auto` (below) still handles
     the common case of scrolling within one fixed-height view. */
  min-height: 100%;
  display: flex;            /* always shown - this module renders the
                                wallet as a full page/iframe, not as a
                                toggled overlay modal on top of some
                                other host page any more, so the old
                                "display:none until .visible" default
                                (see BUILD.md) is gone. */
  align-items: center;      /* center content vertically */
  justify-content: center;  /* center content horizontally */
}

/* inner dialog / panel */
#web3WalletInstanceMiniModal .modal-panel {
  max-width: 100%;
  min-width: 100%;
  max-height: 100%;
  min-height: 100%;
  overflow: auto;
  /* BUG FIXED (Session 17): was hardcoded #fff (light) / #0b1220 (the
     old OS-media-query dark fallback right below, now removed), which
     ignored the admin's own configured background colors entirely -
     `--wkn-bg` is now actually SET on this document, per mode, by
     template/index.html's own applyTheme() (mirroring what
     wallet-bootstrap.js already did for the floating widget button on
     OTHER pages), falling back to the same #fff default when the admin
     hasn't customized branding, so a plain install looks identical to
     before. */
  background: var(--wkn-bg, #fff);
  color: #111827;
  /* This is the ONE scroll container for the entire app (every page -
     home/transfer/tokens/transactions/settings/watch-wallets - lives
     inside it), with zero bottom padding, so scrolling all the way
     down on any page taller than the viewport left its last row/button
     flush against the bottom edge - "some UI is cut off". A generous
     bottom gutter, bigger on mobile where on-screen keyboards and
     browser chrome eat into the visible area even further, pushes
     every page's real last item fully into view once scrolled to the
     bottom. */
  padding-bottom: 48px;
  box-sizing: border-box;
}
@media (max-width: 640px) {
  #web3WalletInstanceMiniModal .modal-panel { padding-bottom: 88px; }
}
html.dark #web3WalletInstanceMiniModal .modal-panel, html[data-wkn-theme="dark"] #web3WalletInstanceMiniModal .modal-panel { color: #e6eef8; }

/* small helper for the icon button */
.web3-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: rgba(255,255,255,0.9);
  border: 1px solid rgba(0,0,0,0.06);
  cursor: pointer;
  box-shadow: 0 3px 10px rgba(2,6,23,0.06);
}
.web3-toggle-btn:active { transform: translateY(1px); }
.web3-toggle-btn svg { width: 20px; height: 20px; display:block; }

/* accessibility focus ring */
.web3-toggle-btn:focus {
  outline: 3px solid rgba(99,102,241,0.18);
  outline-offset: 2px;
}

/* --- Welkin Wallet theme bridge (reads sys_options-driven CSS vars set by wallet-bootstrap.js) --- */
:root { --wkn-primary: #6C5CE7; --wkn-accent: #00C2A8; --wkn-bg: #FFFFFF; }
[data-wkn-theme="dark"] { --wkn-primary: #B8ACFF; --wkn-accent: #2FE6C9; --wkn-bg: #0B1220; }
/* The floating toggle button + slide-out panel's own CSS lives INLINE in
 template/wallet-widget.html itself now, not here - that fragment is
 injected via innerHTML into arbitrary pages sitewide by
 js/wallet-bootstrap.js, never through a real page render, so it can
 never depend on THIS file's <link> tag (only ever added via
 addCss() during an actual page render - i.e. only on the /wallet
 page itself) having loaded. See wallet-widget.html's own header
 comment for the full explanation. */
/* =====================================================================
   Session 11 - modern design system, motion, and a real site-wide
   success/error/warning/info notification + result-modal component.
   Everything below is ADDITIVE - no existing selector above this line
   was removed or renamed, so nothing that already worked (dynamic
   modals, token cards, chips, the wallet-panel bridge vars) can
   regress from this block alone. New custom properties are layered
   on top of (not replacing) the existing --wkn-primary/--wkn-accent/
   --wkn-bg bridge already used by wallet-bootstrap.js.
   ===================================================================== */

:root {
  --wkn-surface: #ffffff;
  --wkn-surface-2: #f8f9fc;
  --wkn-text: #0f172a;
  --wkn-text-muted: #64748b;
  --wkn-border: rgba(15, 23, 42, 0.08);
  --wkn-success: #16a34a;
  --wkn-success-bg: #f0fdf4;
  --wkn-error: #dc2626;
  --wkn-error-bg: #fef2f2;
  --wkn-warning: #d97706;
  --wkn-warning-bg: #fffbeb;
  --wkn-info: #2563eb;
  --wkn-info-bg: #eff6ff;
  --wkn-radius-sm: 8px;
  --wkn-radius-md: 14px;
  --wkn-radius-lg: 20px;
  --wkn-shadow-sm: 0 1px 2px rgba(15,23,42,0.06), 0 1px 3px rgba(15,23,42,0.08);
  --wkn-shadow-md: 0 4px 14px rgba(15,23,42,0.08), 0 2px 6px rgba(15,23,42,0.06);
  --wkn-shadow-lg: 0 12px 32px rgba(15,23,42,0.14), 0 4px 10px rgba(15,23,42,0.08);
}

/* Both mechanisms honored - html.dark (Tailwind class-strategy, and the
   3 pre-existing ".dark X" rules above already assumed this) AND
   html[data-wkn-theme="dark"] (this module's own pre-existing bridge
   attribute, previously only ever set by wallet-bootstrap.js on a HOST
   page for the floating widget button, never on this page's own
   document) - the new theme toggle (see template/index.html) sets BOTH
   so this re-theme applies regardless of which one anything else in
   the stack happens to be watching. */
html.dark, html[data-wkn-theme="dark"] {
  --wkn-surface: #111827;
  --wkn-surface-2: #0b1220;
  --wkn-text: #e6eef8;
  --wkn-text-muted: #94a3b8;
  --wkn-border: rgba(255, 255, 255, 0.08);
  --wkn-success-bg: rgba(22,163,74,0.14);
  --wkn-error-bg: rgba(220,38,38,0.14);
  --wkn-warning-bg: rgba(217,119,6,0.14);
  --wkn-info-bg: rgba(37,99,235,0.16);
}

/* Smooth theme switch - scoped to the properties that actually change on
   toggle, not a blanket `* { transition: all }` (which would fight the
   existing icon-rotate/transform transitions already authored above and
   tank scroll performance on long token lists). */
body, #web3WalletInstanceMiniModal, #web3WalletInstanceMiniModal .modal-panel,
button, input, select, textarea, .token-card, .glass,
[class*="bg-white"], [class*="bg-gray-"], [class*="border-gray-"], [class*="text-gray-"] {
  transition: background-color .25s ease, border-color .25s ease, color .25s ease;
}

/* ---- Global micro-interaction polish (attribute-substring selectors so
   this reaches Tailwind's already-authored utility classes throughout
   the 6,800-line markup without needing to touch that markup itself). ---- */
[class*="rounded-lg"][class*="shadow"] {
  transition: transform .18s ease, box-shadow .18s ease;
}
[class*="rounded-lg"][class*="shadow"]:hover {
  box-shadow: var(--wkn-shadow-md);
}
button:not(:disabled) {
  transition: transform .12s ease, box-shadow .15s ease, background-color .15s ease, border-color .15s ease, opacity .15s ease;
}
button:not(:disabled):active { transform: translateY(1px) scale(0.98); }
button:disabled { opacity: .55; cursor: not-allowed; }
input, select, textarea {
  transition: box-shadow .15s ease, border-color .15s ease;
}
/* BUG FIXED (Session 21): "sharp" + theme-aware active/focus border,
   using the admin's own configured primary color rather than a fixed
   purple - darkened for contrast against a light background, lightened
   against a dark one, since the same raw brand color often reads as
   low-contrast/muddy on one of the two backgrounds otherwise.
   color-mix() is modern-baseline (widely supported since ~2023); the
   plain var(--wkn-primary) fallback one rule up still applies in any
   browser without it - a cosmetic-only degradation, never a broken
   input. */
input:focus, select:focus, textarea:focus {
  outline: none !important;
  box-shadow: 0 0 0 3px rgba(108, 92, 231, 0.18) !important;
  border-color: var(--wkn-primary, #6C5CE7) !important;
}
/* BUG FIXED (Session 23): per instruction, the hidden native <select>
   behind a custom-select button (see wknEnhanceSelect()) never shows
   any focus styling of its own - it is a fully transparent, zero-size-
   visually source-of-truth element, and giving it a box-shadow/border
   change on focus was pure wasted paint work on an invisible element
   (a plausible contributor to "some elements causing it to flicker"),
   plus a stray outline could theoretically show through in some odd
   stacking/rendering edge cases. tabindex="-1" (added in the JS, see
   wknEnhanceSelect()) also removes it from the tab order entirely, so
   it can no longer receive focus via keyboard either - the custom
   button is the only focusable, only visibly-focus-styled element now. */
.wkn-select-wrap select:focus { outline: none !important; box-shadow: none !important; border-color: transparent !important; }
@supports (color: color-mix(in srgb, red, blue)) {
  input:focus, select:focus, textarea:focus {
    border-color: color-mix(in srgb, var(--wkn-primary, #6C5CE7) 70%, black 25%) !important;
  }
  html.dark input:focus, html.dark select:focus, html.dark textarea:focus,
  html[data-wkn-theme="dark"] input:focus, html[data-wkn-theme="dark"] select:focus, html[data-wkn-theme="dark"] textarea:focus {
    border-color: color-mix(in srgb, var(--wkn-primary, #6C5CE7) 70%, white 30%) !important;
  }
  .wkn-select-wrap select:focus { border-color: transparent !important; }
}
/* Theme-aware form fields, EVERYWHERE (including inside dynamically-
   built modal markup, which mostly used bare `border rounded` classes
   with no bg-white/dark:bg-gray-800 pair of its own, so it stayed
   whatever color the browser's own UA default happened to be in dark
   mode - usually still light, hence "some parts didn't change to
   light/dark"). `!important` is deliberate here: this needs to win over
   both a plain unstyled input (no background/color at all) AND an
   input that already carries an explicit `bg-white`/`bg-gray-100`
   Tailwind utility class, since there are too many individual dynamic-
   modal call sites throughout this file to edit each one's classList
   by hand. Placeholder color is the OPPOSITE lightness of the field's
   own text color in each mode, per instruction, so it stays legible
   against the field's own background either way. */
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  background-color: var(--wkn-surface) !important;
  color: var(--wkn-text) !important;
  border-color: var(--wkn-border) !important;
}
input:not([type="checkbox"]):not([type="radio"])::placeholder, textarea::placeholder {
  color: var(--wkn-text-muted) !important;
  opacity: 1;
}
input:disabled, select:disabled, textarea:disabled { opacity: .6; cursor: not-allowed; }
.nav-btn { transition: background-color .15s ease, color .15s ease, padding-left .15s ease; border-left: 3px solid transparent; }
.nav-btn:hover { padding-left: 14px; background-color: rgba(108,92,231,0.08); }
.nav-btn svg { flex: 0 0 auto; opacity: .75; transition: opacity .15s ease, transform .15s ease; }
.nav-btn:hover svg { opacity: 1; transform: scale(1.08); }
/* Semantic, theme-aware "active sidebar item" - replaces the old raw
   bg-gray-100/dark:bg-gray-700 pair the JS toggle used to juggle by
   hand (see Session 12 notes in BUILD.md for why that broke in dark
   mode). Uses the design-system CSS variables directly, so it is
   correct in both themes with zero JS knowledge of color values. */
.wkn-nav-active {
  background: rgba(108,92,231,0.12) !important;
  border-left-color: var(--wkn-primary, #6C5CE7) !important;
  color: var(--wkn-primary, #6C5CE7) !important;
  font-weight: 600;
}
.wkn-nav-active svg { opacity: 1; }
html.dark .wkn-nav-active, html[data-wkn-theme="dark"] .wkn-nav-active { background: rgba(139,124,255,0.18) !important; color: #b7aefc !important; }
.network-chip, .wallet-mode-chip { transition: all .15s ease; }

/* ---- Active/selected-state theming, dark-mode-aware ----
   Several "active tab/chip/sidebar-item" states throughout
   template/index.html are driven by plain JS classList.toggle() calls
   against light-only Tailwind utilities (bg-gray-100, bg-indigo-50,
   bg-yellow-50 + border/text-yellow-800 pairs) with no dark: variant of
   their own - so in dark mode the "active" indicator either vanished
   (nothing readable against a dark background) or looked wrong. Fixed
   here, once, for every one of these classes, rather than touching each
   JS call site individually (there are 3 separate active-state
   functions using this exact same light-only-class pattern: the
   sidebar nav, the network/wallet-mode chips, and the readonly-wallet
   tabs) - so ANY future toggle() call using these same class names is
   covered too, not just the ones found this session. */
html.dark .bg-gray-100, html[data-wkn-theme="dark"] .bg-gray-100 { background-color: rgba(255,255,255,0.10) !important; color: var(--wkn-text) !important; }
html.dark .bg-indigo-50, html[data-wkn-theme="dark"] .bg-indigo-50 { background-color: rgba(99,102,241,0.20) !important; color: #c7d2fe !important; }
html.dark .bg-yellow-50, html[data-wkn-theme="dark"] .bg-yellow-50 { background-color: rgba(234,179,8,0.18) !important; }
html.dark .text-yellow-800, html[data-wkn-theme="dark"] .text-yellow-800 { color: #fde68a !important; }
html.dark .border-yellow-400, html[data-wkn-theme="dark"] .border-yellow-400 { border-color: #ca8a04 !important; }
html.dark .border-gray-300, html[data-wkn-theme="dark"] .border-gray-300 { border-color: rgba(255,255,255,0.14) !important; }
html.dark .text-gray-600, html[data-wkn-theme="dark"] .text-gray-600 { color: var(--wkn-text-muted) !important; }
html.dark .text-gray-500, html[data-wkn-theme="dark"] .text-gray-500 { color: var(--wkn-text-muted) !important; }
html.dark .bg-emerald-600, html[data-wkn-theme="dark"] .bg-emerald-600 { background-color: #059669 !important; }
html.dark .bg-white, html[data-wkn-theme="dark"] .bg-white { background-color: var(--wkn-surface) !important; color: var(--wkn-text) !important; }
html.dark .border, html[data-wkn-theme="dark"] .border { border-color: var(--wkn-border) !important; }

/* Custom scrollbar - subtle, modern, theme-aware */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(100,116,139,0.35); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: rgba(100,116,139,0.55); }

/* Richer glassmorphism (was flat blur-only) */
.glass {
  background: rgba(255,255,255,0.65);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.4);
}
.dark .glass, html[data-wkn-theme="dark"] .glass {
  background: rgba(15,23,42,0.55);
  border: 1px solid rgba(255,255,255,0.06);
}

/* Loading skeleton (shimmer) - for any list/card placeholder markup
   that opts in via class="wkn-skeleton" */
.wkn-skeleton {
  position: relative;
  overflow: hidden;
  background: linear-gradient(90deg, rgba(148,163,184,0.15) 25%, rgba(148,163,184,0.28) 37%, rgba(148,163,184,0.15) 63%);
  background-size: 400% 100%;
  animation: wknShimmer 1.4s ease infinite;
  border-radius: var(--wkn-radius-sm);
}
@keyframes wknShimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

/* ---- Motion primitives ---- */
@keyframes wknFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes wknScaleIn { from { opacity: 0; transform: scale(.92) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }
@keyframes wknScaleOut { from { opacity: 1; transform: scale(1) translateY(0); } to { opacity: 0; transform: scale(.92) translateY(8px); } }
@keyframes wknSlideInRight { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: translateX(0); } }
@keyframes wknSlideOutRight { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(24px); } }
@keyframes wknPulseRing {
  0% { box-shadow: 0 0 0 0 rgba(22,163,74,0.35); }
  70% { box-shadow: 0 0 0 12px rgba(22,163,74,0); }
  100% { box-shadow: 0 0 0 0 rgba(22,163,74,0); }
}
@keyframes wknDrawCheck { to { stroke-dashoffset: 0; } }
@keyframes wknIconPop { 0% { transform: scale(0); } 70% { transform: scale(1.12); } 100% { transform: scale(1); } }

.wkn-page-enter { animation: wknFadeIn .35s ease; }

/* =====================================================================
   Site-wide toast/notification system (#wknToastViewport, created and
   populated entirely by template/index.html's showToast()). Replaces
   the native alert() dialog (overridden in JS) for every one of this
   module's existing ~76 alert() call sites with zero per-call-site
   edits required.
   ===================================================================== */
#wknToastViewport {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 2147483647; /* above every modal, incl. the mobile sidebar (2147483050) */
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: min(380px, calc(100vw - 32px));
  pointer-events: none;
}
@media (max-width: 640px) {
  #wknToastViewport { left: 16px; right: 16px; top: 12px; max-width: none; }
}
.wkn-toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--wkn-radius-md);
  background: var(--wkn-surface);
  color: var(--wkn-text);
  box-shadow: var(--wkn-shadow-lg);
  border: 1px solid var(--wkn-border);
  border-left: 4px solid var(--wkn-info);
  animation: wknSlideInRight .28s cubic-bezier(.34,1.56,.64,1);
  position: relative;
  overflow: hidden;
}
.wkn-toast.wkn-toast--leaving { animation: wknSlideOutRight .22s ease forwards; }
.wkn-toast--success { border-left-color: var(--wkn-success); }
.wkn-toast--error { border-left-color: var(--wkn-error); }
.wkn-toast--warning { border-left-color: var(--wkn-warning); }
.wkn-toast--info { border-left-color: var(--wkn-info); }
.wkn-toast .wkn-toast-icon { flex: 0 0 auto; width: 22px; height: 22px; margin-top: 1px; }
.wkn-toast--success .wkn-toast-icon { color: var(--wkn-success); }
.wkn-toast--error .wkn-toast-icon { color: var(--wkn-error); }
.wkn-toast--warning .wkn-toast-icon { color: var(--wkn-warning); }
.wkn-toast--info .wkn-toast-icon { color: var(--wkn-info); }
.wkn-toast-body { flex: 1 1 auto; font-size: .875rem; line-height: 1.35; word-break: break-word; }
.wkn-toast-close {
  flex: 0 0 auto; background: none; border: none; cursor: pointer; padding: 2px;
  color: var(--wkn-text-muted); border-radius: 6px; line-height: 1;
}
.wkn-toast-close:hover { background: rgba(100,116,139,0.14); }
.wkn-toast-progress {
  position: absolute; left: 0; bottom: 0; height: 3px; background: currentColor; opacity: .35;
  animation-name: wknToastProgress; animation-timing-function: linear; animation-fill-mode: forwards;
}
.wkn-toast--success .wkn-toast-progress { color: var(--wkn-success); }
.wkn-toast--error .wkn-toast-progress { color: var(--wkn-error); }
.wkn-toast--warning .wkn-toast-progress { color: var(--wkn-warning); }
.wkn-toast--info .wkn-toast-progress { color: var(--wkn-info); }
@keyframes wknToastProgress { from { width: 100%; } to { width: 0%; } }

/* =====================================================================
   Result modal - bigger, centered, for significant events (wallet
   created/imported, transaction sent/failed, password changed) with an
   animated success/error SVG icon.
   ===================================================================== */
.wkn-result-backdrop {
  position: fixed; inset: 0; z-index: 2147483100;
  background: rgba(15,23,42,0.55);
  backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  animation: wknFadeIn .18s ease;
}
.wkn-result-backdrop.wkn-toast--leaving { animation: wknFadeIn .16s ease reverse forwards; }
.wkn-result-modal {
  width: 100%; max-width: 380px;
  background: var(--wkn-surface); color: var(--wkn-text);
  border-radius: var(--wkn-radius-lg);
  box-shadow: var(--wkn-shadow-lg);
  padding: 28px 24px 22px;
  text-align: center;
  animation: wknScaleIn .28s cubic-bezier(.34,1.56,.64,1);
}
.wkn-result-icon-wrap {
  width: 72px; height: 72px; margin: 0 auto 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  animation: wknIconPop .4s cubic-bezier(.34,1.56,.64,1);
}
.wkn-result-icon-wrap svg { width: 40px; height: 40px; }
.wkn-result-modal--success .wkn-result-icon-wrap { background: var(--wkn-success-bg); color: var(--wkn-success); }
.wkn-result-modal--error .wkn-result-icon-wrap { background: var(--wkn-error-bg); color: var(--wkn-error); }
.wkn-result-modal--warning .wkn-result-icon-wrap { background: var(--wkn-warning-bg); color: var(--wkn-warning); }
.wkn-result-modal--info .wkn-result-icon-wrap { background: var(--wkn-info-bg); color: var(--wkn-info); }
.wkn-result-icon-wrap .wkn-check-path, .wkn-result-icon-wrap .wkn-x-path {
  stroke-dasharray: 48; stroke-dashoffset: 48; animation: wknDrawCheck .45s .15s ease forwards;
}
.wkn-result-title { font-size: 1.05rem; font-weight: 700; margin-bottom: 6px; }
.wkn-result-message { font-size: .875rem; color: var(--wkn-text-muted); line-height: 1.5; margin-bottom: 20px; }
.wkn-result-actions { display: flex; gap: 10px; justify-content: center; }
.wkn-result-actions button {
  flex: 1 1 auto; padding: 10px 16px; border-radius: var(--wkn-radius-sm);
  font-size: .875rem; font-weight: 600; cursor: pointer; border: 1px solid transparent;
}
.wkn-result-actions .wkn-btn-primary { background: var(--wkn-primary, #6C5CE7); color: #fff; }
.wkn-result-actions .wkn-btn-primary:hover { filter: brightness(1.08); }
.wkn-result-actions .wkn-btn-secondary { background: transparent; border-color: var(--wkn-border); color: var(--wkn-text); }
.wkn-result-actions .wkn-btn-secondary:hover { background: rgba(100,116,139,0.1); }

/* Mobile (Session 18): per instruction, EVERY dialogue except the
   password modal (a separate system entirely - #wkn-wallet-pw-modal in
   wallet-widget.html, deliberately left compact) goes full-screen on
   mobile - this reverses the earlier "alert/confirm/prompt stay
   compact" exception now that the password modal is understood to be
   the ONLY intended exception. `.modal-backdrop-layout`'s own mobile
   rule already does this; `.wkn-result-modal` (showToast's bigger
   sibling showResultModal(), and showConfirmModal() - this app's
   alert()/confirm() replacements) is a completely separate CSS system
   that was never given the same treatment. */
@media (max-width: 640px) {
  .wkn-result-backdrop { padding: 0; }
  .wkn-result-modal {
    max-width: 100%; width: 100%; height: 100%; max-height: 100%;
    border-radius: 0; display: flex; flex-direction: column; justify-content: center;
  }
}

/* Theme toggle - sun/moon crossfade+rotate. Default (light, no .dark)
   shows the moon (click to go dark); .dark shows the sun (click to go
   light) - previously BOTH icons rendered stacked/overlapping with no
   show/hide rule at all, which is why the button looked empty/broken. */
/* BUG FIXED: position:absolute with no top/left/right/bottom relies on
   the browser's "static position" fallback, which is poorly-defined
   (and inconsistent across browsers) for a child of a `display:
   inline-flex` container - almost certainly why this icon was reported
   as invisible/not showing. Explicit top/left/transform-based centering
   removes that ambiguity entirely: every icon is unconditionally
   centered in the button regardless of flex-layout quirks. */
#themeToggle { position: relative; overflow: visible; width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
#themeToggle svg { width: 18px; height: 18px; transition: transform .35s cubic-bezier(.34,1.56,.64,1), opacity .25s ease; position: absolute; top: 50%; left: 50%; }
#themeToggle .wkn-icon-sun { opacity: 0; transform: translate(-50%,-50%) rotate(-90deg) scale(.4); color: #f59e0b; }
#themeToggle .wkn-icon-moon { opacity: 1; transform: translate(-50%,-50%) rotate(0) scale(1); color: var(--wkn-text-muted, #64748b); }
html.dark #themeToggle .wkn-icon-sun, html[data-wkn-theme="dark"] #themeToggle .wkn-icon-sun { opacity: 1; transform: translate(-50%,-50%) rotate(0) scale(1); }
html.dark #themeToggle .wkn-icon-moon, html[data-wkn-theme="dark"] #themeToggle .wkn-icon-moon { opacity: 0; transform: translate(-50%,-50%) rotate(90deg) scale(.4); }

/* Invite-to-connect pulse - purely CSS, keyed off the SAME bg-blue-600
   class the JS already applies before a wallet connects (swapped for
   bg-emerald-600 once connected - see connectWalletOnChange()), so no
   JS change was needed to wire this up. Stops automatically the
   moment that class swap happens on connect. */
#connectBtnTop.bg-blue-600 { animation: wknPulseRing 2.2s ease-in-out infinite; }
#connectBtnTop.bg-emerald-600 { animation: none; }

/* Icon-forward polish - every icon throughout the app (nav, buttons,
   cards) gets a consistent, slightly-muted-until-hover treatment
   instead of looking pasted on. */
svg { flex-shrink: 0; }
.token-card svg, [class*="rounded-lg"] svg { transition: transform .15s ease; }
[class*="rounded-lg"]:hover svg { transform: scale(1.06); }

/* =====================================================================
   Session 14 - theme switch made bulletproof regardless of how UNA's
   own Tailwind build is configured (`darkMode: 'class'` vs the default
   `darkMode: 'media'`). This module has no visibility into or control
   over that host-level config. If it is media-based, then EVERY one of
   the 81 pre-existing `dark:`-prefixed utility classes throughout this
   file's markup only ever activates from the OS's own
   prefers-color-scheme, and is COMPLETELY INERT to the manual toggle
   built in Session 11/14 - explaining "some parts change [this
   module's own new CSS-variable-driven rules] and most didn't [every
   plain dark: utility class]" precisely. Since this can't be verified
   without the host's own tailwind.config, both directions are forced
   here with `!important`, independent of whichever strategy is
   actually active:
   - `html.dark .dark\:X` / `html[data-wkn-theme="dark"] .dark\:X` -
     targets the LITERAL escaped class name Tailwind generates for a
     `dark:` variant, directly, regardless of whether Tailwind's own
     compiled rule for it is class- or media-gated - so switching TO
     dark via this module's toggle takes effect even on a
     media-strategy build, and even if the visitor's OS is set to
     light.
   - `html:not(.dark):not([data-wkn-theme="dark"]) .X` - re-asserts the
     LIGHT utility's own value, `!important`, so switching TO light
     via this module's toggle wins even when the visitor's OS prefers
     dark and a media-strategy build would otherwise still be applying
     the `dark:` variant over it by source order.
   Covers the highest-frequency color pairs actually used throughout
   this file (found by counting every `dark:` occurrence) - not
   claimed to be piece with every single one of the 81, but the
   overwhelming majority share these same handful of color values. */
html.dark .dark\:bg-gray-800, html[data-wkn-theme="dark"] .dark\:bg-gray-800 { background-color: #1f2937 !important; color: #e5e7eb !important; }
html.dark .dark\:bg-gray-900, html[data-wkn-theme="dark"] .dark\:bg-gray-900 { background-color: #111827 !important; color: #e5e7eb !important; }
html.dark .dark\:bg-gray-700, html[data-wkn-theme="dark"] .dark\:bg-gray-700 { background-color: #374151 !important; color: #e5e7eb !important; }
html.dark .dark\:bg-indigo-900, html[data-wkn-theme="dark"] .dark\:bg-indigo-900 { background-color: rgba(49,46,129,0.55) !important; }
html.dark .dark\:text-gray-200, html[data-wkn-theme="dark"] .dark\:text-gray-200 { color: #e5e7eb !important; }
html.dark .dark\:text-gray-300, html[data-wkn-theme="dark"] .dark\:text-gray-300 { color: #d1d5db !important; }
html.dark .dark\:text-gray-400, html[data-wkn-theme="dark"] .dark\:text-gray-400 { color: #9ca3af !important; }
html.dark .dark\:text-gray-100, html[data-wkn-theme="dark"] .dark\:text-gray-100 { color: #f3f4f6 !important; }
html.dark .dark\:text-indigo-200, html[data-wkn-theme="dark"] .dark\:text-indigo-200 { color: #c7d2fe !important; }
html.dark .dark\:border-gray-700, html[data-wkn-theme="dark"] .dark\:border-gray-700 { border-color: #374151 !important; }

html:not(.dark):not([data-wkn-theme="dark"]) .bg-white { background-color: #ffffff !important; color: #0f172a !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .bg-gray-50 { background-color: #f9fafb !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .bg-gray-100 { background-color: #f3f4f6 !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .text-gray-900 { color: #111827 !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .text-gray-800 { color: #1f2937 !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .text-gray-700 { color: #374151 !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .text-gray-600 { color: #4b5563 !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .text-gray-500 { color: #6b7280 !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .text-indigo-700 { color: #4338ca !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .border { border-color: #e5e7eb !important; }
html:not(.dark):not([data-wkn-theme="dark"]) .bg-slate-100 { background-color: #f1f5f9 !important; color: #0f172a !important; }
html.dark .bg-slate-100, html[data-wkn-theme="dark"] .bg-slate-100 { background-color: #334155 !important; color: #e2e8f0 !important; }
html:not(.dark):not([data-wkn-theme="dark"]) body { background-color: #f8f9fc !important; }
html.dark body, html[data-wkn-theme="dark"] body { background-color: var(--wkn-surface-2) !important; }

/* Address/hash/long-string wrapping, site-wide - addresses, tx hashes,
   and similar long unbroken tokens previously overflowed their
   container instead of wrapping to the next line. */
body, .wkn-toast, .wkn-result-modal, .modal-backdrop-layout, code, pre,
[class*="font-mono"], [id*="ddress"], [id*="Hash"], [class*="break"] {
  overflow-wrap: anywhere;
  word-break: break-word;
}
.modal-backdrop-layout * { overflow-wrap: anywhere; }

/* Small mobile edge padding so content never touches the viewport
   walls - a few of this app's full-bleed containers had zero side
   padding on narrow screens. */
@media (max-width: 640px) {
  #web3WalletInstanceMiniModal .modal-panel { padding-left: 2px; padding-right: 2px; box-sizing: border-box; }
  /* Broadened (Session 15) - the top-level modal-panel padding alone
     didn't reach every inner full-bleed section (each page's own
     content div, the sidebar, card grids), which is why edge-to-edge
     content was still reported after the first pass. Small, consistent
     8px gutter applied one level down too, !important since several of
     these inner containers carry their own explicit Tailwind padding/
     margin utility classes that would otherwise win by source order. */
  #web3WalletInstanceMiniModal .modal-panel > * { padding-left: 2px !important; padding-right: 2px !important; box-sizing: border-box; }
  #web3WalletInstanceMiniModal [id^="page-"] { padding-left: 2px; padding-right: 2px; box-sizing: border-box; }
}

/* =====================================================================
   Sitewide custom-themed <select> (Session 15) - see the
   wknEnhanceSelect() JS module in template/index.html for how this is
   wired non-invasively over every existing native <select>. The
   original select is kept functional but visually hidden; everything
   below styles the custom button+listbox drawn in its place.
   ===================================================================== */
.wkn-select-wrap { position: relative; display: inline-block; }
.wkn-select-wrap select {
  /* BUG FIXED (Session 24): reported as an "underlying text" flicker/
     double-label ONLY on hover - the previous approach kept this
     element full-size (position:absolute; inset:0) and relied entirely
     on opacity:0 to hide it, occupying the EXACT same screen footprint
     as the visible custom button on top of it. Native <select> chrome
     is drawn by the OS on some platform/browser combinations, and that
     native rendering is not always fully governed by CSS opacity in
     every engine - a plausible reason its own text could still surface
     briefly right as :hover starts repainting the button above it.
     tabindex="-1" (Session 23) already made it unreachable by keyboard;
     it no longer needs to match the button's footprint either, since
     pointer-events:none already means it never receives a click
     regardless of its own size/position - shrunk to the standard
     "visually hidden but still functional" 1x1px pattern instead, so
     it no longer shares any screen space with the visible button at
     all. Still fully functional for .value reads/writes, still
     dispatches its own 'change' event, still reachable by a screen
     reader that queries the DOM directly. */
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  opacity: 0; pointer-events: none;
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
}
.wkn-select-btn {
  width: 100%; display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--wkn-surface, #fff) !important; color: var(--wkn-text, #0f172a) !important;
  border: 1px solid var(--wkn-border, rgba(15,23,42,0.08)) !important;
  border-radius: var(--wkn-radius-sm, 8px);
  cursor: pointer; text-align: left; font: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
/* BUG FIXED (Session 22): the generic Session 21 hover rule
   (`button[class*="border"]:hover`) also matches this button whenever
   the original <select> it was built from happened to carry a plain
   `border` Tailwind class of its own (copied onto this button - see
   wknEnhanceSelect()) - two separate hover rules (this one changing
   only border-color, that one changing background-color AND color)
   then applied together with different transition timings, reading as
   a color flicker on hover. Made self-contained and `!important` here
   so it always wins outright instead of blending with that generic
   rule. */
.wkn-select-btn:hover {
  border-color: var(--wkn-primary, #6C5CE7) !important;
  background-color: var(--wkn-surface, #fff) !important;
  color: var(--wkn-text, #0f172a) !important;
  transition: border-color .15s ease;
}
.wkn-select-btn.wkn-open { border-color: var(--wkn-primary, #6C5CE7); box-shadow: 0 0 0 3px rgba(108,92,231,0.18); }
.wkn-select-label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wkn-select-caret { width: 14px; height: 14px; flex: 0 0 auto; opacity: .6; transition: transform .18s ease; }
.wkn-select-btn.wkn-open .wkn-select-caret { transform: rotate(180deg); }
.wkn-select-list {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 2147483300;
  margin: 0; padding: 6px; list-style: none;
  background: var(--wkn-surface, #fff); color: var(--wkn-text, #0f172a);
  border: 1px solid var(--wkn-border, rgba(15,23,42,0.08));
  border-radius: var(--wkn-radius-md, 14px);
  box-shadow: var(--wkn-shadow-lg);
  max-height: 260px; overflow-y: auto;
  animation: wknScaleIn .16s cubic-bezier(.34,1.56,.64,1);
}
.wkn-select-option {
  padding: 9px 12px; border-radius: var(--wkn-radius-sm, 8px); cursor: pointer; font-size: .9rem;
  transition: background-color .12s ease;
}
.wkn-select-option:hover { background: rgba(108,92,231,0.1); }
.wkn-select-option.wkn-selected { background: rgba(108,92,231,0.16); color: var(--wkn-primary, #6C5CE7); font-weight: 600; }
.wkn-select-option.wkn-highlighted { background: rgba(108,92,231,0.14); outline: 2px solid var(--wkn-primary, #6C5CE7); outline-offset: -2px; }
.wkn-select-btn:focus-visible { outline: 2px solid var(--wkn-primary, #6C5CE7); outline-offset: 2px; }

/* =====================================================================
   Session 18 - primary action button + card polish, sitewide. Broad,
   attribute-substring-selector approach (same technique used
   throughout this design system) so every existing "primary action"
   button (Send, Save, Add Token, Add Address, Connect, etc. - too many
   individual call sites to hand-edit each one's markup) gets a
   consistently more modern radius/shadow/press-animation without
   needing markup changes at each site.
   ===================================================================== */
button[class*="bg-blue-6"], button[class*="bg-indigo-6"], button[class*="bg-emerald-6"],
button[class*="bg-green-6"], button[class*="bg-red-6"], button[class*="bg-purple-6"] {
  border-radius: var(--wkn-radius-md, 14px) !important;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  transition: transform .15s cubic-bezier(.34,1.56,.64,1), box-shadow .15s ease, filter .15s ease;
  font-weight: 600;
  letter-spacing: .01em;
}
button[class*="bg-blue-6"]:hover, button[class*="bg-indigo-6"]:hover, button[class*="bg-emerald-6"]:hover,
button[class*="bg-green-6"]:hover, button[class*="bg-red-6"]:hover, button[class*="bg-purple-6"]:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(0,0,0,0.18);
  filter: brightness(1.05);
}
button[class*="bg-blue-6"]:active, button[class*="bg-indigo-6"]:active, button[class*="bg-emerald-6"]:active,
button[class*="bg-green-6"]:active, button[class*="bg-red-6"]:active, button[class*="bg-purple-6"]:active {
  transform: translateY(0) scale(.97);
}
/* =====================================================================
   Session 27 - colored action-button hover contrast, root cause and
   fix. Reported for #doTransferMain (bg-emerald-600) specifically, but
   the same root cause applies to EVERY colored action button sitewide
   (Send/Save/Add Token/Add Address/Connect/Reveal/etc).
   ROOT CAUSE: a very early, unscoped rule near the top of this file -
   `button:hover { background-color: rgba(67,56,202,0.05); ... }` - has
   HIGHER CSS SPECIFICITY than a single Tailwind utility class
   (`button:hover` = 1 pseudo-class + 1 element type vs `.bg-emerald-600`
   = 1 class alone; the tie on class-count is broken by element-count,
   which that rule has and the bare utility class doesn't), so it was
   silently overriding every colored button's background to a
   near-transparent tint ON HOVER specifically, while the icon/text
   stayed whatever color they already were (always white here, via
   `text-white`) - against a light page background that IS "white
   background, white icon/text", exactly as reported. The Session 18
   rule just above only ever added transform/shadow/filter on hover,
   never a background-color of its own, so it never corrected this.
   FIX: hover now explicitly INVERTS per instruction - light mode gets
   a dark background with light icon/text, dark mode gets a light
   background with dark icon/text - with `!important` on both
   properties, which is required to beat that older rule (no
   `!important` of its own, but still higher specificity than the
   plain Tailwind class it was clobbering). Selector is
   `[class*="bg-"][class*="text-white"]` rather than the fixed color
   list above, so it automatically covers every CURRENT colored action
   button (including #revealAll's bg-yellow-500, which the fixed
   blue/indigo/emerald/green/red/purple-6 list above never matched at
   all) and any future one, as long as it follows this module's own
   established "colored background + white text" convention for a
   primary action button - no per-color maintenance needed. */
button[class*="bg-"][class*="text-white"]:hover {
  background-color: #0f172a !important; /* dark navy */
  color: #f8fafc !important; /* near-white */
}
html.dark button[class*="bg-"][class*="text-white"]:hover,
html[data-wkn-theme="dark"] button[class*="bg-"][class*="text-white"]:hover {
  background-color: #ede9fe !important; /* light lavender */
  color: #0f172a !important; /* dark navy */
}
button[class*="bg-"][class*="text-white"]:hover svg,
button[class*="bg-"][class*="text-white"]:hover span,
button[class*="bg-"][class*="text-white"]:hover i {
  color: currentColor !important;
  stroke: currentColor;
}
/* Secondary/outlined buttons get the same rounder, livelier treatment,
   a touch more subtly since they're not the primary call to action. */
button[class*="border"]:not([class*="bg-"]) {
  border-radius: var(--wkn-radius-sm, 8px) !important;
  transition: transform .12s ease, background-color .15s ease, border-color .15s ease;
}
button[class*="border"]:not([class*="bg-"]):hover { transform: translateY(-1px); background-color: rgba(108,92,231,0.06); }

/* Cards - bigger radius, a real lift-and-glow on hover instead of the
   flat, static rectangles this reused across token rows/summary panels/
   settings sections. */
.token-card, [class*="rounded-lg"][class*="shadow"], [class*="rounded-lg"][class*="border"] {
  border-radius: var(--wkn-radius-md, 14px) !important;
}
.token-card:hover, [class*="rounded-lg"][class*="shadow"]:hover {
  transform: translateY(-2px);
  box-shadow: var(--wkn-shadow-lg);
}

/* =====================================================================
   Active/inactive token toggle switch (Session 19) - a real iOS-style
   switch, not a checkbox, for the per-user token visibility toggle
   (see renderTokensList()/setTokenActive() in template/index.html).
   ===================================================================== */
.wkn-switch { position: relative; display: inline-block; width: 40px; height: 22px; flex: 0 0 auto; cursor: pointer; }
.wkn-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.wkn-switch-track {
  position: absolute; inset: 0; background: rgba(100,116,139,0.35); border-radius: 999px;
  transition: background-color .18s ease;
}
.wkn-switch-track::before {
  content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.3);
  transition: transform .2s cubic-bezier(.34,1.56,.64,1);
}
.wkn-switch input:checked + .wkn-switch-track { background: var(--wkn-success, #16a34a); }
.wkn-switch input:checked + .wkn-switch-track::before { transform: translateX(18px); }
.wkn-switch input:focus-visible + .wkn-switch-track { outline: 2px solid var(--wkn-primary, #6C5CE7); outline-offset: 2px; }

/* Sidebar as a full-screen mobile modal (Session 20) - per instruction,
   when opened via the hamburger button on a small viewport, the
   sidebar should cover the full page height/width rather than simply
   un-hiding inline within the page's grid layout (its previous,
   desktop-only-appropriate behavior). */
@media (max-width: 640px) {
  #sidebarWeb3Wallet:not(.hidden) {
    position: fixed; inset: 0; z-index: 2147483050;
    width: 100%; height: 100%; max-height: 100%;
    border-radius: 0; overflow-y: auto;
    animation: wknFadeIn .18s ease;
  }
}
.wkn-sidebar-mobile-close { display: none; }
@media (max-width: 640px) {
  .wkn-sidebar-mobile-close {
    display: flex; align-items: center; justify-content: center;
    position: absolute; top: 12px; right: 12px; width: 34px; height: 34px;
    border-radius: 50%; background: rgba(100,116,139,0.12); color: var(--wkn-text, #0f172a);
    border: none; cursor: pointer;
  }
}

/* =====================================================================
   Sidebar profile header (Session 27) - BUG FIXED: on mobile the Setup
   button sat on the same row as the username, right-aligned - exactly
   the same top-right corner .wkn-sidebar-mobile-close (above) occupies
   as an absolutely-positioned overlay, so the two visually clashed.
   A single wrapping flex row with `order` lets the SAME markup reflow
   differently per breakpoint without duplicating the button: desktop
   keeps Setup beside the username (no close button there to clash
   with); mobile drops Setup to a second line shared with the address,
   pinned to the opposite edge from the (now full-width, own-line)
   username - clear of the close button's corner entirely.
   ===================================================================== */
.wkn-sidebar-profile-row { display: flex; align-items: center; flex-wrap: wrap; column-gap: 8px; row-gap: 4px; }
.wkn-sidebar-profile-name-block { order: 1; }
.wkn-sidebar-addr-block { order: 3; width: 100%; }
.wkn-sidebar-setup-wrap { order: 2; margin-left: auto; }
@media (max-width: 640px) {
  .wkn-sidebar-profile-name-block { width: 100%; }
  .wkn-sidebar-addr-block { order: 2; width: auto; flex: 1 1 auto; margin-left: 0; }
  .wkn-sidebar-setup-wrap { order: 3; margin-left: auto; }
}

/* =====================================================================
   Session 21 (strengthened Session 24) - hover background/icon/text
   theme-awareness on outlined/plain action buttons (the colored primary
   buttons from Session 18 already have their own theme-correct hover
   treatment - this covers the plainer "border" buttons: Copy/View/Edit/
   Delete, nav items, etc.).
   BUG FIXED: this previously used var(--wkn-text, ...) for the hover
   text color - reported as background and text reading as "the same
   light color" in light mode specifically. Rather than depend on a
   custom-property resolving correctly in every context this rule can
   apply in (some of these buttons render inside contexts - dynamically
   injected dialogs, etc. - where an ancestor chain to :root cannot be
   assumed), this now uses hardcoded, unambiguous high-contrast colors
   for exactly this rule: a light lavender background with dark navy
   text in light mode, a deep purple background with near-white text in
   dark mode - removing any custom-property indirection as a possible
   point of failure. Selector strengthened (`html body ...`) and
   `svg, span` children pinned to `currentColor` explicitly, so a
   colored icon/text utility class (text-red-600, etc.) can never
   persist through hover and collide with the new background. */
html body button[class*="border"]:hover, html body .nav-btn:hover {
  background-color: #ede9fe !important; /* light lavender */
  color: #0f172a !important; /* dark navy - guaranteed high contrast against the light background above */
}
html.dark body button[class*="border"]:hover, html.dark body .nav-btn:hover,
html[data-wkn-theme="dark"] body button[class*="border"]:hover, html[data-wkn-theme="dark"] body .nav-btn:hover {
  background-color: #3b2f66 !important; /* deep purple */
  color: #f3f0ff !important; /* near-white - guaranteed high contrast against the deep purple above */
}
html body button[class*="border"]:hover svg, html body button[class*="border"]:hover span,
html body .nav-btn:hover svg, html body .nav-btn:hover span {
  color: currentColor !important;
  fill: none;
  stroke: currentColor;
}

/* Remove the earlier separate "double shadow" around opened modals on
   desktop (Session 21) - `.modal-backdrop-layout` already renders a
   solid rgba(0,0,0,0.5) full-screen backdrop; the inner sizing
   wrapper (`.modal-backdrop-layout > div`, added Session 12) ALSO had
   its own `box-shadow: var(--wkn-shadow-lg)`, which - stacked directly
   on top of the backdrop's own solid color - could read as a second,
   offset shadow "halo" around the visible card, per report. Desktop
   only: mobile's full-screen modals have no visible edge for a shadow
   to appear around in the first place, so this is scoped to leave
   that case untouched. */
@media (min-width: 641px) {
  .modal-backdrop-layout > div { box-shadow: none !important; }
  .modal-backdrop-layout > div > div:first-child { box-shadow: var(--wkn-shadow-lg); }
}

/* Wide desktop variant for the two welcome/setup modals (Session 22) -
   lifts the generic `.modal-backdrop` 600px cap (which was silently
   clipping their own intended max-w-2xl/3xl) so they can actually reach
   the "very wide" size asked for on desktop. */
@media (min-width: 641px) {
  .modal-backdrop-layout > .modal-backdrop.wkn-modal-wide { max-width: 960px; }
}

/* BUG FIXED (Session 28): the comment above claimed mobile was already
   covered by the shared `.modal-backdrop-layout > div` mobile rule
   (near the top of this file) - wrong. Both welcome/setup modals have
   an EXTRA level of nesting these other modals don't:
   `.modal-backdrop-layout > .modal-backdrop.wkn-modal-wide > [the
   actual visible white panel, carrying its OWN `max-w-2xl`/`max-w-3xl`
   + `mx-4` Tailwind classes]`. The shared rule's `>` child selector
   only ever reaches the FIRST level (`.wkn-modal-wide` itself, which it
   does correctly force to width/height:100%) - never that inner panel,
   so the panel's own `max-w-2xl`/`max-w-3xl` kept capping it well
   below the viewport width on mobile regardless. Reaches the actual
   panel explicitly here instead. */
@media (max-width: 640px) {
  .modal-backdrop-layout > .modal-backdrop.wkn-modal-wide > div:first-child {
    max-width: 100% !important;
    width: 100% !important;
    height: 100%;
    max-height: 100%;
    margin: 0 !important;
    border-radius: 0;
  }
}

/* Belt-and-suspenders for the double-backdrop bug (Session 22): if two
   .modal-backdrop-layout elements ever nest, only the OUTER one paints
   the backdrop; the inner one becomes a plain transparent centering box. */
.modal-backdrop-layout .modal-backdrop-layout { background: transparent !important; backdrop-filter: none !important; padding: 0; }
.modal-backdrop-layout { backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }

/* Modern, high-contrast avatar (Session 22) - gradient from the admin's
   own brand colors with white text, readable in both themes (the old
   indigo-50 tint + indigo-700 text had weak contrast, worst in dark). */
.wkn-avatar {
  background: linear-gradient(135deg, var(--wkn-primary, #6C5CE7), var(--wkn-accent, #00C2A8));
  color: #fff !important;
  text-shadow: 0 1px 2px rgba(0,0,0,0.35);
  box-shadow: 0 2px 8px rgba(0,0,0,0.18);
  letter-spacing: .02em;
}

/* Watch-wallet card action row (Copy/View/Edit/Delete) - mobile ONLY
   (per instruction): slightly bigger tap targets, evenly filling the
   row's full width with space between them, instead of their normal
   compact, left-packed desktop sizing (`w-auto` there, beside the
   identity block - unaffected by this rule). */
@media (max-width: 640px) {
  .wkn-readonly-actions { justify-content: space-between; }
  .wkn-readonly-actions button {
    flex: 1 1 0; min-width: 0;
    padding: 8px 6px; font-size: 0.8rem; text-align: center;
  }
}

@media (max-width: 720px) {
  .wkn-select-wrap:has(#defaultNetwork),
  .wkn-select-wrap:has(#connectModeTop) {
    display: none !important;
  }
}

/* BUG FIXED (Session 26): mobile is always full-screen already (see
   wallet-widget.html's own @media (max-width: 640px) rule making the
   panel 100vw), so the fullscreen-toggle button beside the home button
   has nothing meaningful to do there - but a VIEWPORT-WIDTH rule also
   hid it on any narrow DESKTOP browser window, which per instruction
   must keep the button (so a desktop visitor can always toggle back
   to the side-panel view). Real mobile-device detection now lives in
   JS instead (navigator.userAgent, not window width) - see
   wknIsMobileDeviceUA() in template/index.html's own script and its
   duplicate in wallet-widget.html - and sets this inline via
   style.display, not a media query. This rule is intentionally gone,
   not just widened: there's no viewport width that stays accurate for
   "is this a phone" as a window gets resized or a device gets rotated. */


/* Testnet badge - follows the wallet's active theme (html.dark / data-wkn-theme),
   not Tailwind's fixed yellow-100/yellow-800 which was unreadable in dark mode. */
.wkn-testnet-badge {
  background: #FEF3C7;
  color: #92400E;
  border: 1px solid #FCD34D;
  font-weight: 600;
  letter-spacing: .02em;
}
html.dark .wkn-testnet-badge,
html[data-wkn-theme="dark"] .wkn-testnet-badge {
  background: rgba(250, 204, 21, .16);
  color: #FDE68A;
  border-color: rgba(250, 204, 21, .45);
}

/* Toast always on top of any modal / mobile side menu */
#wknToastViewport { z-index: 2147483647 !important; }

/* Copyable wallet address (home + sidebar): link colour + copy icon */
.wkn-copyable { cursor: pointer; display: inline-flex; align-items: center; gap: 6px; color: #2563EB !important; }
.wkn-copyable:hover .wkn-copyable-text { text-decoration: underline; }
.wkn-copyable .wkn-copy-icon { flex: 0 0 auto; }
html.dark .wkn-copyable, html[data-wkn-theme="dark"] .wkn-copyable { color: #60A5FA !important; }

/* Long unbroken strings (addresses, mnemonics, private keys) wrap inside the modal instead of widening the page */
.wkn-wrap-text, .modal-backdrop-layout pre {
  white-space: pre-wrap; word-break: break-all; overflow-wrap: anywhere; max-width: 100%; min-width: 0;
}
.modal-backdrop-layout > div > div { max-width: 100%; box-sizing: border-box; }

/* Desktop modal sizing (hotfix 8): narrower welcome/setup/dialog modals,
   no horizontal overflow (inner panels carried `w-full` + `mx-4`, which
   pushed them past their wrapper), and breathing room on the right of
   action-button rows. */
@media (min-width: 641px) {
  .modal-backdrop-layout > .modal-backdrop.wkn-modal-wide { max-width: 680px; }
  .modal-backdrop-layout > .modal-backdrop.wkn-modal-wide > div:first-child {
    max-width: 100% !important; width: 100%; margin: 0 !important; box-sizing: border-box;
  }
  .modal-backdrop-layout > div { overflow-x: hidden; }
  #customDialogModal > div { width: fit-content; min-width: 320px; max-width: min(440px, calc(100vw - 32px)); }
  #customDialogModal > div > div { margin-left: 0 !important; margin-right: 0 !important; width: 100%; }
  .modal-backdrop-layout .flex.justify-end, .modal-backdrop-layout .flex.justify-end.gap-2 { padding-right: 4px; }
}
.modal-backdrop-layout > div > div { box-sizing: border-box; }

#portfolioTotal, #portfolioTotalReadonly { cursor: pointer; -webkit-user-select: none; user-select: none; touch-action: manipulation; }

/* Rounder inputs */


/* Final UI polish (hotfix 8): rounder fields, softer cards, clearer focus, tactile buttons */
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]), select, textarea, .wkn-select-btn {
  border-radius: 16px !important;
  padding-left: 14px; padding-right: 14px;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
input:not([type=checkbox]):not([type=radio]):not([type=range]):focus, select:focus, textarea:focus {
  outline: none; border-color: var(--wkn-primary, #6C5CE7);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--wkn-primary, #6C5CE7) 22%, transparent);
}
#main .rounded-lg, #sidebarWeb3Wallet.rounded-lg { border-radius: 20px; }
#main .rounded-md, #main .p-3.border.rounded { border-radius: 16px; }
#main .rounded.border, #main button.rounded, #main .px-3.rounded, #main button.rounded-md { border-radius: 14px; }
#main .shadow, #sidebarWeb3Wallet.shadow { box-shadow: var(--wkn-shadow-md); }
#main .bg-white.rounded-lg, #main .dark\:bg-gray-800.rounded-lg { border: 1px solid rgba(120,120,120,.12); }
#main button, #sidebarWeb3Wallet button, .modal-backdrop-layout button { transition: transform .12s ease, box-shadow .15s ease, background-color .15s ease, opacity .15s ease; }
#main button:active, .modal-backdrop-layout button:active { transform: scale(.98); }
#main button:focus-visible, #sidebarWeb3Wallet button:focus-visible, .modal-backdrop-layout button:focus-visible, a:focus-visible {
  outline: 2px solid var(--wkn-primary, #6C5CE7); outline-offset: 2px;
}
.modal-backdrop-layout .rounded-lg { border-radius: 22px; }
.modal-backdrop-layout { backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.wkn-toast, .wkn-result-modal { border-radius: 18px; }
@media (prefers-reduced-motion: reduce) { * { animation-duration: .01ms !important; transition-duration: .01ms !important; } }
/* theme-aware thin scrollbar everywhere in the wallet */
.modal-backdrop-layout > div, #main, .wkn-result-modal { scrollbar-width: thin; scrollbar-color: rgba(120,120,120,.45) transparent; }
.modal-backdrop-layout > div::-webkit-scrollbar { width: 10px; }
.modal-backdrop-layout > div::-webkit-scrollbar-thumb { background: rgba(120,120,120,.45); border-radius: 10px; border: 2px solid transparent; background-clip: padding-box; }

/* Transaction cards: on mobile the value/symbol + Copy/View column drops under the icon/text column */
.wkn-tx-row .flex.items-center.gap-2 { flex-wrap: wrap; }
.wkn-tx-row > div:first-child { min-width: 0; }
@media (max-width: 640px) {
  .wkn-tx-row { flex-wrap: wrap; }
  .wkn-tx-row > .wkn-tx-side { width: 100%; align-items: flex-start; text-align: left; padding-left: 52px; }
}

/* Home: portfolio / quick-actions share a height, expanding only grows the portfolio card */
@media (min-width: 768px) { #page-home > .grid { align-items: start; } }

/* Hidden balances: only the balance text is masked (JS swaps digits for asterisks) */

/* Dark mode hover: lighter neutral slate instead of the deep purple */
html.dark body button[class*="border"]:hover, html.dark body .nav-btn:hover,
html[data-wkn-theme="dark"] body button[class*="border"]:hover, html[data-wkn-theme="dark"] body .nav-btn:hover {
  background-color: #556278 !important;
  border-color: #94a3b8 !important;
  color: #ffffff !important;
}
html.dark button:hover, html[data-wkn-theme="dark"] button:hover { border-color: #94a3b8; }
html.dark .nav-btn:hover, html[data-wkn-theme="dark"] .nav-btn:hover { background-color: #556278 !important; }

/* Desktop: sidebar and the settings card are sticky to the viewport and scroll on their own when taller than it */
@media (min-width: 1024px) {
  #sidebarWeb3Wallet { max-height: calc(100vh - 32px); overflow-y: auto; overscroll-behavior: contain; }
  #page-settings > div { max-height: calc(100vh - 32px); overflow-y: auto; overscroll-behavior: contain; }
  #sidebarWeb3Wallet, #page-settings > div { scrollbar-width: thin; scrollbar-color: rgba(120,120,120,.45) transparent; }
  #sidebarWeb3Wallet::-webkit-scrollbar, #page-settings > div::-webkit-scrollbar { width: 8px; }
  #sidebarWeb3Wallet::-webkit-scrollbar-thumb, #page-settings > div::-webkit-scrollbar-thumb { background: rgba(120,120,120,.45); border-radius: 10px; }
}

/* Light mode: crisp, clearly visible focus ring on fields (dark keeps the softer glow above) */
html:not(.dark):not([data-wkn-theme="dark"]) input:not([type=checkbox]):not([type=radio]):not([type=range]):focus,
html:not(.dark):not([data-wkn-theme="dark"]) select:focus,
html:not(.dark):not([data-wkn-theme="dark"]) textarea:focus {
  border-color: var(--wkn-primary, #6C5CE7) !important;
  box-shadow: 0 0 0 1px var(--wkn-primary, #6C5CE7), 0 0 0 4px color-mix(in srgb, var(--wkn-primary, #6C5CE7) 38%, transparent) !important;
}

/* Header brand: full wallet name in wide / full-screen view, short name in the minimized panel and on mobile */
.wkn-brand-short { display: none; }
@media (max-width: 640px) { .wkn-brand-full { display: none; } .wkn-brand-short { display: inline; } }

.wkn-btn-locked{opacity:.5;cursor:not-allowed;filter:grayscale(.3)}

/* ==== Desktop frame: the wallet never scrolls as a whole; only individual blocks do ==== */
@media (min-width: 1024px) {
  #web3WalletInstanceMiniModal { height: 100vh; height: 100dvh; }
  #web3WalletInstanceMiniModal .modal-panel {
    overflow: hidden; padding-bottom: 0; height: 100%; max-height: 100%;
    display: flex; flex-direction: column;
  }
  #web3WalletInstanceMiniModal .modal-panel > .max-w-7xl {
    flex: 1 1 auto; min-height: 0; width: 100%; display: flex; flex-direction: column; padding-bottom: 20px;
  }
  #web3WalletInstanceMiniModal .max-w-7xl > .flex.justify-between { flex: none; }
  #web3WalletInstanceMiniModal .max-w-7xl > .grid {
    flex: 1 1 0; min-height: 0; grid-template-rows: minmax(0, 1fr); align-items: stretch;
  }
  #sidebarWeb3Wallet { height: auto; max-height: 100%; min-height: 0; overflow-y: auto; align-self: start !important; position: static !important; }
  #main {
    height: 100%; min-height: 0; overflow: hidden; display: flex; flex-direction: column;
    align-self: stretch !important; position: static !important;
  }
  /* every page: fills the frame and scrolls itself only if its content is taller than the frame */
  #main > [id^="page-"]:not(.hidden) {
    flex: 1 1 auto; padding-bottom: 12px; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
    scrollbar-width: thin; scrollbar-color: rgba(120,120,120,.45) transparent;
  }
  #main > [id^="page-"]::-webkit-scrollbar, #sidebarWeb3Wallet::-webkit-scrollbar { width: 8px; }
  #main > [id^="page-"]::-webkit-scrollbar-thumb { background: rgba(120,120,120,.45); border-radius: 10px; }

  /* pages whose last block is a list: the block takes the remaining height, the LIST scrolls inside it */
  #page-home:not(.hidden), #page-transactions:not(.hidden), #page-tokens:not(.hidden), #page-settings:not(.hidden) {
    display: flex; flex-direction: column;
  }
  #page-home:not(.hidden) { gap: 1.5rem; }
  #page-home > * { margin-top: 0 !important; flex: none; }
  #page-home > div:last-child { flex: 0 1 auto; min-height: 0; max-height: 100%; margin-bottom: 0 !important; display: flex; flex-direction: column; }
  #page-home > div:last-child > #homeTokenList { flex: 1 1 auto; min-height: 0; max-height: none !important; overflow-y: auto; }

  #page-transactions > div, #page-tokens > div { flex: 0 1 auto; min-height: 0; max-height: 100%; margin-bottom: 0; display: flex; flex-direction: column; }
  #page-transactions > div > .mt-3 { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  #txLocalList, #txOnchainList { flex: 1 1 auto; min-height: 0; max-height: none !important; overflow-y: auto; }
  #page-tokens > div > .grid { flex: 1 1 auto; min-height: 0; grid-template-rows: minmax(0, auto); }
  #page-tokens > div > .grid > .md\:col-span-2 { display: flex; flex-direction: column; min-height: 0; }
  #page-tokens #manageTokensTable { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

  #page-settings > div { flex: 0 1 auto; min-height: 0; max-height: 100%; margin-bottom: 0; overflow-y: auto; overscroll-behavior: contain; }
}

/* PIN fields: plain text inputs masked by CSS so browsers/password managers never offer to save or fill them */
input.wkn-pin, #wkn-wallet-pw-input { -webkit-text-security: disc; text-security: disc; }

/* ==== In-wallet notifications (bell) ==== */
#wknBellBtn { display:inline-flex; align-items:center; justify-content:center; }
.wkn-ntf-layer { z-index: 1000000; }
/* theme tokens - follow the WALLET theme (html[data-wkn-theme] / html.dark), never the OS setting */
.wkn-ntf-layer, .wkn-ntf-panel {
  --ntf-bg:#ffffff; --ntf-text:#0f172a; --ntf-muted:#64748b; --ntf-card:#f8fafc; --ntf-card-bd:rgba(100,116,139,.18);
  --ntf-new:#eef2ff; --ntf-new-bd:rgba(99,102,241,.45); --ntf-ico-bg:rgba(99,102,241,.14); --ntf-ico:#4f46e5;
  --ntf-line:rgba(100,116,139,.15); --ntf-btn:rgba(100,116,139,.14); --ntf-btn-h:rgba(100,116,139,.26);
}
html.dark .wkn-ntf-layer, html.dark .wkn-ntf-panel, html[data-wkn-theme="dark"] .wkn-ntf-layer, html[data-wkn-theme="dark"] .wkn-ntf-panel {
  --ntf-bg:#111827; --ntf-text:#e5e7eb; --ntf-muted:#94a3b8; --ntf-card:#1f2937; --ntf-card-bd:rgba(148,163,184,.2);
  --ntf-new:#262b52; --ntf-new-bd:rgba(129,140,248,.55); --ntf-ico-bg:rgba(129,140,248,.2); --ntf-ico:#a5b4fc;
  --ntf-line:rgba(148,163,184,.18); --ntf-btn:rgba(148,163,184,.16); --ntf-btn-h:rgba(148,163,184,.3);
}
html[data-wkn-theme="light"] .wkn-ntf-layer, html[data-wkn-theme="light"] .wkn-ntf-panel {
  --ntf-bg:#ffffff; --ntf-text:#0f172a; --ntf-muted:#64748b; --ntf-card:#f8fafc; --ntf-card-bd:rgba(100,116,139,.18);
  --ntf-new:#eef2ff; --ntf-new-bd:rgba(99,102,241,.45); --ntf-ico-bg:rgba(99,102,241,.14); --ntf-ico:#4f46e5;
  --ntf-line:rgba(100,116,139,.15); --ntf-btn:rgba(100,116,139,.14); --ntf-btn-h:rgba(100,116,139,.26);
}
.wkn-ntf-panel { background:var(--ntf-bg); color:var(--ntf-text); width:100%; max-width:440px; max-height:82vh; display:flex; flex-direction:column; border-radius:18px; box-shadow:0 24px 60px rgba(15,23,42,.35); overflow:hidden; }
.wkn-ntf-head { display:flex; align-items:center; justify-content:space-between; padding:16px 18px 10px; }
.wkn-ntf-head h3 { margin:0; font-size:18px; font-weight:700; color:var(--ntf-text); }
.wkn-ntf-x { width:32px; height:32px; border-radius:999px; border:0; background:var(--ntf-btn); color:var(--ntf-text); font-size:20px; line-height:1; cursor:pointer; transition:background .15s; }
.wkn-ntf-x:hover { background:var(--ntf-btn-h); }
.wkn-ntf-list { padding:4px 14px 8px; overflow-y:auto; display:flex; flex-direction:column; gap:10px; min-height:80px; }
.wkn-ntf-card { display:flex; align-items:flex-start; gap:12px; padding:12px; border-radius:14px; background:var(--ntf-card); color:var(--ntf-text); border:1px solid var(--ntf-card-bd); position:relative; }
.wkn-ntf-card.is-new { background:var(--ntf-new); border-color:var(--ntf-new-bd); }
.wkn-ntf-card.is-new::after { content:''; position:absolute; top:12px; right:12px; width:8px; height:8px; border-radius:50%; background:#6366f1; }
.wkn-ntf-ico { flex:none; width:36px; height:36px; border-radius:12px; display:flex; align-items:center; justify-content:center; background:var(--ntf-ico-bg); color:var(--ntf-ico); }
.wkn-ntf-body { flex:1; min-width:0; }
.wkn-ntf-text { font-size:14px; line-height:1.35; word-break:break-word; }
.wkn-ntf-card.is-new .wkn-ntf-text { font-weight:600; }
.wkn-ntf-time { font-size:11px; color:var(--ntf-muted); margin-top:3px; }
.wkn-ntf-ago { flex:none; font-size:11px; color:var(--ntf-muted); margin-right:12px; }
.wkn-ntf-empty { display:flex; flex-direction:column; align-items:center; gap:10px; padding:34px 16px; color:var(--ntf-muted); font-size:14px; text-align:center; }
.wkn-ntf-foot { display:flex; justify-content:flex-end; gap:10px; padding:12px 16px 16px; border-top:1px solid var(--ntf-line); }
.wkn-ntf-btn { border:0; border-radius:10px; padding:9px 16px; font-size:14px; font-weight:600; cursor:pointer; transition:filter .15s, background .15s; }
.wkn-ntf-btn.primary { background:#4f46e5; color:#fff; }
.wkn-ntf-btn.primary:hover { filter:brightness(1.1); }
.wkn-ntf-btn.ghost { background:var(--ntf-btn); color:var(--ntf-text); }
.wkn-ntf-btn.ghost:hover:not(:disabled) { background:var(--ntf-btn-h); }
.wkn-ntf-btn:disabled { opacity:.5; cursor:default; }
.modal-backdrop-layout > .wkn-ntf-panel { overflow: hidden; max-width: 440px; }
.wkn-ntf-card { cursor: pointer; transition: background .15s, border-color .15s, transform .1s; }
.wkn-ntf-card:hover { transform: translateY(-1px); }
.wkn-ntf-card:focus-visible { outline: 2px solid #6366f1; outline-offset: 2px; }

/* PIN field: show/hide eye */
.wkn-pin-wrap { position: relative; display: block; width: 100%; }
.wkn-pin-wrap > input { width: 100%; padding-right: 42px !important; box-sizing: border-box; }
.wkn-pin-eye { position: absolute; right: 8px; top: 50%; margin-top: -15px; transform: none !important; width: 30px; height: 30px; border: 0; border-radius: 8px; background: transparent; color: #64748b; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.wkn-pin-eye:hover { background: rgba(100,116,139,.16); color: inherit; }
input.wkn-pin.wkn-pin-show, #wkn-wallet-pw-input.wkn-pin-show { -webkit-text-security: none; text-security: none; }
/* wrong PIN / attempt warning card */
#pwAttemptInfo { background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca; border-radius: 12px; padding: 10px 12px; font-size: 13px; line-height: 1.4; }
#pwAttemptInfo.hidden { display: none; }
.dark #pwAttemptInfo, html[data-wkn-theme="dark"] #pwAttemptInfo { background: rgba(127,29,29,.35); color: #fecaca; border-color: rgba(248,113,113,.4); }

/* mobile token-controls modal: no hover motion/transition inside the overlay (prevents hover flicker in the minimized widget) */
#tokensControlsMobileModal, #tokensControlsMobileModal * { transition: none !important; }
#tokensControlsMobileModal button:hover i, #tokensControlsMobileModal [class*="rounded-lg"]:hover svg { transform: none !important; }

/* minimized widget / mobile: brand name + connect button stay on ONE line (font fitted by JS, see wknFitHeader) */
.wkn-fit-row h1, .wkn-fit-row h1 span, .wkn-fit-row #connectBtnTop { white-space: nowrap !important; }
.wkn-fit-row h1 { min-width: 0; overflow: hidden; }
.wkn-fit-row #connectBtnTop { flex: 0 1 auto; min-width: 0; }
.wkn-fit-row > div:first-child, .wkn-fit-row > div:first-child > div { min-width: 0; flex-shrink: 1; }

/* the global `button:not(:disabled):active { transform: translateY(1px) scale(.98) }` used to REPLACE the eye's centering transform on
   mousedown, so the button jumped ~15px and the click never completed (root cause of the "needs several clicks" eye). Never move it. */
.wkn-pin-eye, .wkn-pin-eye:hover, .wkn-pin-eye:active, .wkn-pin-eye:focus { transform: none !important; border: 0 !important; box-shadow: none !important; }
.wkn-pin-eye svg, .wkn-pin-eye * { pointer-events: none; }

/* minimized widget / mobile header: tighter button cluster, brand name keeps a gutter before the bell */
.wkn-fit-row > div:last-child { gap: 4px !important; flex: 0 0 auto; }
.wkn-fit-row > div:last-child > button { padding-left: 6px !important; padding-right: 6px !important; }
.wkn-fit-row > div:last-child > #connectBtnTop { padding-left: 9px !important; padding-right: 9px !important; }
.wkn-fit-row > div:first-child { padding-right: 12px; gap: 8px !important; }

input.wkn-pin.wkn-pin-show, #wkn-wallet-pw-input.wkn-pin-show { -webkit-text-security: none !important; text-security: none !important; }
