/* Saga map home styles. Markup is rendered by saga.js. Same palette as
   lesson.css (dark navy + cyan/violet dust). All motion is CSS keyframes:
   star twinkle, spark drift, node bob, current-node breathing + ripple. */
:root{ --c:#7ce7ff; --c2:#a98bff; --bg:#070a12; --panel:#0d1220; --line:#1b2436;
       --txt:#cdd6ea; --dim:#6b7896; --ok:#7CFFB0; --warm:#ff9a5c; }
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:radial-gradient(1200px 700px at 70% -10%,#0e1730 0%,var(--bg) 60%);
     color:var(--txt);font:14px/1.5 "Segoe UI",system-ui,sans-serif;overflow:hidden}

.hdr{position:fixed;top:0;left:0;right:0;height:52px;display:flex;align-items:center;gap:18px;padding:0 18px;z-index:10}
.logo{font-weight:800;letter-spacing:2px;color:var(--c);text-shadow:0 0 14px color-mix(in srgb,var(--c) 60%,transparent)}
.logo small{color:var(--dim);font-weight:600;letter-spacing:1px}
.prog{margin-left:auto;padding:5px 14px;border:1px solid var(--line);border-radius:20px;color:var(--dim);font-size:12px;letter-spacing:2px}

/* Stroke/dash values are SVG user units (viewBox height = 100 ≈ viewport height). */
#sky{position:fixed;inset:0;width:100%;height:100%}
#trail{fill:none;stroke:var(--c);stroke-opacity:.14;stroke-width:.4;stroke-linecap:round;
       stroke-dasharray:.9 1.8}
#trailLit{fill:none;stroke:var(--c);stroke-opacity:.85;stroke-width:.55;stroke-linecap:round;
          filter:drop-shadow(0 0 1.2px var(--c));transition:stroke-dasharray 1s ease}

#stars,#sparks,#nodes{position:fixed;inset:0;pointer-events:none}
.star{position:absolute;border-radius:50%;background:#cfe9ff;animation:twinkle ease-in-out infinite}
@keyframes twinkle{0%,100%{opacity:.15}50%{opacity:.85}}
.spark{position:absolute;bottom:-10px;border-radius:50%;background:var(--c);opacity:0;
       box-shadow:0 0 6px var(--c);animation:rise linear infinite}
@keyframes rise{0%{transform:translateY(0);opacity:0}10%{opacity:.7}85%{opacity:.35}100%{transform:translateY(-108vh);opacity:0}}

.node{position:absolute;transform:translate(-50%,-50%);width:190px;text-align:center;pointer-events:auto;cursor:pointer}
.float{position:relative;animation:bob 6s ease-in-out infinite;animation-delay:calc(var(--i,0)*-1.9s)}
@keyframes bob{0%,100%{transform:translateY(-5px)}50%{transform:translateY(5px)}}

.orb{width:112px;height:112px;margin:0 auto;position:relative;border-radius:50%;
     border:2px solid color-mix(in srgb,var(--c) 50%,transparent);background:var(--panel);
     box-shadow:0 0 24px color-mix(in srgb,var(--c) 25%,transparent),inset 0 0 18px color-mix(in srgb,var(--c) 15%,transparent);
     transition:transform .2s}
.node:not(.locked):hover .orb{transform:scale(1.07)}
.art{position:absolute;inset:0;border-radius:50%;overflow:hidden}
.art img{width:100%;height:100%;object-fit:cover}
.mystery{display:grid;place-items:center;height:100%;font-size:44px;font-weight:900;color:var(--dim)}

.badge{display:none;position:absolute}
.node.locked .art img{filter:grayscale(1) brightness(.4)}
.node.locked .orb{border-color:#28324a;box-shadow:none}
.node.locked .banner{color:var(--dim)}
.node.locked .lock{display:grid;inset:0;place-items:center;font-size:30px;border-radius:50%;background:rgba(4,7,13,.45)}
.node.done .check{display:grid;top:-6px;right:-6px;width:30px;height:30px;place-items:center;border-radius:50%;
                  background:var(--ok);color:#04310f;font-weight:900;box-shadow:0 0 12px color-mix(in srgb,var(--ok) 60%,transparent)}
.node.done .orb{border-color:color-mix(in srgb,var(--ok) 55%,transparent);
                box-shadow:0 0 20px color-mix(in srgb,var(--ok) 22%,transparent)}

.node.current .orb{animation:breathe 2.4s ease-in-out infinite}
@keyframes breathe{0%,100%{box-shadow:0 0 22px color-mix(in srgb,var(--c) 35%,transparent)}
                   50%{box-shadow:0 0 48px color-mix(in srgb,var(--c) 80%,transparent)}}
.node.current .pulse{position:absolute;inset:-2px;border-radius:50%;border:2px solid color-mix(in srgb,var(--c) 70%,transparent);
                     animation:ripple 2.4s ease-out infinite}
@keyframes ripple{0%{transform:scale(1);opacity:.8}100%{transform:scale(1.6);opacity:0}}

/* arrival fanfare (.arrive, set by saga.js when returning from a sealed
   ritual): the orb pops in, a frame snaps around the whole node card and
   keeps pulsing, and START flashes until the student clicks through */
.node.arrive .orb{animation:breathe 2.4s ease-in-out infinite,arrivepop .7s cubic-bezier(.34,1.56,.64,1)}
@keyframes arrivepop{0%{transform:scale(.4)}70%{transform:scale(1.15)}100%{transform:scale(1)}}
.frame{position:absolute;inset:-14px -8px;border-radius:26px;pointer-events:none;border:2px solid var(--c);
       box-shadow:0 0 26px color-mix(in srgb,var(--c) 55%,transparent),inset 0 0 20px color-mix(in srgb,var(--c) 18%,transparent);
       animation:framein .8s cubic-bezier(.2,.9,.3,1.2) both,framepulse 1.7s ease-in-out .9s infinite}
@keyframes framein{0%{transform:scale(2.6);opacity:0}55%{opacity:1}100%{transform:scale(1);opacity:1}}
@keyframes framepulse{0%,100%{opacity:.4}50%{opacity:1}}
.node.arrive .start{animation:startflash .85s ease-in-out infinite}
@keyframes startflash{0%,100%{transform:scale(1);filter:brightness(1)}
                      50%{transform:scale(1.14);filter:brightness(1.5);
                          box-shadow:0 0 30px var(--c),0 0 60px color-mix(in srgb,var(--c) 55%,transparent)}}

.banner{margin-top:10px;font-weight:700;font-size:13px;letter-spacing:.4px;text-shadow:0 2px 8px #000}
.banner b{color:var(--c);margin-right:4px}
.start{display:inline-block;margin-top:8px;padding:5px 16px;border-radius:18px;color:#04121a;
       background:linear-gradient(180deg,color-mix(in srgb,var(--c) 55%,#fff),var(--c));font-weight:800;font-size:12px;letter-spacing:1px;
       box-shadow:0 0 18px color-mix(in srgb,var(--c) 55%,transparent)}

.themebtn{margin-left:14px;padding:6px 14px;border-radius:18px;cursor:pointer;font-weight:800;font-size:11px;letter-spacing:1.5px;
          color:var(--c);background:transparent;border:1px solid color-mix(in srgb,var(--c) 45%,transparent);transition:.25s}
.themebtn:hover{background:color-mix(in srgb,var(--c) 14%,transparent);box-shadow:0 0 14px color-mix(in srgb,var(--c) 35%,transparent)}

/* ── onboarding (onboard.js): ✋ high five → Pip intro; first visit only ── */
#ob{position:fixed;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;text-align:center;
    background:radial-gradient(900px 620px at 50% 42%,#0b1428 0%,var(--bg) 78%);transition:opacity .6s}
#ob.bye{opacity:0;pointer-events:none}
#obcam{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transform:scaleX(-1);opacity:0;filter:saturate(.7);transition:opacity .8s}
#ob.live #obcam{opacity:.14}
#ob .obin{position:relative;z-index:2;max-width:560px;padding:24px}
#ob .obin.gone{display:none}
/* --obc (0→1) = hold progress: the glyph flares and the vortex behind winds up */
#ob #rvortex{position:absolute;inset:0;pointer-events:none;z-index:1}
.obhand{font-size:110px;line-height:1;cursor:pointer;animation:obpulse 1.8s ease-in-out infinite;
        filter:drop-shadow(0 0 calc(24px + var(--obc,0)*46px) var(--c)) brightness(calc(1 + var(--obc,0)*.7))}
@keyframes obpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}
#ob h2{margin:14px 0 4px;letter-spacing:4px;color:#fff;text-shadow:0 0 30px color-mix(in srgb,var(--c) 55%,transparent)}
.obsub{color:var(--warm);letter-spacing:2px;font-size:12px;min-height:18px}
.obgauge{width:230px;height:8px;margin:18px auto 8px;border-radius:8px;background:#16203a;overflow:hidden}
.obgauge i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--c),#fff);box-shadow:0 0 12px var(--c)}
.obalt{margin-top:18px;color:var(--dim);font-size:11.5px;letter-spacing:1px}
.obavatar{width:120px;height:120px;margin:0 auto 18px;border-radius:50%;
          background:var(--pip) center/cover no-repeat,radial-gradient(circle at 38% 34%,#eaffff 0%,var(--c) 45%,transparent 78%);
          box-shadow:0 0 44px color-mix(in srgb,var(--c) 65%,transparent);animation:obpop .55s cubic-bezier(.34,1.56,.64,1) both}
@keyframes obpop{0%{transform:scale(0) rotate(-14deg)}100%{transform:scale(1) rotate(0)}}
.obbubble{background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:14px 18px;min-height:74px;text-align:left;cursor:pointer}
.obbubble b{display:block;color:var(--c);font-size:11px;letter-spacing:2px;margin-bottom:4px}
.obgo{margin-top:18px;border:none;cursor:pointer;font-size:14px;padding:10px 30px}
.obgo.gone{display:none}
.obflash{position:absolute;inset:0;background:#fff;opacity:0;pointer-events:none;z-index:3}
.obflash.go{animation:obflash .8s ease}
@keyframes obflash{0%{opacity:0}20%{opacity:.95}100%{opacity:0}}

.shake{animation:shake .45s ease}
@keyframes shake{0%,100%{translate:0}20%{translate:-7px 0}40%{translate:7px 0}60%{translate:-5px 0}80%{translate:5px 0}}

.toast{position:fixed;left:50%;bottom:36px;transform:translateX(-50%) translateY(12px);opacity:0;z-index:20;
       padding:10px 20px;border:1px solid var(--line);border-radius:22px;background:rgba(10,15,27,.92);
       color:var(--warm);font-size:13px;letter-spacing:.4px;pointer-events:none;transition:.3s}
.toast.show{opacity:1;transform:translateX(-50%)}
