/* ============================================================
   MASTERY PEAK
   Note: the first ~20 lines are actually the outer .castle-scene
   wrapper, not Mastery Peak - it's a single short rule that happened
   to sit at this point in the original file before the file was split
   by section. Left here rather than moved, to keep this split a pure
   reordering-free extraction of the original biomes.css (verified
   byte-for-byte against it). All the substantial content below that
   first rule is Mastery Peak's.
   ============================================================ */

  /* ============================================================
     CASTLE OF GAMES - interior scene
     ============================================================ */
  .castle-scene{
    position:absolute; inset:0; z-index:5;
    display:flex;
    flex-direction:column;
    opacity:0; visibility:hidden; pointer-events:none;
    transition:opacity .25s ease;
    background:
      radial-gradient(ellipse 70% 55% at 82% 0%, rgba(200,30,58,.16), transparent 62%),
      radial-gradient(ellipse 55% 40% at 4% 100%, rgba(150,60,220,.10), transparent 60%),
      linear-gradient(160deg, var(--castle-bg) 0%, #0a0812 100%);
    color:var(--castle-ink);
    font-family:'Spectral',serif;
    overflow:hidden;
    cursor:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M12%201L21%208L12%2023L3%208Z%22%20fill%3D%22%23c81e3a%22%20stroke%3D%22%23f4e9cf%22%20stroke-width%3D%221.3%22%20stroke-linejoin%3D%22round%22/%3E%3Cpath%20d%3D%22M3%208H21M8%208L12%201L16%208M8%208L12%2023L16%208%22%20stroke%3D%22%23f4e9cf%22%20stroke-width%3D%220.9%22%20fill%3D%22none%22/%3E%3C/svg%3E") 12 3, auto;
  }
  #destPanel.show.castle-mode .castle-scene{ opacity:1; visibility:visible; pointer-events:auto; }

  /* ============================================================
     MASTERY PEAK - interior scene (imported from peak.html)
     ============================================================ */
  /* ── mountain scene ── */
      .peak-scene {
        position: absolute;
        inset: 0;
        z-index: 5;
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: opacity .25s ease;
        background: #0a0e1a;
        /* .peak-scene itself no longer scrolls - see .peak-scroll-inner
           below. Everything that's a direct child of .peak-scene (top
           bar, progress ring, back-to-top, parallax/gradient/particle
           layers) is therefore genuinely static relative to the screen:
           plain position:absolute against a non-scrolling ancestor just
           works, on every browser, with no transform/compositing hacks
           needed. */
        overflow: hidden;
        cursor: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M2%2020L9%207L13%2014L17%205L22%2020Z%22%20fill%3D%22%23dfe8ff%22%20stroke%3D%22%231c2130%22%20stroke-width%3D%221.3%22%20stroke-linejoin%3D%22round%22/%3E%3C/svg%3E") 12 20, auto;
      }
      .peak-scroll-inner {
        /* This is the ONE element that actually scrolls. Previously
           .peak-scene itself had overflow-y:auto while ALSO being the
           containing block for the "pinned" overlay elements
           (.scroll-gradient, .parallax-bg, .peak-progress, .back-top,
           .peak-topbar, etc). That doesn't work: position:absolute
           descendants of a scrolling element scroll away together WITH
           the rest of that element's content once you scroll it - they
           are not automatically exempt just because they're absolute.
           That's what was causing the sky/parallax band and the HUD
           elements to visibly detach and vanish after about one screen's
           worth of scrolling, on both mobile and desktop.
           Splitting the scrolling region into its own dedicated element,
           with the overlay chrome living OUTSIDE it as siblings, is the
           standard, reliable way to build a fixed header/footer over an
           independently scrolling content pane - it needs no special
           positioning trickery for the overlays at all. */
        position: absolute;
        inset: 0;
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        padding: 0 0 80px 0;
        transform: translateZ(0);
      }
      #destPanel.show.peak-mode .peak-scene{ opacity: 1; visibility: visible; pointer-events: auto; }
  
      /* Dynamic background gradient */
      .scroll-gradient {
        /* This and the other overlay layers below (parallax-bg, particles,
           cloud-layer, peak-topbar, peak-progress, back-top) are
           position:absolute against .peak-scene. That only stays visually
           pinned during scroll because .peak-scene itself does NOT scroll
           (see .peak-scroll-inner) - absolute-positioned children of an
           element that DOES scroll move away with its content just like
           anything else in it, which is what used to make this whole
           layer detach and vanish after the first screen of scrolling. */
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 0;
        pointer-events: none;
        transition: none;
        /* No will-change here on purpose: `background` isn't a compositable
           property, so will-change:background doesn't get this onto the GPU -
           it just forces the browser to keep a standing paint-promoted layer
           for a full-viewport element that JS already repaints on every
           scroll tick, which is pure overhead stacked on top of an already
           expensive per-frame repaint. */
      }
  
      /* Parallax layers */
      .parallax-bg {
        position: absolute; /* was fixed - see .scroll-gradient note above */
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        pointer-events: none;
        z-index: 0;
        will-change: transform;
        overflow: hidden;
      }
      .parallax-bg .layer {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-size: cover;
        background-repeat: repeat-x;
        background-position: bottom center;
        will-change: transform;
        transition: none;
      }
      .parallax-bg .layer-mountains {
        /* Was height:70%/bottom:0, which put a hard div edge partway down the
           viewport - stacked with will-change:transform GPU layer promotion,
           that edge showed up as a visible seam. Spanning the full height and
           moving the same visual transition into gradient stops (which always
           blend continuously, no compositing edge) removes the seam while
           keeping the same color distribution. */
        background: linear-gradient(180deg, transparent 0%, transparent 51%, #1c3350 72%, #2c4a63 86%, #4a6a74 100%);
        opacity: 0.5;
        height: 100%;
        top: 0;
      }
      .parallax-bg .layer-ridges {
        background: linear-gradient(180deg, transparent 0%, transparent 69.8%, #16233d 80.8%, #1c3350 100%);
        opacity: 0.35;
        height: 100%;
        top: 0;
      }
      .parallax-bg .layer-mist {
        background: radial-gradient(ellipse at 30% 80%, rgba(200, 220, 255, 0.08), transparent 60%),
          radial-gradient(ellipse at 70% 70%, rgba(200, 220, 255, 0.05), transparent 50%);
        height: 100%;
        bottom: 0;
        opacity: 0.6;
      }
      .parallax-bg .layer-glow {
        background: radial-gradient(ellipse at 50% 100%, rgba(244, 233, 207, 0.04), transparent 50%);
        height: 100%;
        bottom: 0;
        opacity: 0.6;
      }
  
      /* ── floating particles ── */
      #peakParticles {
        position: absolute; /* was fixed - see .scroll-gradient note above */
        inset: 0;
        pointer-events: none;
        z-index: 1;
        overflow: hidden;
      }
      .peak-particle {
        position: absolute;
        border-radius: 50%;
        background: rgba(255, 255, 255, 0.5);
        animation: floatParticle linear infinite;
        will-change: transform;
      }
      @keyframes floatParticle {
        0% {
          transform: translateY(-10vh) translateX(0) scale(1);
          opacity: 0;
        }
        10% {
          opacity: 1;
        }
        90% {
          opacity: 1;
        }
        100% {
          transform: translateY(110vh) translateX(var(--drift)) scale(0.4);
          opacity: 0;
        }
      }
  
      /* ── Cloud layer (JS-driven) ── */
      .cloud-layer {
        position: absolute; /* was fixed - see .scroll-gradient note above */
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        pointer-events: none;
        z-index: 1;
        overflow: hidden;
      }
      .cloud-obj {
        position: absolute;
        border-radius: 50%;
        background: rgba(220, 235, 255, 0.15);
        filter: blur(2px);
        will-change: transform, opacity;
      }
      .cloud-obj::before {
        content: '';
        position: absolute;
        border-radius: 50%;
        background: inherit;
        filter: blur(4px);
      }
  
      /* ── top bar ── */
      .peak-topbar {
        /* Every other pinned overlay in this scene (.scroll-gradient,
           .parallax-bg, #peakParticles, .cloud-layer, .peak-progress,
           .back-top, #summitCelebration) is position:absolute against
           .peak-scene rather than position:fixed/sticky, specifically
           because .peak-scene is itself the scrolling container - see the
           .scroll-gradient comment. This was the one element still using
           position:sticky, and unlike the others it would intermittently
           let card content underneath paint over it mid-scroll (sticky
           elements are re-anchored by the browser on every scroll frame,
           which is extra per-frame work the plain-absolute elements never
           need and where this was going wrong). Matching the same
           position:absolute; top:0 pattern as everything else pins it
           just as reliably at the top and removes that per-frame
           re-anchoring step entirely. */
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        box-sizing: border-box;
        z-index: 20;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 18px 34px;
        background: rgba(10, 14, 26, 0.85);
        backdrop-filter: blur(16px);
        border-bottom: 1px solid rgba(238, 244, 251, 0.08);
        flex-shrink: 0;
        /* Even with .peak-scene no longer scrolling, this bar still sits
           in a very busy stacking context (confetti canvas, particles,
           clouds, parallax layers all animating via rAF simultaneously).
           Under enough simultaneous layer churn, headless/low-power
           renderers can occasionally show a stale raster of whatever's
           immediately behind it for a frame - giving it its own stable,
           dedicated compositing layer stops it from ever depending on
           being freshly repainted in lockstep with everything else. */
        transform: translateZ(0);
        will-change: transform;
      }
      .peak-title {
        margin: 0;
        font-weight: 400;
        font-family: 'Cinzel', serif;
        letter-spacing: 0.22em;
        font-size: 13px;
        color: rgba(238, 244, 251, 0.6);
        text-transform: uppercase;
      }
      .peak-title strong {
        color: #dfe8ff;
      }
      .peak-return {
        font-family: 'Oswald', sans-serif;
        letter-spacing: 0.12em;
        font-size: 12px;
        font-weight: 600;
        text-transform: uppercase;
        color: rgba(238, 244, 251, 0.7);
        background: transparent;
        border: 1px solid rgba(238, 244, 251, 0.2);
        border-radius: 2px;
        padding: 9px 20px;
        cursor: pointer;
        transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, transform 0.15s ease;
      }
      .peak-return:hover,
      .peak-return:focus-visible {
        color: #0d1220;
        background: #dfe8ff;
        border-color: #dfe8ff;
        transform: translateY(-1px);
      }
      .peak-return:active {
        transform: scale(0.95);
      }
  
      /* ── progress ring (fixed, bottom-left) ── */
      .peak-progress {
        position: absolute; /* was fixed - see .scroll-gradient note above; this is also the "stays put while content underneath moves and overlaps" element that was reported */
        bottom: 30px;
        left: 30px;
        z-index: 100;
        display: flex;
        align-items: center;
        gap: 14px;
        pointer-events: none;
        background: rgba(10, 14, 26, 0.8);
        backdrop-filter: blur(16px);
        border: 1px solid rgba(238, 244, 251, 0.10);
        border-radius: 50px;
        padding: 10px 20px 10px 14px;
        box-shadow: 0 8px 40px rgba(0, 0, 0, 0.6);
        transition: border-color 0.4s ease;
      }
      .progress-ring-wrap {
        position: relative;
        width: 52px;
        height: 52px;
        flex-shrink: 0;
      }
      .progress-ring-wrap svg {
        transform: rotate(-90deg);
        width: 52px;
        height: 52px;
      }
      .progress-ring-wrap .bg-ring {
        fill: none;
        stroke: rgba(238, 244, 251, 0.12);
        stroke-width: 3;
      }
      .progress-ring-wrap .fg-ring {
        fill: none;
        stroke: #f4e9cf;
        stroke-width: 3;
        stroke-linecap: round;
        transition: stroke-dashoffset 0.2s ease, stroke 0.4s ease;
      }
      .progress-label {
        font-family: 'Share Tech Mono', monospace;
        font-size: 13px;
        color: #f4e9cf;
        letter-spacing: 0.04em;
        white-space: nowrap;
        transition: color 0.4s ease;
      }
      .progress-label small {
        display: inline-block;
        font-size: 9px;
        opacity: 0.5;
        letter-spacing: 0.08em;
        margin-left: 4px;
      }
  
      /* ── trail container ── */
      .peak-trail {
        position: relative;
        z-index: 2;
        padding: 20px 20px 40px;
        max-width: 900px;
        margin: 0 auto;
      }
  
      /* ── trail line ── */
      .trail-line-wrap {
        position: absolute;
        top: 0;
        left: 50%;
        width: 4px;
        height: 100%;
        transform: translateX(-50%);
        pointer-events: none;
        z-index: 0;
        opacity: 0.6;
      }
      .trail-line-wrap svg {
        display: block;
        width: 100%;
        height: 100%;
      }
      .trail-line-wrap .trail-path {
        fill: none;
        stroke: url(#trailGrad);
        stroke-width: 3;
        stroke-dasharray: 8 12;
        animation: trailFlow 2.4s linear infinite;
      }
      .trail-line-wrap .trail-glow {
        fill: none;
        stroke: rgba(244, 233, 207, 0.12);
        stroke-width: 12;
        filter: blur(8px);
      }
      @keyframes trailFlow {
        0% {
          stroke-dashoffset: 0;
        }
        100% {
          stroke-dashoffset: -20;
        }
      }
  
      /* ── camp cards ── */
      .peak-camp {
        position: relative;
        z-index: 2;
        margin-bottom: 80px;
        display: flex;
        justify-content: center;
        opacity: 0;
        transform: translateY(50px) scale(0.95);
        transition: opacity 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          transform 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2);
        /* will-change is applied in JS only for the ~0.9s this actually
           transitions, then removed - see mountain.js. Six cards each
           holding a permanent will-change is six standing GPU layers for
           content that (after that one reveal) never changes again; on a
           phone GPU that's compositing budget better spent on the parts of
           the scene that animate continuously (particles, clouds). */
      }
      .peak-camp.visible {
        opacity: 1;
        transform: translateY(0) scale(1);
      }
      /* Alternate card positioning with wide margins to push cards away from trail */
      .peak-camp:nth-child(odd) .pc-card {
        margin-right: 6%;
        margin-left: auto;
      }
      .peak-camp:nth-child(even) .pc-card {
        margin-left: 6%;
        margin-right: auto;
      }
  
      /* ── Camp marker (small circle on the trail line) ── */
      .pc-marker {
        position: absolute;
        left: 50%;
        top: 20px;
        width: 16px;
        height: 16px;
        margin-left: -8px;
        border-radius: 50%;
        background: #f4e9cf;
        border: 3px solid #0d1220;
        box-shadow: 0 0 0 4px rgba(244, 233, 207, 0.12);
        z-index: 2;
        transition: transform 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          box-shadow 0.5s ease, background 0.5s ease;
        left: 50%;
        transform: translateX(-50%);
      }
      .peak-camp.visible .pc-marker {
        transform: translateX(-50%) scale(1.2);
        box-shadow: 0 0 0 10px rgba(244, 233, 207, 0.06), 0 0 40px 14px rgba(244, 233, 207, 0.10);
      }
      /* active camp = "you are here", now the only position indicator on
         the trail since the redundant floating orb was removed, so it gets
         a stronger pulse and adopts that category's own accent color */
      .peak-camp.active-camp .pc-marker {
        background: var(--accent, #ffd97a);
        box-shadow: 0 0 0 16px color-mix(in srgb, var(--accent, #ffd97a) 16%, transparent),
          0 0 60px 28px color-mix(in srgb, var(--accent, #ffd97a) 20%, transparent);
        transform: translateX(-50%) scale(1.4);
        animation: markerBreathe 2.2s ease-in-out infinite;
      }
      @keyframes markerBreathe {
        0%, 100% { transform: translateX(-50%) scale(1.4); }
        50% { transform: translateX(-50%) scale(1.55); }
      }

      .pc-card {
        width: min(85%, 400px);
        background: rgba(10, 14, 26, 0.6);
        border: 1px solid rgba(238, 244, 251, 0.08);
        border-left: 3px solid color-mix(in srgb, var(--accent, #f4e9cf) 45%, transparent);
        border-radius: 10px;
        padding: 24px 26px 28px;
        backdrop-filter: blur(8px);
        transition: transform 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          box-shadow 0.4s ease, border-color 0.4s ease, background 0.4s ease;
        box-shadow: 0 8px 40px rgba(0, 0, 0, 0.3);
        position: relative;
        overflow: visible;
        cursor: default;
      }
      .pc-card::before {
        content: '';
        position: absolute;
        inset: 0;
        background: linear-gradient(135deg, rgba(244, 233, 207, 0.03), transparent 60%);
        pointer-events: none;
        border-radius: 10px;
      }
      .pc-card:hover {
        transform: translateY(-6px) scale(1.01);
        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
        border-color: rgba(238, 244, 251, 0.18);
        border-left-color: var(--accent, #f4e9cf);
      }
      .peak-camp.active-camp .pc-card {
        background: rgba(20, 28, 50, 0.75);
        border-color: rgba(244, 233, 207, 0.2);
        border-left-color: var(--accent, #f4e9cf);
        box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4), 0 0 40px color-mix(in srgb, var(--accent, #f4e9cf) 12%, transparent);
      }
      .pc-card h3 {
        font-family: 'Oswald', sans-serif;
        font-weight: 600;
        font-size: 16px;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        margin-bottom: 14px;
        display: flex;
        align-items: center;
        gap: 12px;
        color: #f4e9cf;
      }
      .pc-card h3 .pc-icon {
        width: 24px;
        height: 24px;
        flex-shrink: 0;
        opacity: 0.95;
        color: var(--accent, #f4e9cf);
      }
      .pc-skills {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
      }
      .pc-skill {
        font-family: 'Share Tech Mono', monospace;
        font-size: 11px;
        letter-spacing: 0.02em;
        padding: 5px 14px;
        border-radius: 24px;
        background: rgba(238, 244, 251, 0.05);
        border: 1px solid rgba(238, 244, 251, 0.08);
        display: flex;
        align-items: center;
        gap: 8px;
        color: #eef4fb;
        transition: all 0.3s ease;
        cursor: pointer;
        position: relative;
        user-select: none;
      }
      .pc-skill .pc-dot {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        flex-shrink: 0;
        transition: transform 0.3s ease, box-shadow 0.3s ease;
      }
      .pc-skill.lvl-core .pc-dot {
        background: #f4e9cf;
        box-shadow: 0 0 10px rgba(244, 233, 207, 0.4);
      }
      .pc-skill.lvl-comfortable .pc-dot {
        background: #9fc7e8;
        box-shadow: 0 0 10px rgba(159, 199, 232, 0.3);
      }
      .pc-skill.lvl-learning .pc-dot {
        background: transparent;
        border: 1.5px solid rgba(238, 244, 251, 0.4);
      }
      .pc-skill:hover {
        background: rgba(238, 244, 251, 0.10);
        border-color: rgba(238, 244, 251, 0.2);
        transform: translateY(-2px);
        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
      }
      .pc-skill:hover .pc-dot {
        transform: scale(1.5);
        box-shadow: 0 0 20px rgba(244, 233, 207, 0.5);
      }
      .pc-skill .skill-tip {
        position: absolute;
        bottom: calc(100% + 10px);
        left: 50%;
        transform: translateX(-50%) scale(0.9);
        background: rgba(10, 14, 26, 0.95);
        backdrop-filter: blur(12px);
        border: 1px solid rgba(238, 244, 251, 0.12);
        border-radius: 6px;
        padding: 6px 16px;
        font-family: 'Spectral', serif;
        font-size: 11px;
        color: #f4e9cf;
        white-space: nowrap;
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.25s ease, transform 0.25s ease;
        z-index: 50;
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
      }
      .pc-skill:hover .skill-tip {
        opacity: 1;
        transform: translateX(-50%) scale(1);
      }
      .pc-skill.skill-flash {
        animation: skillFlash 0.4s ease;
      }
      @keyframes skillFlash {
        0% {
          background: rgba(244, 233, 207, 0.3);
          transform: scale(1);
        }
        50% {
          transform: scale(1.15);
          background: rgba(244, 233, 207, 0.5);
        }
        100% {
          transform: scale(1);
          background: rgba(238, 244, 251, 0.05);
        }
      }
  
      /* ── Legend ── */
      .skill-legend {
        display: flex;
        gap: 20px;
        justify-content: center;
        flex-wrap: wrap;
        margin: 10px 0 24px;
        font-family: 'Share Tech Mono', monospace;
        font-size: 10px;
        color: rgba(238, 244, 251, 0.55);
        letter-spacing: 0.04em;
      }
      .skill-legend span {
        display: flex;
        align-items: center;
        gap: 6px;
      }
      .skill-legend .dot-sample {
        width: 9px;
        height: 9px;
        border-radius: 50%;
        flex-shrink: 0;
      }
      .skill-legend .dot-sample.core {
        background: #f4e9cf;
        box-shadow: 0 0 8px rgba(244, 233, 207, 0.4);
      }
      .skill-legend .dot-sample.comfortable {
        background: #9fc7e8;
        box-shadow: 0 0 8px rgba(159, 199, 232, 0.3);
      }
      .skill-legend .dot-sample.learning {
        background: transparent;
        border: 1.5px solid rgba(238, 244, 251, 0.4);
      }
  
      /* ── intro ── */
      .peak-intro {
        position: relative;
        z-index: 2;
        text-align: center;
        margin-bottom: 80px;
        opacity: 0;
        transform: translateY(30px);
        transition: opacity 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          transform 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2);
      }
      .peak-intro.visible {
        opacity: 1;
        transform: translateY(0);
      }
      .peak-intro .pi-eyebrow {
        font-family: 'Share Tech Mono', monospace;
        font-size: 11px;
        letter-spacing: 0.24em;
        text-transform: uppercase;
        color: rgba(238, 244, 251, 0.5);
        margin-bottom: 10px;
      }
      .peak-intro h2 {
        font-family: 'Cinzel', serif;
        font-weight: 700;
        font-size: clamp(30px, 4.5vw, 44px);
        letter-spacing: 0.02em;
        margin-bottom: 10px;
        background: linear-gradient(135deg, #f4e9cf, #dfe8ff);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
      }
      .peak-intro p {
        font-style: italic;
        color: rgba(238, 244, 251, 0.7);
        font-size: 15px;
        max-width: 500px;
        margin: 0 auto;
      }
  
      /* ── summit ── */
      .peak-summit {
        position: relative;
        z-index: 2;
        text-align: center;
        margin: 80px 0 70px;
        padding: 50px 20px 40px;
        background: rgba(10, 14, 26, 0.3);
        border-radius: 16px;
        border: 1px solid rgba(244, 233, 207, 0.08);
        backdrop-filter: blur(4px);
        opacity: 0;
        transform: translateY(40px) scale(0.97);
        transition: opacity 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          transform 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          box-shadow 0.6s ease;
      }
      .peak-summit.visible {
        opacity: 1;
        transform: translateY(0) scale(1);
      }
      .peak-summit.visible.summit-reached {
        box-shadow: 0 0 80px 30px rgba(244, 233, 207, 0.06);
      }
      .peak-summit .ps-eyebrow {
        font-family: 'Share Tech Mono', monospace;
        font-size: 11px;
        letter-spacing: 0.24em;
        text-transform: uppercase;
        color: rgba(36, 28, 8, 0.5);
        margin-bottom: 8px;
      }
      .peak-summit h3 {
        font-family: 'Cinzel', serif;
        font-weight: 700;
        font-size: 26px;
        color: #f4e9cf;
        margin-bottom: 28px;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 16px;
        flex-wrap: wrap;
        text-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
      }
      .summit-flag {
        display: inline-block;
        width: 48px;
        height: 56px;
        flex-shrink: 0;
        filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.3));
      }
      .summit-flag .flag-pole {
        fill: #4a3826;
      }
      .summit-flag .flag-cloth {
        fill: #f4e9cf;
        transform-origin: 14px 12px;
        animation: waveFlag 1.8s ease-in-out infinite alternate;
      }
      .summit-flag .flag-cloth-shadow {
        fill: rgba(0, 0, 0, 0.15);
        transform-origin: 14px 12px;
        animation: waveFlag 1.8s ease-in-out infinite alternate;
      }
      @keyframes waveFlag {
        0% {
          transform: rotate(-4deg) skewX(-2deg);
        }
        100% {
          transform: rotate(4deg) skewX(2deg);
        }
      }
  
      /* ── Glass Box ── */
      .glass-box {
        background: rgba(10, 14, 26, 0.6);
        backdrop-filter: blur(12px);
        border: 1px solid rgba(238, 244, 251, 0.10);
        border-radius: 16px;
        padding: 30px 24px;
        box-shadow: 0 8px 40px rgba(0, 0, 0, 0.3);
        transition: border-color 0.3s ease, box-shadow 0.3s ease;
      }
      .glass-box:hover {
        border-color: rgba(238, 244, 251, 0.18);
        box-shadow: 0 12px 48px rgba(0, 0, 0, 0.4);
      }
  
      .ps-badges {
        display: flex;
        gap: 24px;
        justify-content: center;
        flex-wrap: wrap;
      }
      .ps-badge {
        width: 140px;
        text-decoration: none;
        color: #f4e9cf;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 8px;
        transition: transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          filter 0.3s ease;
        position: relative;
      }
      .ps-badge:hover {
        transform: translateY(-8px) scale(1.04);
        filter: drop-shadow(0 12px 32px rgba(244, 233, 207, 0.2));
      }
      .ps-badge:active {
        transform: scale(0.95);
      }
      .ps-flag {
        width: 52px;
        height: 62px;
        flex-shrink: 0;
        transition: transform 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.2);
      }
      .ps-badge:hover .ps-flag {
        transform: rotate(-5deg) scale(1.06);
      }
      .ps-badge .ps-label {
        font-family: 'Oswald', sans-serif;
        font-weight: 600;
        font-size: 12px;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        text-align: center;
        line-height: 1.3;
      }
      .ps-badge .ps-date {
        font-family: 'Share Tech Mono', monospace;
        font-size: 9.5px;
        opacity: 0.7;
      }
  
      /* ── roadmap ── */
      .peak-climbing {
        position: relative;
        z-index: 2;
        text-align: center;
        max-width: 580px;
        margin: 0 auto;
        padding-top: 10px;
        opacity: 0;
        transform: translateY(30px);
        transition: opacity 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2),
          transform 0.9s cubic-bezier(0.2, 0.9, 0.3, 1.2);
      }
      .peak-climbing.visible {
        opacity: 1;
        transform: translateY(0);
      }
      .peak-climbing .pcl-eyebrow {
        font-family: 'Share Tech Mono', monospace;
        font-size: 11px;
        letter-spacing: 0.24em;
        text-transform: uppercase;
        color: rgba(238, 244, 251, 0.5);
        margin-bottom: 10px;
      }
      .peak-climbing h3 {
        font-family: 'Cinzel', serif;
        font-weight: 700;
        font-size: 20px;
        color: #f4e9cf;
        margin-bottom: 18px;
        text-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
      }
      .route-list {
        display: flex;
        flex-direction: column;
        gap: 12px;
        align-items: flex-start;
      }
      .route-item {
        display: flex;
        align-items: center;
        gap: 14px;
        font-family: 'Share Tech Mono', monospace;
        font-size: 12px;
        color: #eef4fb;
        padding: 6px 0;
        width: 100%;
        border-bottom: 1px solid rgba(238, 244, 251, 0.06);
      }
      .route-item:last-child {
        border-bottom: none;
      }
      .route-marker {
        width: 10px;
        height: 10px;
        border-radius: 2px;
        background: #ffd97a;
        flex-shrink: 0;
        transform: rotate(45deg);
        box-shadow: 0 0 8px rgba(255, 217, 122, 0.3);
      }
      .route-text {
        text-align: left;
      }
  
      /* ── back to top ── */
      .back-top {
        position: absolute; /* was fixed - see .scroll-gradient note above; this is also the "stays put while content underneath moves and overlaps" element that was reported */
        bottom: 30px;
        right: 30px;
        z-index: 90;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        background: rgba(10, 14, 26, 0.9);
        backdrop-filter: blur(12px);
        border: 1px solid rgba(238, 244, 251, 0.15);
        color: #f4e9cf;
        font-size: 20px;
        cursor: pointer;
        opacity: 0;
        transform: translateY(24px) scale(0.8);
        transition: opacity 0.35s ease, transform 0.35s ease, background 0.3s ease, box-shadow 0.3s ease;
        display: flex;
        align-items: center;
        justify-content: center;
        box-shadow: 0 4px 28px rgba(0, 0, 0, 0.5);
        pointer-events: none;
      }
      .back-top.visible {
        opacity: 1;
        transform: translateY(0) scale(1);
        pointer-events: auto;
      }
      /* Applied by mountain.js whenever a card/heading is currently
         scrolling directly behind this badge - see updateBadgeCollisions.
         Dims rather than hides outright so it doesn't itself become a
         "content flickering in and out" distraction; pointer-events stay
         off while dimmed so a half-see-through button can't be tapped by
         mistake. */
      .peak-progress.badge-dim,
      .back-top.badge-dim {
        opacity: 0.22;
        pointer-events: none;
        transition: opacity 0.2s ease;
      }
      .back-top:hover {
        background: rgba(244, 233, 207, 0.12);
        border-color: rgba(238, 244, 251, 0.35);
        box-shadow: 0 4px 40px rgba(0, 0, 0, 0.6);
        color: #fff;
      }
      .back-top:active {
        transform: scale(0.9);
      }

      /* ── responsive ── */
      @media (max-width: 700px) {
        .peak-camp:nth-child(odd) .pc-card,
        .peak-camp:nth-child(even) .pc-card {
          margin-left: auto;
          margin-right: auto;
          width: 92%;
        }
        /* On desktop the trail marker sits in the gap beside an
           off-center card. This media query re-centers every card
           (above), which means that gap no longer exists - the marker's
           left:50%/top:20px was landing squarely on top of each card's
           heading, chopping out a circular bite of the title text. Moving
           it to sit just above the card, in the margin between one camp
           and the next, keeps it as a trail waypoint without ever
           overlapping card content. */
        .pc-marker {
          top: 0;
          transform: translate(-50%, -100%) translateY(-14px);
        }
        .peak-camp.visible .pc-marker {
          transform: translate(-50%, -100%) translateY(-14px) scale(1.2);
        }
        .peak-camp.active-camp .pc-marker {
          transform: translate(-50%, -100%) translateY(-14px) scale(1.4);
        }
        @keyframes markerBreatheMobile {
          0%, 100% { transform: translate(-50%, -100%) translateY(-14px) scale(1.4); }
          50% { transform: translate(-50%, -100%) translateY(-14px) scale(1.55); }
        }
        .peak-camp.active-camp .pc-marker {
          animation: markerBreatheMobile 2.2s ease-in-out infinite;
        }
        .peak-topbar {
          padding: 14px 18px;
        }
        .peak-title {
          font-size: 10px;
        }
        .peak-progress {
          bottom: 16px;
          left: 16px;
          padding: 6px 14px 6px 10px;
          gap: 10px;
          border-radius: 30px;
        }
        .progress-ring-wrap {
          width: 40px;
          height: 40px;
        }
        .progress-ring-wrap svg {
          width: 40px;
          height: 40px;
        }
        .progress-label {
          font-size: 11px;
        }
        .progress-label small {
          font-size: 8px;
        }
        .pc-card {
          padding: 18px 18px 22px;
        }
        .ps-badge {
          width: 110px;
        }
        .ps-flag {
          width: 40px;
          height: 48px;
        }
        .back-top {
          width: 44px;
          height: 44px;
          font-size: 18px;
          bottom: 16px;
          right: 16px;
        }
        .skill-legend {
          font-size: 9px;
          gap: 12px;
        }
        .peak-summit h3 {
          font-size: 20px;
        }
        .summit-flag {
          width: 40px;
          height: 48px;
        }
        .glass-box {
          padding: 20px 16px;
        }
      }
      @media (prefers-reduced-motion: reduce) {
        .peak-camp,
        .peak-intro,
        .peak-summit,
        .peak-climbing {
          opacity: 1 !important;
          transform: none !important;
          transition-duration: 0.001s !important;
        }
        .trail-line-wrap .trail-path {
          animation: none;
        }
        .peak-camp.active-camp .pc-marker {
          animation: none;
        }
        .pc-skill .skill-tip {
          display: none;
        }
        .peak-particle {
          animation-duration: 20s !important;
        }
        .ps-badge:hover {
          transform: none !important;
        }
        .pc-card:hover {
          transform: none !important;
        }
        .back-top {
          transition-duration: 0.001s !important;
        }
        .summit-flag .flag-cloth {
          animation: none !important;
        }
        .summit-flag .flag-cloth-shadow {
          animation: none !important;
        }
        .parallax-bg .layer {
          will-change: auto;
        }
      }
    

