/* Sherwood Insights — committed dark theme (deliberate single theme).
   Brand palette: black ground, chartreuse primary, white type, with
   Crayola Blue and Blush Rose as the secondary/categorical pair. */

:root{
  --bg:#000000;            /* brand black — the page plane */
  --surface:#0a0a0a;       /* cards / chart surface */
  --surface-2:#141414;     /* raised chips, table header */
  --line:#242424;          /* hairline borders */
  --grid:#1b1b1b;          /* chart gridlines (one step off surface) */
  --ink:#ffffff;           /* brand white — primary type */
  --ink-2:#b4b4b4;         /* secondary text */
  --muted:#797979;         /* muted labels/axis — 4.55:1 on card surface, AA text */

  /* Chartreuse is the primary: it carries the data and the brand chrome, and
     doubles as the "passed a check" colour. Severity above that uses the
     conventional amber/red ramp — a risk tool should not make a reader learn a
     new colour language to find out that something is wrong. */
  --accent:#CCFF00;        /* Chartreuse — primary */
  --accent-2:#3272FF;      /* Crayola Blue — secondary */
  --accent-dim:#354200;
  --good:#CCFF00;
  --warn:#efb13c;
  --crit:#ed5e4f;
  --info:#3272FF;
  /* cluster (categorical) hues — validator-passed (all-pairs, dark surface) */
  --c1:#8a63e0; --c2:#219a76; --c3:#bd8a1f;
  --c-other:#8b8b8b;       /* clusters beyond the 3 brand hues */
  --c-none:#454545;        /* unclustered holder */
  --contract:#9aa3ad;      /* contract/DEX nodes */
  --radius:12px;
  --display:'DM Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --brand:'Manrope',system-ui,-apple-system,'Segoe UI',sans-serif;  /* wordmark only */
  --mono:'IBM Plex Mono',ui-monospace,Consolas,monospace;
  --ls:-0.04em;            /* brand tracking: -4% */
  --rail:236px;            /* desktop sidebar width */

  /* Type scale. 21 ad-hoc pixel values collapsed into 15 steps, so a size
     change is one edit and the mobile scale can exist at all. Prose captions
     sit at --fs-cap / --fs-cap-sm; those two are deliberately close to body,
     because at 11px the supporting lines under a number were too small to be
     read at a glance and were carrying real meaning. */
  --fs-display:clamp(26px,4vw,38px); /* hero headline — fluid, no mobile step needed */
  --fs-hero:46px;      /* risk score */
  --fs-2xl:31px;       /* behaviour tile value */
  --fs-xl:26px;        /* token price */
  --fs-lg:23px;        /* KPI value */
  --fs-md:22px;        /* score grade */
  --fs-title:19px;     /* token name */
  --fs-h2:18px;        /* section heads */
  --fs-h3:15px;        /* brand, card heads */
  --fs-body:14px;      /* running prose */
  --fs-cap:13.5px;     /* prose caption */
  --fs-cap-sm:13px;    /* small prose caption */
  --fs-data:12.5px;    /* numeric readouts */
  --fs-data-sm:11.5px; /* dense numerics, addresses */
  --fs-chip:11px;      /* chips and pills */
  --fs-label:10.5px;   /* uppercase mono labels */
  --fs-micro:9.5px;    /* micro labels */

}

*{box-sizing:border-box}

/* The `hidden` attribute is only a UA `display:none`, so any author rule that
   sets `display` on the same element beats it — `.scanveil{display:grid}` left
   the scan veil painted over the page forever after it was supposedly hidden,
   and `.maptoggle{display:inline-flex}` showed the shared-tokens toggle on maps
   with no hubs. One global rule closes it for every current and future case. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-weight:400;
  letter-spacing:var(--ls);
  font-size:var(--fs-h3);line-height:1.55;
}
a{color:var(--accent);text-decoration:none}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
h1,h2,h3{margin:0;text-wrap:balance}
.mono{font-family:var(--mono);letter-spacing:0;text-transform:uppercase}

/* DM Sans carries the display voice; Inter carries running text. Both sit at
   -4% tracking, which is the brand's, and mono opts out below — monospace at
   negative tracking collides on digits and stops being scannable. */
h1,h2,h3,h4,.brand-name,.hero h1,.kpi-v,.bt-v,.score-num,.score-grade{
  font-family:var(--display);letter-spacing:var(--ls);
}
.hero p,.beh-headline,.hab-read{font-weight:300}
a,button,.maptoggle,.tcard,.rel-row{font-weight:500}

/* ---------------- top bar */
.topbar{
  position:sticky;top:0;z-index:50;display:flex;align-items:center;
  flex-wrap:wrap;gap:18px;
  padding:10px clamp(16px,2.2vw,40px);background:rgba(8,10,8,.93);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
}
.brand{display:flex;align-items:baseline;gap:9px;color:var(--ink);flex:0 0 auto}
.brand-mark{width:23px;height:23px;color:var(--accent);align-self:center;flex:0 0 auto}
/* The wordmark is set in the logo's own face: Manrope, Regular "Robin" against
   Bold "Sight", one colour, -4% tracking. It is the only place Manrope is
   used — headings stay on DM Sans. */
.brand-name{font-family:var(--brand);font-weight:400;font-size:var(--fs-h3);letter-spacing:-.04em;white-space:nowrap}
.brand-name em{font-style:normal;font-weight:700;color:inherit}
.brand-token{
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);font-weight:600;
  color:var(--accent);border:1px solid var(--accent-dim);border-radius:99px;
  padding:2px 7px;align-self:center;
}
.search{position:relative;flex:1 1 480px;max-width:640px}
.search input{
  width:100%;padding:9px 14px;border-radius:9px;border:1px solid var(--line);
  background:var(--surface);color:var(--ink);font:inherit;font-size:var(--fs-body);
}
.search input::placeholder{color:var(--muted)}
.search input:focus{outline:none;border-color:var(--accent)}
.suggest{
  position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:60;
  background:var(--surface-2);border:1px solid var(--line);border-radius:10px;
  overflow:hidden;box-shadow:0 12px 32px rgba(0,0,0,.5);
}
.suggest button{
  display:flex;width:100%;gap:10px;align-items:center;padding:9px 12px;text-align:left;
}
.suggest button:hover,.suggest button:focus-visible{background:var(--accent-dim)}
.suggest .s-sym{font-weight:700;min-width:70px}
.suggest .s-name{color:var(--ink-2);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.suggest .s-addr{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);color:var(--muted)}
.topbar-right{display:flex;gap:8px;flex:0 0 auto}

/* Full-bleed means the topbar no longer has a max-width to hide behind, so it
   has to fold on its own below tablet rather than pushing a horizontal
   scrollbar onto every page. */
@media (max-width:760px){
  .topbar{flex-wrap:wrap;row-gap:9px}
  .search{flex:1 1 100%;max-width:none;order:3}
  .topbar-right{margin-left:auto}
}
@media (max-width:520px){
  .chainchip{display:none}
  .brand-token{display:none}
}
.chainchip,.aichip{
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);padding:5px 10px;border-radius:999px;
  border:1px solid var(--line);color:var(--ink-2);background:var(--surface);white-space:nowrap;
}
.aichip.on{color:var(--good);border-color:var(--accent-dim)}

/* ---------------- layout */
.view{max-width:none;margin:0;padding:22px clamp(16px,2.2vw,40px) 60px}
.hero{padding:34px 0 10px;max-width:760px}
.hero h1{font-size:var(--fs-display);font-weight:800;line-height:1.1}
.hero p{color:var(--ink-2);margin:12px 0 0;max-width:56ch}

.trend-section{margin-top:34px}
.trend-head{display:flex;align-items:baseline;gap:12px;margin-bottom:12px}
.trend-head h2{font-size:var(--fs-h2);font-weight:700}
.srcnote{color:var(--muted);font-size:var(--fs-cap)}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:10px}
.tcard{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:13px 15px;display:flex;flex-direction:column;gap:7px;text-align:left;
  transition:border-color .15s;
}
.tcard:hover{border-color:var(--accent)}
.tcard .t-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.tcard .t-sym{font-weight:800;font-size:var(--fs-h3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tcard .t-price{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-cap-sm);color:var(--ink-2)}
.tcard .t-mid{display:flex;justify-content:space-between;align-items:center}
.delta{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data);font-weight:600}
.delta.up{color:var(--good)}.delta.down{color:var(--crit)}.delta.flat{color:var(--muted)}
.tcard .t-stats{display:flex;gap:12px;color:var(--muted);font-size:var(--fs-data-sm);font-family:var(--mono);letter-spacing:0;text-transform:uppercase}
.empty{color:var(--muted);padding:16px 4px;font-size:var(--fs-body)}

/* ---------------- token header */
.token-head{
  display:flex;flex-wrap:wrap;align-items:center;gap:18px;
  padding:16px 0 14px;
}
.th-id{display:flex;align-items:center;gap:12px;min-width:240px}
.th-icon{width:40px;height:40px;border-radius:50%;background:var(--surface-2);
  display:flex;align-items:center;justify-content:center;font-weight:800;color:var(--accent);
  border:1px solid var(--line);overflow:hidden;flex:0 0 auto}
.th-icon img{width:100%;height:100%;object-fit:cover}
.th-name{font-size:var(--fs-title);font-weight:800}
.th-sym{color:var(--ink-2);font-weight:600;margin-left:6px}
.th-addr{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data-sm);color:var(--muted);display:flex;gap:6px;align-items:center}
.th-addr button{color:var(--muted);font-size:var(--fs-chip);border:1px solid var(--line);border-radius:6px;padding:1px 7px}
.th-addr button:hover{color:var(--accent);border-color:var(--accent)}
.th-price{display:flex;align-items:baseline;gap:10px;margin-left:auto}
.th-price .p{font-size:var(--fs-xl);font-weight:800}
/* KPI strip. Each card leads with the number that drives a decision, and
   carries either a real series or a plain-language qualifier - never a
   decorative sparkline over data we do not actually have. */
/* 178px keeps all six on one line down to ~1130px, which is where the
   strip stops being a scannable row and starts being a list. */
.statrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));
  gap:9px;width:100%}
.kpi{
  background:var(--surface);border:1px solid var(--line);border-radius:10px;
  padding:11px 14px 10px;display:flex;flex-direction:column;gap:7px;min-width:0;
}
.kpi-k{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.kpi-main{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}
.kpi-v{font-size:var(--fs-lg);font-weight:800;letter-spacing:-.01em;line-height:1.05;white-space:nowrap}
.kpi-v.grade-good{color:var(--good)}
.kpi-v.grade-warn{color:var(--warn)}
.kpi-v.grade-crit{color:var(--crit)}
/* The sparkline carries a fixed 104px width attribute. Left rigid it pushes
   the whole document sideways in a two-up KPI grid on a phone, so let flex
   shrink it; the viewBox scales the drawing down rather than clipping it. */
.kpi-spark{flex:0 1 auto;min-width:0;max-width:100%;overflow:visible;color:var(--accent)}
.kpi-spark.tone-warn{color:var(--warn)}
.kpi-spark.tone-crit{color:var(--crit)}
.kpi-spark.tone-accent{color:var(--accent)}
.kpi-foot{display:flex;align-items:baseline;gap:7px;min-height:15px}
.kpi-d{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data-sm);font-weight:700}
.kpi-d.up{color:var(--good)}.kpi-d.down{color:var(--crit)}.kpi-d.flat{color:var(--muted)}
.kpi-w{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);letter-spacing:.1em;color:var(--muted)}
.kpi-sub{font-size:var(--fs-cap-sm);color:var(--muted);line-height:1.3;
  /* Two lines rather than one truncated one: at the larger caption size this
     text no longer fits on a single line, and it is the line that says what
     the number means. */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.kpi-sub.alert{color:var(--warn)}
.kpi.pending .kpi-v{color:var(--muted)}
.progress{color:var(--muted);font-size:var(--fs-data);font-family:var(--mono);letter-spacing:0;text-transform:uppercase;min-height:20px;padding:2px 0 10px}

/* ---------------- signals board */
.mainnav{display:flex;gap:2px;margin-left:6px;flex:0 0 auto}
.mainnav a{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
  font-size:var(--fs-label);padding:6px 11px;border-radius:99px;color:var(--muted);
  text-decoration:none;transition:.15s;white-space:nowrap}
.mainnav a:hover{color:var(--ink-2)}
.mainnav a.on{background:var(--surface-2);color:var(--accent)}

.sig-head{padding:26px 0 14px}
.sig-head h1{font-family:var(--display);font-size:clamp(24px,3.4vw,34px);margin:0;letter-spacing:var(--ls)}
.sig-head p{color:var(--ink-2);margin:9px 0 0;max-width:62ch;font-weight:300}
.sig-live{margin-left:auto;display:flex;align-items:center;gap:8px;
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
  font-size:var(--fs-chip);color:var(--muted);white-space:nowrap}
.sig-dot{width:7px;height:7px;border-radius:50%;background:var(--accent);flex:0 0 auto}
.sig-dot.beat{animation:sig-beat 1s ease-out}
@keyframes sig-beat{0%{box-shadow:0 0 0 0 rgba(204,255,0,.55)}
  100%{box-shadow:0 0 0 11px rgba(204,255,0,0)}}

.sig-windows{display:inline-flex;gap:3px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:99px;padding:3px;margin-bottom:12px}
.sig-windows button{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
  font-size:var(--fs-micro);padding:6px 12px;border:0;border-radius:99px;background:none;
  color:var(--muted);cursor:pointer;transition:.15s}
.sig-windows button:hover{color:var(--ink-2)}
.sig-windows button.on{background:var(--accent);color:#000;font-weight:600}

.sig-feed{display:flex;gap:7px;flex-wrap:wrap;min-height:22px;margin-bottom:14px;align-items:center}
.sig-feedlbl{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
  font-size:var(--fs-micro);color:var(--muted)}
.sig-move{font-family:var(--mono);letter-spacing:0;font-size:var(--fs-chip);
  padding:3px 9px;border-radius:99px;border:1px solid var(--line);white-space:nowrap;
  animation:sig-in .45s ease-out}
.sig-move.up{color:var(--accent);border-color:var(--accent-dim)}
.sig-move.down{color:var(--crit)}
@keyframes sig-in{from{opacity:0;transform:translateX(-12px)}to{opacity:1;transform:none}}

.sig-board{display:grid;grid-template-columns:repeat(auto-fit,minmax(248px,1fr));gap:12px}
.sig-col{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:13px;min-width:0}
.sig-col.definitely{border-color:#3d4d00}
.sig-col.avoid{opacity:.7}
.sig-colhead{display:flex;align-items:baseline;gap:8px;margin-bottom:11px}
.sig-colhead h3{font-size:var(--fs-h3);margin:0}
.sig-col.definitely .sig-colhead h3{color:var(--accent)}
.sig-col.avoid .sig-colhead h3{color:var(--crit)}
.sig-n{margin-left:auto;font-family:var(--mono);letter-spacing:0;
  font-size:var(--fs-chip);color:var(--muted)}

.sig-card{background:var(--surface-2);border:1px solid var(--line);border-radius:9px;
  padding:10px 11px;margin-bottom:7px;cursor:pointer;transition:border-color .15s}
.sig-card:hover{border-color:var(--accent)}
.sig-card.moved{animation:sig-pop 1.6s ease-out}
@keyframes sig-pop{0%{border-color:var(--accent);box-shadow:0 0 0 0 rgba(204,255,0,.45)}
  100%{border-color:var(--line);box-shadow:0 0 0 14px rgba(204,255,0,0)}}
.sig-top{display:flex;align-items:center;gap:8px}
.sig-ic{width:26px;height:26px;border-radius:50%;overflow:hidden;flex:0 0 auto;
  display:grid;place-items:center;background:var(--surface);border:1px solid var(--line);
  font-family:var(--mono);letter-spacing:0;font-size:var(--fs-micro);font-weight:600;color:var(--muted)}
.sig-ic img{width:100%;height:100%;object-fit:cover}
.sig-id{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.sig-sym{font-size:var(--fs-cap-sm);font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.sig-name{font-size:var(--fs-micro);color:var(--muted);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.sig-ev{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
  font-size:var(--fs-micro);padding:2px 6px;border-radius:99px;
  border:1px solid var(--line);color:var(--muted);margin-left:auto;white-space:nowrap}
.sig-ev.strong{color:var(--accent);border-color:var(--accent-dim)}
.sig-ev.fair{color:var(--warn)}
.sig-str{font-family:var(--display);font-weight:800;font-size:var(--fs-md);letter-spacing:var(--ls)}
.sig-bars{display:flex;gap:3px;margin-top:9px}
.sig-bars i{flex:1;height:4px;border-radius:2px;background:var(--line);
  position:relative;overflow:hidden;cursor:help}
.sig-bars i span{position:absolute;inset:0 auto 0 0;background:var(--accent);border-radius:2px}
.sig-meta{display:flex;gap:11px;margin-top:8px;font-family:var(--mono);letter-spacing:0;
  font-size:var(--fs-micro);color:var(--muted)}
.sig-more{display:block;width:100%;margin-top:4px;padding:9px;border-radius:8px;
  background:none;border:1px dashed var(--line);color:var(--muted);cursor:pointer;
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-micro)}
.sig-more:hover{color:var(--accent);border-color:var(--accent-dim)}
.sig-foot{margin-top:18px;color:var(--muted);font-size:var(--fs-cap-sm);line-height:1.6;max-width:88ch}


/* ---------------- mobile shell

   Two problems this solves. First, the desktop topbar folded into three stacked
   rows on a phone and ate ~270px before any content appeared. Second, switching
   between Scanner and Signals lived at the top of a long scroll, which is the
   worst place to put the most frequent action on a touch device.

   So on phones the section switch moves to a bottom tab bar in the thumb zone,
   the topbar collapses to brand + status, and anything that was a wide flex row
   scrolls inside its own container rather than pushing the document sideways. */

.tabbar{display:none}

/* Below the rail the drawer already lists every feature, so the topbar sheds
   its duplicate nav and the chain chip rather than overflowing. */
@media (max-width:1079px){
  .mainnav{display:none}
  .chainchip{display:none}
  .search{flex:1 1 240px;min-width:0}
  .topbar-right{flex:0 0 auto}
}

@media (max-width:760px){
  /* --- topbar: one compact row, nav moves to the bottom bar --- */
  .topbar{gap:10px;padding:9px 14px}
  .brand-name{font-size:14px}
  .brand-token{display:none}
  .mainnav{display:none}
  .search{order:3;flex:1 1 100%;max-width:none}
  .topbar-right{margin-left:auto}
  .chainchip,.aichip{display:none}

  /* --- bottom tabs --- */
  .tabbar{
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:60;
    background:rgba(0,0,0,.94);backdrop-filter:blur(10px);
    border-top:1px solid var(--line);
    padding:6px 8px calc(6px + env(safe-area-inset-bottom,0px));
  }
  .tabbar a{
    flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
    padding:7px 4px;border-radius:10px;text-decoration:none;color:var(--muted);
    font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
    font-size:var(--fs-micro);transition:color .15s,background .15s;
  }
  .tabbar a svg{width:19px;height:19px}
  .tabbar a.on{color:var(--accent);background:var(--surface-2)}
  /* keep the last card clear of the fixed bar */
  body{padding-bottom:64px}

  /* --- signals: reclaim vertical space --- */
  .view{padding:14px 14px 26px}
  .sig-head{padding:14px 0 10px;gap:10px}
  .sig-head h1{font-size:22px}
  .sig-head p{font-size:var(--fs-cap);margin-top:6px}
  .sig-live{margin-left:0;width:100%}
  .sig-windows{width:100%;overflow-x:auto;scrollbar-width:none;
    -webkit-overflow-scrolling:touch}
  .sig-windows::-webkit-scrollbar{display:none}
  .sig-windows button{flex:0 0 auto}
  /* the move feed is a ticker, not a list: scroll it sideways in place */
  .sig-feed{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;
    -webkit-overflow-scrolling:touch;padding-bottom:2px}
  .sig-feed::-webkit-scrollbar{display:none}
  /* the label is a flex item in a nowrap scroller: let it keep its own width
     instead of shrinking and breaking across two lines beside the ticker */
  .sig-feedlbl{flex:0 0 auto;white-space:nowrap;padding-right:2px}
  .sig-move{flex:0 0 auto}
  .sig-board{grid-template-columns:1fr;gap:10px}
  .sig-card{padding:11px 12px}
  .sig-ic{width:30px;height:30px}
  /* touch targets: 44px is the accepted floor for a reliable tap */
  .sig-windows button,.tabbar a{min-height:38px}

  /* --- scanner: stack the columns --- */
  .scan-grid{grid-template-columns:1fr}
  .statrow{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
  .bubble-wrap{height:min(62vh,420px)}
  .maplegend{display:none}
  table.holders{font-size:var(--fs-data-sm)}
  .hero{padding:20px 0 6px}
}

@media (max-width:420px){
  .sig-head h1{font-size:20px}
  .statrow{grid-template-columns:repeat(2,1fr)}
  .tabbar a span{font-size:9px}
}


/* ---------------- app shell: landing, menu button, drawer

   The product now has two surfaces. `#/` is a landing page — no search, no
   chain chip, no nav, because none of it means anything before you have picked
   a feature. Everything under `#/app/` is the application, where Scanner and
   Signals are peers sharing one chrome.

   `body.in-app` is the switch. It is set by the router, so the topbar and tab
   bar reveal themselves as part of entering the app rather than being wired
   view by view. */

.menubtn{
  display:none;flex:0 0 auto;align-items:center;justify-content:center;
  width:36px;height:36px;margin-left:-6px;border:0;border-radius:9px;
  background:transparent;color:var(--ink-2);cursor:pointer;
  transition:background .15s,color .15s;
}
.menubtn:hover{background:var(--surface-2);color:var(--ink)}
.menubtn svg{width:20px;height:20px}
body.in-app .menubtn{display:flex}

/* --- drawer --- */

.drawer-scrim{
  position:fixed;inset:0;z-index:80;background:rgba(0,0,0,.62);
  backdrop-filter:blur(2px);opacity:0;transition:opacity .22s ease;
}
body.drawer-open .drawer-scrim{opacity:1}

.drawer{
  position:fixed;top:0;left:0;bottom:0;z-index:90;width:min(310px,86vw);
  display:flex;flex-direction:column;gap:2px;padding:16px 14px
    calc(16px + env(safe-area-inset-bottom,0px));
  background:var(--surface);border-right:1px solid var(--line);
  transform:translateX(-100%);transition:transform .22s cubic-bezier(.22,.61,.36,1);
  overflow-y:auto;overscroll-behavior:contain;
}
body.drawer-open .drawer{transform:translateX(0)}

.drawer-head{display:flex;align-items:center;gap:9px;padding:2px 4px 16px}
.drawer-head .brand-mark{width:24px;height:24px;color:var(--accent);flex:0 0 auto}
.drawer-head .brand-name{font-family:var(--brand);font-size:var(--fs-h3);
  letter-spacing:-.04em;color:var(--ink)}
.drawer-x{margin-left:auto;width:30px;height:30px;border:0;border-radius:8px;
  background:transparent;color:var(--muted);font-size:22px;line-height:1;
  cursor:pointer;transition:background .15s,color .15s}
.drawer-x:hover{background:var(--surface-2);color:var(--ink)}

.drawer-lbl{
  margin:14px 6px 6px;font-family:var(--mono);font-size:var(--fs-label);
  letter-spacing:0;text-transform:uppercase;color:var(--muted);
}
.drawer-lbl:first-of-type{margin-top:4px}

.drawer-item{
  display:flex;align-items:center;gap:11px;padding:10px 10px;border-radius:10px;
  text-decoration:none;color:var(--ink-2);border:1px solid transparent;
  transition:background .15s,color .15s,border-color .15s;
}
.drawer-item svg{width:19px;height:19px;flex:0 0 auto;color:var(--muted)}
.drawer-item span{display:flex;flex-direction:column;gap:1px;min-width:0}
.drawer-item b{font-family:var(--display);font-size:var(--fs-body);font-weight:600;
  letter-spacing:var(--ls);color:var(--ink)}
.drawer-item em{font-style:normal;font-size:var(--fs-cap-sm);color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.drawer-item:hover{background:var(--surface-2)}
.drawer-item:hover svg{color:var(--ink-2)}
.drawer-item.on{background:var(--accent-dim);border-color:var(--accent)}
.drawer-item.on svg,.drawer-item.on b{color:var(--accent)}

.drawer-foot{
  margin-top:auto;padding:16px 6px 2px;display:flex;flex-direction:column;gap:6px;
  border-top:1px solid var(--line);font-family:var(--mono);
  font-size:var(--fs-micro);letter-spacing:0;text-transform:uppercase;
  color:var(--muted);line-height:1.5;
}


/* ---------------- wallet, tier and watchlist

   The account block sits at the top of the drawer rather than in a view of its
   own: it is status, not a destination, and the drawer is already the menu on
   every width. Meters read used against allowance, so the free tier's limits
   are legible before they bite rather than only at the moment they block. */

.walletchip{
  display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;
  border:1px solid var(--line);border-radius:999px;background:var(--surface-2);
  color:var(--ink-2);cursor:pointer;font-family:var(--mono);
  font-size:var(--fs-label);letter-spacing:0;text-transform:uppercase;
  white-space:nowrap;transition:color .15s,border-color .15s,background .15s;
}
.walletchip:hover{color:var(--ink);border-color:var(--ink-2)}
.walletchip.on{color:var(--accent);border-color:var(--accent-dim);background:var(--accent-dim)}

.acct{margin:0 0 4px;padding:0 0 14px;border-bottom:1px solid var(--line)}
.acct-head{display:flex;align-items:center;gap:8px}
.acct-head .drawer-lbl{margin:4px 6px 6px;flex:1}
.acct-tier{
  padding:3px 9px;border:1px solid var(--accent);border-radius:999px;
  background:var(--accent-dim);color:var(--accent);font-family:var(--mono);
  font-size:var(--fs-micro);letter-spacing:0;text-transform:uppercase;
}
#acctBody{display:flex;flex-direction:column;gap:9px;padding:0 6px}

.acct-addr{display:flex;align-items:center;gap:8px}
.acct-addr a{
  font-family:var(--mono);font-size:var(--fs-data-sm);letter-spacing:0;
  text-transform:uppercase;color:var(--ink);text-decoration:none;
}
.acct-addr a:hover{color:var(--accent)}
.acct-addr button{
  padding:2px 8px;border:1px solid var(--line);border-radius:7px;
  background:transparent;color:var(--muted);cursor:pointer;
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:0;
  text-transform:uppercase;
}
.acct-addr button:hover{color:var(--ink);border-color:var(--ink-2)}

.acct-warn{
  display:flex;flex-direction:column;gap:7px;padding:9px 10px;border-radius:9px;
  background:rgba(239,177,60,.09);border:1px solid rgba(239,177,60,.4);
  font-size:var(--fs-cap-sm);color:var(--warn);
}
.acct-warn button{
  align-self:flex-start;padding:5px 11px;border:1px solid var(--warn);
  border-radius:8px;background:transparent;color:var(--warn);cursor:pointer;
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:0;
  text-transform:uppercase;
}
.acct-warn button:hover{background:rgba(239,177,60,.16)}

.acct-meter{display:flex;flex-direction:column;gap:5px}
.am-head{
  display:flex;justify-content:space-between;align-items:baseline;
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:0;
  text-transform:uppercase;color:var(--muted);
}
.am-head b{color:var(--ink);font-weight:500}
.acct-meter i{display:block;height:4px;border-radius:3px;background:var(--surface-2);overflow:hidden}
.acct-meter i span{display:block;height:100%;background:var(--accent);border-radius:3px}
.acct-meter i span.spent{background:var(--warn)}

.acct-note{margin:0;font-size:var(--fs-cap-sm);line-height:1.55;color:var(--muted)}

.btn-wallet{
  display:inline-flex;align-items:center;justify-content:center;min-height:38px;
  padding:0 16px;border-radius:9px;border:1px solid var(--accent);
  background:var(--accent);color:#000;cursor:pointer;text-decoration:none;
  font-family:var(--mono);font-size:var(--fs-label);letter-spacing:0;
  text-transform:uppercase;transition:background .15s,border-color .15s,color .15s;
}
.btn-wallet:hover{background:#dcff33;border-color:#dcff33}
.btn-wallet:disabled{background:transparent;border-color:var(--line);color:var(--muted);cursor:default}
.btn-wallet.ghost{background:transparent;border-color:var(--line);color:var(--muted)}
.btn-wallet.ghost:hover{color:var(--ink);border-color:var(--ink-2);background:transparent}

.acct-lbl{
  margin:2px 0 -2px;font-family:var(--mono);font-size:var(--fs-micro);
  letter-spacing:0;text-transform:uppercase;color:var(--muted);
}
.wallet-opt{
  display:flex;align-items:center;gap:9px;min-height:42px;padding:9px 11px;
  border-radius:9px;border:1px solid var(--line);background:var(--surface-2);
  color:var(--ink);cursor:pointer;text-decoration:none;
  font-family:var(--display);font-size:var(--fs-body);text-align:left;
}
a.wallet-opt::after{
  content:"→";margin-left:auto;color:var(--muted);font-family:var(--mono);
}
a.wallet-opt:hover::after{color:var(--accent)}
.wallet-opt:hover{border-color:var(--accent)}
.wallet-opt img{width:20px;height:20px;border-radius:5px;flex:0 0 auto}

/* --- star --- */

.star{
  display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;padding:0;border:0;border-radius:8px;
  background:transparent;color:var(--muted);cursor:pointer;
  transition:color .15s,background .15s;
}
.star svg{width:16px;height:16px}
.star:hover{color:var(--ink);background:var(--surface-2)}
.star.on{color:var(--accent)}
.star.on svg path{fill:var(--accent)}

/* The star sits in the card's top row as an ordinary flex item. Floating it in
   the corner overlapped the strength number, and revealing it on hover hid it
   entirely from touch. Always visible, muted until it is on. */
.sig-card .star,.tcard .star{flex:0 0 auto;margin-right:-4px}
.star:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.th-star{margin-left:8px;width:32px;height:32px}
.th-star svg{width:19px;height:19px}
.th-id{align-items:center}

/* --- watchlist --- */

.wl-count{
  font-family:var(--mono);font-size:var(--fs-label);letter-spacing:0;
  text-transform:uppercase;color:var(--muted);
}
.wl-lede{margin:0 0 16px;max-width:66ch;font-size:var(--fs-cap);line-height:1.6;color:var(--ink-2)}
.wl-body{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:10px}

.wl-card{
  display:flex;align-items:center;gap:11px;padding:12px 12px;cursor:pointer;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  transition:border-color .15s,background .15s;
}
.wl-card:hover{border-color:var(--ink-2);background:var(--surface-2)}
.wl-ic{flex:0 0 auto}
.wl-id{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.wl-sym{font-family:var(--display);font-size:var(--fs-h3);font-weight:600;
  letter-spacing:var(--ls);color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wl-name{font-size:var(--fs-cap-sm);color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wl-right{display:flex;align-items:center;gap:9px;flex:0 0 auto}
.wl-tier{
  padding:3px 8px;border-radius:999px;border:1px solid var(--line);
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:0;
  text-transform:uppercase;color:var(--muted);white-space:nowrap;
}
.wl-tier.t-definitely{color:var(--accent);border-color:var(--accent-dim);background:var(--accent-dim)}
.wl-tier.t-probably{color:var(--accent);border-color:var(--line)}
.wl-tier.t-potential{color:var(--info);border-color:var(--line)}
.wl-tier.t-watch{color:var(--ink-2);border-color:var(--line)}
.wl-tier.t-avoid{color:var(--crit);border-color:var(--line)}
.wl-str{font-family:var(--mono);font-size:var(--fs-md);color:var(--ink);letter-spacing:0}
.wl-card .star{flex:0 0 auto}

.wl-empty{
  grid-column:1/-1;display:flex;flex-direction:column;align-items:flex-start;gap:10px;
  padding:34px 26px;background:var(--surface);border:1px solid var(--line);
  border-radius:14px;
}
.wl-empty h3{margin:0;font-family:var(--display);font-size:var(--fs-title);
  font-weight:600;letter-spacing:var(--ls);color:var(--ink)}
.wl-empty p{margin:0;max-width:56ch;font-size:var(--fs-cap);line-height:1.6;color:var(--ink-2)}
.wl-note{grid-column:1/-1;margin:4px 0 0;font-size:var(--fs-cap-sm);color:var(--muted)}

@media (max-width:760px){
  .walletchip{height:28px;padding:0 10px}
  .wl-body{grid-template-columns:1fr}
  .wl-lede{font-size:var(--fs-cap-sm);margin-bottom:12px}
  /* touch has no hover, so a star that only appears on hover is unreachable */
  .sig-card .star,.tcard .star{opacity:1}
  .tabbar a svg{width:18px;height:18px}
}


/* --- tier gate --- */

.sig-locked{
  display:flex;align-items:center;gap:10px;margin-top:2px;padding:11px 12px;
  border:1px dashed var(--line);border-radius:12px;background:transparent;
  cursor:pointer;transition:border-color .15s,background .15s;
}
.sig-locked:hover{border-color:var(--accent-dim);background:var(--surface-2)}
.sl-n{
  flex:0 0 auto;min-width:34px;text-align:center;font-family:var(--mono);
  font-size:var(--fs-data);letter-spacing:0;color:var(--accent);
}
.sl-t{display:flex;flex-direction:column;gap:2px;min-width:0}
.sl-t b{font-family:var(--display);font-size:var(--fs-cap);font-weight:600;
  letter-spacing:var(--ls);color:var(--ink-2)}
.sl-t em{font-style:normal;font-family:var(--mono);font-size:var(--fs-micro);
  letter-spacing:0;text-transform:uppercase;color:var(--muted)}

.view.blocked > *:not(.token-head){display:none !important}
.view.blocked .token-head{display:block;background:none;border:0;padding:0}

.scan-blocked{
  display:flex;flex-direction:column;gap:12px;align-items:flex-start;
  padding:36px 28px;background:var(--surface);border:1px solid var(--line);
  border-radius:14px;
}
.scan-blocked h2{margin:0;font-family:var(--display);font-size:var(--fs-xl);
  font-weight:600;letter-spacing:var(--ls);color:var(--ink)}
.scan-blocked p{margin:0;max-width:60ch;font-size:var(--fs-cap);line-height:1.6;color:var(--ink-2)}
.sb-row{display:flex;flex-wrap:wrap;gap:9px;margin-top:2px}


/* ---------------- page header band

   The title used to sit in a flex row that squeezed it into a third of a wide
   screen and left the rest empty. It is a two-column band now: the writing on
   the left at a readable measure, account status on the right. On a phone the
   aside is dropped — the drawer already carries the same numbers, and vertical
   space there is worth more. */

.sig-head,.hero{
  display:grid;grid-template-columns:minmax(0,1fr);gap:18px;align-items:start;
}
.ph-main{min-width:0}
.sig-head .ph-main p,.hero .ph-main p{max-width:64ch}
.pagehead-aside{display:none}

/* ---------------- desktop shell

   Above this width the app stops pretending to be a phone. The drawer becomes a
   permanent rail, the hamburger disappears, and the topbar loses the brand and
   nav it was duplicating — leaving it to the search box and status. */

@media (min-width:1080px){
  body.in-app{padding-left:var(--rail)}

  .menubtn,.drawer-scrim,.tabbar{display:none !important}
  .topbar-brand,.mainnav{display:none}

  .drawer{
    transform:none;width:var(--rail);z-index:40;
    border-right:1px solid var(--line);background:var(--surface);
    padding:18px 14px calc(18px + env(safe-area-inset-bottom,0px));
  }
  .drawer-x{display:none}
  .drawer-head{padding-bottom:18px}
  /* The rail is the control surface; the allowance meters live in the page
     header on this width, so showing them twice would just be noise. */
  .acct{order:5;margin-top:auto;border-top:1px solid var(--line);border-bottom:0;
        padding:14px 0 4px}
  .acct .acct-meter,.acct .acct-note{display:none}
  .acct-head .drawer-lbl{margin-top:0}
  .drawer-foot{order:6;margin-top:0}

  .topbar{padding-left:clamp(16px,2.2vw,40px)}
  .search{max-width:560px}

  .sig-head,.hero{grid-template-columns:minmax(0,1fr) 268px;gap:30px}
  .sig-head{padding:30px 0 16px}
  .hero{max-width:none;padding:34px 0 14px}
  .pagehead-aside{display:flex;flex-direction:column;gap:10px}
}

@media (min-width:1400px){
  .search{max-width:680px}
  .sig-head,.hero{grid-template-columns:minmax(0,1fr) 300px}
}

/* ---------------- tier card in the page header */

.pagehead-aside{
  padding:14px 15px 13px;background:var(--surface);border:1px solid var(--line);
  border-radius:13px;
}
.ph-tier-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.ph-tier-lbl{
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:0;
  text-transform:uppercase;color:var(--muted);
}
.ph-tier-name{
  font-family:var(--display);font-size:var(--fs-title);font-weight:600;
  letter-spacing:var(--ls);color:var(--accent);
}
.ph-tier-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:0;
  text-transform:uppercase;color:var(--muted);
}
.ph-tier-row b{color:var(--ink);font-weight:500}
.ph-tier-foot{margin-top:2px;padding-top:10px;border-top:1px solid var(--line)}
.ph-tier-addr{
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:0;
  text-transform:uppercase;color:var(--ink-2);
}
.ph-tier-cta{
  width:100%;min-height:34px;border:1px solid var(--accent);border-radius:9px;
  background:var(--accent);color:#000;cursor:pointer;font-family:var(--mono);
  font-size:var(--fs-micro);letter-spacing:0;text-transform:uppercase;
  transition:background .15s,border-color .15s;
}
.ph-tier-cta:hover{background:#dcff33;border-color:#dcff33}

/* ---------------- scan veil

   Covers the grid while the six blocking passes run. The backdrop stays blurred
   rather than opaque on purpose: you can see the panels assembling underneath,
   which is the difference between "loading" and "watching something happen". */
.scanveil{
  position:fixed;inset:0;z-index:40;display:grid;place-items:center;
  padding:24px;background:rgba(0,0,0,.80);
  backdrop-filter:blur(11px) saturate(.55);
  -webkit-backdrop-filter:blur(11px) saturate(.55);
  animation:veil-in .3s ease-out;
}
.scanveil.lifting{animation:veil-out .4s ease-in forwards;pointer-events:none}
@keyframes veil-in{from{opacity:0}to{opacity:1}}
@keyframes veil-out{to{opacity:0}}
body.scanning{overflow:hidden}

.scanveil-inner{
  width:min(430px,88vw);display:flex;flex-direction:column;align-items:center;gap:19px;
}

/* radar */
.radar{width:152px;height:152px;color:var(--accent);flex:0 0 auto}
.radar .rr{fill:none;stroke:var(--line);stroke-width:1}
.radar .rx{stroke:var(--line);stroke-width:1;opacity:.5}
.radar .sweep{transform-origin:64px 64px;animation:radar-sweep 2.6s linear infinite}
@keyframes radar-sweep{to{transform:rotate(360deg)}}
.radar .core{fill:var(--accent)}
.radar .blip{
  fill:var(--accent);opacity:.9;transform-box:fill-box;transform-origin:center;
  animation:blip-in .45s ease-out backwards;
}
@keyframes blip-in{from{opacity:0;transform:scale(.2)}to{opacity:.9;transform:scale(1)}}

/* phase steps */
.scan-steps{display:flex;gap:4px;justify-content:center;flex-wrap:wrap;width:100%}
.step{
  display:flex;flex-direction:column;align-items:center;gap:6px;width:62px;
  color:var(--muted);transition:color .3s ease;
}
.step-ic{width:17px;height:17px;flex:0 0 auto}
.step-l{
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
  font-size:var(--fs-micro);line-height:1;white-space:nowrap;
}
.step.done{color:var(--ink-2)}
.step.active{color:var(--accent)}
.step.active .step-ic{animation:step-pulse 1.5s ease-in-out infinite}
@keyframes step-pulse{0%,100%{opacity:1}50%{opacity:.4}}

/* bar */
.scan-bar{
  width:100%;height:4px;border-radius:99px;background:var(--surface-2);overflow:hidden;
}
.scan-bar i{
  display:block;height:100%;width:0;border-radius:99px;background:var(--accent);
  box-shadow:0 0 12px rgba(204,255,0,.45);transition:width .4s ease-out;
}

.scan-meta{
  display:flex;justify-content:space-between;align-items:baseline;gap:12px;width:100%;
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);
}
.scan-now{color:var(--ink-2);text-align:left;line-height:1.4}
.scan-eta{color:var(--accent);white-space:nowrap;font-weight:600}
.scan-hint{
  margin:0;color:var(--muted);font-size:var(--fs-cap);line-height:1.5;text-align:center;
}

@media (max-width:520px){
  /* 6 steps must hold one row: 6x48 + 5x4 gap = 308, inside 375 - 48 padding */
  .scanveil{padding:16px}
  .step{width:48px}
  .step-l{font-size:8px}
  .scan-meta{flex-direction:column;align-items:center;gap:5px}
  .scan-now{text-align:center}
}

/* The sweep and the pulse are decoration; the bar and the step states carry the
   information on their own, so motion-sensitive readers lose nothing. */
@media (prefers-reduced-motion:reduce){
  .scanveil,.scanveil.lifting{animation:none}
  .radar .sweep{animation:none;opacity:.35}
  .radar .blip{animation:none}
  .step.active .step-ic{animation:none}
  .scan-bar i{transition:none}
}

/* ---------------- scan grid & cards */
.scan-grid{display:grid;grid-template-columns:minmax(320px,22vw) 1fr;gap:14px;align-items:start}
@media (max-width:980px){.scan-grid{grid-template-columns:1fr}}
.col-side,.col-main{display:flex;flex-direction:column;gap:14px;min-width:0}
.card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:16px 18px;
}
.card h3{font-size:var(--fs-body);font-weight:800;letter-spacing:.02em;display:flex;gap:8px;align-items:baseline}
.card-body{margin-top:12px}
.card-toolhead{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
.ghostbtn{color:var(--muted);font-size:var(--fs-data);border:1px solid var(--line);border-radius:7px;padding:3px 10px}
.ghostbtn:hover{color:var(--ink);border-color:var(--muted)}
.tag-beta{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);color:var(--muted);font-weight:400}

/* score */
.score-hero{display:flex;align-items:center;gap:16px}
.score-num{font-size:var(--fs-hero);font-weight:800;line-height:1}
.score-grade{
  font-size:var(--fs-md);font-weight:800;border:2px solid currentColor;border-radius:10px;
  padding:6px 13px;line-height:1;
}
.score-sub{color:var(--muted);font-size:var(--fs-cap);margin-top:4px}
.meter{height:8px;border-radius:99px;background:var(--surface-2);margin:14px 0 4px;overflow:hidden}
.meter i{display:block;height:100%;border-radius:99px}
.contribs{margin:12px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:7px}
.contribs li{display:flex;gap:9px;font-size:var(--fs-cap-sm);line-height:1.45;align-items:baseline}
.contribs .cdot{flex:0 0 8px;width:8px;height:8px;border-radius:50%;position:relative;top:-1px}
.contribs .cdelta{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data-sm);color:var(--muted);margin-left:auto;white-space:nowrap;font-variant-numeric:tabular-nums}
.sev-critical{background:var(--crit)}.sev-warn{background:var(--warn)}
.sev-good{background:var(--good)}.sev-info{background:var(--info)}
.t-critical{color:var(--crit)}.t-warn{color:var(--warn)}.t-good{color:var(--good)}.t-info{color:var(--info)}

/* safety */
.flags{display:flex;flex-direction:column;gap:8px}
.flagrow{display:flex;gap:9px;align-items:baseline;font-size:var(--fs-cap-sm)}
.flagrow .fmark{flex:0 0 auto;width:8px;height:8px;border-radius:50%;position:relative;top:-1px}
.flagrow .fk{color:var(--ink)}
.flagrow .fv{color:var(--muted);font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data-sm);margin-left:auto;white-space:nowrap}
.safety-summary{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:10px}
.spill{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);padding:3px 9px;border-radius:99px;border:1px solid var(--line)}
.spill[title]{cursor:help}

/* "Audited by Claude" mark — the Sherwood sight around its arrow. Marks the
   panel whose findings come from our own on-chain audit rather than a vendor. */
.audit-badge{
  display:inline-flex;align-items:center;gap:5px;vertical-align:middle;margin-left:9px;
  padding:3px 10px 3px 7px;border-radius:99px;cursor:help;
  border:1px solid var(--accent-dim);background:rgba(59,214,129,.075);color:var(--accent);
  font-size:var(--fs-label);font-weight:700;letter-spacing:.08em;text-transform:uppercase;
}
.audit-shield{width:12px;height:14px;flex:none}
.flagrow .fk-ev{
  margin-left:7px;padding:1px 5px;border-radius:4px;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);
  background:var(--surface);border:1px solid var(--line);color:var(--muted);
  white-space:nowrap;cursor:help;
}
/* Market-cap habitat — where this token's crowd holds, by position and by
   dollar. The two bars are drawn on one shared scale on purpose: the gap
   between them is the whole point, and per-series scaling would hide it. */
.hab-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));
  gap:8px;margin-bottom:16px}
.hab-stat{display:flex;flex-direction:column;gap:2px;padding:8px 10px;border-radius:8px;
  background:var(--surface);border:1px solid var(--line);cursor:help}
.hab-k{font-size:var(--fs-label);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.hab-v{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-body);font-weight:600}
.hab-list{display:flex;flex-direction:column;gap:7px}
.hab-row{display:grid;grid-template-columns:104px 1fr auto;gap:11px;align-items:center}
.hab-row.here .hab-band{color:var(--accent);font-weight:600}
.hab-band{font-size:var(--fs-data-sm);color:var(--muted);font-family:var(--mono);letter-spacing:0;text-transform:uppercase;white-space:nowrap}
.hab-bars{display:flex;flex-direction:column;gap:3px;min-width:0}
.hab-track{position:relative;display:block;height:11px;border-radius:3px;background:var(--surface)}
.hab-fill{display:block;height:100%;border-radius:3px}
.hab-fill.cnt{background:#4a5a52}
.hab-fill.val{background:var(--accent)}
.hab-pct{position:absolute;right:6px;top:0;line-height:11px;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;
  font-size:var(--fs-micro);color:var(--muted)}
.hab-here{font-size:var(--fs-label);letter-spacing:.05em;text-transform:uppercase;color:var(--accent);
  white-space:nowrap}
.hab-legend{display:flex;gap:14px;margin-top:13px}
.hab-key{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-cap-sm);color:var(--muted)}
.hab-key::before{content:"";width:10px;height:10px;border-radius:2px;background:#4a5a52}
.hab-key.val::before{background:var(--accent)}
.hab-read{margin:14px 0 0;font-size:var(--fs-body);line-height:1.55;color:var(--ink)}
.hab-caveat{margin:9px 0 0;padding-top:9px;border-top:1px solid var(--line);
  font-size:var(--fs-cap-sm);line-height:1.5;color:var(--muted)}

/* Related tokens — co-holding across the top holders' portfolios. */
/* ---------------- verdict tabs (risk score / AI read / contract safety)

   One card, three panels. The tab bar scrolls rather than wraps: three labels
   plus badges do not fit a 320px column, and a wrapped tab bar reads as two
   rows of unrelated buttons. */
.verdict-card{padding-top:10px}
.vtabs{
  display:flex;gap:2px;padding:3px;margin:0 0 2px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:9px;
  overflow-x:auto;scrollbar-width:none;
}
.vtabs::-webkit-scrollbar{display:none}
.vtab{
  display:inline-flex;align-items:center;gap:6px;flex:1 0 auto;justify-content:center;
  padding:6px 10px;border:0;border-radius:7px;background:none;color:var(--muted);
  font-family:var(--display);font-size:var(--fs-cap-sm);font-weight:600;letter-spacing:var(--ls);
  white-space:nowrap;cursor:pointer;transition:color .15s,background .15s;
}
.vtab:hover{color:var(--ink-2)}
/* Selected reads as raised, so the active pill is lighter than the bar it sits
   in, not darker. The fill stays neutral because each tab already carries a
   colour-coded badge, and an accent-filled pill would fight it. */
.vtab.on{background:var(--line);color:var(--ink)}
.vtab:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
/* The badge is the tab's whole job when its panel is hidden: it reports the
   grade, the number of findings, or that the AI read is off. */
.vtab-badge{
  font-family:var(--mono);letter-spacing:0;font-style:normal;font-size:var(--fs-micro);font-weight:600;
  min-width:15px;height:15px;padding:0 4px;border-radius:5px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--line);color:var(--ink-2);
}
.vtab-badge.good{background:var(--accent-dim);color:var(--accent)}
.vtab-badge.warn{background:rgba(239,177,60,.18);color:var(--warn)}
.vtab-badge.crit{background:rgba(237,94,79,.18);color:var(--crit)}
.vtab-badge.muted{background:var(--line);color:var(--muted)}
.vpane:focus{outline:none}
.vpane:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
.vpane-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:10px;min-height:1px}
.vpane-head:empty{display:none}
.vpane-head .audit-badge{margin-left:0}

/* Related tokens now sits in the side column, where the wide row grid would
   overflow 320px. Same information, tighter columns — but only while the column
   is actually narrow: below 980px the grid collapses to one full-width column
   and the rows get their normal proportions back. */
@media (min-width:981px){
  .col-side .rel-row{grid-template-columns:20px minmax(58px,1fr) minmax(34px,1.5fr) 26px 38px;gap:7px;padding:6px 4px}
  .col-side .rel-ic{width:20px;height:20px}
  .col-side .rel-count{font-size:var(--fs-data-sm)}
  .col-side .rel-lift{font-size:var(--fs-micro)}
}

.rel-list{display:flex;flex-direction:column;gap:1px}
.rel-row{
  display:grid;grid-template-columns:22px minmax(90px,1.05fr) minmax(60px,2fr) 32px 46px;
  gap:10px;align-items:center;width:100%;text-align:left;padding:6px 8px;
  background:none;border:0;border-radius:7px;color:inherit;font:inherit;cursor:pointer;
}
.rel-row:hover{background:var(--surface)}
.rel-row:focus-visible{outline:1px solid var(--accent);outline-offset:-1px}
.rel-ic{
  width:22px;height:22px;border-radius:50%;overflow:hidden;display:grid;place-items:center;
  background:var(--surface);border:1px solid var(--line);
  font-size:var(--fs-micro);font-weight:700;color:var(--muted);
}
.rel-ic img{width:100%;height:100%;object-fit:cover}
.rel-name{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.rel-sym{font-size:var(--fs-data);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rel-full{font-size:var(--fs-label);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rel-barwrap{height:7px;border-radius:99px;background:var(--surface);overflow:hidden}
.rel-bar{display:block;height:100%;border-radius:99px;background:var(--accent)}
.rel-bar.stock{background:#6d7ad4}          /* tokenised stocks read differently from memecoins */
.rel-count{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data);text-align:right;cursor:help}
.rel-lift{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);color:var(--muted);text-align:right;cursor:help}
.rel-legend{margin-top:11px;padding-top:9px;border-top:1px solid var(--line);
  color:var(--muted);font-size:var(--fs-cap-sm)}

/* Function signatures are code, not label text: Solidity identifiers are
   case-sensitive, so uppercasing `mint(address,uint256)` would print a symbol
   that does not exist. This is the one mono element that stays as written. */
.flagrow .fk-ev{text-transform:none}

.audit-foot{margin-top:13px;padding-top:10px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:4px}
.audit-meta{color:var(--muted);font-size:var(--fs-cap-sm);font-family:var(--mono);letter-spacing:0;text-transform:uppercase}
.audit-gap{color:var(--muted);font-size:var(--fs-cap-sm);opacity:.8}
.spill.ok{color:var(--good)}.spill.bad{color:var(--crit)}.spill.mid{color:var(--warn)}

/* AI card */
.ai-head{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.ai-headline{font-size:var(--fs-body);font-weight:700;line-height:1.45}
.ai-flags{display:flex;flex-direction:column;gap:9px;margin-top:10px}
.ai-flag{display:flex;gap:9px;align-items:baseline;font-size:var(--fs-cap-sm);line-height:1.5}
.cites{display:inline-flex;gap:4px;flex-wrap:wrap;margin-left:6px}
.cite{
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-micro);color:var(--muted);
  border:1px solid var(--line);border-radius:5px;padding:0 5px;white-space:nowrap;
}
.ai-watch{margin:12px 0 0;padding-left:18px;color:var(--ink-2);font-size:var(--fs-data);display:flex;flex-direction:column;gap:4px}
.ai-note{color:var(--muted);font-size:var(--fs-cap-sm);margin-top:12px;border-top:1px dashed var(--line);padding-top:8px}
.bigbtn{
  width:100%;padding:10px;border-radius:9px;background:var(--accent-dim);color:var(--good);
  font-weight:700;border:1px solid transparent;
}
.bigbtn:hover{border-color:var(--accent)}
.bigbtn[disabled]{opacity:.55;cursor:default}

/* bubble map */
.bubble-wrap{position:relative;margin-top:10px}
#bubbleCanvas{width:100%;height:460px;display:block;border-radius:9px;background:var(--bg);cursor:grab}
#bubbleCanvas.dragging{cursor:grabbing}
.bubble-tip{
  position:absolute;pointer-events:none;background:var(--surface-2);border:1px solid var(--line);
  border-radius:9px;padding:8px 11px;font-size:var(--fs-data);z-index:20;max-width:260px;
  box-shadow:0 8px 24px rgba(0,0,0,.45);
}
.tip-v{font-weight:800;font-size:var(--fs-body)}
.tip-k{color:var(--muted);font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label)}
.bubble-hint{position:absolute;bottom:8px;right:12px;color:var(--muted);font-size:var(--fs-label);font-family:var(--mono);letter-spacing:0;text-transform:uppercase;pointer-events:none}
.maplegend{display:flex;gap:12px;flex-wrap:wrap;font-size:var(--fs-cap-sm);color:var(--ink-2);align-items:center}
.maplegend .lg{display:inline-flex;align-items:center;gap:5px}
.lg i{width:9px;height:9px;border-radius:50%;display:inline-block}
.lg i.sq{border-radius:2px}
.lg i.hollow{background:none !important;border:1.5px dashed var(--info)}
.cluster-strip{display:flex;gap:7px;flex-wrap:wrap;margin-top:12px}
.clchip{
  display:inline-flex;gap:7px;align-items:center;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);
  border:1px solid var(--line);border-radius:99px;padding:4px 10px;color:var(--ink-2);
}
.clchip:hover{border-color:var(--muted)}
.clchip.active{border-color:var(--accent);color:var(--ink)}
.clchip i{width:8px;height:8px;border-radius:50%}

/* wallet panel */
.wrow{display:flex;justify-content:space-between;gap:10px;font-size:var(--fs-cap-sm);padding:5px 0;border-bottom:1px dashed var(--line)}
.wrow:last-child{border-bottom:none}
.wrow .wk{color:var(--muted)}
.wrow .wv{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data);text-align:right;overflow-wrap:anywhere}

/* chart */
/* ---------------- price chart: TradingView's renderer over the Sherwood index.
   The toolbar reuses the pill vocabulary of the screener's window switch, the
   legend is the mono readout face, and the insight lines are prose captions
   because each one is a sentence, not a number. */
.tv{margin-top:10px}
.tv-bar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.tv-tfs{display:inline-flex;gap:2px;background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:2px}
.tv-btn{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);
  color:var(--muted);padding:4px 8px;border-radius:6px;border:0;background:none;cursor:pointer;
  transition:color .15s,background .15s}
.tv-btn:hover{color:var(--ink)}
.tv-btn.on{background:var(--accent);color:#000;font-weight:600}
.tv-bar>.tv-btn{border:1px solid var(--line);background:var(--surface-2)}
.tv-bar>.tv-btn.on{background:var(--accent);border-color:var(--accent)}
.tv-sep{width:1px;height:18px;background:var(--line);margin:0 2px}
.tv-select{margin-left:auto;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);
  color:var(--ink-2);background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:4px 8px;
  max-width:min(100%,280px)}
.tv-wrap{position:relative;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--surface)}
.tv-chart{height:420px;width:100%}
.tv-legend{position:absolute;top:8px;left:10px;z-index:3;display:flex;flex-wrap:wrap;gap:3px 10px;align-items:baseline;
  pointer-events:none;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);
  color:var(--muted);max-width:calc(100% - 84px)}
.tv-lg-name{color:var(--ink);font-weight:600;font-size:var(--fs-data)}
.tv-lg-name em{font-style:normal;color:var(--muted);font-weight:400;font-size:var(--fs-chip)}
.tv-lg-kv b{font-weight:400;color:var(--muted);margin-right:3px}
.tv-lg-kv i{font-style:normal;color:var(--ink-2);font-variant-numeric:tabular-nums}
.tv-lg-kv.up i{color:var(--good)}.tv-lg-kv.down i{color:var(--crit)}
.tv-lg-time{color:var(--muted)}
.tv-empty{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;text-align:center;
  padding:24px;color:var(--muted);font-size:var(--fs-body);line-height:1.5;background:rgba(10,10,10,.85);max-width:none}
.tv-insights{display:flex;flex-direction:column;gap:2px;margin-top:10px}
.tv-ins{display:flex;gap:9px;align-items:flex-start;text-align:left;padding:6px 8px;border-radius:7px;
  border:1px solid transparent;background:none;color:var(--ink-2);font:inherit;font-size:var(--fs-cap);
  line-height:1.45;cursor:pointer;width:100%}
.tv-ins:hover:not(:disabled){border-color:var(--line);background:var(--surface-2);color:var(--ink)}
.tv-ins:disabled{cursor:default}
.tv-ins .dot{flex:none;width:7px;height:7px;border-radius:50%;margin-top:6px;background:var(--muted)}
.tv-ins.tone-good .dot{background:var(--good)}.tv-ins.tone-warn .dot{background:var(--warn)}
.tv-ins.tone-crit .dot{background:var(--crit)}.tv-ins.tone-info .dot{background:var(--info)}
/* Bar panel: what happened inside the candle under the cursor. Floats on the
   side away from the cursor; a click pins it and lets the addresses be
   opened. On phones it sits under the chart instead. */
.tv-panel{position:absolute;top:34px;bottom:30px;width:min(340px,62%);z-index:5;overflow:auto;
  background:rgba(10,10,10,.94);backdrop-filter:blur(6px);border:1px solid var(--line);border-radius:10px;
  padding:10px 12px;font-size:var(--fs-cap-sm);color:var(--ink-2);line-height:1.45;pointer-events:none}
.tv-panel.at-left{left:10px}.tv-panel.at-right{right:72px}
.tv-panel.pinned{pointer-events:auto;border-color:var(--accent-dim)}
.tv-p-head{display:flex;justify-content:space-between;gap:8px;align-items:baseline;margin-bottom:6px;
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);color:var(--muted)}
.tv-p-head b{color:var(--ink);font-weight:600;font-size:var(--fs-chip)}
.tv-p-stats{display:grid;grid-template-columns:repeat(4,auto);gap:2px 10px;margin-bottom:6px;
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);color:var(--muted)}
.tv-p-stats i{font-style:normal;color:var(--ink-2)}
.tv-p-sec{font-family:var(--mono);letter-spacing:.06em;text-transform:uppercase;font-size:var(--fs-micro);color:var(--muted);
  margin:9px 0 4px;padding-top:7px;border-top:1px solid var(--line)}
.tv-p-sub{font-family:var(--mono);letter-spacing:.04em;text-transform:uppercase;font-size:var(--fs-micro);color:var(--muted);margin:7px 0 2px}
.tv-p-sum{color:var(--ink);margin-bottom:2px}
.tv-p-empty{color:var(--muted)}
.tv-row{display:flex;flex-wrap:wrap;gap:4px 7px;align-items:baseline;padding:3px 0}
.tv-row .arr{flex:none;font-family:var(--mono);font-size:var(--fs-chip)}
.tv-row.buy .arr{color:var(--good)}.tv-row.sell .arr{color:var(--crit)}
.tv-row .who{font-family:var(--mono);letter-spacing:0;text-transform:none;font-size:var(--fs-chip);color:var(--ink);flex:none}
.tv-row .who:hover{color:var(--accent)}
.tv-row .what{color:var(--ink-2)}
.tv-row .tag{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-micro);padding:1px 5px;
  border-radius:4px;border:1px solid var(--line);color:var(--muted);white-space:nowrap}
.tv-row .tag.warn{color:var(--warn);border-color:rgba(239,177,60,.45)}
.tv-row .tag.crit{color:var(--crit);border-color:rgba(237,94,79,.45)}
.tv-row .tag.good{color:var(--good);border-color:var(--accent-dim)}
.tv-row .tag.info{color:var(--info);border-color:rgba(50,114,255,.45)}
.tv-row .who-box{display:inline-flex;gap:5px;align-items:baseline;flex:none}
/* The journey chip is neutral white, not chartreuse. Chartreuse is the buy
   colour in this panel, so an accent chip on every row made a list of buys
   and sells read as if all of it were buys. */
.tv-vis{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-micro);padding:1px 6px;
  border-radius:4px;border:1px solid var(--line);background:none;color:var(--ink);cursor:pointer}
.tv-vis:hover{background:var(--ink);color:#000;border-color:var(--ink)}

/* Buy/sell filter on the bar panel. The active pill takes the semantic colour
   of what it shows rather than the accent: an accent-filled "sells" pill would
   say the opposite of what it does. */
.tv-p-sec.with-flt{display:flex;align-items:center;gap:8px}
.tv-p-flt{display:inline-flex;gap:2px;margin-left:auto;padding:2px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:7px}
.tv-p-flt button{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-micro);
  line-height:1.6;padding:1px 8px;border:0;border-radius:5px;background:none;color:var(--muted);cursor:pointer}
.tv-p-flt button:hover{color:var(--ink)}
.tv-p-flt button.on{color:#000;font-weight:600}
.tv-p-flt button.on[data-f="all"]{background:var(--ink)}
.tv-p-flt button.on[data-f="buy"]{background:var(--good)}
.tv-p-flt button.on[data-f="sell"]{background:var(--crit)}
/* resize grip under the chart */
.tv-grip{height:14px;display:flex;align-items:center;justify-content:center;cursor:ns-resize;touch-action:none;
  color:var(--line);margin-top:2px;border-radius:6px}
.tv-grip i{display:block;width:44px;height:4px;border-radius:2px;background:currentColor}
.tv-grip:hover,.tv-grip.on{color:var(--muted)}
.tv-grip.on i{background:var(--accent)}

/* ---------------- wallet journey (journey.js) */
.wj-overlay{position:fixed;inset:0;z-index:120;background:rgba(0,0,0,.72);backdrop-filter:blur(4px);
  display:flex;align-items:flex-start;justify-content:center;padding:clamp(10px,4vh,48px) clamp(8px,3vw,32px);overflow:auto}
.wj-card{width:min(1120px,100%);background:var(--surface);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 30px 80px rgba(0,0,0,.6);display:flex;flex-direction:column;max-height:calc(100vh - 20px)}
.wj-head{display:flex;justify-content:space-between;gap:12px;padding:16px 18px 12px;border-bottom:1px solid var(--line)}
.wj-eyebrow{display:block;font-family:var(--mono);letter-spacing:.08em;text-transform:uppercase;font-size:var(--fs-label);color:var(--muted)}
.wj-who{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;margin-top:4px}
.wj-who b{font-family:var(--display);font-size:var(--fs-title);color:var(--ink);letter-spacing:var(--ls)}
.wj-addr{font-family:var(--mono);letter-spacing:0;font-size:var(--fs-data-sm);color:var(--ink-2);word-break:break-all}
.wj-addr:hover{color:var(--accent)}
.wj-tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:7px}
.wj-tag{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-micro);padding:2px 7px;
  border-radius:4px;border:1px solid var(--line);color:var(--muted)}
.wj-tag.warn{color:var(--warn);border-color:rgba(239,177,60,.45)}.wj-tag.info{color:var(--info);border-color:rgba(50,114,255,.45)}
.wj-x{flex:none;width:34px;height:34px;border-radius:50%;border:1px solid var(--line);background:none;color:var(--ink-2);font-size:20px;line-height:1;cursor:pointer}
.wj-x:hover{color:var(--ink);border-color:var(--muted)}
.wj-body{padding:14px 18px 18px;overflow:auto}
.wj-loading{color:var(--muted);padding:26px 4px;font-size:var(--fs-body)}
.wj-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px;margin-bottom:14px}
.wj-kpi{display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:9px;background:var(--bg);border:1px solid var(--line);min-width:0}
.wj-kpi .k{font-family:var(--mono);letter-spacing:.08em;text-transform:uppercase;font-size:var(--fs-label);color:var(--muted)}
.wj-kpi .v{font-family:var(--display);font-weight:700;font-size:var(--fs-md);color:var(--ink);letter-spacing:var(--ls);line-height:1.2;overflow-wrap:anywhere}
.wj-kpi.good .v{color:var(--good)}.wj-kpi.crit .v{color:var(--crit)}
.wj-kpi .s{font-size:var(--fs-cap-sm);color:var(--ink-2);line-height:1.4}
.wj-status{display:inline-block;align-self:flex-start;font-family:var(--mono);letter-spacing:.04em;text-transform:uppercase;font-size:var(--fs-chip);
  padding:3px 9px;border-radius:99px;border:1px solid var(--line);color:var(--ink)}
.wj-status.good{color:var(--good);border-color:var(--accent-dim)}.wj-status.warn{color:var(--warn);border-color:rgba(239,177,60,.45)}
.wj-status.crit{color:var(--crit);border-color:rgba(237,94,79,.45)}
.wj-tl{position:relative;border:1px solid var(--line);border-radius:10px;background:var(--bg);padding:6px 4px 0;overflow:hidden}
.wj-svg{display:block;width:100%;height:auto}
.wj-pin{cursor:pointer}
.wj-tip{position:absolute;z-index:3;pointer-events:none;background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
  padding:7px 10px;font-size:var(--fs-cap-sm);color:var(--ink-2);max-width:230px;line-height:1.4;box-shadow:0 8px 24px rgba(0,0,0,.5)}
.wj-tip b{display:block;color:var(--ink);margin-bottom:2px}
.wj-ledger{margin-top:14px}
.wj-sec{font-family:var(--mono);letter-spacing:.06em;text-transform:uppercase;font-size:var(--fs-micro);color:var(--muted);margin:0 0 6px}
.wj-table{width:100%;border-collapse:collapse;font-size:var(--fs-cap-sm)}
.wj-table th{text-align:left;font-family:var(--mono);letter-spacing:.06em;text-transform:uppercase;font-size:var(--fs-micro);color:var(--muted);
  font-weight:400;padding:5px 8px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surface)}
.wj-table td{padding:5px 8px;border-bottom:1px solid var(--grid);color:var(--ink-2);white-space:nowrap}
.wj-table td.mono{font-family:var(--mono);letter-spacing:0;font-variant-numeric:tabular-nums}
.wj-table td.up{color:var(--good)}.wj-table td.down{color:var(--crit)}
.wj-table .sym{font-family:var(--mono)}
.wj-table .sym.good{color:var(--good)}.wj-table .sym.crit{color:var(--crit)}.wj-table .sym.warn{color:var(--warn)}.wj-table .sym.muted{color:var(--muted)}
.wj-ledger{max-height:300px;overflow:auto}
@media (max-width:600px){
  .tv-chart{height:300px}.tv-select{margin-left:0;width:100%}
  .tv-panel{position:static;width:auto;max-height:380px;margin:0;border-radius:0;border-width:1px 0 0;pointer-events:auto}
  .wj-overlay{padding:0}.wj-card{border-radius:0;max-height:100vh;min-height:100vh}
  .wj-table{font-size:var(--fs-micro)}
}

/* distribution */
.distbar{display:flex;height:26px;border-radius:7px;overflow:hidden;gap:2px;background:var(--bg)}
.distbar i{display:block;height:100%;min-width:1px}
.distlegend{display:flex;gap:14px;flex-wrap:wrap;margin-top:10px;font-size:var(--fs-cap);color:var(--ink-2)}
.distlegend .lg i{border-radius:2px}
.distnums{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;color:var(--muted);font-size:var(--fs-chip);margin-left:4px;font-variant-numeric:tabular-nums}

/* holder behavior */
/* Behaviour indicator tiles. Each states one number and what it implies; the
   per-class and per-bucket detail they replaced now lives in the tooltips. */
/* Fixed 3-wide rather than auto-fit: the tile count varies with the data (4-6
   depending on what the profiling found), and auto-fit kept stranding a single
   tile on its own row. Three across also gives each number room to be big. */
/* Holder-map toolbar toggle for the shared-token layer. */
.maptoggle{display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);letter-spacing:.06em;color:var(--muted);
  border:1px solid var(--line);border-radius:99px;padding:3px 10px 3px 7px;
  user-select:none;transition:color .15s,border-color .15s}
.maptoggle:hover{color:var(--accent);border-color:var(--accent-dim)}
.maptoggle input{accent-color:var(--accent);width:12px;height:12px;margin:0}
.maplegend .lg i.tok{background:transparent;border:2px solid var(--accent);border-radius:50%}

.beh-tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:10px;margin:18px 0 6px}
@media (max-width:1080px){.beh-tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:600px){.beh-tiles{grid-template-columns:1fr}}
/* The chart's indicator tiles are the behaviour panel's, deliberately: the same
   figure/bar/implication shape means a reader learns it once. One rule set
   feeds both, so they cannot drift apart. */
.beh-tile,.tv-tile{
  background:var(--surface-2);border:1px solid var(--line);border-left:3px solid var(--line);
  border-radius:11px;padding:13px 15px 14px;display:flex;flex-direction:column;gap:9px;
  min-width:0;cursor:help;
}
.beh-tile.tone-crit,.tv-tile.tone-crit{border-left-color:var(--crit)}
.beh-tile.tone-warn,.tv-tile.tone-warn{border-left-color:var(--warn)}
.beh-tile.tone-ok,.tv-tile.tone-ok{border-left-color:var(--accent)}
.bt-k{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bt-v{font-size:var(--fs-2xl);font-weight:800;line-height:1;letter-spacing:-.02em}
.beh-tile.tone-crit .bt-v,.tv-tile.tone-crit .bt-v{color:var(--crit)}
.beh-tile.tone-warn .bt-v,.tv-tile.tone-warn .bt-v{color:var(--warn)}
.beh-tile.tone-ok .bt-v,.tv-tile.tone-ok .bt-v{color:var(--accent)}
.bt-bar{display:block;height:5px;border-radius:3px;background:var(--line);overflow:hidden}
.bt-bar i{display:block;height:100%;border-radius:3px;background:var(--accent)}
.beh-tile.tone-crit .bt-bar i,.tv-tile.tone-crit .bt-bar i{background:var(--crit)}
.beh-tile.tone-warn .bt-bar i,.tv-tile.tone-warn .bt-bar i{background:var(--warn)}
.bt-sub{font-size:var(--fs-cap);line-height:1.4;color:var(--muted)}

/* Chart tiles sit under the chart and are buttons: each one focuses the chart
   on the evidence behind its number, so the tile is a way in, not just a
   readout. */
.tv-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px;margin:12px 0 4px}
button.tv-tile{text-align:left;font:inherit;color:inherit;cursor:pointer;transition:border-color .15s,background .15s}
button.tv-tile:hover{border-color:var(--muted);background:var(--surface)}
button.tv-tile:hover .bt-k{color:var(--ink-2)}
button.tv-tile.tone-crit:hover{border-left-color:var(--crit)}
button.tv-tile.tone-warn:hover{border-left-color:var(--warn)}
button.tv-tile.tone-ok:hover{border-left-color:var(--accent)}

.beh-headline{font-size:var(--fs-body);font-weight:600;line-height:1.5;max-width:72ch}
.beh-sub{color:var(--ink-2);font-size:var(--fs-body);margin-top:8px}
.beh-section{margin-top:16px}
.beh-section h4{
  margin:0 0 8px;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
}
.beh-row{display:grid;grid-template-columns:110px 36px 1fr 56px;gap:10px;align-items:center;padding:3px 0;font-size:var(--fs-data)}
.beh-label{color:var(--ink)}
.beh-n{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);color:var(--muted);text-align:right;font-variant-numeric:tabular-nums}
.minibar{height:8px;border-radius:99px;background:var(--surface-2);overflow:hidden;display:block}
.minibar i{display:block;height:100%;border-radius:99px;background:var(--accent)}
.beh-pct{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip);color:var(--ink-2);text-align:right;font-variant-numeric:tabular-nums}
.beh-foot{color:var(--muted);font-size:var(--fs-cap-sm);margin-top:14px;border-top:1px dashed var(--line);padding-top:8px}

/* holders table */
.tablewrap{overflow-x:auto;margin-top:10px}
table.holders{border-collapse:collapse;width:100%;font-size:var(--fs-data);min-width:560px}
.holders th{
  text-align:left;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-label);letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);padding:8px 10px;border-bottom:1px solid var(--line);font-weight:600;
}
.holders td{padding:7px 10px;border-bottom:1px solid var(--grid);font-variant-numeric:tabular-nums}
.holders tr:hover td{background:var(--surface-2)}
.holders .num{text-align:right;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data)}
.holders .addr{font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-data-sm)}
.holders .addr a{color:var(--ink-2)}
.holders .addr a:hover{color:var(--accent)}
.badge{
  display:inline-block;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-micro);border-radius:5px;
  padding:1px 6px;border:1px solid var(--line);color:var(--muted);margin-left:6px;white-space:nowrap;
}
.badge.warn{color:var(--warn);border-color:rgba(239,177,60,.4)}
.badge.crit{color:var(--crit);border-color:rgba(237,94,79,.4)}
.cl-ind{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);letter-spacing:0;text-transform:uppercase;font-size:var(--fs-chip)}
.cl-ind i{width:8px;height:8px;border-radius:50%;display:inline-block}

.foot{
  max-width:none;margin:0;padding:18px clamp(16px,2.2vw,40px) 40px;color:var(--muted);
  font-size:var(--fs-cap);border-top:1px solid var(--line);
}

@media (prefers-reduced-motion:no-preference){
  .tcard,.card{transition:border-color .15s ease}
}

/* Mobile type scale. Only the tokens move — every rule above already reads
   from them, so the whole system steps down in one place. Display sizes shed
   the most, captions the least: a caption is already at its readable floor. */
@media (max-width:600px){
  :root{
    --fs-hero:36px;
    --fs-2xl:26px;
    --fs-xl:22px;
    --fs-lg:20px;
    --fs-md:19px;
    --fs-title:17px;
    --fs-h2:16px;
    --fs-h3:14px;
    --fs-body:13.5px;
    --fs-cap:13px;
    --fs-cap-sm:12.5px;
    --fs-data:12px;
    --fs-data-sm:11px;
    --fs-chip:10.5px;
    --fs-label:10px;
    --fs-micro:9px;
  }
}
