/* /books landing page. Brand tokens + fonts live in /assets/css/brand.css. */
/* WorldHop Books landing page.

   The framework below (site-header, mobile-menu, .wrap, .section, .btn,
   .eyebrow, .hero, .closing, footer) is COPIED VERBATIM from usa/styles.css
   so the two pages are pixel-identical in their shared furniture. Change a
   shared value here and make the same change there — the same warning the
   root styles.css already carries about the global nav block.

   Page-specific rules for the shelf, USP bands and interior gallery are in
   the BOOKS PAGE block at the bottom. */
*{box-sizing:border-box}
html{overflow-x:clip}
body{
  margin:0;font-family:"Nunito Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  color:var(--ink);
  background:
    radial-gradient(circle at 10% 6%,rgba(242,181,42,.12),transparent 18rem),
    radial-gradient(circle at 85% 30%,rgba(25,178,166,.1),transparent 22rem),
    #f7eedc;
  overflow-x:clip;
}
a{color:inherit}
img{max-width:100%;display:block}
/* Every cover/mosaic image on this page carries width+height HTML
   attributes (correct practice — it reserves layout space and avoids a
   flash of blank space while the image loads). But those attributes also
   become a low-priority CSS width+height, and when a rule below sets only
   `width` for one of these images, that HTML-attribute height (not
   "auto") wins and stretches the image instead of scaling it — exactly
   the bug that shipped here. This is the blanket fix: any image with
   both attributes gets height:auto by default, so a rule only has to
   fight this if it deliberately wants something else. */
img[width][height]{height:auto}
.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:30px}
.display{font-family:"Lilita One",cursive;text-transform:uppercase;text-shadow:0 2px 0 rgba(255,255,255,.2)}
.eyebrow{display:inline-flex;align-items:center;gap:8px;color:var(--orange);background:#fff3db;border:1px solid #e3c999;border-radius:99px;padding:6px 13px;font-family:"Nunito Sans",sans-serif;font-weight:800;font-size:13px;letter-spacing:.03em;text-transform:uppercase}
.eyebrow:before{content:"✦";color:var(--mango)}
.section{padding:80px 0}
.section h2{font-size:var(--h2);line-height:1.06;max-width:none;margin:14px 0 0}
.section .sub{font-size:18px;color:var(--muted);max-width:640px;margin-top:14px;line-height:1.55}
.center{text-align:center}
.center .sub{margin-inline:auto}

/* Buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:"Lilita One",cursive;text-transform:uppercase;letter-spacing:.02em;font-size:16px;border:2px solid rgba(18,33,49,.7);border-radius:17px;box-shadow:0 7px 0 var(--orange-dark),0 13px 22px rgba(0,0,0,.2);padding:15px 25px;background:var(--orange);color:var(--cream);text-decoration:none;transition:transform .15s ease}
.btn:hover{transform:translateY(-2px);filter:saturate(1.1)}
.btn.teal{background:var(--teal);box-shadow:0 7px 0 var(--teal-dark),0 13px 22px rgba(0,0,0,.2)}
.btn.ghost{background:var(--paper);color:var(--night);box-shadow:0 7px 0 #c5b28e,0 13px 22px rgba(0,0,0,.14)}
.cta-row{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin-top:30px}
.notify-link{font-weight:800;font-size:14px;color:var(--muted);text-decoration:underline;text-underline-offset:3px}

.appstore{display:flex;align-items:center;gap:10px;background:var(--night-deep);border:2px solid rgba(244,233,211,.35);border-radius:14px;padding:10px 18px;box-shadow:0 7px 0 #02070e,0 13px 22px rgba(0,0,0,.25);transition:transform .15s ease;text-decoration:none;color:var(--cream);cursor:default}
.appstore:hover{transform:translateY(-2px)}
.appstore svg{width:26px;height:26px;flex:0 0 auto}
.appstore .t{display:flex;flex-direction:column;line-height:1.15}
.appstore .t small{font-size:10px;opacity:.75;font-weight:700}
.appstore .t strong{font-family:"Lilita One",cursive;font-size:16px;font-weight:400;text-transform:none}

/* ==========================================================================
   GLOBAL WORLDHOP.APP NAV — this exact block (selectors + values) is
   duplicated verbatim in the root styles.css and club/common.css. All
   three pages must render this pixel-identical: same header height, same
   logo size, same link sizing/gap, same background, same breakpoints. If
   you change ANY value here, make the same change in the other two files.
   ========================================================================== */
.site-header{height:150px;background:var(--night);color:var(--cream);position:relative;z-index:50}
.site-header .wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:30px;height:100%;display:flex;align-items:center;justify-content:space-between;gap:28px}
.site-header .brand{display:flex;align-items:center;text-decoration:none}
.site-header .brand img{height:120px;width:auto;object-fit:contain}
.site-header nav.links{display:flex;align-items:center;gap:44px}
.site-header nav.links a{font-family:var(--font-display);font-weight:400;font-size:22px;letter-spacing:.5px;text-transform:uppercase;color:var(--cream);text-decoration:none;opacity:.82;white-space:nowrap}
.site-header nav.links a:hover{opacity:1}
.site-header nav.links a.active{opacity:1;color:var(--mango)}
.site-header nav.links a.nav-cta{display:inline-flex;align-items:center;justify-content:center;padding:14px 30px;font-size:18px;border-radius:15px;border:2px solid rgba(18,33,49,.7);background:var(--orange);color:var(--cream);box-shadow:0 6px 0 var(--orange-d),0 12px 20px rgba(0,0,0,.22);opacity:1;letter-spacing:.4px;transition:transform .15s ease}
.site-header nav.links a.nav-cta:hover{transform:translateY(-2px);filter:brightness(1.06);opacity:1}

.hamburger{display:none;flex-direction:column;justify-content:center;gap:6px;width:56px;height:56px;padding:14px;background:rgba(255,241,210,.1);border:2px solid rgba(244,233,211,.45);border-radius:15px;cursor:pointer}
.hamburger span{display:block;height:5px;width:100%;border-radius:3px;background:var(--cream)}
.mobile-menu{position:fixed;inset:0;z-index:300;background:linear-gradient(160deg,#081d39,#041225);display:flex;flex-direction:column;padding:26px 24px 40px}
.mobile-menu[hidden]{display:none}
.mm-close{align-self:flex-end;display:grid;place-items:center;width:56px;height:56px;font-size:24px;color:var(--cream);background:rgba(255,241,210,.1);border:2px solid rgba(244,233,211,.45);border-radius:15px;cursor:pointer;line-height:1}
.mm-links{margin:auto 0;display:flex;flex-direction:column;gap:22px;padding:20px 0}
.mm-links a{font-family:var(--font-display);font-weight:400;font-size:36px;color:var(--cream);text-decoration:none;text-transform:uppercase;text-align:center;letter-spacing:.5px}
.mm-links a.active{color:var(--mango)}
.mm-links a.mm-cta{margin-top:20px;font-size:26px;background:var(--orange);color:var(--cream);border:2px solid rgba(18,33,49,.7);border-radius:16px;box-shadow:0 6px 0 var(--orange-d);padding:18px 24px}
.mm-links a.mm-cta.active{color:var(--cream)}

@media(max-width:860px){
  .site-header nav.links{display:none}
  .hamburger{display:flex}
}
@media(max-width:700px){
  .site-header{height:100px}
  .site-header .brand img{height:64px}
}

/* Hero — matches the WorldHop app/Club hero treatment: navy background,
   inverted (light) copy. Just the front cover, bigger, tilted, with a
   soft coloured blob behind it for texture (same idea as the dashed
   orbit rings/blob shapes used behind the Club's hero art). */
.hero{padding:36px 0 60px;position:relative;background:var(--night);color:var(--cream);overflow:hidden}
.hero .grid{display:grid;grid-template-columns:1.05fr .95fr;gap:50px;align-items:center}
.hero h1{font-size:clamp(44px,6vw,72px);line-height:1;margin:0}
.hero h1 .accent{color:var(--mango)}
.hero .lede{font-size:19px;color:rgba(255,241,210,.82);max-width:52ch;margin-top:18px;line-height:1.6}
.hero-visual{position:relative;display:grid;place-items:center;min-height:460px}
.hero-blob{position:absolute;width:min(440px,88%);aspect-ratio:1/1;background:linear-gradient(135deg,var(--teal),var(--teal-d));border-radius:42% 58% 65% 35%/45% 45% 55% 55%;transform:rotate(-8deg);z-index:1;opacity:.9}
.hero-cover{position:relative;width:380px;max-width:82%;height:auto;border-radius:18px;box-shadow:0 34px 50px rgba(0,0,0,.4);border:3px solid var(--night);z-index:2;transform:rotate(3deg)}

/* Book section */
.book-spread{display:grid;grid-template-columns:1fr 1fr;gap:40px;align-items:center}
.book-subtitle{color:var(--teal);font-size:clamp(24px,3vw,34px);line-height:1.05;margin:8px 0 0}
.book-visual{position:relative;display:grid;place-items:center;min-height:420px}
.book-visual-blob{position:absolute;width:min(380px,80%);aspect-ratio:1/1;background:linear-gradient(135deg,var(--teal),var(--teal-d));border-radius:42% 58% 65% 35%/45% 45% 55% 55%;z-index:1;opacity:.9}
.book-fan{position:absolute;width:220px;max-width:56%;aspect-ratio:31/44;object-fit:cover;height:auto;border-radius:14px;border:3px solid var(--night);box-shadow:0 18px 30px rgba(8,29,57,.28);z-index:2}
.book-fan-left{left:0;top:16%;transform:rotate(-12deg)}
.book-fan-right{right:0;top:24%;transform:rotate(10deg)}
.book-fan-main{position:relative;width:280px;max-width:70%;z-index:3;transform:rotate(-2deg);box-shadow:0 24px 40px rgba(8,29,57,.34)}
.book-copy .cta-row{margin-top:20px}
.book-copy .cta-row .btn{min-width:240px}
.book-facts{list-style:none;padding:0;margin:22px 0 0;display:grid;gap:12px}
.book-facts li{display:flex;gap:12px;align-items:flex-start;font-size:16px;font-weight:700;color:var(--ink)}
.book-facts li:before{content:"✓";flex:0 0 auto;width:26px;height:26px;border-radius:50%;background:var(--teal);color:var(--cream);display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:900}

/* Feature / gallery cards */
.gallery{display:grid;grid-template-columns:repeat(5,1fr);gap:22px;margin-top:46px}
.gallery-card{border:2px solid var(--ink);border-radius:22px;background:var(--paper);box-shadow:0 8px 0 #c5b28e,0 18px 28px rgba(8,29,57,.12);overflow:hidden;transition:transform .25s ease}
.gallery-card:hover{transform:translateY(-6px) rotate(.3deg)}
.gallery-card img{aspect-ratio:31/44;object-fit:cover;width:100%;height:auto;transform:scale(1.05);transform-origin:center}
.gallery-card span{display:block;padding:10px 12px;font-family:"Lilita One",cursive;font-size:13px;text-transform:uppercase;letter-spacing:.02em;color:var(--night);text-align:center;line-height:1.2}
.gallery-more{text-align:center;margin-top:26px;font-family:"Lilita One",cursive;font-weight:400;font-size:22px;letter-spacing:.02em;color:var(--night)}

/* Companion checklist — open layout (no card/box): copy on the left,
   the checklist preview image on the right, scaled down and tilted. */
.checklist-layout{display:grid;grid-template-columns:1.1fr .9fr;gap:54px;align-items:center;margin-top:44px}
.checklist-visual{display:flex;justify-content:center}
.checklist-visual img{width:78%;max-width:300px;height:auto;border-radius:14px;border:2px solid var(--line);box-shadow:0 20px 34px rgba(8,29,57,.22);transform:rotate(4deg)}

/* Promo bands (app / club) */
.promo{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
.promo-band{padding:64px 0}
.promo-band + .promo-band{border-top:1px solid var(--line)}
.promo-visual{position:relative;border-radius:24px;border:3px solid var(--night);box-shadow:0 18px 30px rgba(8,29,57,.22);overflow:hidden;min-height:260px;display:flex;align-items:center;justify-content:center;background:var(--night);color:var(--cream);text-align:center;padding:30px}
.promo-visual:before,.promo-visual:after{content:"";position:absolute;border:3px dashed rgba(244,233,211,.25);border-radius:50%}
.promo-visual:before{width:150px;height:150px;left:-40px;top:-40px;transform:rotate(12deg)}
.promo-visual:after{width:190px;height:190px;right:-55px;bottom:-55px;transform:rotate(-10deg)}
.promo-visual .glyph{position:relative;z-index:1;font-family:"Lilita One",cursive;font-size:22px;text-transform:uppercase;line-height:1.4;text-shadow:0 3px 0 rgba(0,0,0,.25)}
.promo-visual.club{background:linear-gradient(135deg,#3abcae,#18887e)}

/* App promo — full-width navy band with inverted (light-on-dark) copy,
   matching the WorldHop app/Club hero treatment. The glyph box switches
   to a warm orange/mango gradient so it still pops against the navy
   band instead of blending into it. */
.promo-band.dark{background:var(--night);color:var(--cream)}
.promo-band.dark .sub{color:rgba(255,241,210,.78)}
.promo-band.dark .notify-link{color:rgba(255,241,210,.75)}
.promo-visual.appglow{background:linear-gradient(135deg,var(--orange),var(--mango));color:var(--night)}
.promo-visual.appglow:before,.promo-visual.appglow:after{border-color:rgba(6,29,59,.2)}
.promo-visual.appglow .glyph{text-shadow:none}

/* Next books shelf — just Africa/Asia/Europe live for now, so 3 columns
   keeps the shelf centred instead of leaving a gap for a missing 4th. */
.book-shelf{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin:46px auto 0;max-width:640px}
.shelf-card{position:relative;border-radius:16px;overflow:hidden;border:2.5px solid var(--night);box-shadow:0 10px 0 #c5b28e,0 20px 30px rgba(8,29,57,.16)}
.shelf-card img{aspect-ratio:2/3;object-fit:cover;width:100%;height:auto}
.shelf-card .tag{position:absolute;top:10px;left:10px;background:var(--orange);color:var(--cream);font-family:"Lilita One",cursive;font-size:11px;text-transform:uppercase;padding:4px 10px;border-radius:99px;border:1.5px solid var(--night)}
.shelf-card .label{position:absolute;bottom:0;left:0;right:0;padding:10px 10px 8px;background:linear-gradient(0deg,rgba(8,29,57,.92),transparent);color:var(--cream);font-family:"Lilita One",cursive;font-size:13px;text-transform:uppercase;text-align:center}
.shelf-note{text-align:center;color:var(--muted);font-weight:700;margin-top:22px}

/* Closing CTA */
.closing{position:relative;padding:100px 0 100px;background:
  radial-gradient(circle at 50% 40%,rgba(30,90,168,.38),transparent 28rem),
  linear-gradient(rgba(4,18,37,.9),rgba(4,18,37,.98));
  color:var(--cream);text-align:center;overflow:hidden}
.closing h2{font-size:var(--h2);line-height:1.05;text-shadow:0 6px 0 #061326}
.closing p{color:rgba(244,233,211,.85);max-width:60ch;margin:16px auto 0;font-size:17px;line-height:1.6}
.closing .cta-row{justify-content:center}

/* Footer (matches worldhop.app) */
.footer{padding:50px 0;background:#020b17;position:relative;text-align:center}
.footer-logo{display:block;text-align:center;margin-bottom:20px}
.footer-lockup{width:260px;height:auto;margin:0 auto;display:inline-block;object-fit:contain;filter:drop-shadow(0 12px 18px rgba(0,0,0,.45))}
.foot-strap{font-family:"Lilita One",cursive;font-weight:400;text-transform:uppercase;color:var(--mango);font-size:22px;line-height:1.25;letter-spacing:.4px;margin:0 auto 16px;max-width:30ch}
.footer nav{margin:0 auto 4px}
.footer nav a{font-family:"Lilita One",cursive;font-weight:400;text-transform:uppercase;font-size:15px;letter-spacing:.5px;color:var(--cream);opacity:.82;margin:0 11px;display:inline-block;text-decoration:none}
.footer nav a:hover{opacity:1}
.foot-copy{margin-top:16px;opacity:.55;text-align:center;font-size:13px}

/* Responsive */
@media (max-width:980px){
  .hero .grid{grid-template-columns:1fr;text-align:center}
  .hero .lede{margin-inline:auto}
  .hero .cta-row{justify-content:center}
  .book-spread{grid-template-columns:1fr}
  .book-copy{text-align:center}
  .book-copy .cta-row{justify-content:center}
  .book-facts{text-align:left;max-width:420px;margin-inline:auto}
  .checklist-layout{grid-template-columns:1fr;text-align:center}
  .checklist-visual{order:-1}
  .checklist-visual img{margin-inline:auto;max-width:240px}
  .promo{grid-template-columns:1fr;text-align:center}
  .gallery{grid-template-columns:repeat(3,1fr)}
  .book-shelf{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:700px){
  .wrap{padding-inline:20px}
  .section{padding:56px 0}
  .gallery{grid-template-columns:repeat(2,1fr)}
  .book-shelf{grid-template-columns:repeat(2,1fr)}
  .cta-row{justify-content:center}
  .book-visual{min-height:340px}
  .book-fan{width:170px}
  .book-fan-main{width:220px}
}

/* ==========================================================================
   BOOKS PAGE — everything below is specific to /books.
   ========================================================================== */

/* Section eyebrows here are plain text, not the chip/pill the /usa page uses:
   no background, no border, no leading glyph, and a few px larger. Orange on
   the light sections; on the two navy bands (hero, feature) orange sits too
   dark against the background to read comfortably, so those switch to mango.
   Both are brand colours and the size/weight/tracking are identical, so the
   two variants still read as one treatment. */
.eyebrow{
  display:block;
  background:none;border:0;border-radius:0;padding:0;
  color:var(--orange);
  font-family:var(--font-body);font-weight:900;
  font-size:16px;line-height:1.2;letter-spacing:.12em;text-transform:uppercase;
  margin:0 0 10px;
}
.eyebrow:before{content:none}
.hero .eyebrow,.feature .eyebrow{color:var(--mango)}

/* One H2 size for every section on the page — the previous four different
   clamps made "Eleven books, one journey" and "A few pages from around the
   world" read as different ranks when they are peers. 8px larger at the top
   end than the /usa scale it came from. */
:root{--h2:clamp(36px,4.8vw,58px)}

/* Headings on the page's cream sections are aqua. NOTE: --teal (#24B8A6)
   only reaches 2.16:1 against the cream, which fails even the relaxed
   large-text bar, so this uses --teal-d (#167F77) at 4.23:1. Still clearly
   aqua, actually readable. Same reason the cream-background eyebrows use
   --orange-d rather than --orange. */
.usp-band h2,.section h2{color:var(--teal-d)}
.usp-band .eyebrow,.section .eyebrow{color:var(--orange-d)}

/* ==========================================================================
   TINTED BANDS — a full-bleed mango or teal band behind a USP.
   The interiors are black-and-white line art, so the colour has to come from
   the band itself; the artwork keeps its white ground and navy border and
   lifts off the colour rather than blending into it.
   ========================================================================== */
.usp-band{padding:0}
.usp-band + .usp-band .usp{border-top:0}
.usp-band:not([class*="tint-"]) + .usp-band:not([class*="tint-"]) .usp{border-top:1px solid var(--line)}
.tint-mango{background:var(--mango)}
.tint-teal{background:var(--teal)}
/* Navy type on both tints: 10.1:1 on mango, 6.8:1 on teal. */
.tint-mango h2,.tint-teal h2{color:var(--night)}
.tint-mango .eyebrow,.tint-teal .eyebrow{color:var(--night);opacity:.68}
.tint-mango .usp p,.tint-teal .usp p{color:rgba(6,29,59,.84)}
/* A heavier shadow under the artwork so it still sits proud of a saturated
   background rather than floating flat on it. */
.tint-mango .usp-art img,.tint-teal .usp-art img{box-shadow:0 20px 38px rgba(6,29,59,.32)}

/* Hero: three covers fanned instead of the single tilted cover /usa uses.
   The centre cover leads; the two behind it are rotated out and dimmed
   slightly so the eye lands on one thing, not three competing things. */
.hero-fan{position:relative;z-index:2;display:grid;place-items:center;min-height:560px;width:100%}
.hero-fan img{position:absolute;width:300px;max-width:56%;aspect-ratio:31/40;object-fit:cover;border-radius:16px;border:3px solid var(--night);box-shadow:0 22px 38px rgba(0,0,0,.42)}
.hero-fan .fan-left{transform:rotate(-13deg) translate(-58%,4%);filter:brightness(.82)}
.hero-fan .fan-right{transform:rotate(12deg) translate(58%,7%);filter:brightness(.82)}
.hero-fan .fan-main{position:relative;width:360px;max-width:68%;transform:rotate(-2deg);box-shadow:0 30px 50px rgba(0,0,0,.5);z-index:3}

/* Backdrop behind the fan: one soft aqua disc plus two dashed rings that
   turn slowly in opposite directions. The rings are what actually carry the
   movement — a plain rotating circle looks static, but a DASHED one reads as
   turning because the dashes travel round the edge, and the second ring is a
   slight ellipse so its rotation is unmistakable.

   The covers bob on the `translate` property rather than `transform`, because
   each one already carries a rotate/translate for its position in the fan and
   animating `transform` would wipe that out. `translate` composes with it
   instead of replacing it. */
.hero-orbits{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;z-index:0}
.hero-orbits span{position:absolute;border-radius:50%}
.hero-orbits .aqua{
  width:min(430px,84%);aspect-ratio:1;
  background:radial-gradient(circle at 38% 32%,rgba(36,184,166,.92),rgba(22,127,119,.78) 58%,rgba(22,127,119,0) 73%);
}
.hero-orbits .ring{border:2px dashed rgba(255,241,210,.24);background:none}
.hero-orbits .ring-1{width:min(540px,98%);aspect-ratio:1;animation:orbit-cw 52s linear infinite}
.hero-orbits .ring-2{width:min(410px,78%);aspect-ratio:1/1.16;animation:orbit-ccw 38s linear infinite}
@keyframes orbit-cw{to{transform:rotate(360deg)}}
@keyframes orbit-ccw{to{transform:rotate(-360deg)}}

.hero-fan img{animation:cover-bob 7s ease-in-out infinite}
.hero-fan .fan-left{animation-delay:-2.3s}
.hero-fan .fan-right{animation-delay:-4.6s}
@keyframes cover-bob{0%,100%{translate:0 0}50%{translate:0 -15px}}

/* Anyone who has asked their system to calm motion down gets the same
   composition, held still. */
@media(prefers-reduced-motion:reduce){
  .hero-orbits .ring,.hero-fan img{animation:none}
}

/* Stat strip under the hero — the numbers do the selling, so they get to be
   big and unadorned rather than sitting inside cards. */
.stat-strip{background:var(--night);color:var(--cream);border-top:1px solid rgba(255,241,210,.14);padding:34px 0 42px}
.stat-strip .wrap{display:grid;grid-template-columns:repeat(4,1fr);gap:26px;text-align:center}
.stat-strip b{display:block;font-variant-numeric:tabular-nums;font-family:"Lilita One",cursive;font-size:clamp(34px,4.4vw,52px);line-height:1;color:var(--mango)}
.stat-strip span{display:block;margin-top:8px;font-weight:800;font-size:13px;letter-spacing:.06em;text-transform:uppercase;color:rgba(255,241,210,.72)}

/* USP bands — copy one side, a real interior page the other, alternating.
   The artwork IS the argument here, so it gets equal width, a real border
   and a shadow rather than being a decorative background wash. */
.usp{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center;padding:74px 0}
.usp + .usp{border-top:1px solid var(--line)}
.usp.flip .usp-art{order:-1}
.usp h2{font-size:var(--h2);line-height:1.06;margin:14px 0 0}
.usp p{font-size:17px;line-height:1.62;color:var(--muted);margin:16px 0 0;max-width:52ch}
.usp-art{position:relative;display:flex;justify-content:center}
/* The tilt leans each page TOWARDS its copy, not away from it — art on the
   right leans left, art on the left leans right. Both signs flip together;
   changing one without the other makes half the page lean the wrong way. */
.usp-art img{width:100%;max-width:400px;height:auto;border-radius:16px;border:2.5px solid var(--night);background:#fff;box-shadow:0 18px 34px rgba(8,29,57,.2);transform:rotate(1.5deg)}
.usp.flip .usp-art img{transform:rotate(-1.5deg)}

/* Feature book — the one title that is actually buyable today gets a band of
   its own, above the shelf, so it is never just one card among eleven. */
.feature{background:var(--night);color:var(--cream)}
.feature .inner{display:grid;grid-template-columns:.85fr 1.15fr;gap:56px;align-items:center;padding:78px 0}
.feature h2{font-size:var(--h2);line-height:1.04;margin:14px 0 0}
.feature .sub{color:rgba(255,241,210,.8);max-width:54ch}
.feature-cover{width:100%;max-width:330px;height:auto;border-radius:18px;border:3px solid var(--night);box-shadow:0 28px 46px rgba(0,0,0,.45);transform:rotate(-2.5deg);margin-inline:auto}
.feature .book-facts li{color:var(--cream)}
.feature .cta-row{margin-top:26px}

/* The shelf — the traditional shop grid. Same card language as /usa's
   .shelf-card (border, hard shadow, corner tag, gradient label) scaled up
   to a browsable eleven-book grid. */
.shelf{display:grid;grid-template-columns:repeat(4,1fr);gap:26px;margin-top:46px}
.book-card{position:relative;display:flex;flex-direction:column;border:2.5px solid var(--night);border-radius:18px;overflow:hidden;background:var(--paper);box-shadow:0 9px 0 #c5b28e,0 20px 30px rgba(8,29,57,.14);transition:transform .22s ease}
.book-card:hover{transform:translateY(-6px)}
.book-card .art{position:relative;display:block}
.book-card .art img{aspect-ratio:31/40;object-fit:cover;width:100%;height:auto}
.book-card .tag{position:absolute;top:11px;left:11px;z-index:2;font-family:"Lilita One",cursive;font-size:11px;text-transform:uppercase;letter-spacing:.03em;padding:5px 11px;border-radius:99px;border:1.5px solid var(--night);background:var(--mango);color:var(--night)}
.book-card .tag.live{background:var(--teal);color:var(--cream)}
.book-card .body{display:flex;flex-direction:column;flex:1;padding:15px 15px 17px;gap:4px}
.book-card h3{font-family:"Lilita One",cursive;text-transform:uppercase;font-size:17px;line-height:1.15;margin:0;color:var(--night)}
.book-card .meta{font-size:13px;font-weight:700;color:var(--muted);margin:0}
.book-card .card-cta{margin-top:auto;padding-top:13px}
.book-card .card-cta a{display:inline-flex;align-items:center;gap:6px;font-family:"Lilita One",cursive;font-size:13px;text-transform:uppercase;color:var(--cream);background:var(--orange);border:2px solid var(--night);border-radius:11px;padding:9px 14px;text-decoration:none;box-shadow:0 4px 0 var(--night)}
.book-card .card-cta a:active{transform:translateY(3px);box-shadow:none}
.book-card .card-cta .soon{display:inline-block;font-weight:800;font-size:12.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}

/* Interior gallery — a wide look-inside strip. Scrolls sideways on a phone
   rather than stacking eleven tall pages down the page. */
.inside-strip{display:grid;grid-template-columns:repeat(6,1fr);gap:18px;margin-top:44px}
.inside-strip figure{margin:0;border:2px solid var(--night);border-radius:14px;overflow:hidden;background:#fff;box-shadow:0 7px 0 #c5b28e}
/* Zoomed 10% so the artwork's own drawn border falls outside the frame and
   the mosaic bleeds to the card edge. The figure's overflow:hidden clips the
   sides; the caption below carries an opaque background (see next rule) to
   cover the downward spill, since a transform overflows its box without
   affecting layout. Same technique as .gallery-card on /usa. */
.inside-strip img{aspect-ratio:3/4;object-fit:cover;width:100%;height:auto;transform:scale(1.1);transform-origin:center}
.inside-strip figcaption{position:relative;z-index:1;background:var(--white);padding:9px 9px 10px;font-size:11px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;color:var(--night);text-align:center;line-height:1.25}

@media(max-width:1000px){
  .shelf{grid-template-columns:repeat(3,1fr)}
  .inside-strip{grid-template-columns:repeat(3,1fr)}
  .feature .inner{grid-template-columns:1fr;gap:40px}
  .usp{grid-template-columns:1fr;gap:34px;padding:56px 0}
  .usp.flip .usp-art{order:0}
  .usp-art img{max-width:330px}
}
@media(max-width:700px){
  .hero-fan{min-height:390px}
  .hero-fan img{width:210px}
  .hero-fan .fan-main{width:245px}
  .stat-strip .wrap{grid-template-columns:repeat(2,1fr);gap:24px}
  .shelf{grid-template-columns:repeat(2,1fr);gap:16px}
  .book-card h3{font-size:15px}
  .inside-strip{grid-template-columns:repeat(2,1fr)}
}

/* App band CSS moved to /assets/css/components.css on 30 Aug 2026 so /usa
   could use the same block instead of a placeholder. Same selectors, same
   values — it is loaded after this file, so nothing about the cascade
   changed. Edit it there, and it changes on both pages at once. */




/* ==========================================================================
   HOST BANNER — reusable component.

   A full-bleed colour band with the host artwork constrained to the content
   column and anchored flush to the bottom edge (the source PNG is already
   cropped there, like the app shot). Deliberately self-contained: no
   dependency on anything else in this stylesheet, so the whole block plus the
   markup pattern can be lifted onto /usa, /club or the homepage as-is.

     <section class="host-banner host-banner-navy">
       <div class="wrap"><img src="/assets/images/Host-banner.webp" ...></div>
     </section>

   Colour is the only thing a variant changes. If this ends up on a second
   page, move this block to a shared stylesheet rather than copying it.
   ========================================================================== */
.host-banner{
  --host-headroom:30px;      /* navy above the heads; the art has almost none of its own */
  position:relative;
  overflow:hidden;           /* lets the art crop cleanly at narrow widths */
  padding-top:var(--host-headroom);
  line-height:0;             /* kills the inline-block baseline gap under the image */
}
.host-banner .wrap{display:flex;justify-content:center;align-items:flex-end}
.host-banner img{display:block;width:100%;height:auto}

/* Colour variants — the whole point of the component. */
.host-banner-navy {background:var(--night)}
.host-banner-teal {background:var(--teal)}
.host-banner-mango{background:var(--mango)}
.host-banner-cream{background:var(--paper)}

/* Sitting directly under the navy feature band, the seam would otherwise be
   invisible but the stacked padding would read as a gap. Pull them together. */
.feature + .host-banner-navy{padding-top:0}

/* Narrow viewports: a 2.31 ratio image at full width leaves the hosts about
   an inch tall. Switch to a fixed height and let the ends crop instead — the
   outermost characters are the least important. */
@media (max-width:820px){
  .host-banner .wrap{padding-inline:0}
  .host-banner img[width][height]{width:auto;height:300px;max-width:none;margin-inline:auto}
}
@media (max-width:520px){
  .host-banner img[width][height]{height:230px}
}

/* ==========================================================================
   ENTRANCE + SCROLL REVEAL

   Everything here is gated behind html.js (set by an inline script in the
   head). With JavaScript off the class never lands, none of the hidden states
   apply, and the page renders complete and static — a reveal effect must
   never be the reason someone sees a blank page.
   ========================================================================== */
.js [data-reveal]{opacity:0;transform:translateY(26px);transition:opacity .75s ease,transform .75s cubic-bezier(.2,.75,.3,1)}
.js [data-reveal].revealed{opacity:1;transform:none}

/* Staggered groups — children arrive one after another rather than as a slab.
   Used for the eleven-book shelf and the look-inside strip. */
.js [data-reveal-stagger] > *{opacity:0;transform:translateY(22px);transition:opacity .6s ease,transform .6s cubic-bezier(.2,.75,.3,1)}
.js [data-reveal-stagger].revealed > *{opacity:1;transform:none}
.js [data-reveal-stagger].revealed > *:nth-child(1){transition-delay:0ms}
.js [data-reveal-stagger].revealed > *:nth-child(2){transition-delay:70ms}
.js [data-reveal-stagger].revealed > *:nth-child(3){transition-delay:140ms}
.js [data-reveal-stagger].revealed > *:nth-child(4){transition-delay:210ms}
.js [data-reveal-stagger].revealed > *:nth-child(5){transition-delay:280ms}
.js [data-reveal-stagger].revealed > *:nth-child(6){transition-delay:350ms}
.js [data-reveal-stagger].revealed > *:nth-child(7){transition-delay:420ms}
.js [data-reveal-stagger].revealed > *:nth-child(8){transition-delay:490ms}
.js [data-reveal-stagger].revealed > *:nth-child(9){transition-delay:560ms}
.js [data-reveal-stagger].revealed > *:nth-child(10){transition-delay:630ms}
.js [data-reveal-stagger].revealed > *:nth-child(11){transition-delay:700ms}
.js [data-reveal-stagger].revealed > *:nth-child(12){transition-delay:770ms}

/* Hero entrance: the copy rises in, and the three covers fan out from a
   single stacked pile in the middle to their resting positions.

   Each cover needs its OWN keyframes because the `to` state has to land
   exactly on that cover's resting transform — a shared set would snap them
   all to the same angle at the end. The bob from earlier runs on `translate`,
   a separate property, so it composes with this instead of fighting it; it is
   simply delayed until the fan has finished. */
.js .hero-copy-in{opacity:0;transform:translateY(28px);animation:hero-rise .85s cubic-bezier(.2,.8,.3,1) .1s forwards}
@keyframes hero-rise{to{opacity:1;transform:none}}

.js .hero-fan img{opacity:0}
.js .hero-fan .fan-main {animation:fan-in-main  .9s cubic-bezier(.2,.85,.3,1) .18s both, cover-bob 7s ease-in-out 1.5s infinite}
.js .hero-fan .fan-left {animation:fan-in-left  .9s cubic-bezier(.2,.85,.3,1) .42s both, cover-bob 7s ease-in-out 1.7s infinite}
.js .hero-fan .fan-right{animation:fan-in-right .9s cubic-bezier(.2,.85,.3,1) .54s both, cover-bob 7s ease-in-out 1.9s infinite}
@keyframes fan-in-main {from{opacity:0;transform:rotate(0deg) translate(0,7%) scale(.88)} to{opacity:1;transform:rotate(-2deg)}}
@keyframes fan-in-left {from{opacity:0;transform:rotate(0deg) translate(0,7%) scale(.88)} to{opacity:1;transform:rotate(-13deg) translate(-58%,4%)}}
@keyframes fan-in-right{from{opacity:0;transform:rotate(0deg) translate(0,7%) scale(.88)} to{opacity:1;transform:rotate(12deg) translate(58%,7%)}}

/* Calm mode: everything present, nothing performing. */
@media (prefers-reduced-motion:reduce){
  .js [data-reveal],.js [data-reveal-stagger] > *{opacity:1;transform:none;transition:none}
  .js .hero-copy-in{opacity:1;transform:none;animation:none}
  .js .hero-fan img{opacity:1;animation:none}
}

/* Hero copy needs air between the last word and the covers beside it — at
   1100–1300px the lede was running right up to the fanned artwork. */
.hero .grid > .hero-copy-in{padding-right:clamp(0px,3.4vw,54px)}
@media (max-width:980px){.hero .grid > .hero-copy-in{padding-right:0}}


}

/* Status badge straddles the top edge of the card, centred, rather than
   sitting inside the top-left corner.

   This needs the card itself to stop clipping — it carried overflow:hidden so
   the cover's square corners would not poke through the card's rounded ones.
   That job moves to .art, which keeps its own rounded top and its own
   clipping, freeing the card to let the badge hang outside. */
.book-card{overflow:visible}
.book-card .art{overflow:hidden;border-radius:15px 15px 0 0}
.book-card .tag{
  top:0;left:50%;right:auto;
  transform:translate(-50%,-50%);
  white-space:nowrap;
  z-index:3;
  box-shadow:0 3px 0 rgba(6,29,59,.28);
}
/* Row gap has to clear the half-badge now hanging above each card. */
.shelf{row-gap:38px}
@media (max-width:700px){.shelf{row-gap:30px}}

/* The Apple glyph is a bare <path> with no fill attribute, and SVG's default
   fill is BLACK — it does not inherit the badge's text colour, so on the dark
   badge it rendered invisible. currentColor ties it to .appstore's own colour,
   so the mark always matches the "Coming soon on the / App Store" text beside
   it, including on any future badge variant. (The homepage sets fill:#fff
   inline for the same reason; this is the same fix, self-maintaining.)
   The Google Play glyph is unaffected — its paths carry their own brand
   fills. */
.appstore .apple{fill:currentColor}

/* ==========================================================================
   BRANDMARK IN THE NAV

   The stacked brandmark (globe over WORLD HOP) replaced the horizontal
   wordmark. It is square rather than 2:1, so at the old 120px height it read
   as small and left the bar looking empty — this sizes it up and lets it hang
   past the bottom of the bar.

   It overhangs DOWNWARD only: the header sits at the top of the document, so
   anything spilling upward is clipped by the viewport edge. The brand is
   therefore pinned near the top of the bar; only the brand, not the whole
   .wrap, or the nav links and hamburger would be dragged up with it.

   The header already carries position:relative and z-index:50, which is what
   keeps the overhanging part above the hero below it.
   ========================================================================== */
.site-header .brand{align-self:flex-start;margin-top:6px}
.site-header .brand img{height:190px;width:auto;object-fit:contain}
@media(max-width:860px){.site-header .brand img{height:170px}}
@media(max-width:700px){.site-header .brand{margin-top:6px}.site-header .brand img{height:132px}}
@media(max-width:480px){.site-header .brand img{height:112px}}

/* The brandmark hangs ~46px past the bar and the hero copy shares its left
   edge, so the hero needs that much clearance or the eyebrow/heading collides
   with the logo. Values are the old padding plus the overhang. */
.hero{padding-top:76px}
@media(max-width:700px){.hero{padding-top:64px}}

/* ==========================================================================
   FOOTER SOCIAL ROW
   Inline SVG on purpose. worldhop.app makes no third-party requests anywhere
   — that is a stated promise on the homepage and in the privacy policy, and
   pulling five brand glyphs off a CDN would break it for the sake of 2KB.
   The paths are simple-icons (CC0).

   fill:currentColor so the icons inherit exactly what the footer links beside
   them use: cream at .82, full opacity on hover. Do not hard-code a colour.

   The .footer .social a selector is (0,2,1) on purpose — it has to outrank the
   blanket `.footer a{display:inline-block;margin:0 9px 8px}` inside the
   980px media query, which would otherwise re-space the row on mobile.

   CHANGE IT HERE, CHANGE IT IN usa/styles.css AND books/styles.css.
   ========================================================================== */
.footer .social{margin:16px auto 0;display:flex;justify-content:center;align-items:center;gap:20px}
.footer .social a{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;margin:0;color:var(--cream);opacity:.82;transition:opacity .18s ease,transform .18s ease}
.footer .social a:hover,.footer .social a:focus-visible{opacity:1;transform:translateY(-2px)}
.footer .social svg{width:20px;height:20px;fill:currentColor;display:block}
@media(max-width:430px){.footer .social{gap:14px}}
@media(prefers-reduced-motion:reduce){.footer .social a{transition:none}.footer .social a:hover{transform:none}}
