/* ============================================================================
   KNULL STORE — knull.css
   The dark-eerie-golden marble theme ("Knull theme").
   Every value in here was MEASURED from the reference pictures in
   ./reference/ (pixel sampling + ink-height analysis) — do not re-eyeball.

   Ship with:  assets/marble.jpg  (histogram-matched black marble)
               knull-chart.js     (the glowing gold chart w/ lit cracks)

   Read README.md before using. The one rule that has burned us before:
   NEVER build the gold gradient border with the two-background
   (padding-box/border-box) trick on a translucent card — it bleeds the
   gradient across the whole face and washes the theme out. Use the masked
   ring below (.kn-ring pattern). Always.
   ============================================================================ */

:root{
  /* ---------- surfaces ---------- */
  --kn-black:#000000;
  /* THE page background — quilted from the reference pictures' own
     background pixels (tools/make_background.py). marble.jpg (denser veins)
     is only for the chart's ember pass. */
  --kn-marble:url("assets/background.jpg");  /* override path per app */
  --kn-fill-hi:rgba(8,7,13,.62);             /* card fill, top */
  --kn-fill-lo:rgba(4,3,7,.80);             /* card fill, bottom */
  --kn-panel-hi:rgba(4,3,7,.30);            /* outer panel fill, top */
  --kn-panel-lo:rgba(3,2,5,.46);

  /* ---------- gold family (the theme's voice) ---------- */
  --kn-gold:#8b30ef;        /* accents, active icons, live dots */
  --kn-gold-hi:#8b30ef;     /* brightest highlights, line ends, logo top */
  --kn-gold-line:#8b30ef;   /* chart line mid, gauges, donut arcs */
  --kn-gold-mid:#6b27d6;    /* link text, ring top edge */
  --kn-gold-deep:#3d1080;   /* logo bottom, deep ring */

  /* ---------- semantic: the OG Vortex neon green/red, they GLOW ---------- */
  --kn-green:#2ee6a8;       /* gains  (bright variant #54f0bd) */
  --kn-red:#f2554a;         /* losses (bright variant #ff7a70) */
  --kn-glow-green:0 0 14px rgba(46,230,168,.5);
  --kn-glow-red:0 0 14px rgba(242,85,74,.5);
  --kn-white:#ffffff;       /* headings + big numbers, always pure white */
  --kn-text:var(--z-text);        /* table/body text */
  --kn-muted:var(--z-muted);       /* labels */
  --kn-dim:var(--z-dim);         /* table headers, timeframe pills */
  --kn-faint:var(--z-dim);       /* timestamps, chevrons */
  --kn-axis:var(--z-dim);        /* chart axis labels */

  /* ---------- lines ---------- */
  --kn-grid:rgba(139,48,239,.045);         /* chart gridlines */
  --kn-row:rgba(155,130,238,.045);          /* table row dividers */
  --kn-row-strong:rgba(155,130,238,.07);

  /* ---------- ring gradients (borders) ---------- */
  --kn-ring-panel:linear-gradient(158deg,var(--z-accent) 0%,var(--z-accent-soft) 13%,var(--z-line) 40%,var(--z-card) 72%,var(--z-card) 100%);
  --kn-ring-card:linear-gradient(150deg,var(--z-accent-soft) 0%,var(--z-accent-deep) 15%,var(--z-line) 45%,var(--z-card) 76%,var(--z-card-hi) 100%);
  --kn-ring-active:linear-gradient(150deg,#6b27d6 0%,var(--z-accent-soft) 30%,var(--z-line) 70%,var(--z-line) 100%);
  --kn-ring-btn:linear-gradient(150deg,#6b27d6,var(--z-accent-deep) 60%,var(--z-raised));
  --kn-ring-soft:linear-gradient(150deg,var(--z-accent-deep),var(--z-line) 55%,var(--z-card));

  /* ---------- glows ---------- */
  --kn-glow-panel:0 0 40px -18px rgba(139,48,239,.30), 0 18px 46px -26px #000;
  --kn-glow-card:0 0 24px -18px rgba(139,48,239,.26), 0 12px 30px -24px #000;
  --kn-glow-kpi:0 0 30px -16px rgba(139,48,239,.30), 0 12px 30px -24px #000;
  --kn-glow-active:0 0 20px -8px rgba(139,48,239,.28);
  --kn-glow-hover:0 0 20px -4px rgba(139,48,239,.45);
  --kn-glow-focus:0 0 22px -6px rgba(139,48,239,.42);

  /* ---------- type (sizes measured from ink height) ---------- */
  --kn-font:"Segoe UI Variable Text","Segoe UI",Inter,system-ui,-apple-system,sans-serif;
  --kn-h1:38px;         /* page greeting, w700, ls -.6px  */
  --kn-big:31px;        /* hero money number, w600, ls -.4px */
  --kn-kpi:23px;        /* secondary hero number, w600 */
  --kn-stat:22px;       /* stat-card number, w600, ls -.2px */
  --kn-title:17px;      /* card section title, w600 */
  --kn-nav:14px;        /* sidebar items */
  --kn-label:13px;      /* card labels, table cells, pct */
  --kn-small:12.5px;    /* sub-values, buttons */
  --kn-th:11px;         /* table headers, chart axis */

  --kn-r-panel:20px; --kn-r-card:15px; --kn-r-pill:11px; --kn-r-btn:9px;
  /* --kn-r-box was used in six places by modules/brokers.js and defined in
     none, so border-radius:var(--kn-r-box) was an invalid declaration that
     browsers drop in silence -- leaving 36 elements on the Connections page
     with SQUARE corners while every .kn-box in the rest of the app is round.
     That is most of why that page read as "choppy" next to everything else.
     10px matches --z-r-box, the inner-box radius the tokens already define. */
  --kn-r-box:10px;
}

/* ============================== BASE ==================================== */
.kn-app{
  position:relative; background:var(--kn-black);
  font-family:var(--kn-font); color:var(--kn-text);
  -webkit-font-smoothing:antialiased;
}
/* one continuous marble slab behind everything + warm light top-right */
.kn-app::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:var(--kn-marble) center/cover no-repeat;
}
.kn-app::after{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(52% 38% at 82% -6%,rgba(139,48,239,.075),transparent 62%),
             radial-gradient(40% 30% at 6% 4%,rgba(139,48,239,.045),transparent 60%);
}
.kn-app>*{position:relative; z-index:1;}

.kn-app ::-webkit-scrollbar{width:9px;height:9px}
.kn-app ::-webkit-scrollbar-thumb{background:var(--z-line);border-radius:6px}
.kn-app ::-webkit-scrollbar-thumb:hover{background:var(--z-line)}
.kn-app ::-webkit-scrollbar-track{background:transparent}
.kn-app ::selection{background:rgba(139,48,239,.25); color:#fff}

/* ======================= THE MASKED RING (border) ========================
   Draws the gold gradient as a true 1px ring, so translucent fills stay
   clean. Apply the pattern to any element with a --ring variable set.     */
.kn-panel::before,.kn-box::before,.kn-nav.on::before,.kn-btn::before,
.kn-pill.on::before,.kn-input-wrap::before,.kn-menu::before,.kn-tip::before,
.kn-dock::before,.kn-datechip::before,.kn-ring::before{
  content:""; position:absolute; inset:0; border-radius:inherit; padding:1px;
  background:var(--ring,var(--kn-ring-card)); pointer-events:none; z-index:3;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
}

/* ============================== PANELS ================================== */
/* outer app frames: sidebar, main content area */
.kn-panel{
  position:relative; border-radius:var(--kn-r-panel);
  --ring:var(--kn-ring-panel);
  background:linear-gradient(180deg,var(--kn-panel-hi),var(--kn-panel-lo));
  box-shadow:var(--kn-glow-panel);
}

/* ============================== BOXES =================================== */
/* THE box. Near-black translucent face over the marble, top-lit gold ring,
   warm lift in the top-left corner, soft outer glow. */
.kn-box{
  position:relative; border-radius:var(--kn-r-card); overflow:hidden;
  --ring:var(--kn-ring-card);
  background:linear-gradient(180deg,var(--kn-fill-hi),var(--kn-fill-lo));
  box-shadow:var(--kn-glow-card);
}
.kn-box::after{           /* the warm top-left light */
  content:""; position:absolute; inset:0; border-radius:inherit;
  pointer-events:none; z-index:0;
  background:radial-gradient(52% 40% at 1% 0%,rgba(160,132,244,.055),transparent 60%),
             linear-gradient(180deg,rgba(240,200,130,.028),transparent 12%);
}
.kn-box>*{position:relative; z-index:1;}
.kn-box.kpi{box-shadow:var(--kn-glow-kpi);}       /* hero/value cards */
.kn-box.hover,.kn-box.clickable:hover{box-shadow:var(--kn-glow-hover); cursor:pointer;}

/* ============================== TYPE ==================================== */
.kn-h1   {font-size:var(--kn-h1);   font-weight:700; color:var(--kn-white); letter-spacing:-.6px; line-height:1;}
.kn-big  {font-size:var(--kn-big);  font-weight:600; color:var(--kn-white); letter-spacing:-.4px; line-height:1;}
.kn-kpi  {font-size:var(--kn-kpi);  font-weight:600; color:var(--kn-white); line-height:1;}
.kn-stat {font-size:var(--kn-stat); font-weight:600; color:var(--kn-white); letter-spacing:-.2px; line-height:1;}
.kn-title{font-size:var(--kn-title);font-weight:600; color:var(--kn-white); letter-spacing:-.1px;}
.kn-label{font-size:var(--kn-label);color:var(--kn-muted); letter-spacing:.1px;}
.kn-sub  {font-size:var(--kn-label);color:var(--kn-muted);}
.kn-tiny {font-size:var(--kn-th);   color:var(--kn-dim);}
.kn-pos  {color:var(--kn-green); text-shadow:var(--kn-glow-green);}
.kn-neg  {color:var(--kn-red);   text-shadow:var(--kn-glow-red);}
.kn-pct  {font-size:var(--kn-label);}
.kn-num  {font-variant-numeric:tabular-nums;}

/* ============================ SIDEBAR NAV =============================== */
/* inactive: quiet muted text, transparent. active: gold ring + warm fill +
   glow — the ring around it IS the "enabled" signal. Icons go gold.       */
.kn-nav{
  position:relative; display:flex; align-items:center; gap:13px;
  height:42px; padding:0 15px; border-radius:var(--kn-r-pill); cursor:pointer;
  font-size:var(--kn-nav); color:var(--kn-muted);
  background:transparent;
  transition:background .18s ease, box-shadow .18s ease, color .18s ease;
}
.kn-nav .ico{width:17px;height:17px;flex:none;color:var(--kn-muted);transition:color .18s ease;}
.kn-nav:hover{background:rgba(139,48,239,.05); color:var(--z-text);}
.kn-nav:hover .ico{color:var(--z-text);}
.kn-nav.on{
  --ring:var(--kn-ring-active);
  background:linear-gradient(180deg,rgba(22,16,38,.62),rgba(12,8,22,.50));
  box-shadow:var(--kn-glow-active);
  /* ACTIVE IS BRIGHT, NOT PURPLE. Purple was the ink here, which made the
     selected tab the hardest one on the bar to read. The lit background and
     the ring already say it is selected. */
  color:var(--kn-text);
}
.kn-nav.on .ico{color:var(--kn-muted);}

/* ============================== BUTTONS ================================= */
.kn-btn{
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  gap:7px; height:31px; padding:0 15px; border-radius:var(--kn-r-btn);
  border:0; cursor:pointer; font-family:var(--kn-font);
  font-size:var(--kn-small); color:var(--z-text);
  --ring:var(--kn-ring-btn);
  /* TWO background layers, always. The top one is a wash driven by
     --kn-btn-wash and is transparent at rest; hover only changes that variable.
     Written as a single background-image on :hover instead, it REPLACED this
     gradient rather than sitting over it, and the button lost its own face the
     moment you pointed at it. One source of truth for the base, and the hover
     rule never restates it. */
  --kn-btn-wash:transparent;
  background:linear-gradient(var(--kn-btn-wash),var(--kn-btn-wash)),
             linear-gradient(180deg,rgba(19,14,34,.78),rgba(18,12,7,.78));
  transition:box-shadow .18s, background .18s, color .18s;
}
/* brightness() was doing the hover lift here, and filter builds a compositing
   layer -- so every button's LABEL dropped to grayscale antialiasing the moment
   the pointer touched it and snapped back on the way out. On a page of buttons
   that reads as the whole UI going soft. A translucent wash plus the existing
   ring gets the same lift with no layer, so the text never moves.
   :active keeps a filter deliberately: it lasts one frame while the mouse is
   down, nobody is reading during it, and the dimming is the whole point. */
.kn-btn:hover{box-shadow:var(--kn-glow-hover);
  --kn-btn-wash:rgba(139,48,239,.16);
  color:var(--kn-text);}
.kn-btn:active{filter:brightness(.92);}
.kn-btn.quiet{--ring:var(--kn-ring-soft);}
.kn-btn.danger{color:var(--z-red-br); --ring:linear-gradient(150deg,var(--z-red-deep),var(--z-red-line) 60%,var(--z-ink-red));}

/* "View all →" style link */
.kn-link{
  display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  font-size:var(--kn-label); color:var(--kn-muted);
  transition:color .16s, gap .16s;
}
.kn-link:hover{color:var(--kn-muted); gap:9px; text-decoration:none;}

/* timeframe / segment pills: 1H 24H [7D] 30D … */
.kn-pill{
  position:relative; font-size:var(--kn-small); color:var(--kn-dim);
  padding:4px 9px; border-radius:7px; cursor:pointer;
  transition:color .16s, background .16s;
}
.kn-pill:hover{color:var(--z-text); background:rgba(139,48,239,.06);}
.kn-pill.on{
  color:var(--kn-text); --ring:var(--kn-ring-btn);
  background:linear-gradient(180deg,rgba(22,16,38,.70),rgba(12,8,22,.62));
}

/* ============================== INPUTS ================================== */
.kn-input-wrap{
  position:relative; display:flex; align-items:center; gap:9px;
  height:37px; padding:0 13px; border-radius:10px;
  --ring:var(--kn-ring-soft);
  background:linear-gradient(180deg,rgba(9,7,14,.62),rgba(5,4,8,.74));
  transition:box-shadow .2s;
}
.kn-input-wrap:focus-within{box-shadow:var(--kn-glow-focus);}
.kn-input-wrap input{
  flex:1; background:none; border:0; outline:0;
  color:var(--z-text); font-size:14px; font-family:var(--kn-font);
}
.kn-input-wrap input::placeholder{color:var(--z-faint);}

/* toggle switch — gold when on (use green fill for buy/safety switches) */
.kn-toggle{
  position:relative; width:38px; height:21px; border-radius:11px; cursor:pointer;
  background:rgba(255,255,255,.07); border:1px solid rgba(255,255,255,.12);
  transition:.2s; flex:none;
}
.kn-toggle::after{
  content:""; position:absolute; top:2px; left:2px; width:15px; height:15px;
  border-radius:50%; background:var(--kn-faint); transition:.2s;
}
.kn-toggle.on{background:rgba(139,48,239,.26); border-color:rgba(139,48,239,.5);}
.kn-toggle.on::after{left:19px; background:var(--kn-gold);}
.kn-toggle.on.green{background:rgba(46,230,168,.22); border-color:rgba(46,230,168,.5);}
.kn-toggle.on.green::after{background:var(--kn-green); box-shadow:0 0 8px rgba(46,230,168,.6);}

/* ============================== TABLES ================================== */
.kn-table{width:100%; border-collapse:collapse;}
.kn-table thead th{
  font-size:var(--kn-th); font-weight:400; color:var(--kn-dim);
  text-align:right; padding:0 0 9px; letter-spacing:.2px;
}
.kn-table thead th:first-child{text-align:left;}
.kn-table tbody td{
  font-size:var(--kn-label); color:var(--kn-text); text-align:right;
  padding:9px 0; border-top:1px solid var(--kn-row);
}
.kn-table tbody td:first-child{text-align:left;}
.kn-table tbody tr{transition:background .15s;}
.kn-table tbody tr:hover{background:rgba(139,48,239,.055);}
.kn-table .sym{color:var(--kn-white);}

/* round token avatar + rank number */
.kn-av{width:22px;height:22px;border-radius:50%;flex:none;display:inline-flex;
       align-items:center;justify-content:center;font-size:12px;line-height:1;}
.kn-rank{color:var(--kn-dim);font-size:12px;width:14px;display:inline-block;}

/* circled up/down icons for buy/sell rows (finance ref) */
.kn-chip-up,.kn-chip-down{
  width:26px;height:26px;border-radius:50%;flex:none;display:inline-flex;
  align-items:center;justify-content:center;font-size:12px;
}
.kn-chip-up{color:var(--kn-green);border:1px solid rgba(46,230,168,.4);
  background:rgba(46,230,168,.08);box-shadow:0 0 12px -4px rgba(46,230,168,.5);}
.kn-chip-down{color:var(--kn-red);border:1px solid rgba(242,85,74,.45);
  background:rgba(242,85,74,.08);box-shadow:0 0 12px -4px rgba(242,85,74,.5);}

/* ========================= SMALL DATA VIZ =============================== */
/* semicircle gauge + donut are drawn with the recipes in knull-chart.js;
   these are the supporting bits */
.kn-progress{height:6px;border-radius:3px;background:var(--z-line);overflow:hidden;}
/* The fill ended on the ramp's MID stop and held it for the last 40% of the
   bar, so a long bar was a wide band of #8b30ef -- the brightest single area of
   purple anywhere in the app, and the thing that reads as pink on Landon's
   display. It now runs deep to fill and stops there, which is where the
   wordmark ends too. */
.kn-progress i{display:block;height:100%;border-radius:3px;
  background:linear-gradient(90deg,#2a0b5c,#6b27d6);}

/* live pulsing dot */
.kn-dot{width:5px;height:5px;border-radius:50%;display:inline-block;
  background:var(--kn-gold);box-shadow:0 0 8px var(--kn-gold);
  animation:kn-pulse 1.8s ease-in-out infinite;}
.kn-dot.green{background:var(--kn-green);box-shadow:0 0 10px var(--kn-green);}
@keyframes kn-pulse{0%,100%{opacity:1}50%{opacity:.25}}

/* calendar / event date chip (finance ref, Upcoming Events) */
.kn-datechip{
  position:relative; width:44px; border-radius:10px; text-align:center;
  padding:5px 0 6px; --ring:var(--kn-ring-soft);
  background:linear-gradient(180deg,rgba(19,14,34,.7),rgba(18,12,7,.7));
}
.kn-datechip b{display:block;font-size:10px;letter-spacing:.12em;color:var(--kn-muted);font-weight:600;}
.kn-datechip span{display:block;font-size:16px;font-weight:600;color:var(--kn-white);margin-top:1px;}

/* ========================= OVERLAYS ==================================== */
.kn-tip{                                   /* chart tooltip chip */
  position:absolute; z-index:5; pointer-events:none;
  background:rgba(12,8,5,.95); border-radius:9px; padding:7px 11px;
  --ring:linear-gradient(150deg,rgba(107,39,214,.55),rgba(60,44,28,.55));
  font-size:12px; color:var(--z-text); white-space:nowrap;
  box-shadow:0 8px 26px rgba(0,0,0,.7);
}
.kn-tip b{color:#fff;font-weight:600;}

.kn-toast{
  position:fixed; left:50%; bottom:26px; transform:translate(-50%,14px); z-index:40;
  background:rgba(14,10,7,.96); color:var(--z-text);
  border:1px solid rgba(139,48,239,.42); border-radius:11px;
  padding:9px 17px; font-size:var(--kn-label); opacity:0; pointer-events:none;
  transition:opacity .18s, transform .18s; white-space:nowrap;
  box-shadow:0 10px 34px rgba(0,0,0,.7);
}
.kn-toast.show{opacity:1; transform:translate(-50%,0);}

.kn-menu{
  position:absolute; z-index:30; min-width:210px; border-radius:13px; padding:7px;
  background:rgba(9,7,14,.97);
  --ring:linear-gradient(150deg,rgba(107,39,214,.45),rgba(40,30,19,.45));
  box-shadow:0 20px 50px rgba(0,0,0,.8);
  opacity:0; transform:translateY(-6px); pointer-events:none;
  transition:opacity .16s, transform .16s;
}
.kn-menu.show{opacity:1; transform:translateY(0); pointer-events:auto;}
.kn-menu .mi{padding:9px 11px; border-radius:8px; font-size:var(--kn-label);
  color:var(--z-text); cursor:pointer; display:flex; align-items:center; gap:10px;}
.kn-menu .mi:hover{background:rgba(139,48,239,.09); color:#fff;}
.kn-menu .mh{padding:8px 11px 6px; font-size:var(--kn-th); color:var(--kn-faint); letter-spacing:.4px;}

/* bottom dock (portrait/tablet ref): panel strip w/ centered logo notch */
.kn-dock{
  position:relative; display:flex; align-items:center; justify-content:space-around;
  height:64px; border-radius:16px;
  --ring:var(--kn-ring-panel);
  background:linear-gradient(180deg,var(--kn-panel-hi),var(--kn-panel-lo));
  box-shadow:var(--kn-glow-panel);
}
.kn-dock .kn-nav{height:48px;flex-direction:column;gap:5px;font-size:11px;padding:0 13px;}
.kn-dock .kn-nav .ico{width:19px;height:19px;}

/* ====================== MOTION / TRANSITIONS ============================ */
/* Pages cross-fade. NO loading screens, NO data-rain — clean fades only. */
.kn-page{opacity:0; pointer-events:none; transition:opacity .22s ease;}
.kn-page.on{opacity:1; pointer-events:auto;}
.kn-fade-in{animation:kn-fade .28s ease both;}
@keyframes kn-fade{from{opacity:0}to{opacity:1}}
