/* The index page's header, shared. Extracted verbatim from index.html's "top bar" block by
   tools/… — the subpages load this so all pages wear the SAME morphing pill, not a lookalike. */
:root{
  --pos:#CCFF00;
  --pill-pad:26px; --pill-gap:30px;
  --spring:linear(0,0.0854,0.2781,0.5027,0.7108,0.8767,0.9921,1.0602,1.0903,1.0936,1.0808,1.0608,1.0397,1.0212,1.0072,0.9979,0.9929,0.9911,0.9914,0.993,0.995,0.9969,0.9985);
}
/* ── top bar ─────────────────────────────────────────── */
  /* The bar is a transparent sticky rail; .shell carries all the chrome so it can morph from a
     full-width bar into a floating pill.

     EVERY shell child is absolutely positioned. That is the whole trick: the shell's width is
     animated continuously, and absolute children are laid out against its padding box without
     participating in flow — so nothing ever reflows, nothing has to be display:none'd to get out of
     the way, and no element can snap into a new position. A flex row cannot do this: shrinking it
     re-solves the layout every frame and the items jump. */
  .bar{position:sticky;top:0;z-index:50;display:flex;justify-content:center;pointer-events:none;}
  .shell{
    pointer-events:auto;
    position:relative;
    height:62px;width:100%;
    padding-inline:var(--pad);   /* never applied to the absolute kids; read by JS to get --pad in px */
    background:transparent;
    /* Backdrop blur removed so the page's glow + grain read straight through the bar at the top,
       seamless with the rest of the page — no frosted strip, no seam where the header ends. The pill
       state stays legible on its own near-opaque fill (set per frame in render) plus its border,
       shadow and frost sheen. */
    /* No visible edge as a bar. The border exists so the PILL can fade one in — a floating surface
       needs an edge to separate it from the page; a full-width bar sitting at the top does not. */
    border:1px solid transparent;
    border-radius:0;
    /* visible, not hidden: the logo + connect glows must bloom past the pill edge on hover. The
       frost self-clips (border-radius:inherit) and the fill + backdrop-filter clip to border-radius,
       so nothing here needs a hard rectangular clip. */
    overflow:visible;
    /* No `contain:paint` here. It makes the element its own backdrop root, so backdrop-filter has
       nothing behind it to sample and silently does nothing — the pill then reads as bare text
       floating over the page. Same trap applies to filter/opacity/transform on any ancestor. */
  }
  /* The pill's gradient rides on its own layer so it can cross-fade. A background-image cannot be
     interpolated from a flat colour, so animating `background` directly would pop. */
  /* Sheen only. The pill's actual opacity is on .shell's own background-color (set per frame in
     render) — this layer just adds the top-light that sells it as glass. Kept deliberately weak so
     that if it ever failed to render, nothing about the pill's legibility would change. */
  .frost{
    position:absolute;inset:0;pointer-events:none;opacity:0;border-radius:inherit;
    background:linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,0) 58%);
  }

  /* .brand is used in the header AND the footer, so the absolute positioning MUST stay scoped to
     the shell. Applying it to `.brand` globally tore the footer logo out of the footer and left it
     floating over the page at top:50% of the viewport. */
  .shell > .brand, .shell > .nav, .shell > .next,
  .shell > .connect, .shell > .divider{position:absolute;top:50%;}
  .shell > .brand{transform:translateY(-50%);}

  .brand{display:flex;align-items:center;gap:11px;font-family:var(--display);
    font-size:20px;letter-spacing:.01em;text-transform:uppercase;white-space:nowrap;
    text-decoration:none;color:var(--bone);transition:color .18s;}
  a.brand{cursor:pointer;}
  a.brand:hover{color:var(--acc);}

  /* THE MARK. A squircle with a bullish index line knocked out of it: two peaks, the second
     overtopping the first, tail lifting. It reads as an M and as an uptrend at once.
     Inline SVG rather than an <img> so the tile can take `currentColor` and follow --acc, and so it
     costs no extra request. The line is a fixed ink because it has to contrast with the tile, not
     track it. Canonical source: site/brand/memex-logo.svg. */
  .glyph{width:36px;height:36px;flex:none;display:block;color:var(--acc);
         filter:drop-shadow(0 0 10px rgba(204,255,0,.32));
         transition:filter .32s ease;will-change:transform;transform-origin:50% 60%;}
  .glyph svg{display:block;width:100%;height:100%;}
  /* the mark lifts on hover — a small reward for it being interactive */
  a.brand:hover .glyph{filter:drop-shadow(0 0 20px rgba(204,255,0,.6)) drop-shadow(0 0 6px rgba(204,255,0,.5));}

  .nav{display:flex;gap:22px;transform:translateY(-50%);}
  .xlink{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;flex:none;
    border:1px solid var(--line);border-radius:9px;color:var(--bone-dim);background:transparent;
    transition:color .15s ease,border-color .15s ease,transform .15s ease;}
  .xlink svg{width:15px;height:15px;}
  .xlink:hover{color:var(--acc);border-color:rgba(204,255,0,.4);transform:translateY(-1px);}
  footer .xlink{width:38px;height:38px;}
  .nav a{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--bone-dim);text-decoration:none;padding:4px 0;border-bottom:1px solid transparent;
    transition:color .16s,border-color .16s;}
  .nav a:hover{color:var(--acc);border-bottom-color:var(--acc);}

  /* Mobile hamburger + dropdown — .nav is display:none <=900px, so this is the only way in there. */
  .navtoggle{display:none;}
  .shell > .navtoggle{position:absolute;top:50%;transform:translateY(-50%);}
  .navmenu{position:fixed;z-index:110;top:68px;left:12px;right:12px;
    background:var(--ink-2);border:1px solid var(--line);border-radius:14px;padding:7px;
    opacity:0;visibility:hidden;transform:translateY(-8px);
    transition:opacity .18s ease,transform .18s ease,visibility .18s;
    box-shadow:0 24px 54px -20px rgba(0,0,0,.85);}
  .navmenu.open{opacity:1;visibility:visible;transform:translateY(0);}
  .navmenu a{display:block;padding:14px 16px;border-radius:9px;text-decoration:none;
    font-family:var(--mono);font-size:12.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--bone);}
  .navmenu a:hover,.navmenu a:active{background:rgba(204,255,0,.08);color:var(--acc);}
  @media (min-width:901px){.navmenu{display:none;}}
  @media (max-width:900px){
    .navtoggle{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;
      border:1px solid var(--line);border-radius:3px;background:var(--ink-2);color:var(--bone-dim);
      cursor:pointer;pointer-events:auto;-webkit-tap-highlight-color:transparent;
      transition:border-color .18s,background .18s,color .18s;}
    .navtoggle:hover,.navtoggle[aria-expanded="true"]{border-color:var(--acc);color:var(--acc);}
    .navtoggle svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;}
  }

  /* Every value below that differs between bar and pill — padding, border alpha, background alpha,
     font-size, letter-spacing, the glow — is interpolated per frame in JS. Nothing here flips. */
  .next{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
    color:var(--bone-dim);display:flex;gap:9px;align-items:center;white-space:nowrap;
    border:1px solid var(--line);border-radius:3px;padding:0 12px;background:var(--ink-2);
    height:34px;box-sizing:border-box;transform:translateY(-50%);}
  .next b{color:var(--pos);font-weight:400;font-variant-numeric:tabular-nums;}
  /* Applied for one synchronous measurement at init, never during animation. */
  /* MUST mirror the pill-state values render() interpolates to, or the measured pill width will
     not match what is actually drawn there. */
  .next.bare{padding:0;border-color:transparent;background:transparent;
    font-size:12px;letter-spacing:.1em;}
  /* The countdown is INSIDE .next and grows in the pill, so it changes .next's width. Measuring
     the pill width without it set to the pill size gives a value that is too small, and the gap
     between the mark and the countdown collapses. */
  .next.bare b{font-size:15px;}

  /* A separate element, not a ::before, so its opacity can be driven per frame and so it never
     takes part in .next's width. */
  .divider{width:1px;height:17px;opacity:0;transform:translateY(-50%);
    background:linear-gradient(180deg,transparent,rgba(255,255,255,.20),transparent);}

  /* Matched to the timer pill: same box (7px pad + 1px border) and a min-width so the two read as an
     equal pair. The transparent border keeps the lime fill while equalising height with .next. */
  .connect{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
    background:var(--acc);color:#1A2200;border:1px solid transparent;border-radius:3px;padding:0 14px;
    min-width:150px;height:34px;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;
    cursor:pointer;font-weight:700;transform:translateY(-50%);
    transition:filter .16s,box-shadow .44s var(--spring),scale .5s var(--spring);}
  .xbar{width:34px;height:34px;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;
    background:var(--ink-2);border:1px solid var(--line);border-radius:3px;color:var(--bone);
    transform:translateY(-50%);transition:background .16s,color .16s,border-color .16s,box-shadow .44s var(--spring),scale .5s var(--spring);}
  .shell > .xbar{position:absolute;top:50%;}
  .xbar svg{width:15px;height:15px;}
  .xbar:hover{background:var(--acc);color:#1A2200;border-color:transparent;scale:1.08;
    box-shadow:0 12px 26px -8px rgba(204,255,0,.5);}
  .xbar:active{scale:.93;}
  @media (max-width:900px){.xbar{display:none;}}   /* mobile has its own X row in the menu */
  /* hover is filter-only: transform belongs to the scroll animation and the two would fight */
  .connect:hover{filter:brightness(1.1);scale:1.05;box-shadow:0 12px 26px -8px rgba(204,255,0,.5);}
  .connect:active{scale:.93;transition-duration:.12s;}

  
/* subpages mark the current page in the nav; index's nav is all anchors and never needed this */
.nav a.on{color:var(--acc);}
.navmenu a.on{color:var(--acc);}
/* header-relevant responsive rules, lifted from index's tablet/phone blocks */
@media (max-width:900px){ .nav{display:none;} }
@media (max-width:560px){
  :root{--pill-pad:18px;--pill-gap:16px;}
  #nextLabel{display:none;}
  .brand{font-size:18px;gap:9px;}
  .glyph{width:30px;height:30px;}
  .nav a{padding:8px 0;}
}
@media (max-width:380px){ :root{--pill-pad:15px;--pill-gap:12px;} .brand{font-size:17px;} }

/* ── the index page look, shared: key-light glows, film grain, scrollbar, selection ── */
html{scroll-behavior:smooth;scroll-padding-top:84px;}
body{
  background-color:var(--ink);
  background-image:
    radial-gradient(1700px 1050px at 88% -22%, rgba(204,255,0,.20), transparent 72%),
    radial-gradient(1300px 900px at -6% 4%, rgba(122,153,0,.10), transparent 72%),
    radial-gradient(1900px 1200px at 50% 128%, rgba(204,255,0,.07), transparent 70%);
  background-attachment:fixed;
}
  ::selection{background:var(--acc);color:#1A2200;text-shadow:none;}
  ::-moz-selection{background:var(--acc);color:#1A2200;text-shadow:none;}

  /* GRAIN. A tile of fractal noise (inline SVG feTurbulence — resolution-independent, no asset to
     load, no CSP concern), painted as WHITE specks whose alpha comes from the noise. On a near-black
     page an `overlay` blend has nothing to lift, so the grain must add its own light — white-alpha
     grain shows clearly on the dark ground without greying the flat blacks. Fixed, pointer-events
     none, and below the sticky bar (50) / menus (120) so the chrome stays crisp. */
  body::after{
    content:"";
    /* Oversized (200% and offset -50%) so the jitter animation can translate the tile around without
       ever exposing an edge. z-index:-1 keeps it BEHIND all content — it paints over the body's glow
       background but under every card, heading and control, so those stay crisp and only the exposed
       background is textured. */
    position:fixed; top:-50%; left:-50%; width:200%; height:200%; z-index:-1; pointer-events:none;
    /* Whiten the noise, turn it into alpha, then a gamma curve pushes the mid tones toward clear so
       the specks that remain are higher-contrast and read individually — more obvious grain, even as
       the overall opacity drops. Slightly coarser tile helps each speck register. */
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.5 0.5 0.5 0 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='gamma' amplitude='1' exponent='2.4' offset='0'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size:200px 200px;
    opacity:.10;
    will-change:transform;
    animation:grain .5s steps(1) infinite;
  }
  /* Discrete jumps, not a smooth drift — that flicker is what reads as real film grain. Transform
     only, so it composites on the GPU and costs nothing. */
  @keyframes grain{
    0%{transform:translate(0,0)} 10%{transform:translate(-6%,-4%)} 20%{transform:translate(5%,-8%)}
    30%{transform:translate(-8%,6%)} 40%{transform:translate(7%,9%)} 50%{transform:translate(-9%,-6%)}
    60%{transform:translate(9%,3%)} 70%{transform:translate(-4%,8%)} 80%{transform:translate(6%,-9%)}
    90%{transform:translate(-7%,-3%)} 100%{transform:translate(0,0)}
  }
  @media (prefers-reduced-motion:reduce){ body::after{animation:none} }

  /* ── scrollbar ───────────────────────────────────────── */
  /* Applies to the page and to the inner overflow-x containers, so a scrolling table matches. */
  html{scrollbar-width:thin;scrollbar-color:#5C7300 var(--ink);}
  ::-webkit-scrollbar{width:12px;height:12px;}
  ::-webkit-scrollbar-track{background:var(--ink);}
  ::-webkit-scrollbar-thumb{
    background:linear-gradient(180deg,#7A9900,#4D6100);
    border-radius:99px;
    /* the border is the same colour as the track, which is what makes the thumb read as inset
       rather than filling the whole gutter */
    border:3px solid var(--ink);
    background-clip:padding-box;
  }
  ::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,var(--acc),#0C8F4B);
    background-clip:padding-box;}
  ::-webkit-scrollbar-corner{background:var(--ink);}


/* ── app feel: page swaps crossfade instead of flashing, and the bar holds still ── */
@view-transition{navigation:auto;}
@media (prefers-reduced-motion:reduce){@view-transition{navigation:none;}}
/* NOT view-transition-name on header.bar: naming an element makes it a backdrop root, and the
   pill's backdrop-filter then has nothing to sample, so the frost silently disappears. The
   page crossfade below is kept; the header simply crossfades with it. */
::view-transition-old(root),::view-transition-new(root){animation-duration:.22s;}

/* Pre-engine frame == engine frame. These are exactly render(0)'s bar-state positions, so the
   first paint - and the view-transition snapshot taken from it - can never show the header's
   absolutely-positioned children stacked in a corner while the script boots. The engine's inline
   styles take over from here on every frame. */
.shell > .brand{left:var(--pad);}
.shell > .nav{left:calc(var(--pad) + 64px);}      /* pad + 36px mark + 28px gap */
.shell > .navtoggle{left:calc(var(--pad) + 50px);} /* pad + mark + 14px */
.shell > .connect{right:var(--pad);}
.shell > .xbar{right:calc(var(--pad) + 160px);}    /* pad + 150px connect + 10px */
.shell > .next{right:calc(var(--pad) + 196px);}    /* pad + connect + 12px + 34px X */

/* ── wallet menu (subpages) — lifted verbatim from index so the popup is the same object ── */
  .wmenu{position:fixed;z-index:120;width:268px;background:var(--ink-2);border:1px solid var(--line);
    border-radius:12px;padding:14px;box-shadow:0 24px 60px rgba(0,0,0,.55);
    opacity:0;visibility:hidden;transform:translateY(-6px);transition:.16s;}
  .wmenu.open{opacity:1;visibility:visible;transform:translateY(0);}
  .wmenu-addr{display:flex;align-items:center;justify-content:space-between;gap:8px;
    font-family:var(--mono);font-size:12px;color:var(--bone);}
  .wmenu-addr button{background:none;border:0;color:var(--bone-faint);cursor:pointer;padding:2px;
    display:grid;place-items:center;border-radius:4px;}
  .wmenu-addr button:hover{color:var(--acc);}
  .wmenu-bal{margin:12px 0;display:grid;gap:7px;}
  .wmenu-bal div{display:flex;justify-content:space-between;gap:10px;font-family:var(--mono);
    font-size:11.5px;color:var(--bone-faint);}
  .wmenu-bal b{color:var(--bone);font-weight:500;}
  .wmenu-lab{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
    color:var(--bone-faint);margin:0 0 7px;}
  .wmenu hr{border:0;border-top:1px solid var(--line);margin:13px 0;}
  .wmenu-note{font-family:var(--mono);font-size:10.5px;line-height:1.5;color:var(--bone-faint);
    margin:8px 0 0;min-height:15px;}
  .wmenu-note.ok{color:var(--acc);}
  .wmenu-wallet{width:100%;margin-top:13px;display:flex;align-items:center;justify-content:center;
    gap:8px;padding:11px;border-radius:8px;border:1px solid var(--acc-2);background:rgba(204,255,0,.07);
    color:var(--acc);cursor:pointer;font-family:var(--mono);font-size:11px;letter-spacing:.12em;
    text-transform:uppercase;transition:.15s;}
  .wmenu-wallet:hover{background:rgba(204,255,0,.14);border-color:var(--acc);}
  .wmenu-foot{display:flex;gap:7px;margin-top:7px;}
  .wmenu-foot a,.wmenu-foot button{flex:1;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;
    text-transform:uppercase;text-align:center;padding:9px 6px;border-radius:7px;cursor:pointer;
    border:1px solid var(--line);background:var(--ink);color:var(--bone-dim);text-decoration:none;
    transition:.15s;}
  .wmenu-foot a:hover{border-color:var(--acc);color:var(--acc);}
  .wmenu-foot button:hover{border-color:var(--flare);color:var(--flare);}
  /* .connect press = the composing scale spring in .connect:active above (weighty click) */
