/* ============================================================
   Shared 3D passport component  ·  used by the app, the claim
   reveal, and the public verify page.
   Built on the :root tokens in styles.css (--palm, --gold,
   --gold-light, --paper, --ar, --serif). Pure CSS/SVG 3D —
   no dependency. Behaviour lives in passport-3d.js.

   Markup contract:
     <div class="pp3d" data-passport-3d data-pp-open="open|closed">
       <div class="pp3d-book">
         <div class="pp3d-inside"> ...surface-specific spread... </div>
         <div class="pp3d-cover">
           <div class="pp3d-cover-face"> crest · title · chip </div>
           <div class="pp3d-cover-back"></div>
         </div>
       </div>
     </div>
   ============================================================ */

@property --pp-floatY { syntax:'<length>'; inherits:false; initial-value:0px; }

.pp3d{
  --tiltX:0deg; --tiltY:0deg;
  perspective:1600px;
  width:min(86vw,320px);
  margin:10px auto 22px;
  user-select:none; -webkit-user-select:none;
}

/* the book: floats (translateY var, animated) + tilts (rotate vars, JS/hover) */
.pp3d-book{
  position:relative; width:100%; aspect-ratio:330/452;
  transform-style:preserve-3d;
  transform:
    translateY(var(--pp-floatY))
    rotateX(calc(6deg + var(--tiltX)))
    rotateY(calc(-16deg + var(--tiltY)));
  animation:pp3dFloat 7s ease-in-out infinite;
  cursor:pointer; will-change:transform; touch-action:manipulation;
}
@keyframes pp3dFloat{ 0%,100%{ --pp-floatY:0px; } 50%{ --pp-floatY:-14px; } }
/* while a finger/gyro is driving the tilt, freeze the bob and track tightly */
.pp3d.pp-tilting .pp3d-book{ animation-play-state:paused; }
.pp3d-book{ transition:transform .5s cubic-bezier(.22,1,.32,1); }
.pp3d.pp-tilting .pp3d-book{ transition:transform .1s ease-out; }
/* open = you're reading the ID page: flatten toward the viewer, stop the bob */
.pp3d[data-pp-open="open"] .pp3d-book{
  animation-play-state:paused;
  transform:
    translateY(0)
    rotateX(calc(2deg + var(--tiltX)))
    rotateY(calc(-5deg + var(--tiltY)));
}

/* ---------- cover ---------- */
.pp3d-cover{
  position:absolute; inset:0; border-radius:12px;
  transform-style:preserve-3d;
  transform-origin:right center;               /* RTL: hinges on the right */
  transform:rotateY(0deg) translateZ(2px);
  transition:transform .8s cubic-bezier(.22,1,.32,1);
  z-index:2;
}
.pp3d[data-pp-open="open"] .pp3d-cover{ transform:rotateY(-158deg) translateZ(2px); }

.pp3d-cover-face, .pp3d-cover-back{
  position:absolute; inset:0; border-radius:12px;
  backface-visibility:hidden; -webkit-backface-visibility:hidden;
  overflow:hidden;
}
/* front — the green passport cover */
.pp3d-cover-face{
  display:flex; flex-direction:column; align-items:center; justify-content:space-between;
  padding:34px 24px 46px; text-align:center;
  background:radial-gradient(120% 120% at 30% 12%, #10493a 0%, #0c3b2e 42%, #072a20 100%);
  box-shadow:0 40px 90px rgba(0,0,0,.5), inset 0 0 0 1px rgba(231,206,143,.16);
}
/* embossed inner frame */
.pp3d-cover-face::before{
  content:""; position:absolute; inset:14px; border-radius:6px;
  border:1px solid rgba(231,206,143,.32); box-shadow:inset 0 0 0 3px rgba(7,42,32,.5);
  pointer-events:none;
}
/* gold-foil sheen sweep */
.pp3d-cover-face::after{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:3;
  background:linear-gradient(115deg, transparent 36%, rgba(231,206,143,.05) 46%, rgba(255,244,214,.11) 50%, rgba(231,206,143,.05) 54%, transparent 64%);
  background-size:340% 340%; mix-blend-mode:screen;
  animation:pp3dSheen 12s ease-in-out infinite;
}
@keyframes pp3dSheen{ 0%,12%{ background-position:120% 120%; } 55%,100%{ background-position:-30% -30%; } }
/* back of the cover — plain leather-green, seen when open */
.pp3d-cover-back{
  transform:rotateY(180deg);
  background:linear-gradient(160deg,#0a3226,#072a20);
  box-shadow:inset 0 0 0 1px rgba(231,206,143,.1), inset 0 0 60px rgba(0,0,0,.5);
}

/* gold aura behind the whole book */
.pp3d-book::before{
  content:""; position:absolute; inset:-24%; border-radius:50%; z-index:-1;
  background:radial-gradient(50% 50% at 50% 50%, rgba(231,206,143,.16), rgba(201,162,75,.06) 45%, transparent 72%);
  filter:blur(8px); opacity:.5; pointer-events:none; transform:translateZ(-40px);
}

/* ---------- cover contents (shared helper classes) ---------- */
.pp3d-issuer{ font-size:9px; letter-spacing:.26em; text-transform:uppercase; color:var(--gold-light,#E7CE8F); opacity:.85; position:relative; z-index:2; }
.pp3d-crest{ position:relative; z-index:2; filter:drop-shadow(0 3px 10px rgba(201,162,75,.35)); }
.pp3d-title{ font-family:var(--ar,'Cairo'),sans-serif; direction:rtl; font-size:19px; font-weight:800; color:var(--gold-light,#E7CE8F); line-height:1.5; position:relative; z-index:2; }
.pp3d-title small{ display:block; font-family:var(--serif,'Playfair Display'),serif; font-size:12px; letter-spacing:.14em; color:var(--paper,#F6F1E6); margin-top:6px; direction:ltr; font-weight:600; }
.pp3d-chip{ width:34px; height:26px; border-radius:4px; margin:2px auto 0; position:relative; z-index:2;
  background:linear-gradient(135deg,var(--gold-light,#E7CE8F),var(--gold-dark,#8A6A2E)); opacity:.9; }
.pp3d-foot{ font-size:8.5px; letter-spacing:.22em; text-transform:uppercase; color:var(--gold,#C9A24B); position:relative; z-index:2; }

/* "tap to open" cue — a visible pill on the closed cover */
.pp3d-hint{ position:absolute; left:50%; bottom:12px; z-index:4;
  font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; white-space:nowrap;
  color:#0C3B2E; background:linear-gradient(135deg,var(--gold-light,#E7CE8F),var(--gold,#C9A24B));
  padding:6px 14px; border-radius:100px; pointer-events:none;
  box-shadow:0 4px 12px rgba(0,0,0,.4);
  animation:pp3dHint 2.2s ease-in-out infinite; }
@keyframes pp3dHint{ 0%,100%{ transform:translateX(-50%) translateY(0); opacity:.9; } 50%{ transform:translateX(-50%) translateY(-3px); opacity:1; } }
.pp3d[data-pp-open="open"] .pp3d-hint{ opacity:0; animation:none; }

/* ---------- inside (the ID / visa spread), sits under the cover ---------- */
.pp3d-inside{
  position:absolute; inset:0; border-radius:12px; overflow:hidden;
  display:flex; flex-direction:column; justify-content:center;      /* centre the content */
  padding:28px 22px 54px; transform:translateZ(0);
  /* a lighter steel-teal "data page" so it reads as the passport interior,
     distinct from the app's green branding behind it */
  background:radial-gradient(120% 90% at 50% 0%, #16455c 0%, #103449 45%, #0d2a3d 100%);
  box-shadow:inset 0 0 0 1px rgba(231,206,143,.3), inset 0 0 60px rgba(0,0,0,.45);
}
/* engraved gold frame — the border that makes the open page read as a passport */
.pp3d-inside::before{ content:""; position:absolute; inset:12px; border-radius:6px;
  border:1px solid rgba(231,206,143,.32); pointer-events:none; }
/* faux machine-readable zone along the bottom */
.pp3d-inside::after{
  content:"P<SAU<AI<PASSPORT<<<<<<<<<<<<<<<<<<<\A" "<<<<<<<<<<<<SAU<26<<<<<<<<<<<<<<<<<08";
  position:absolute; left:14px; right:14px; bottom:14px; white-space:pre; overflow:hidden;
  direction:ltr; unicode-bidi:isolate;                 /* MRZ is a machine string, always LTR */
  font-family:'IBM Plex Mono',monospace; font-size:8.5px; line-height:1.75;
  letter-spacing:.1em; text-align:center; color:rgba(231,206,143,.5);
  border-top:1px solid rgba(231,206,143,.18); padding-top:8px;
}
/* let the app's existing .cred render cleanly as the inner page */
.pp3d-inside .cred{ background:none !important; border:none !important; box-shadow:none !important; margin:0 !important; padding:0 !important; }

/* ---------- flip-book variant: data page + one page per stamp ---------- */
/* the inside becomes a 3D binding the pages hinge on; it hides its own frame/MRZ
   (each page carries its own) and must not clip, so pages can turn out of plane */
.pp3d--pages .pp3d-inside{
  display:block; padding:0; overflow:visible;
  background:none; box-shadow:none; transform-style:preserve-3d;
}
.pp3d--pages .pp3d-inside::before, .pp3d--pages .pp3d-inside::after{ display:none; }

/* each page: a full passport-sized leaf that turns on the right hinge (RTL) */
.pp-page{
  position:absolute; inset:0; border-radius:12px; overflow:hidden;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:12px;
  padding:30px 24px; text-align:center;
  background:radial-gradient(120% 90% at 50% 0%, #16455c 0%, #103449 45%, #0d2a3d 100%);
  box-shadow:inset 0 0 0 1px rgba(231,206,143,.3), inset 0 0 55px rgba(0,0,0,.45);
  backface-visibility:hidden; -webkit-backface-visibility:hidden;
  transform-origin:right center;
  transition:transform .6s cubic-bezier(.4,0,.2,1), opacity .4s ease;
  transform:rotateY(-108deg); opacity:0; pointer-events:none;
}
.pp-page::before{ content:""; position:absolute; inset:12px; border-radius:6px;
  border:1px solid rgba(231,206,143,.3); pointer-events:none; }
.pp-page[data-state="active"]{ transform:rotateY(0deg); opacity:1; pointer-events:auto; z-index:3; }
.pp-page[data-state="before"]{ transform:rotateY(108deg); opacity:0; z-index:1; }   /* already turned */
.pp-page[data-state="after"]{ transform:rotateY(-108deg); opacity:0; z-index:1; }    /* not yet reached */

.pp-page-eyebrow{ font-family:var(--serif,'Playfair Display'),serif; font-size:10px; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase; color:var(--gold-light,#E7CE8F); opacity:.85; }
.pp-page--id{ justify-content:flex-start; padding-top:34px; }
.pp-page--id .pp-page-eyebrow{ margin-bottom:18px; }

/* a stamp page: big seal, city, earned/locked status */
.pp-stamp-big{ width:130px; height:130px; display:grid; place-items:center; }
.pp-stamp-city{ font-family:var(--ar,'Cairo'),sans-serif; direction:rtl; font-size:26px; font-weight:800; color:var(--paper,#F6F1E6); line-height:1.3; }
.pp-stamp-city small{ display:block; font-family:var(--serif,'Playfair Display'),serif; font-size:12px; letter-spacing:.18em; color:var(--gold-light,#E7CE8F); margin-top:4px; direction:ltr; }
.pp-stamp-status{ font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim,#a9bcb0);
  border:1px solid var(--line,rgba(201,162,75,.28)); border-radius:100px; padding:5px 14px; }
.pp-stamp-status.on{ color:#9fe6c4; border-color:rgba(21,127,90,.6); background:rgba(21,127,90,.14); }
.pp-stamp-status.prog{ color:var(--gold-light,#E7CE8F); border-color:rgba(201,162,75,.5); background:rgba(201,162,75,.1); }
/* earned = inked gold seal, slightly pressed; locked = greyed out */
.pp-stamp-big.earned{ transform:rotate(-6deg); filter:drop-shadow(0 3px 10px rgba(201,162,75,.45)); }
.pp-stamp-big.locked{ filter:grayscale(1) brightness(.6); opacity:.38; }
/* 10·10·10·10: filling ring around the not-yet-earned stamp (done/total lessons) */
.pp-stamp-big{ position:relative; }
.pp-stamp-ring{ position:absolute; inset:0; display:grid; place-items:center; pointer-events:none; }
.pp-stamp-ring .sap-ring{ width:130px; height:130px; }

/* nav bar under the passport (open only): prev · dots · next */
.pp-nav{ display:none; direction:ltr; align-items:center; justify-content:center; gap:16px; margin-top:14px; }
.pp3d[data-pp-open="open"] .pp-nav{ display:flex; }
.pp-nav-btn{ width:36px; height:36px; border-radius:50%; display:grid; place-items:center;
  border:1px solid var(--line-2,rgba(201,162,75,.5)); background:rgba(255,255,255,.03);
  color:var(--gold-light,#E7CE8F); font:600 20px/1 var(--serif,serif); cursor:pointer; transition:.2s; }
.pp-nav-btn:hover{ border-color:var(--gold,#C9A24B); background:rgba(201,162,75,.1); }
.pp-nav-btn:active{ transform:scale(.94); }
.pp-dots{ display:flex; gap:8px; }
.pp-dot{ width:7px; height:7px; border-radius:50%; background:rgba(231,206,143,.28); cursor:pointer; transition:.2s; }
.pp-dot.on{ background:var(--gold-light,#E7CE8F); transform:scale(1.3); }

/* close chip on the open passport */
.pp-close{ position:absolute; top:8px; left:8px; z-index:6; width:30px; height:30px; border-radius:50%;
  display:none; place-items:center; cursor:pointer;
  border:1px solid var(--line,rgba(201,162,75,.28)); background:rgba(0,0,0,.4); color:var(--gold-light,#E7CE8F); font-size:14px; }
.pp3d[data-pp-open="open"] .pp-close{ display:grid; }

/* ---------- reduced motion / no-sensor fallback ---------- */
@media (prefers-reduced-motion:reduce){
  .pp3d-book{ animation:none; --pp-floatY:0px; }
  .pp3d-cover-face::after{ animation:none; }
  .pp3d-cover{ transition:transform .18s ease; }
}

@media (max-width:380px){
  .pp3d{ width:82vw; }
  .pp3d-title{ font-size:17px; }
}
