/* ============================================================
   SaferICO — shared product UI

   Every SaaS screen (workspace, account, login, readiness, the
   Mini App) drew its own buttons, chips, cards and modals. They
   drifted: three greens for "good", four button radii, two
   different meanings for an amber pill. That is not cosmetic —
   a risk colour that means "medium" on one page and "warning"
   on another is a safety bug.

   So: ONE file, namespaced `sfi-`, with its own `--sfi-*`
   tokens so it can be dropped onto a page that already owns
   --cyan / --line without colliding with it.

   Load with:  <link rel="stylesheet" href="sfi-ui.css">
   Pairs with: sfi-ui.js  (window.SFIUI)
   ============================================================ */

:root{
  --sfi-bg:#04060C; --sfi-panel:rgba(10,18,34,.72); --sfi-panel2:rgba(13,22,40,.9);
  --sfi-blue:#3B6FF0; --sfi-cyan:#22D9FF; --sfi-violet:#8B5CF6;
  --sfi-green:#34D399; --sfi-amber:#FBBF24; --sfi-orange:#FB923C; --sfi-red:#F87171;
  --sfi-txt:#EAF2FF; --sfi-mut:#8296B4; --sfi-mut2:#5E7191;
  --sfi-line:rgba(120,190,255,.13); --sfi-line2:rgba(130,200,255,.26);
  --sfi-disp:'Space Grotesk',system-ui,sans-serif;
  --sfi-body:'DM Sans',system-ui,sans-serif;
  --sfi-mono:'JetBrains Mono',ui-monospace,monospace;
  --sfi-r:12px;          /* the one card/button radius */
  --sfi-r-lg:18px;
  --sfi-ease:cubic-bezier(.22,1,.36,1);
}

/* ---------------------------------------------------------------- buttons */
.sfi-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:10px 16px;border-radius:var(--sfi-r);border:1px solid var(--sfi-line2);
  background:transparent;color:var(--sfi-txt);
  font-family:var(--sfi-disp);font-size:13px;font-weight:700;line-height:1;
  cursor:pointer;text-decoration:none;white-space:nowrap;
  transition:transform .14s var(--sfi-ease),background .14s,border-color .14s,opacity .14s;
}
.sfi-btn:hover{border-color:var(--sfi-cyan);text-decoration:none;transform:translateY(-1px)}
.sfi-btn:active{transform:translateY(0)}
.sfi-btn svg{width:15px;height:15px;flex:none}
.sfi-btn.pri{background:linear-gradient(135deg,#2CE2FF,#0FB6F0);color:#02131C;border-color:transparent}
.sfi-btn.pri:hover{box-shadow:0 10px 26px -12px rgba(34,217,255,.8)}
.sfi-btn.ghost{border-color:var(--sfi-line);color:var(--sfi-mut)}
.sfi-btn.ghost:hover{color:var(--sfi-txt)}
.sfi-btn.danger{border-color:rgba(248,113,113,.4);color:#FCA5A5}
.sfi-btn.danger:hover{border-color:var(--sfi-red);background:rgba(248,113,113,.08)}
.sfi-btn.warm{background:linear-gradient(135deg,#FBBF24,#FB923C);color:#231603;border-color:transparent}
.sfi-btn.sm{padding:7px 12px;font-size:12px;border-radius:10px}
.sfi-btn.block{width:100%}
.sfi-btn[disabled],.sfi-btn.busy{opacity:.55;cursor:not-allowed;transform:none}
/* Touch targets. 44px is the floor a thumb can hit reliably; below it,
   confirming a transaction on a phone becomes a coin flip. */
@media(max-width:640px){ .sfi-btn{min-height:44px;padding:12px 18px;font-size:13.5px} .sfi-btn.sm{min-height:38px} }

/* ------------------------------------------------------------------ chips */
.sfi-chip{
  display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border-radius:100px;
  border:1px solid var(--sfi-line);background:rgba(120,190,255,.04);
  font-family:var(--sfi-mono);font-size:10.5px;letter-spacing:.06em;color:var(--sfi-mut);
  white-space:nowrap;
}
.sfi-chip svg{width:12px;height:12px}
.sfi-chip.on{color:#6EE7B7;border-color:rgba(52,211,153,.4);background:rgba(52,211,153,.08)}
.sfi-chip.off{color:#FCA5A5;border-color:rgba(248,113,113,.35);background:rgba(248,113,113,.07)}
.sfi-chip.warn{color:#FCD34D;border-color:rgba(251,191,36,.38);background:rgba(251,191,36,.07)}
.sfi-chip.info{color:#A5C8FF;border-color:rgba(59,111,240,.4);background:rgba(59,111,240,.09)}
.sfi-chip.dot::before{content:'';width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;
  box-shadow:0 0 8px currentColor}

/* ------------------------------------------------------------- risk scale
   Four levels, one meaning, one colour, everywhere. Anything that grades a
   finding, a token, a pool or a wallet uses these and nothing else. */
.sfi-risk{
  display:inline-flex;align-items:center;gap:6px;padding:4px 9px;border-radius:7px;
  font-family:var(--sfi-mono);font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  border:1px solid currentColor;background:rgba(255,255,255,.03);
}
.sfi-risk::before{content:'';width:6px;height:6px;border-radius:2px;background:currentColor;flex:none}
.sfi-risk[data-lvl="critical"]{color:#F87171;background:rgba(248,113,113,.11)}
.sfi-risk[data-lvl="high"]    {color:#FB923C;background:rgba(251,146,60,.11)}
.sfi-risk[data-lvl="medium"]  {color:#FBBF24;background:rgba(251,191,36,.10)}
.sfi-risk[data-lvl="low"]     {color:#34D399;background:rgba(52,211,153,.10)}
.sfi-risk[data-lvl="info"]    {color:#8296B4;background:rgba(130,150,180,.10)}
.sfi-risk[data-lvl="unknown"] {color:#8296B4;background:transparent;border-style:dashed}

/* ------------------------------------------------------------------ cards */
.sfi-card{border:1px solid var(--sfi-line);border-radius:var(--sfi-r-lg);background:var(--sfi-panel);padding:18px}
.sfi-card > h3{font-family:var(--sfi-disp);font-size:11.5px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--sfi-cyan);margin:0 0 13px}
.sfi-row{display:flex;align-items:center;gap:12px;padding:13px 14px;border:1px solid var(--sfi-line);
  border-radius:var(--sfi-r);background:rgba(120,190,255,.025);margin-bottom:8px}
.sfi-row .g{flex:1;min-width:0}
.sfi-row .g b{display:block;font-size:13.5px;font-weight:700;margin-bottom:3px}
.sfi-row .g small{display:block;color:var(--sfi-mut2);font-family:var(--sfi-mono);font-size:11px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sfi-row .r{flex:none;display:flex;align-items:center;gap:6px}

/* key/value rows — the shape used by every review + detail panel */
.sfi-kv{border:1px solid var(--sfi-line);border-radius:var(--sfi-r);overflow:hidden}
.sfi-kv .k{display:flex;justify-content:space-between;align-items:center;gap:14px;
  padding:11px 13px;border-bottom:1px solid var(--sfi-line);font-size:12.5px}
.sfi-kv .k:last-child{border-bottom:none}
.sfi-kv .k > span{color:var(--sfi-mut);flex:none}
.sfi-kv .k > b{font-weight:700;text-align:right;word-break:break-all;font-size:12.5px}
.sfi-kv .k > b.mono{font-family:var(--sfi-mono);font-size:11.5px}
.sfi-kv .k.hot > b{color:#FCD34D}

/* ------------------------------------------------------------------ modal */
.sfi-modal{position:fixed;inset:0;z-index:9000;display:none;align-items:center;justify-content:center;
  padding:18px;background:rgba(2,5,11,.74);backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px)}
.sfi-modal.on{display:flex;animation:sfi-fade .18s ease}
@keyframes sfi-fade{from{opacity:0}to{opacity:1}}
.sfi-modal-box{width:100%;max-width:420px;max-height:88vh;display:flex;flex-direction:column;
  background:linear-gradient(180deg,var(--sfi-panel2),#070c17);border:1px solid var(--sfi-line2);
  border-radius:var(--sfi-r-lg);overflow:hidden;box-shadow:0 40px 90px -22px #000;
  animation:sfi-pop .26s var(--sfi-ease)}
.sfi-modal-box.wide{max-width:620px}
@keyframes sfi-pop{from{opacity:0;transform:translateY(14px) scale(.975)}to{opacity:1;transform:none}}
.sfi-modal-h{display:flex;align-items:center;gap:11px;padding:15px 16px;border-bottom:1px solid var(--sfi-line);flex:none}
.sfi-modal-h .ic{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;flex:none;
  background:rgba(120,190,255,.08);border:1px solid var(--sfi-line)}
.sfi-modal-h .ic svg{width:17px;height:17px;color:var(--sfi-cyan)}
.sfi-modal-h .t{flex:1;min-width:0}
.sfi-modal-h b{display:block;font-family:var(--sfi-disp);font-size:14.5px;font-weight:700}
.sfi-modal-h small{display:block;color:var(--sfi-mut2);font-size:11.5px;margin-top:2px}
.sfi-modal-h .x{border:none;background:transparent;color:var(--sfi-mut2);cursor:pointer;padding:4px;flex:none}
.sfi-modal-h .x svg{width:17px;height:17px}
.sfi-modal-b{padding:16px;overflow-y:auto;flex:1;font-size:13px;line-height:1.65;color:var(--sfi-txt)}
.sfi-modal-f{display:flex;gap:9px;padding:13px 16px;border-top:1px solid var(--sfi-line);flex:none}
.sfi-modal-f .sfi-btn{flex:1}
@media(max-width:520px){
  .sfi-modal{padding:0;align-items:flex-end}
  .sfi-modal-box{max-width:none;max-height:94vh;border-radius:var(--sfi-r-lg) var(--sfi-r-lg) 0 0}
  .sfi-modal-f{flex-direction:column-reverse}
}

/* ------------------------------------------------------------------ alert
   An error the user can act on: one sentence of what happened, then buttons. */
.sfi-alert{border:1px solid var(--sfi-line2);border-radius:var(--sfi-r);padding:13px 14px;
  background:rgba(120,190,255,.04);font-size:12.5px;line-height:1.65}
.sfi-alert b{display:block;font-family:var(--sfi-disp);font-size:13.5px;margin-bottom:5px}
.sfi-alert p{color:var(--sfi-mut);margin:0}
.sfi-alert .acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:11px}
.sfi-alert.bad{border-color:rgba(248,113,113,.36);background:rgba(248,113,113,.07)}
.sfi-alert.bad b{color:#FCA5A5}
.sfi-alert.warn{border-color:rgba(251,191,36,.36);background:rgba(251,191,36,.06)}
.sfi-alert.warn b{color:#FCD34D}
.sfi-alert.good{border-color:rgba(52,211,153,.36);background:rgba(52,211,153,.06)}
.sfi-alert.good b{color:#6EE7B7}

/* ------------------------------------------------------- empty states
   An empty panel is a dead end unless it says what to do next, so the CTA
   is part of the component and not an afterthought. */
.sfi-empty{border:1px dashed var(--sfi-line2);border-radius:var(--sfi-r-lg);padding:30px 22px;text-align:center}
.sfi-empty .ic{width:46px;height:46px;margin:0 auto 13px;border-radius:14px;display:grid;place-items:center;
  background:radial-gradient(circle at 30% 20%,rgba(34,217,255,.16),rgba(59,111,240,.08));border:1px solid var(--sfi-line)}
.sfi-empty .ic svg{width:21px;height:21px;color:var(--sfi-cyan);opacity:.9}
.sfi-empty b{display:block;font-family:var(--sfi-disp);font-size:15px;font-weight:700;margin-bottom:6px}
.sfi-empty p{color:var(--sfi-mut);font-size:12.5px;line-height:1.7;max-width:380px;margin:0 auto}
.sfi-empty .acts{display:flex;justify-content:center;flex-wrap:wrap;gap:8px;margin-top:16px}

/* -------------------------------------------------------------- skeletons
   Shown while a panel loads instead of a spinner: the page does not jump when
   the data lands, because the shape was already there. */
.sfi-skel{border:1px solid var(--sfi-line);border-radius:var(--sfi-r);background:rgba(120,190,255,.025);
  padding:14px 15px;margin-bottom:8px;overflow:hidden}
.sfi-skel .l{height:11px;border-radius:6px;margin-bottom:9px;
  background:linear-gradient(90deg,rgba(120,190,255,.07) 25%,rgba(120,190,255,.16) 37%,rgba(120,190,255,.07) 63%);
  background-size:400% 100%;animation:sfi-shimmer 1.35s ease-in-out infinite}
.sfi-skel .l:last-child{margin-bottom:0}
.sfi-skel .l.w40{width:40%}.sfi-skel .l.w60{width:60%}.sfi-skel .l.w75{width:75%}.sfi-skel .l.w30{width:30%}
@keyframes sfi-shimmer{0%{background-position:100% 50%}100%{background-position:0 50%}}
@media(prefers-reduced-motion:reduce){.sfi-skel .l{animation:none}}

/* ---------------------------------------------------------------- toasts */
#sfi-toasts{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:9500;
  display:flex;flex-direction:column;gap:8px;pointer-events:none;width:min(420px,calc(100vw - 28px))}
.sfi-toast{pointer-events:auto;display:flex;align-items:center;gap:10px;padding:12px 14px;
  border-radius:var(--sfi-r);border:1px solid var(--sfi-line2);background:var(--sfi-panel2);
  backdrop-filter:blur(14px);font-size:12.5px;box-shadow:0 20px 44px -18px #000;animation:sfi-toast-in .28s var(--sfi-ease)}
@keyframes sfi-toast-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.sfi-toast.out{opacity:0;transform:translateY(10px);transition:.25s}
.sfi-toast .d{width:7px;height:7px;border-radius:50%;flex:none;background:var(--sfi-cyan);box-shadow:0 0 10px currentColor}
.sfi-toast.ok  .d{background:var(--sfi-green)}
.sfi-toast.bad .d{background:var(--sfi-red)}
.sfi-toast.warn .d{background:var(--sfi-amber)}

/* ------------------------------------------------------------ status bar
   Plan · wallet · network · credits · last sync. The five facts that decide
   whether the next thing the user clicks will work. */
.sfi-status{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:8px 14px;border-bottom:1px solid var(--sfi-line);background:rgba(6,11,22,.6);
  font-family:var(--sfi-mono);font-size:11px;color:var(--sfi-mut)}
.sfi-status .s{display:inline-flex;align-items:center;gap:6px;padding:4px 9px;border-radius:8px;
  border:1px solid var(--sfi-line);background:rgba(120,190,255,.03);white-space:nowrap}
.sfi-status .s b{color:var(--sfi-txt);font-family:var(--sfi-mono);font-weight:600}
.sfi-status .s.live{color:#6EE7B7;border-color:rgba(52,211,153,.36);background:rgba(52,211,153,.08)}
.sfi-status .s.demo{color:#FCD34D;border-color:rgba(251,191,36,.36);background:rgba(251,191,36,.07);cursor:pointer}
.sfi-status .s.bad{color:#FCA5A5;border-color:rgba(248,113,113,.36);background:rgba(248,113,113,.07);cursor:pointer}
.sfi-status .s.click{cursor:pointer}
.sfi-status .s.click:hover{border-color:var(--sfi-line2)}
.sfi-status .grow{flex:1}
.sfi-status .sync{color:var(--sfi-mut2);font-size:10px}
.sfi-status .meter{width:54px;height:5px;border-radius:100px;background:rgba(120,190,255,.12);overflow:hidden}
.sfi-status .meter i{display:block;height:100%;background:linear-gradient(90deg,#22D9FF,#3B6FF0)}
.sfi-status .meter.hot i{background:linear-gradient(90deg,#FBBF24,#F87171)}
@media(max-width:640px){
  .sfi-status{gap:6px;padding:7px 10px;overflow-x:auto;flex-wrap:nowrap;-webkit-overflow-scrolling:touch}
  .sfi-status::-webkit-scrollbar{display:none}
  .sfi-status .grow,.sfi-status .sync{display:none}
}

/* ----------------------------------------------------------- trust panel */
.sfi-trust{display:grid;gap:9px}
.sfi-trust .t{display:flex;gap:11px;align-items:flex-start;padding:11px 12px;border:1px solid var(--sfi-line);
  border-radius:var(--sfi-r);background:rgba(52,211,153,.04)}
.sfi-trust .t .ic{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;flex:none;
  background:rgba(52,211,153,.1);border:1px solid rgba(52,211,153,.24)}
.sfi-trust .t .ic svg{width:14px;height:14px;color:#6EE7B7}
.sfi-trust .t b{display:block;font-size:12.5px;font-weight:700;margin-bottom:2px}
.sfi-trust .t p{color:var(--sfi-mut);font-size:11.5px;line-height:1.6;margin:0}
.sfi-trust .t code{font-family:var(--sfi-mono);font-size:10.5px;background:rgba(120,190,255,.08);
  padding:1px 5px;border-radius:4px;word-break:break-all}

/* --------------------------------------------------------- capability map */
.sfi-caps{width:100%;border-collapse:collapse;font-size:12.5px}
.sfi-caps th,.sfi-caps td{padding:9px 8px;border-bottom:1px solid var(--sfi-line);text-align:center}
.sfi-caps th{font-family:var(--sfi-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--sfi-mut2)}
.sfi-caps th.now{color:var(--sfi-cyan)}
.sfi-caps td:first-child,.sfi-caps th:first-child{text-align:left;color:var(--sfi-txt);font-weight:600}
.sfi-caps td.y{color:#6EE7B7}
.sfi-caps td.n{color:var(--sfi-mut2);opacity:.55}
.sfi-caps tr.locked td:first-child{color:var(--sfi-mut)}
.sfi-caps col.now{background:rgba(34,217,255,.05)}

/* ------------------------------------------------------------- wallet grid */
.sfi-wallets{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:9px}
.sfi-wallets a{display:flex;flex-direction:column;align-items:center;gap:8px;padding:15px 10px;
  border:1px solid var(--sfi-line);border-radius:var(--sfi-r);background:rgba(120,190,255,.03);
  text-decoration:none;color:var(--sfi-txt);font-family:var(--sfi-disp);font-size:12.5px;font-weight:600;
  transition:transform .15s var(--sfi-ease),border-color .15s}
.sfi-wallets a:hover{transform:translateY(-2px);border-color:var(--sfi-line2);text-decoration:none}
.sfi-wallets a .em{font-size:24px;line-height:1}
.sfi-wallets a small{color:var(--sfi-mut2);font-size:10.5px;font-family:var(--sfi-body);font-weight:400}
