:root{
  --ground:#07080a; --alt:#060709; --card:#101114; --card-stroke:#1b1c1f; --card2:#07080a; --card-border:#222535;
  --lime:#abdc69; --lime-text:#0e0e12; --mint:#c9ffc8; --teal:#75c5a4; --teal-dark:#3b8d76;
  --muted:#3c3c3d; --muted2:#484848; --tab-bg:#1d1d28; --tab-active:#04797f; --white:#fff;
  --ease-out:cubic-bezier(0.23,1,0.32,1); --ease-in-out:cubic-bezier(0.77,0,0.175,1);
  --sans:Jost,-apple-system,"Segoe UI",sans-serif; --word:"Contrail One",var(--sans);
}
*{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:0;scroll-snap-type:y mandatory}
/* the slide deck (Chris, 18 Sep): the page snaps from section to section, never resting in between; every section is a full
   screen (the lore is two stops: closed and open). scroll-snap-stop keeps a big flick from skipping a slide. Each section clears
   the 60px fixed bar with its own top padding, so the snap lines sit at 0. Phones snap the same way (the block at the end of
   this file sizes each phone slide to one screen); their menu taps jump instead of gliding, so scroll-behavior is auto there. */
.hero,#lore,#memes,#token,#library,#faq{scroll-snap-align:start;scroll-snap-stop:always}
.loreend{position:absolute;left:0;right:0;bottom:0;height:1px;scroll-snap-align:end;scroll-snap-stop:always}
#sitefoot{scroll-snap-align:end}
/* phones (Chris, 19 Sep): no slide deck at all - plain sections that scroll the way a phone normally scrolls. The menu
   still jumps straight to a section (js/app.js "where the page's anchors land"), so scroll-behavior stays auto here. */
@media(max-width:900px){html{scroll-snap-type:none;scroll-behavior:auto}}
body{background:var(--ground);color:var(--white);font-family:var(--sans);line-height:1.4}
img{max-width:100%;display:block}
a{color:inherit}
button{font-family:inherit;color:inherit}
::selection{background:var(--lime);color:var(--lime-text)}
:focus-visible{outline:2px solid var(--lime);outline-offset:3px}  /* no border-radius here: it would override each element's own corners */

.wrap{max-width:1346px;margin:0 auto;padding:0 22px}
.sect{padding:88px 0}
#create{padding:clamp(80px,7.35vw,127px) 0 clamp(100px,9.95vw,172px)}
#library{padding:clamp(70px,5.8vw,100px) 0 clamp(90px,8.8vw,152px)}
#faq{padding:90px 0 clamp(60px,8vw,120px)}   /* 90 clears the fixed bar on every screen */
#agreement{padding:0}
.altbg{background:var(--alt)}
.librarysect{background:var(--card2)}
@media(max-width:700px){.sect{padding:56px 0}}

.card{border:2px solid var(--card-stroke);border-radius:12px;background:var(--card);
  box-shadow:inset 4px 4px 24px rgba(0,0,0,.7)}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:46px;
  border:none;border-radius:10px;padding:0 22px;font-family:var(--sans);font-size:16px;
  font-weight:500;text-transform:uppercase;text-decoration:none;cursor:pointer;text-align:center;
  box-shadow:4px 4px 15px rgba(0,0,0,.25);
  /* this is the EXIT timing; :hover sets the slower enter. movement ease-out, colour ease */
  transition:transform 150ms var(--ease-out),background-color 150ms ease,
    color 150ms ease,box-shadow 150ms var(--ease-out)}
.btn:active{transform:scale(.97);transition-duration:100ms}
.btn.primary{background:var(--lime);color:var(--lime-text)}
.btn.secondary{background:var(--teal-dark);color:var(--white)}  /* Chris's call: the brand teal reads better on the scene; white on it is 3.9:1, under the 4.5 bar */
.btn.full{width:100%}
.btn.sm{height:40px;padding:0 20px;font-size:15px}
@media(hover:hover) and (pointer:fine){
  .btn:hover{transform:translateY(-2px);box-shadow:4px 8px 20px rgba(0,0,0,.3);transition-duration:200ms}
  /* pressing a hovered button has to out-specify :hover, or the press never shows */
  .btn:hover:active{transform:translateY(-2px) scale(.97);transition-duration:100ms}
  .btn.primary:hover{background:#bce97a}
  .btn.secondary:hover{background:#46a084}
}

/* nav */
#nav{position:fixed;top:0;left:0;right:0;z-index:50;height:60px;transition:background-color 200ms var(--ease-out),backdrop-filter 200ms var(--ease-out)}
#nav.solid{background:rgba(7,8,10,.85);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}   /* the prefix: iOS before 18 only knows the -webkit- form */
.navrow{height:60px;display:flex;align-items:center;gap:20px;max-width:none;padding:0 2.55% 0 4.2%}
.word{display:inline-flex;align-items:center;text-decoration:none;line-height:0}
.word .logo{width:169px;height:27px}
.word.small .logo{width:140px;height:auto}
.navlinks{display:flex;align-items:center;gap:40px;margin-left:auto}
.navlinks a:not(.btn){font-size:16px;font-weight:500;text-transform:uppercase;text-decoration:none;color:var(--white);
  transition:color 160ms var(--ease-out)}
.navlinks a:not(.btn).here::after{content:"";position:absolute;left:0;right:0;bottom:-7px;height:2px;background:var(--mint)}   /* Chris (18 Sep): the section you are in, underlined in mint (js/app.js "navHere") */
.navlinks a:not(.btn){position:relative}
@media(hover:hover) and (pointer:fine){.navlinks a:not(.btn):hover{color:var(--mint)}}
.navbuy{height:28px;width:139px;padding:0;border-radius:10px;font-size:13px;margin-left:-6px}  /* the BUY pill lives in the link list (phones need it in the menu); -6px keeps its old 34px gap after FAQ */
.navtoggle{display:none;background:none;border:none;color:var(--white);cursor:pointer;padding:6px;line-height:0}

/* phones: the menu is a panel under the bar (Chris's mockup): near-black, thin teal line, big corners; the items stack
   with dividers, the picked one turns lime with its words under it, and the BUY pill sits at the bottom */
@media(max-width:900px){
  .navlinks{position:absolute;top:60px;left:24px;right:24px;background:rgba(7,8,10,.9);border:1px solid var(--teal);border-radius:26px;
    flex-direction:column;align-items:stretch;gap:0;padding:4px 26px 28px;margin-left:0;
    display:none}
  .navlinks.open{display:flex}
  .navlinks a:not(.btn){padding:18px 0;border-bottom:1px solid #2b2d31}
  .navlinks a:not(.btn).here{color:var(--lime)}
  .navlinks a:not(.btn).here::after{display:none}   /* the phone menu marks the section in lime, not with a line: the items already carry dividers */
  .navlinks a.navtoken{display:none}   /* TOKEN is left out of the phone menu: the BUY pill goes to the same place (mockup) */
  .navlinks .navbuy{align-self:flex-start;margin:32px 0 0;width:auto;padding:0 17px}
  .navtoggle{display:inline-flex;margin-left:auto}   /* the three bars sit at the right edge */
}

/* hero */
.hero{position:relative;overflow:hidden;min-height:620px;height:100vh;height:100svh;  /* no footer: the scene is the whole page */
  box-shadow:10px 4px 74px rgba(0,0,0,.85)}
.herolayers{position:absolute;top:0;right:0;height:105.7%;min-width:125.6%;aspect-ratio:3336/1425;pointer-events:none}  /* Figma: three 2170x927 layers at (-442,0) in a 1728 frame; the hero shows the top 877 */
.herobg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:right top}
.heroshade{position:absolute;inset:0;background:linear-gradient(90deg,#000 0%,rgba(0,0,0,.92) 10%,rgba(0,0,0,.81) 20%,rgba(0,0,0,.67) 30%,rgba(0,0,0,.53) 40%,rgba(0,0,0,.39) 50%,rgba(0,0,0,.25) 60%,rgba(0,0,0,.13) 70%,rgba(0,0,0,.04) 80%,rgba(0,0,0,0) 86%)}  /* the Figma "Overlay 1" PNG, sampled every 10% */
.heroape{position:absolute;right:0;bottom:0;width:52.4%;height:auto}  /* the ape cropped to its bounding box, 1520x993 of the 3336x1425 layer; 52.4 = the Figma 45.56% + 15% (Chris, 18 Sep) */
/* hero ambient motion: the city drifts around behind the ape; the ape slowly leans in, then back. transform only. */
.herobg{transform-origin:50% 50%;will-change:transform;animation:herodrift 60s ease-in-out infinite alternate}
.heroape{transform-origin:50% 55%;will-change:transform;animation:heroclose 20s ease-in-out infinite alternate}  /* Chris: 20s in, 20s back; the 60s background no longer mirrors it exactly */
@keyframes herodrift{  /* pans the full hidden slack (25.6% of the hero = 20.4% of this image is off the left edge) while
  zooming out 1.1 -> 1 as the ape leans in (1 -> 1.12); at scale 1 the pan ends with the image's left edge on the hero's */
  from{transform:translateX(0) scale(1.1)}
  to{transform:translateX(20%) scale(1)}
}
@keyframes heroclose{from{transform:scale(1)}to{transform:scale(1.06)}}   /* Chris (18 Sep): 6%, halved from 12% - shared by the hero ape and the token ape */
@media(prefers-reduced-motion:reduce){.herobg,.heroape{animation:none}}
.herocontent{position:relative;height:100%;display:flex;flex-direction:column;align-items:flex-start;
  justify-content:flex-start;padding-top:clamp(100px,9.6vw,165px);padding-left:calc(22px + 2.95vw);gap:0}  /* Figma: copy column starts x=242 (wrap edge 191 + 51); the tag no longer sits above the headline */
.herocontent h1{font-weight:700;font-size:clamp(27px,2.76vw,47.7px);line-height:1.22;letter-spacing:.005em;text-transform:uppercase;max-width:16.4em;margin:0}   /* Chris (18 Sep): all caps, two lines; 10% under the first caps size so the ape can grow. Figma: wraps after "this". Drop shadow removed 18 Sep to match the lore/membership copy, which has none */
.herocontent h1 em{font-style:italic;font-weight:900;color:var(--lime)}
.herosub{font-weight:700;font-style:italic;white-space:nowrap;color:var(--mint);margin:clamp(4px,.58vw,10px) 0 clamp(28px,3.36vw,58px);
  font-size:min(clamp(22px,2.617vw,45.22px),calc((97vw - 46px) / var(--subk,21)));}   /* one line at every width until app.js "hero subtitle" sizes it to end where the headline's longest line ends */
.herobtns{display:flex;gap:20px;flex-wrap:wrap;margin:0}
.herotag{font-weight:700;font-size:18px;color:var(--mint);margin:clamp(40px,4.3vw,74px) 0 0}  /* Chris (17 Sep): under the buttons, mint */
@media(max-width:600px){.herobtns{gap:16px}.hero{min-height:520px}}

/* headings/body helpers */
.h2{font-weight:700;font-size:clamp(30px,4.05vw,70px);color:var(--mint);opacity:.8;line-height:1.1}
.h2.center{text-align:center}
.h2.left{text-align:left}
.h2.sm{font-size:clamp(26px,2.9vw,50px)}
.h2.sm.tight{font-size:clamp(22px,2.46vw,42.5px)}  /* agreement: 50px less 15%, holds one line */
.h2 .white{color:var(--white);opacity:1}
.h2 .mint{color:var(--mint)}
.lead{font-weight:500;font-size:clamp(16px,1.85vw,32px);color:var(--white);opacity:.8;max-width:1237px;margin-left:auto;margin-right:auto;
  text-align:center;max-width:1237px;margin:18px auto 0}
.sub{font-weight:700;font-size:clamp(18px,1.9vw,32.9px);color:var(--white);margin-top:14px}
.body{font-weight:500;font-size:clamp(16px,1.5vw,26.4px);color:var(--white);opacity:.8;margin-top:16px}

/* creator card */
.creator{margin-top:clamp(40px,4.6vw,80px);padding:30px 47px 40px;position:relative}
.cardlabel{display:block;font-weight:700;font-size:16px;color:var(--muted2);text-transform:uppercase;margin-bottom:22px}
.creatorheader{display:grid;grid-template-columns:minmax(0,600px) 1fr;gap:36px}
.creatorheader .cardlabel{margin-bottom:22px}
.creatorgrid{display:grid;grid-template-columns:minmax(0,600px) 1fr;gap:36px;align-items:stretch}
.creatorleft{display:flex;flex-direction:column;gap:16px}
.stage{position:relative;border-radius:8px;overflow:hidden;aspect-ratio:1200/675;background:#000;
  border:2px solid #363E46}
.stage .layer{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:opacity 260ms var(--ease-out),filter 260ms var(--ease-out)}
.stage .layer.out{opacity:0;filter:blur(4px)}
#cap{position:absolute;left:56.6%;right:3.4%;top:15%;color:#fff;font-weight:500;
  font-size:calc(clamp(10px,2.05vw,25px) * var(--fit,1));line-height:1.55;overflow-wrap:anywhere;white-space:pre-wrap}  /* show Enter line breaks, like the download does */
#stamp{position:absolute;right:3.4%;top:6.5%;font-family:var(--sans);font-weight:500;
  font-size:clamp(6px,.85vw,10px);letter-spacing:.16em;color:rgba(255,255,255,.5);
  transition:transform 220ms var(--ease-out),color 220ms var(--ease-out)}
.stage .sweep{position:absolute;left:50.4%;right:0;top:0;bottom:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 0%,rgba(171,220,105,.16) 48%,transparent 100%);
  transform:translateY(-100%);opacity:0}
.stage.filing .sweep{animation:sweep 620ms var(--ease-in-out)}
.stage.filing #stamp{transform:scale(1.14);color:var(--lime)}
@keyframes sweep{0%{transform:translateY(-100%);opacity:1}100%{transform:translateY(100%);opacity:0}}

.creatorright{position:relative;min-height:260px}
.apes{position:absolute;inset:0;display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:max-content;align-content:start;gap:8px;overflow-y:auto;padding:2px;scrollbar-width:thin;scrollbar-color:var(--teal-dark) var(--tab-bg)}
.apes::-webkit-scrollbar{width:10px}
.apes::-webkit-scrollbar-track{background:var(--tab-bg);border-radius:99px}
.apes::-webkit-scrollbar-thumb{background:var(--teal-dark);border-radius:99px;border:2px solid var(--tab-bg);transition:background 160ms var(--ease-out)}
@media(hover:hover) and (pointer:fine){.apes::-webkit-scrollbar-thumb:hover{background:var(--teal)}}
.apes button{padding:0;border:2px solid transparent;border-radius:6px;background:none;cursor:pointer;
  overflow:hidden;line-height:0;transition:border-color 160ms var(--ease-out),transform 160ms var(--ease-out)}
.apes img{width:100%;aspect-ratio:1/1;object-fit:cover;object-position:50% 22%}
.apes button[aria-pressed=true]{border-color:var(--lime)}
.apes button:active{transform:scale(.96)}
@media(hover:hover) and (pointer:fine){.apes button:hover{border-color:var(--teal)}}

textarea{width:100%;min-height:93px;resize:vertical;background:#09090a;border:2px solid var(--teal-dark);
  border-radius:12px;color:var(--white);font-family:var(--sans);font-weight:600;font-size:24px;
  padding:14px 18px;transition:border-color 160ms var(--ease-out),box-shadow 160ms var(--ease-out)}
textarea::placeholder{color:rgba(255,255,255,.3)}
textarea:focus{outline:none;border-color:var(--lime);box-shadow:0 0 0 3px rgba(171,220,105,.14)}

@media(max-width:880px){.creatorheader{grid-template-columns:1fr;gap:0}.creatorheader .cardlabel:first-child{margin-bottom:8px}.creatorgrid{grid-template-columns:1fr}.creator{padding:24px}}

/* token (18 Sep, Chris's bar scene, assets in Desktop/Site Assets 2/Tokan section): one full screen. Three layers on one
   box - the bar room blurred 5px, Chris's dark gradient (clear on the left, black on the right), and the ape + counter
   cut-out (the same pixel size as the room, so both `cover` the box identically and stay aligned) - with the copy on
   the right, over the dark side. The ids and the .cabox/.copybtn/#tokenbtn wiring are the launch-day switch's (app.js). */
.tokensect{position:relative;padding:0;height:100vh;height:100svh;min-height:640px;overflow:hidden;background:#000;display:flex;align-items:center}
.tokenscene{position:absolute;inset:0}
.tokenscene>div{position:absolute;inset:0;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}   /* longhands: a `background:` shorthand here would reset each layer's image */
/* ambient motion, on the hero's clock (Chris): the room drifts sideways while zooming out over 60s, the ape leans in over 20s,
   both easing in and out and reversing. The bar image has no hidden slack like the hero's city does, so the room's pan is
   4% (what a 1.1 zoom frees up) instead of the hero's 20%; it hangs 2% past each edge so the blur never shows a soft border. */
.tokenscene .tokenbar{background-image:url(../img/token/bar.webp);filter:blur(3px);   /* Chris: 5px was too much */
  inset:-2%;will-change:transform;animation:tokendrift 60s ease-in-out infinite alternate}
@keyframes tokendrift{from{transform:translateX(-4%) scale(1.1)}to{transform:translateX(0) scale(1)}}
.tokenscene .tokendark{background-image:url(../img/token/dark.webp);background-size:100% 100%}
.tokenscene .tokenape{background-image:url(../img/token/ape.webp);transform-origin:50% 100%;will-change:transform;
  animation:heroclose 20s ease-in-out infinite alternate}   /* the hero ape's exact lean-in (1 -> 1.06 over 20s, back over 20s), grown from the counter so the bar stays put */
@media(prefers-reduced-motion:reduce){.tokenscene .tokenbar,.tokenscene .tokenape{animation:none}}
.tokensect .wrap{position:relative;z-index:1;width:100%}
.tokencopy{margin-left:auto;width:min(100%,560px)}   /* right-aligned in the wrap: starts ~57% across, like the lore's column */
.tokenh2{font-size:clamp(28px,3.6vw,58px);line-height:1.3;color:var(--white);opacity:1;
  text-shadow:3.2px 3.2px 7.9px rgba(0,0,0,.55)}
.cabox{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:25px;height:auto;min-height:74px;
  border:2px solid var(--teal-dark);border-radius:12px;background:rgba(9,9,10,.5);padding:14px 20px}
.cabox span{font-weight:500;font-size:20px;color:var(--white)}
.cabox code{font-weight:500;font-size:18px;color:var(--lime);word-break:break-all;font-family:ui-monospace,monospace}
.copybtn{margin-left:auto;display:inline-flex;align-items:center;gap:6px;background:none;border:none;
  color:var(--teal);cursor:pointer;padding:4px;border-radius:6px;position:relative;
  transition:color 160ms var(--ease-out),transform 160ms var(--ease-out)}
.copybtn:active{transform:scale(.94)}
.copybtn .ic-copy,.copybtn .ic-check{transition:opacity 160ms var(--ease-out)}
.copybtn .copied{font-size:13px;font-weight:500;color:var(--lime);opacity:0;transition:opacity 160ms var(--ease-out)}
.copybtn.done .copied{opacity:1}
@media(hover:hover) and (pointer:fine){.copybtn:hover{color:var(--mint)}}
.tokenlede{font-weight:600;font-size:clamp(14px,1.5vw,24.4px);color:var(--white);margin-top:25px;max-width:56ch}
.tokencopy .body{max-width:56ch;margin-top:16px;font-weight:400;font-size:clamp(12.8px,1.2vw,21.12px);opacity:1}
.tokencopy .btn{margin-top:40px}
@media(max-width:900px){   /* phones: the scene fills the top 58% of the screen with the ape framed (a landscape image `cover`ing a
  portrait box would blow him up to face size), fading to black at its foot; the copy sits on the black below it.
  (19 Sep: the phone deck block at the end of this file brings the scene down to 46% so the whole section is one screen) */
  .tokensect{height:auto;min-height:100svh;display:block}
  .tokenscene{bottom:auto;height:58svh}
  .tokenscene>div{background-position:30% 50%}
  .tokendark{display:none}
  .tokenscene::after{content:"";position:absolute;inset:0;pointer-events:none;   /* a scrim over the top of the bar so the headline reads there, and solid black before the band ends so there is no seam */
    background:linear-gradient(180deg,rgba(0,0,0,.66) 0%,rgba(0,0,0,.42) 16%,rgba(0,0,0,0) 34%),linear-gradient(180deg,rgba(0,0,0,0) 42%,#000 93%)}
  .tokensect .wrap{padding-top:calc(58svh - 70px);padding-bottom:48px}
  .tokencopy{width:100%}
}
@media(max-width:700px){.cabox{flex-direction:column;align-items:flex-start}.copybtn{margin-left:0}}

/* memes hub (18 Sep, Chris's mock): "Let there be memes." over two cards that jump to the library and the lab. Measured
   off the mock at 2000 wide -> 1728: heading 82px, cards 598 wide with a 60px gap, titles 45px mint, body 19px. The lab
   card is two layers - the room with the ape painted out, and the cut-out ape - so on hover the ape leans in while the
   room eases back. The library card is one flat image until Chris cuts its ape out too. */
#memes{padding:clamp(70px,6.9vw,120px) 0 clamp(80px,7.5vw,130px)}
.memesh2{font-weight:700;font-size:clamp(38px,4.75vw,82px);line-height:1.1;text-transform:uppercase;text-align:center;margin:0 0 clamp(36px,4.6vw,80px)}
.memesh2 .white{color:var(--white)}
.memesh2 .mint{color:var(--mint)}
.memecards{display:grid;grid-template-columns:repeat(2,minmax(0,598px));justify-content:center;gap:clamp(28px,3.5vw,60px)}
.memecard{display:block;text-decoration:none;text-align:center;color:var(--white);border-radius:20px}
.memeart{position:relative;display:block;aspect-ratio:992/624;border-radius:20px;overflow:hidden;background:#050505;isolation:isolate}   /* Figma Frame 6 is 992x624 */
.memebg,.memefig{position:absolute;inset:0;background:center/cover no-repeat;transition:transform 500ms var(--ease-out),filter 500ms ease}
.memebg{transform:scale(1.08)}   /* at rest the room sits a little large, so on hover it can settle back */
.memefig{transform-origin:50% 100%;bottom:-2px}   /* anchored to the bottom, and 2px past the card's edge so sub-pixel rounding never shows the room under the ape */
/* library card: both layers placed exactly as Figma Frame 7 (29:13, 992x624) has them - each image 1092x700, the room at
   -70,-38 and the ape at -60,-66 - so the frame IS the rest state; on hover the room shrinks by the same ratio the lab's does */
.art-library .memebg{background-image:url(../img/memes/library-bg.webp);background-size:100% 100%;inset:auto;left:-7.06%;top:-6.09%;width:110.08%;height:112.18%;transform:none}
.art-library .memefig{background-image:url(../img/memes/library-ape.webp);background-size:100% 100%;inset:auto;left:-6.05%;top:-10.58%;width:110.1%;height:112.18%}
.art-lab .memebg{background-image:url(../img/memes/lab-bg.webp)}
.art-lab .memefig{background-image:url(../img/memes/lab-ape.webp)}
.memeglow{position:absolute;left:19.4%;top:14.4%;width:55.4%;aspect-ratio:1;border-radius:50%;opacity:0;transition:opacity 500ms ease;   /* Frame 6's "Back Light SHine": 550px circle at 192,90 */
  background:radial-gradient(circle closest-side,#c9ffc8 0%,rgba(201,255,200,0) 97%)}
.art-library .memeglow{left:17.6%;top:22.4%;width:45%}   /* Frame 7: 446px circle at 175,140 */
.memetitle{display:block;margin-top:clamp(18px,2.3vw,40px);font-weight:700;font-size:clamp(26px,2.6vw,45px);line-height:1.1;text-transform:uppercase;color:var(--mint);
  text-shadow:4px 4px 10px rgba(0,0,0,.5)}
.memebody{display:block;margin:14px auto 0;max-width:37ch;font-weight:400;font-size:clamp(16px,1.15vw,20px);line-height:1.5}
/* the way in (Chris, 19 Sep): on a phone nothing said the card was tappable. A span, not a button - the whole card is
   already the link - and pointer-events:none so every tap lands on the card and the card's own hover drives the button. */
.memebtn{margin-top:clamp(14px,1.5vw,22px);pointer-events:none}
@media(hover:hover) and (pointer:fine){
  /* Chris (18 Sep): the room eases back and blurs (Figma's 3.5px on a 992 frame, scaled to the ~600px card) while the ape
     steps forward a touch. 1.02 not 1 keeps the blur's soft edge outside the card. Back-light at 50%. */
  .memecard:hover .memebg{transform:scale(1.02);filter:blur(2.2px)}
  .memecard:hover .art-library .memebg{transform:scale(.945)}   /* the library room starts at its Figma size, so it shrinks by 1.08 -> 1.02's ratio */
  .memecard:hover .memeglow{opacity:.25}   /* Chris: the lab's back-light at a quarter strength */
  .memecard:hover .art-library .memeglow{opacity:.5}   /* the library's at half */
  .memecard:hover .memefig{transform:scale(1.02)}   /* Chris: 2%, no lift - it grows from the bottom edge (origin below), so the desk line never shows */
  .memecard:hover .memetitle{color:var(--lime);transition:color 200ms ease}
  .memecard:hover .memebtn{background:#bce97a;transform:translateY(-2px);box-shadow:4px 8px 20px rgba(0,0,0,.3);transition-duration:200ms}   /* the button follows the card, not its own hover (it takes no pointer events) */
  .memecard:active .memebtn{transform:translateY(-2px) scale(.97);transition-duration:100ms}
}
@media(prefers-reduced-motion:reduce){.memebg,.memefig{transition:none}}
@media(max-width:760px){.memecards{grid-template-columns:minmax(0,520px)}}

/* library (Chris's 18 Sep mock): no card -- a 170px column of title + category tabs on the left, a 2x2 grid of 16:9 tiles
   on the right, page squares and DOWNLOAD ALL under the grid. Measured off the mock at 1716 wide: content 1247 wide, the
   grid starts 70px after the column, tiles 487x273 with 33/35px gaps, 50px page squares, a 175x44 button. */
.libgrid{display:grid;grid-template-columns:170px minmax(0,1fr);column-gap:clamp(32px,4.1vw,70px);max-width:1247px;margin:0 auto}
.libside{display:flex;flex-direction:column;align-items:flex-start}
.libtitle{font-weight:700;text-transform:uppercase;line-height:1.05;white-space:nowrap;padding-top:6px}  /* nowrap: "THE MEMES" holds one line in the 170px column */
.libtitle span{display:block}
.libtitle .mint{color:var(--mint);font-size:29px}
.libtitle .white{color:var(--white);font-size:40px}
.libtitle::after{content:"";display:block;width:170px;height:3px;background:#2b2e35;margin:22px 0 28px}
.libtabs{display:flex;flex-direction:column;gap:18px}
.libtab{width:170px;height:50px;border-radius:8px;border:1px solid transparent;background:#16171b;color:#6d7175;
  font-size:15px;font-weight:500;text-transform:uppercase;letter-spacing:.02em;cursor:pointer;
  transition:background-color 160ms ease,color 160ms ease,border-color 160ms ease,transform 160ms var(--ease-out)}
.libtab:active{transform:scale(.97)}
.libtab[aria-selected=true]{background:var(--tab-active);border-color:#22b1b8;color:var(--white);box-shadow:0 0 18px rgba(4,121,127,.35)}
@media(hover:hover) and (pointer:fine){.libtab:not([aria-selected=true]):hover{color:var(--white);background:#1d1e24}}

/* the grid is a wrapping row, two tiles across: each tile's width is its share of the row by aspect ratio (flex-grow = --ar) and
   its height follows (aspect-ratio = --ar), so two tiles in a row always come out the same height whatever their shapes.
   16:9 is the default; app.js sets --ar on the odd ones. min-width 40% is what makes it two across. */
.libmain{container-type:inline-size}   /* lets .pack size its floor off its own width (cqw) */
/* the grid always stands as tall as a full page of four 16:9 tiles (two rows + the row gap), so the page squares and DOWNLOAD
   ALL under it never move when a page has fewer or shorter tiles (Chris). Tiles pack to the top of that box. */
.pack{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:flex-start;gap:35px 33px;
  min-height:calc((100cqw - 33px) / 1.7778 + 35px);transition:opacity 180ms var(--ease-out)}
.pack.fading{opacity:0}
.pack .tile{position:relative;display:block;border-radius:6px;overflow:hidden;background:#000;text-decoration:none;
  flex:var(--ar,1.7778) 1 0;min-width:40%;aspect-ratio:var(--ar,1.7778)}
.pack .tile img{width:100%;height:100%;object-fit:cover;transition:transform 500ms var(--ease-out)}   /* the tile already has the image's shape, so cover = exact fit */
/* the mock has nothing on the tiles; the tile itself is the download. A small DOWNLOAD chip shows on hover (desktop) or
   always (touch, which has no hover) so people know a tap saves the file. */
.pack .act{position:absolute;right:10px;top:10px;display:inline-flex;align-items:center;gap:5px;   /* top corner: the memes carry their watermark bottom-right */
  background:rgba(13,13,16,.85);color:var(--white);border:1px solid var(--card-border);
  border-radius:6px;padding:6px 10px;font-family:ui-monospace,monospace;font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;opacity:0;transition:opacity 160ms var(--ease-out)}
.pack .act svg{width:11px;height:11px;flex:none}
@media(hover:none){.pack .act{opacity:1}}
@media(hover:hover) and (pointer:fine){
  .pack .tile:hover img{transform:scale(1.03)}
  .pack .tile:hover .act{opacity:1;border-color:var(--lime);color:var(--lime)}
}

.libfoot{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-top:26px}
.libpages{display:flex;gap:20px}
.pg{width:50px;height:50px;border-radius:8px;border:1px solid transparent;background:#121316;color:#6d7175;
  font-size:16px;font-weight:500;cursor:pointer;
  transition:background-color 160ms ease,color 160ms ease,border-color 160ms ease,transform 160ms var(--ease-out)}
.pg:active{transform:scale(.95)}
.pg[aria-current=page]{background:#1a1b1f;border-color:#2b2e35;color:var(--white)}
@media(hover:hover) and (pointer:fine){.pg:not([aria-current=page]):hover{color:var(--white);background:#1a1b1f}}
#dlall{height:44px;border-radius:8px;font-size:15px;padding:0 28px}

@media(max-width:900px){   /* phones and tablets: the column goes on top, the tabs run in a row, the grid keeps two across */
  #memes,#library{padding-top:90px}   /* the titles clear the fixed bar */
  .libgrid{grid-template-columns:1fr;row-gap:28px}
  .libtitle::after{margin:16px 0 20px}
  .libtabs{flex-direction:row;flex-wrap:wrap;gap:12px}
  .libtab{width:auto;height:44px;padding:0 18px}
  .pack{gap:20px;min-height:calc((100cqw - 20px) / 1.7778 + 20px)}
}
@media(max-width:560px){   /* phones: still two tiles across (Chris, 19 Sep - one long column made the library endless), with a tighter
  gap. The floor under the grid is two rows of 16:9 tiles plus the gap, so the page squares and DOWNLOAD ALL never move. */
  .pack{gap:12px;min-height:calc((100cqw - 12px) / 1.7778 + 12px)}
  .pack .act{padding:4px 6px;gap:3px;font-size:7px;letter-spacing:.06em;right:6px;top:6px}   /* the DOWNLOAD chip, trimmed so it covers little of a half-width tile */
  .pack .act svg{width:9px;height:9px}
  .libpages{gap:12px}
  .pg{width:44px;height:44px}
}

/* faq */
.faq{margin-top:27px}
.faq .q{width:100%;background:none;border:0;border-bottom:1px solid var(--card-border);
  color:var(--white);font-family:var(--sans);font-size:20px;font-weight:500;text-align:left;
  padding:30px 0;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:18px;
  min-height:56px;transition:color 160ms ease,border-color 160ms ease}
@media(hover:hover) and (pointer:fine){.faq .q:hover{color:var(--mint)}}
/* open: question stays mint, and the line moves from under the question to under the answer */
.faq .q[aria-expanded=true]{color:var(--mint);border-bottom-color:transparent}
.faq .q .ind{flex:none;width:14px;height:14px;position:relative}
.faq .q .ind:before,.faq .q .ind:after{content:"";position:absolute;background:var(--mint);
  border-radius:2px;transition:transform 240ms var(--ease-out),opacity 200ms var(--ease-out)}
.faq .q .ind:before{left:0;top:6px;width:14px;height:2px}
.faq .q .ind:after{left:6px;top:0;width:2px;height:14px}
.faq .q[aria-expanded=true] .ind:after{transform:rotate(90deg);opacity:0}
.faq .a{display:grid;grid-template-rows:0fr;border-bottom:1px solid var(--card-border);
  transition:grid-template-rows 280ms var(--ease-out)}
.faq .a.open{grid-template-rows:1fr}
.faq .a>div{overflow:hidden}
.faq .a p{color:var(--white);font-size:16px;padding:4px 0 22px;max-width:66ch}

/* footer */
#sitefoot{background:#0e1015;border-top:1px solid #1f2229;padding:40px 0}   /* Chris (18 Sep): a shade off the FAQ's black above it */
.footrow{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap}
@media(max-width:700px){.footca code{word-break:break-all}}
.footleft{display:flex;flex-direction:column;align-items:flex-start;gap:14px;color:var(--white)}
.footx{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;flex:none;
  border-radius:10px;background:var(--teal-dark);color:var(--white);text-decoration:none;
  box-shadow:4px 4px 15px rgba(0,0,0,.25);
  transition:background-color 150ms ease,transform 150ms var(--ease-out),box-shadow 150ms var(--ease-out)}
.footx:active{transform:scale(.95);transition-duration:100ms}
@media(hover:hover) and (pointer:fine){
  .footx:hover{background:#46a084;transform:translateY(-2px);box-shadow:4px 8px 20px rgba(0,0,0,.3);transition-duration:200ms}
  .footx:hover:active{transform:translateY(-2px) scale(.95);transition-duration:100ms}
}
.footca{display:inline-flex;align-items:center;gap:8px;font-size:14px;flex-wrap:wrap}
.foottick{font-weight:600}
.footsep{color:var(--muted2)}
.footca code{font-family:ui-monospace,monospace;color:var(--lime)}
.copybtn.small svg{width:16px;height:16px}
.footbottom{max-width:1346px;margin:24px auto 0;padding:0 22px;color:#8a8f8c;font-size:13px}

/* scroll reveals: hidden only once JS confirms it can animate them back in */
html.js [data-reveal]{opacity:0;transform:translateY(14px)}
html.js [data-reveal].in{opacity:1;transform:none;
  transition:opacity 520ms var(--ease-out),transform 520ms var(--ease-out)}
html.js [data-reveal-stagger] [data-reveal].in{transition-delay:min(calc(var(--i,0) * 50ms),400ms)}   /* descendants, not just children: the FAQ buttons sit inside .item wrappers. Must out-specify the .in rule above, which zeroes transition-delay through its shorthand - without this the stagger never ran (fixed 18 Sep) */

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  html.js [data-reveal]{transform:none;transition:opacity 150ms linear}
  .btn:hover,.footx:hover{transform:none}  /* colour still changes; the lift does not */
  [data-reveal-stagger]>*{transition-delay:0ms}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important}
}

/* mobile creator order: stage, then controls */
@media(max-width:880px){
  .creatorleft{display:contents}
  .creatorgrid>.stage,.creatorleft>.stage{order:1}
  .creatorright{order:2;min-height:0}
  .apes{position:static;max-height:260px}
  #input{order:3}
  #dl{order:4}
}
/* Figma: nav BUY pill 139×28, radius 10 */
.btn.pill{min-height:28px;height:28px;padding:0 17px;font-size:14px;border-radius:10px;white-space:nowrap;width:auto}

/* ---- typewriter caret in the preview ---- */
#caret{display:inline-block;width:.07em;height:1.05em;margin-left:.04em;vertical-align:-.16em;
  background:var(--lime);animation:blink 1.06s steps(1,end) infinite}
#cap.typing #caret{animation:none}           /* solid while characters are moving */
@keyframes blink{0%,49%{opacity:1}50%,100%{opacity:0}}
@media(prefers-reduced-motion:reduce){#caret{animation:none}}

/* phones (Chris's mockup): still scene, no drift, no lean. The city is covered by a flat 40% #050404 layer, and the ape,
   sized down to the width of the screen, sits on that layer at the very bottom, under the copy. */
@media(max-width:900px){
  .hero{--apew:min(105vw,600px,calc((100svh - 400px) / .6533))}   /* the ape's width: a bit wider than the screen, but never taller than what a small-viewport screen has left under 400px of copy, so the hero is exactly one screen on every phone (19 Sep; the short-phone block at the end of this file tightens the copy to match) */
  .herolayers{left:0;height:100%;min-width:0;width:100%;aspect-ratio:auto}
  .herobg{object-position:17% 40%;animation:none}   /* the first window: mullion at the left edge, the diagonal beam across the top (mockup) */
  .heroshade{background:rgba(5,4,4,.4)}
  .heroape{width:var(--apew);max-width:none;height:auto;right:auto;left:50%;transform:translateX(-56%);animation:none}  /* head a little left of centre, the right chair arm still in frame */
  .herosub{text-wrap:balance}   /* "If you're still here, / you're one of us." instead of a lone "us." */
  .herocontent{z-index:1;padding-left:22px;padding-top:96px}
  /* Chris's phone sizes (17 Sep): headline 24, subhead 17, tag 12 under the buttons, mono 10 */
  .herocontent h1{font-size:24px;line-height:1.5}
  .herosub{font-size:17px;margin:4px 0 24px}
  .herotag{font-size:12px;margin-top:24px}
  .hero{height:auto;min-height:100vh;min-height:100svh;padding-bottom:calc(var(--apew) * .6533 + 12px)}   /* the copy stops above the ape's head */
  .navrow{padding:0 22px}
}

/* ================= MVP (2026-09-16): hero-only landing, nav bubbles, membership lightbox, FAQ page ================= */
/* word bubbles. Phones: the words drop in under the open menu item, the row growing from nothing (a grid row going
   0fr -> 1fr, so nothing animates a real height) and the divider moves below them. Desktop: the ape says it (below). */
.bubble{opacity:0}
.bubble.show{opacity:1}
.navlinks .bubble{display:grid;grid-template-rows:0fr;font-size:14px;font-weight:400;line-height:1.35;color:var(--white);
  border-bottom:1px solid #2b2d31;transition:grid-template-rows 150ms ease,opacity 110ms ease}
.navlinks .bubble.show{grid-template-rows:1fr;transition:grid-template-rows 220ms var(--ease-out),opacity 220ms var(--ease-out)}
.navlinks .bubble>span{overflow:hidden;min-height:0}
.navlinks .bubble>span::after{content:"";display:block;height:18px}   /* the row's bottom padding, clipped away while closed */
.navlinks a:not(.btn):has(+.bubble:not([hidden])){padding-bottom:6px;border-bottom:0}
.navlinks a:not(.btn)[aria-expanded=true]{color:var(--mint)}
@media(max-width:900px){.navlinks a:not(.btn)[aria-expanded=true]{color:var(--lime)}}   /* the picked menu item on phones (mockup) */
/* the ape's speech bubble (desktop landing page): Chris's SVG shape, cream with a 3px black stroke, tail pointing down-left
   at the ape's head. Sits at the same spot as the Figma (rect left 80.7% / top 17.3% of the 2170x927 layer box). */
.bubble.onape{position:absolute;top:auto;right:auto;left:min(74.1%,calc(100% - 312px));bottom:calc(72% + 10px);max-width:300px;  /* bottom-left anchored: the tail tip (the TOKEN bubble's, the biggest) is the same spot for every message */background:#ededd7;border:3px solid #000;
  border-radius:20px;padding:22px 28px 20px 27px;color:#111;font-size:19px;font-weight:600;line-height:1.5;box-shadow:none;
  transform-origin:28px calc(100% + 31px);   /* the tail's tip: 3px border + 22px tail offset + 2.9px into the tail; 34.3px below the box less 3px border */
  transform:scale(.5);transition:opacity 200ms ease,transform 200ms ease}
.bubble.onape.show{transform:none;transition:opacity 600ms var(--ease-out),transform 600ms var(--ease-out)}  /* Chris: grow from the tip, 50% -> 100%, ~600ms */
.bubbletail{position:absolute;left:22px;bottom:-34.3px;width:58px;height:38.3px;overflow:visible}

/* membership lightbox: a modal, so it stays centred and scales from the middle. 220ms in, 150ms out */
.lightbox{margin:auto;border:0;padding:0;background:transparent;max-width:none;max-height:none;overflow:visible;color:var(--white)}  /* margin:auto restores centring (the global reset zeroes it) */
.lightbox::backdrop{background:rgba(6,7,9,.7);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);opacity:0;transition:opacity 150ms ease}
.lightbox.open::backdrop{opacity:1;transition:opacity 220ms var(--ease-out)}
.lbpanel{position:relative;display:grid;grid-template-columns:643fr 614fr;column-gap:clamp(24px,5.45vw,93px);align-items:center;
  width:min(1350px,calc(100vw - 48px));max-height:calc(100vh - 72px);overflow:auto;
  opacity:0;transform:scale(.95);transition:opacity 150ms ease,transform 150ms ease}
.lightbox.open .lbpanel{opacity:1;transform:none;transition:opacity 220ms var(--ease-out),transform 220ms var(--ease-out)}
.lbclose{position:absolute;top:-52px;right:0;z-index:1;width:40px;height:40px;border-radius:50%;border:2px solid var(--teal-dark);
  background:var(--card);color:var(--white);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity 150ms ease,background-color 160ms ease,transform 160ms var(--ease-out)}
.lightbox.open .lbclose{opacity:1}
@media(hover:hover) and (pointer:fine){.lbclose:hover{background:var(--teal-dark)}}
.lbclose:hover:active{transform:scale(.94);transition-duration:100ms}
.lbimg{display:block;width:100%;height:auto;margin:0}  /* the PNG carries its own rounded dark frame */
.lbtitle{font-weight:700;font-size:clamp(30px,3.125vw,54px);line-height:1.2;color:var(--mint);margin:0 0 clamp(10px,1.33vw,23px);text-wrap:balance}  /* no lone "you." */
.lbsub{font-weight:700;font-size:clamp(21px,2.07vw,35.7px);line-height:1.2;margin:0 0 clamp(20px,2.7vw,47px)}
.check{display:flex;align-items:center;gap:clamp(16px,2vw,34px);font-weight:400;font-size:clamp(17px,1.61vw,27.8px);
  color:var(--white);opacity:.9;cursor:pointer;margin:0 0 clamp(14px,1.45vw,25px);position:relative}
.check input{position:absolute;opacity:0;width:1px;height:1px}
.check .box{flex:none;width:32px;height:32px;border-radius:10px;border:3px solid var(--teal);background:rgba(0,0,0,.5);
  transition:background-color 120ms ease,transform 120ms var(--ease-out)}
.check:active .box{transform:scale(.92)}
.check input:checked+.box{background:var(--teal)}
.check input:focus-visible+.box{outline:2px solid var(--lime);outline-offset:3px}
.lbform .btn{margin-top:clamp(12px,1.1vw,19px)}
.lberror{margin-top:14px;font-size:15px;font-weight:500;color:#ffb8a8}
/* result screens: one centred column (Chris's mockup): headline, paragraph, image, button */
.lbpanel.done{display:flex;flex-direction:column;align-items:center;width:min(960px,calc(100vw - 48px))}  /* wide enough for the 46px headline on one line */
.labpanel{text-align:center;padding:24px 0}   /* the laboratory notice: the certificate screens' bare headline + button */
.labpanel .lbhead{margin-bottom:clamp(22px,2.6vw,40px)}
.lbdone{display:flex;flex-direction:column;align-items:center;text-align:center;animation:lbdone 260ms var(--ease-out) both}
@keyframes lbdone{from{opacity:0}}  /* fade only, no translateY -- a vertical offset here briefly counts as scrollable
  "ink overflow" inside .lbpanel's overflow:auto box, which could nudge its measured size for the ~260ms the motion plays
  and show up as a sizing flicker between the survey image and the result image */
.lbhead{font-weight:700;font-size:clamp(26px,2.66vw,46px);line-height:1.2;color:var(--mint);margin:0 0 clamp(14px,2vw,34px);text-wrap:balance}
.lbtext{font-weight:400;font-size:clamp(13.5px,.99vw,17.1px);line-height:1.43;max-width:770px;margin:0 0 clamp(22px,2.4vw,42px);color:var(--white)}  /* 10% under the mockup's 19px (Chris) */
.lbtext p+p{margin-top:.9em}
.lbcertimg{display:block;width:min(660px,calc(100% - 14px));height:auto;aspect-ratio:1672/941;margin:0 auto clamp(24px,2.7vw,46px);
  border-radius:13px;box-shadow:0 0 0 6.5px rgba(0,0,0,.64)}  /* on-screen only: the ape images' 16px ring at this size; the download is the bare certificate */
.lbtext .lblead{font-weight:500}   /* Chris: the opening line stays medium; the small print under it is 400 */
.lbtext em{font-style:italic;font-weight:inherit;color:var(--mint)}   /* the proof line: mint, italic, the weight of the line above it */
/* the step after the download: post it on X, or step back to the certificate */
.lbpost .lbtext{max-width:46ch}
.lbback{display:inline-block;margin-top:clamp(16px,1.6vw,26px);background:none;border:0;padding:6px 2px;cursor:pointer;
  font-family:var(--sans);font-size:15px;font-weight:500;color:var(--white);opacity:.7;text-decoration:underline;
  text-underline-offset:3px;transition:opacity 160ms var(--ease-out),color 160ms var(--ease-out)}
@media(hover:hover) and (pointer:fine){.lbback:hover{opacity:1;color:var(--mint)}}
.lbback:active{transform:scale(.97)}
@media(max-width:760px){   /* phones: the survey and the "doesn't believe you" screen drop their pictures; the certificate fills the width */
  .lbpanel,.lbpanel.done{grid-template-columns:1fr;width:calc(100vw - 32px);max-height:calc(100vh - 32px);padding-top:52px}   /* clears the close button */
  .lbimg{display:none!important}
  .lbclose{top:8px;right:8px}
  .check .box{width:28px;height:28px}
  .lbcertimg{width:calc(100% - 14px)}   /* leaves room for its 6.5px ring */
}
@media(prefers-reduced-motion:reduce){
  .bubble,.bubble.show,.navlinks .bubble,.navlinks .bubble.show,.bubble.onape,.bubble.onape.show,.lbpanel,.lightbox.open .lbpanel,.lightbox::backdrop,.lightbox.open::backdrop{transition:opacity 100ms linear;transform:none}
  .lbdone{animation:none}
}

/* announcement typed out under the hero buttons (starts ~3s in). The invisible ghost holds the full text so the box
   never changes size while the copy types, fades, and hands over to the small Repeat button. */
.herotype{position:relative;margin-top:clamp(18px,2vw,34px);max-width:620px;font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  font-weight:400;font-size:clamp(13px,1.05vw,18px);line-height:2.2;color:var(--white)}
.herotype .ghost,.herotype .t{white-space:pre-wrap}   /* only the copy keeps its line breaks: pre-wrap on the box turned the markup's newlines into blank lines under it */
.herotype .ghost{visibility:hidden}
.herotype .typed{position:absolute;inset:0}
.herotype .caret{display:none;width:.55em;height:1.05em;margin-left:2px;vertical-align:-.15em;background:var(--lime)}
.herotype.live .caret{display:inline-block;animation:blink 1.06s steps(1,end) infinite}
@media(prefers-reduced-motion:reduce){.herotype.live .caret{animation:none}}
@media(max-width:900px){.herotype{margin-top:12px;font-size:10px;line-height:2;max-width:none}}   /* phones: shown at once (no typing); Chris: 10px */

/* FAQ page: the sign-off under the questions */
.faqend{margin-top:clamp(44px,5vw,72px);display:flex;flex-direction:column;align-items:flex-start;gap:24px}
.faqend p{font-size:clamp(18px,1.6vw,24px);font-weight:500;color:var(--white)}

/* FAQ page: clears the fixed bar */
#faq.faqmain{padding-top:calc(60px + clamp(40px,5vw,80px));min-height:70vh}

/* ================= v2 (2026-09-17): the whole page again -- lore, membership, pre-launch token ================= */
/* lore (18 Sep, Chris's Figma frames 19 -> 30, 1728x927): one screen that stays pinned while the page scrolls 250vh.
   The scene is Figma's frame as a 1728x927 STAGE, and its four layers (city, back-light glow, dark overlay, cut-out ape)
   sit at their frame-19 pixels; .reveal (js/app.js "lore") moves each to its frame-30 pixels over 2.4s while the circle
   window opens over 2s, and swaps the copy. js sets --k/--ox/--oy (how the stage is scaled and placed on this screen:
   desktop = full width, centred vertically; phones = the circle 72% of the width, up top) and --k2/--ox2/--oy2 for the
   open state (the stage zooms until the frame-30 city covers the screen; on desktop that is no change). */
#lore{height:250vh;position:relative}
.lorepin{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;background:#000}
.lorescene{position:absolute;left:0;top:0;width:1728px;height:927px;transform-origin:0 0;
  transform:translate(var(--ox,0px),var(--oy,0px)) scale(var(--k,1));
  clip-path:circle(342.5px at 521.5px 459.5px)}   /* frame 19's window: Ellipse 71, 685 wide at 179,117 */
.fitted .lorescene{transition:clip-path 2s var(--ease-in-out),transform 2.4s var(--ease-in-out)}   /* only once js has placed the stage, so the placing itself never animates */
.lorescene>div{position:absolute;transform-origin:0 0;transition:transform 2.4s var(--ease-in-out),opacity 1.2s ease}
.lorecity{left:-270px;top:0;width:1728px;height:1130px}
.lorecity>span{position:absolute;inset:0;background:url(../img/lore/city.webp) center/cover;
  animation:loredrift 30s ease-in-out infinite}   /* Chris (18 Sep): the city drifts 20px each way on a 30s loop */
.lorescene .loreglow{left:73px;top:173px;width:958px;height:958px;border-radius:50%;opacity:0;transform:none;
  transition:opacity 800ms ease;   /* beats the .lorescene>div transition above: this one never animates its transform */
  background:radial-gradient(circle closest-side,#c9ffc8 0%,rgba(201,255,200,0) 97%)}   /* "Back Light SHine" at its frame-30 place. Chris (18 Sep): it never moves and is never in the circle - it comes up behind him once the scene has finished opening. closest-side: the fade reaches the circle's edge, not the box corner */
.loredark{left:0;top:-400px;width:1728px;height:1727px;opacity:0;   /* "Dark Transition": frame 30 only, black from the right edge, at 80%. Taller than the frame: screens taller than the stage show city above and below it */
  background:linear-gradient(270deg,#000 15.865%,rgba(0,0,0,0) 100%)}
.loreape{left:75px;top:166px;width:939px;height:1004px}
.loreape>span{position:absolute;inset:0;background:url(../img/lore/ape.webp) 0 0/100% 100% no-repeat;transform-origin:50% 100%;will-change:transform}   /* he grows upward from his feet, not out from the middle */
.reveal .loreape>span{animation:lorebreathe 10s ease-in-out infinite}   /* Chris (18 Sep): 5s up to 1% bigger and 5s back down, on the open membership scene only - never in the circle.
     Both loops live on an inner span: the div itself is busy carrying the reveal transform, and one element cannot hold both */
@keyframes lorebreathe{from,to{transform:scale(1)}50%{transform:scale(1.01)}}
@keyframes loredrift{from,to{transform:translateX(-20px)}50%{transform:translateX(20px)}}
.reveal .lorescene{clip-path:circle(1600px at 521.5px 459.5px);transform:translate(var(--ox2,0px),var(--oy2,0px)) scale(var(--k2,1))}
.reveal .lorecity{transform:translate(-28px,-130px) scale(1.2639)}   /* frame 30: 2184 wide at -298,-130 */
.reveal .lorescene .loreglow{opacity:1;transition-delay:2.4s}   /* waits out the 2.4s scene transition, then fades up on its own; on the way back it fades out at once (no delay) */
.reveal .loredark{opacity:.8}
.reveal .loreape{transform:translate(97px,7px) scale(.869)}          /* frame 30: 816 wide at 172,173 */

.lorephone{display:none}   /* the two phone scenes; the phone block at the end of this file turns them on */
.lorecopy{position:absolute;left:55.9%;width:32%;top:50%;transform:translateY(-50%);display:grid}
.lorecopy>*{grid-area:1/1}   /* both copies share one cell; the taller one sets the height */
.lorecopy1{transition:opacity 600ms var(--ease-out) .9s,transform 600ms var(--ease-out) .9s}   /* on the way back it returns after the circle has closed */
.lorecopy2{opacity:0;transform:translateY(18px);visibility:hidden;   /* and leaves at once; hidden for real so its button cannot be tabbed to or clicked while faded out */
  transition:opacity 600ms var(--ease-out),transform 600ms var(--ease-out),visibility 0s linear 600ms}
.reveal .lorecopy1{opacity:0;transform:translateY(-18px);transition-delay:0s}
.reveal .lorecopy2{opacity:1;transform:none;visibility:visible;transition-delay:1.15s}   /* arrives as the circle finishes opening */
.lorebtn{margin-top:clamp(22px,2.3vw,40px)}
.loreeyebrow{font-weight:700;font-size:clamp(15px,1.5vw,26px);text-transform:uppercase;letter-spacing:.02em;color:var(--mint);margin:0 0 .3em}
.loreh2{font-weight:700;font-size:clamp(38px,5.55vw,96px);line-height:1.15;text-transform:uppercase;color:var(--white);margin:0 0 .35em;text-wrap:balance}
.lorebody{font-weight:400;font-size:clamp(16px,1.5vw,26px);line-height:1.4;color:var(--white);margin:0 0 1.4em}
.lorebody strong{font-weight:700;color:#C9FFC8}
.lorecommon{font-weight:500;font-size:clamp(22px,2.31vw,40px);line-height:1.25;color:var(--teal);margin:0}
.loreeyebrow2{font-weight:700;font-size:clamp(17px,2.15vw,37px);line-height:1.3;text-transform:uppercase;color:var(--white);margin:0 0 .4em}
.loreh2b{font-weight:700;font-size:clamp(38px,5.55vw,96px);line-height:1.1;text-transform:uppercase;margin:0 0 .35em}
.loreh2b .white{color:var(--white)}
.loreh2b .mint{color:var(--mint)}
.lorebody2{font-weight:400;font-size:clamp(16px,1.5vw,26px);line-height:1.55;color:var(--white);margin:0}
.lorebody2 em{font-style:italic}
/* ---- the lore on phones (Chris, 19 Sep): two plain scenes, no pin, no opening circle, nothing animated ----
   The desktop stage (`.lorescene`) is switched off and the two `.lorephone` scenes take over, each followed by its own
   copy: the ape in a circle over black, then the open city scene fading into the copy under it (the same shape as the
   token section on a phone). Both scenes are the SAME two images as the desktop stage, placed by percentages of their
   own box - the circle's numbers are the desktop window's exact crop (Figma frame 19: a 685px window at 179,117 of the
   1728x927 stage, with the city at -270,0 and the ape at 75,166), so the phone circle frames him identically. */
@media(max-width:900px){
  #lore{height:auto}
  .lorepin{position:static;height:auto;overflow:visible;display:flex;flex-direction:column;background:#000}
  .lorescene,.loreend{display:none}   /* the desktop stage and the desktop deck's snap marker */
  .lorephone{display:block;position:relative;overflow:hidden;flex:none}
  .lorephone span{position:absolute;background-repeat:no-repeat;background-size:100% 100%}
  .lorecopy{display:contents}   /* both copies join the column below their own scene */
  .lorecopy1{order:2}
  .lorephone2{order:3}
  .lorecopy2{order:4;opacity:1;visibility:visible;transform:none;transition:none}   /* nothing fades in on a phone: it is simply the next thing down the page */
  .lorecopy1,.lorecopy2{position:static;width:auto;padding:26px 22px 34px;transform:none;transition:none}
  /* Chris (19 Sep): no circle on a phone - page 1's words follow straight on from the hero's martini ape, on black */
  .lorephone1{display:none}
  .lorecopy1{padding-top:clamp(72px,13vw,92px);padding-bottom:clamp(96px,26vw,150px)}   /* Chris: three times the black under "All with one thing in common..." before the next scene */   /* like every other section: enough room that tapping THE LORE does not leave the words under the fixed bar */
  /* scene 2: the open scene, a band that fades into the copy below it. 46svh (Chris): the copy that follows, membership
     button and all, then lands inside the same screenful on a phone. */
  .lorephone2{width:100%;height:46svh;min-height:280px}
  .lorephone2 .lpcity{inset:0;width:auto;height:auto;background-size:cover;background-position:64% 45%;background-image:url(../img/lore/city.webp)}
  .lorephone2 .lpape{left:-4%;bottom:0;height:94%;width:auto;aspect-ratio:939/1004;background-image:url(../img/lore/ape.webp)}   /* Chris: sized to the band's HEIGHT, so he is never cut off at the head; the 6% left over is city above him */
  .lorephone2::after{content:"";position:absolute;inset:0;pointer-events:none;   /* solid black before the band ends, so the join with the copy below is invisible */
    background:linear-gradient(180deg,rgba(0,0,0,0) 40%,rgba(0,0,0,.72) 72%,#000 93%)}
  .loreeyebrow{font-size:14px}
  .loreh2,.loreh2b{font-size:clamp(30px,8.8vw,42px)}
  .loreh2b{margin-bottom:.25em}
  .lorebody,.lorebody2{font-size:15px}
  .lorebody2{line-height:1.45}
  .lorecommon{font-size:24px}
  .loreeyebrow2{font-size:15px;margin-bottom:.3em}
  .lorecopy2{padding-top:18px;padding-bottom:26px}
  .lorebtn{margin-top:18px}
}
@media(prefers-reduced-motion:reduce){   /* no opening circle, no drift: the layers cut and the copy crossfades */
  .lorescene,.lorescene>div{transition:opacity 300ms ease}
  .lorecity>span,.loreape>span{animation:none}
  .reveal .lorescene .loreglow{transition-delay:.3s}   /* the scene now cuts in 300ms: the glow follows it, not the 2.4s desktop opening */
  .lorecopy1,.lorecopy2{transform:none!important;transition:opacity 300ms ease,visibility 0s linear 300ms;transition-delay:0s!important}
}
/* token before launch: the contract box says so, in the site's own face */
.cabox code.notyet{color:#ABDC69;text-transform:uppercase;font-family:var(--sans);font-weight:600;font-size:16px;letter-spacing:.01em;word-break:normal}   /* Chris (18 Sep): caps, mint green (Chris, 18 Sep); 16px keeps it on one line beside the label (371px slot). break-all is for the hex address, not these words */
/* FAQ sign-off */
.faqclose{margin-top:40px;font-size:clamp(18px,1.6vw,24px);font-weight:500;color:var(--white)}

/* ================= 18 Sep: the slide deck - every desktop section is one screen ================= */
@media(min-width:901px){
  #memes{min-height:100svh;display:flex;flex-direction:column;justify-content:center;padding:80px 0 40px}
  .memesh2{margin-bottom:clamp(24px,4.5vh,80px)}
  .memecards{grid-template-columns:repeat(2,minmax(0,min(598px,max(340px,calc((100svh - 536px) * 1.5)))))}   /* a card is ~0.63 x its width + 216px tall (title, one line of body, the button); two rows of copy above/below */
  #library{min-height:100svh;display:flex;flex-direction:column;justify-content:center;padding:80px 0 40px}
  #memes .wrap,#library .wrap{width:100%}   /* a flex item with margin:auto is sized to its content, not stretched; the tile grid needs the full width */
  .libgrid{max-width:min(1247px,calc((100svh - 252px) * 1.7778 + 273px))}   /* the grid is a full page of 16:9 tiles tall; this keeps that under the screen */
  #faq{min-height:100svh;padding:90px 0 40px}
  .faq{display:grid;grid-template-columns:1fr 1fr;column-gap:clamp(40px,4vw,70px);align-items:start}   /* ten questions in two columns: one screen */
  .faq .q{padding:clamp(16px,2.6vh,30px) 0}
}

/* ================= 19 Sep: phones scroll naturally =================
   Chris (19 Sep): mobile does not need the desktop's slide deck - plain sections, scrolled the way a phone scrolls, with
   nothing animated. So: no snapping (the rule at the top of this file), no section forced to the screen's height except
   the hero (which is a full-bleed scene), no pinned lore and no opening circle (the lore block above). What is left here
   is phone TYPE and SPACING: comfortable sizes, room to breathe, and the pictures given their own bands. */
@media(max-width:900px){
  /* the memes hub: heading, then the two cards stacked, each with its way in under the words */
  #memes{padding:90px 0 64px}
  .memesh2{font-size:clamp(30px,8.4vw,40px);margin-bottom:clamp(22px,6vw,32px)}
  .memecards{gap:clamp(44px,12vw,60px);grid-template-columns:minmax(0,min(100%,340px))}   /* Chris: smaller pictures, and daylight between a card's button and the next card */
  .memetitle{font-size:clamp(24px,7vw,30px);margin-top:12px}
  .memebody{font-size:15px;margin-top:8px;line-height:1.45}
  .btn.memebtn{margin-top:16px;height:44px;font-size:15px;max-width:100%}
  /* the token: the bar scene as a band at the top, fading into the copy under it */
  .tokensect{min-height:0}
  /* the scene starts BELOW the fixed bar (Chris, 19 Sep): the room above the ape's head is 26.5% of the band, and the bar
     was covering the part of it the headline needs, so the headline had nowhere to go but onto his head. overflow:hidden
     because the blurred room hangs 2% past its box (see .tokenbar) and would otherwise show below the fade. */
  .tokenscene{top:60px;height:52svh;min-height:300px;overflow:hidden}
  .tokenscene .tokenbar,.tokenscene .tokenape{animation:none}   /* like the hero and the lore: no ambient loops on phones */
  .tokensect .wrap{padding-top:calc(52svh + 24px);padding-bottom:56px}   /* the address box picks up just under the band (which now starts 60px down) */
  html.js .tokencopy[data-reveal]{transform:none}   /* the reveal's translateY would make .tokencopy the anchor for the headline below; on a phone it just fades */
  .tokenh2{position:absolute;top:70px;left:22px;right:22px;   /* Chris: ON the scene and clear of the ape's head - 10px into the band, which now begins under the 60px bar */
    font-size:clamp(17px,4.9vw,21px);line-height:1.3;text-shadow:0 2px 10px rgba(0,0,0,.9),3.2px 3.2px 7.9px rgba(0,0,0,.75)}
  .cabox{margin-top:18px;padding:12px 16px;min-height:0;gap:4px}
  .cabox span{font-size:17px}
  .cabox code.notyet{font-size:14px}
  .tokenlede{font-size:15px;margin-top:20px}
  .tokencopy .body{font-size:14px;margin-top:10px;line-height:1.5}
  .tokencopy .btn{margin-top:26px}
  .libtab{height:40px;padding:0 12px;font-size:12px}   /* the three tabs hold one row on a 375px screen */
  .libtitle{align-self:stretch}   /* Chris: so the rule under it runs the whole way across, not just under the words */
  .libtitle::after{width:100%}
  .libtitle span{display:inline}   /* Chris: THE MEMES LIBRARY on one line */
  .libtitle .mint,.libtitle .white{font-size:clamp(23px,7.2vw,30px)}
  .libtitle::after{margin:14px 0 18px}
  #library{padding-bottom:44px}   /* Chris: less black between the library and the FAQ */
  #faq{padding-top:72px}   /* up from 90 (Chris), but still clear of the fixed bar when FAQ is tapped in the menu */
}
/* short phones (an iPhone SE and the like, ~550px of screen): only the hero has to fit one screen, so only the hero
   tightens - its copy comes in and the ape shrinks with it (the --apew rule higher up). Everything else just scrolls. */
@media(max-width:900px) and (max-height:650px){
  .herocontent{padding-top:72px}
  .herocontent h1{font-size:22px;line-height:1.4}
  .herosub{margin-bottom:18px}
  .herotag{margin-top:16px}
  .herotype{font-size:10px;line-height:1.8;margin-top:10px}
}
