• Websites
  • Courses
  • Purchase
  • Blog
  • About
  • Login

QuantaLumin Partners with Stripe...

Source Code

The Markdown we wrote for this page is displayed below. We then generated the HTML using a static site generator and our in-house code. Your browser then uses our Style Sheets and some Javascript to beautifully render the HTML. Please click the button to restore the page.

Restore Page
---
title: ""
description: "Purchase Your QuantaLumin Website"
date: ""
draft: false
params:
   list: false
summaries: false
sections:
- section: "wrapper style3 content-align-center pad"
---

<div id="payment-table"></div>

<!-- Loading Spinner -->
<div id="loading-spinner" style="display: none;">
  <div class="spinner"></div>
  <p id="loading-text">QuantaLumin Partners with Stripe...</p>
</div>

<style>


/* Loading Spinner Style */
#loading-spinner {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  z-index: 1000;
  background-color: rgba(0, 0, 0, 0.7);
  padding: 20px;
  border-radius: 8px;
  color: white;
  font-size: 1.2rem;
  display: none;
}

.spinner {
  border: 5px solid #000000;
  border-top: 5px solid #a3ff98;

  border-radius: 50%;
  width: 50px;
  height: 50px;
  animation: spin 2s linear infinite;
}

#loading-text {
  color: #ffffff;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Text Color Animation */
#loading-text {
}

}

  /* Payment Table Container */
  #payment-table {
    position: relative;
    overflow: visible;
  }

  /* ---------- Billing Controls Layout Refinement ---------- */
  .billing-controls {
    max-width: 800px;
    margin: 1rem auto;
    padding: 1rem;
    background: none;
    box-shadow: none;
    border-radius: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  /* Currency and Discount Inputs Container (moved to top) */
  .billing-extra {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
  }
  .currency-select,
  .discount-input {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: white;
  }
  .currency-select label,
  .discount-input label {
    font-size: 0.9rem;
    font-weight: bold;
    color: white;
  }
  .currency-select select,
  .discount-input input {
    padding: 0.4rem;
    border: 1px solid #ccc;
    border-radius: 4px;
    flex: 1;
    color: white;
  }

  /* Billing Courses Button (separate and wide) */
  .billing-courses {
    display: flex;
    justify-content: center;
    width: 100%;
  }
  .billing-courses .plan-button {
    width: 100%;
    background: black;
    color: white;
    border: none;
    padding: 0.5rem 1rem;
    cursor: pointer;
    background-image: linear-gradient(100deg, #000, #fff 50%, #000);
    background-size: 400% 200%;
    animation: shimmer 7s infinite;
  }

  /* Billing Toggle now contains only the websites buttons */
  .billing-toggle {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .billing-websites {
    color: black;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch; /* Enables smooth scrolling on iOS */
  }

  .billing-icon {
    font-size: 1.2rem;
    margin-right: 0.5rem;
  }

  .billing-toggle button {
    padding: 0.5rem 1rem;
    border: 1px solid #ccc;
    background: white;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.2s;
  }
  .billing-toggle button.active {
    background: #333;
    color: white;
    border-color: white;
  }

  /* Navbar styling in header-divider */
  .header-divider {
    overflow: visible; /* Ensure submenu is not clipped */
  }
  .header-divider {
    width: 100%;
    padding: 0.5rem 2.1rem;
    background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    transition: height 0.3s ease;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  #navbar ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: 1rem;
  }

  #navbar ul li {
    position: relative;
  }


    #navbar ul li a {
      display: block;       /* Make the whole li clickable */
      text-decoration: none; /* Remove underlines */
      padding: 0.5rem 1rem;
      color: inherit;
      transition: background 0.2s;
    }

  #navbar ul li a:hover {
    background-color: #f0f0f0;
    border-radius: 4px;
  }

  /* Ensure submenu styling */
  .submenu {
    display: none;
    position: absolute;
    top: calc(100% - 5px);
    left: 0;
    background: white;
    border: 1px solid #ccc;
    padding: 0.5rem;
    white-space: nowrap;
    z-index: 10000;
    border-radius: 4px;
  }

  .submenu li {
    display: block;
    margin: 0;
  }

  .submenu li a {
    padding: 0.3rem 0.8rem;
    color: black;
  }

  /* On mobile, make header-divider split vertically */
  @media (max-width: 600px) {
    .header-divider {
      flex-direction: column;
      align-items: stretch;
      height: auto;
      text-align: center;
      padding: 1rem 0;
    }

    .header-left, .header-center, .header-right {
      width: 100%;
      justify-content: center;
    }

    #navbar {
      z-index: 10000;
    }
    #navbar ul {
      flex-direction: column;
      align-items: top;
    }
    #navbar ul li {
      width: 100%;
    }

    .submenu {
      position: absolute;
      top: 100%;
      width: 100%;
      left: 0;
      text-align: center;
    }
  }
.has-submenu {
  cursor: pointer;
  position: relative;
}
.has-submenu:hover {
  background-color: #f0f0f0;
}
  /* ---------- Swipe Animations for Billing Buttons ---------- */
  @keyframes slideOut {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(-100%); opacity: 0; }
  }
  .slide-out { animation: slideOut 0.3s forwards; }

  @keyframes slideIn {
    from { transform: translateX(100%); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
  }
  .slide-in { animation: slideIn 0.3s forwards; }

  /* Discount Input Box Styles */
  .discount-input {
    margin: 0.5rem;
  }
  .discount-input input {
    padding: 0.4rem;
    border: 1px solid #ccc;
  }

  /* ---------- Orbital & Nucleus Animation ---------- */
  .orbit-rotation #orbital-1 {
    animation: rotateOrbit1 20s linear infinite;
    transform-origin: 0 0;
  }
  .orbit-rotation #orbital-2 {
    animation: rotateOrbit2 25s linear infinite;
    transform-origin: 0 0;
  }
  .orbit-rotation #orbital-3 {
    animation: rotateOrbit3 30s linear infinite;
    transform-origin: 0 0;
  }
  .orbit-rotation #orbital-4 {
    animation: rotateOrbit4 35s linear infinite;
    transform-origin: 0 0;
  }
  @keyframes rotateOrbit1 { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
  @keyframes rotateOrbit2 { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }
  @keyframes rotateOrbit3 { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
  @keyframes rotateOrbit4 { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }

  /* Nucleus & Glow */
  .nucleus-filled { fill: #a3ff98 !important; }
  @keyframes nucleusFlash {
    0%   { stroke: none; stroke-width: 0; }
    30%  { stroke: yellow; stroke-width: 4; }
    60%  { stroke: yellow; stroke-width: 4; }
    100% { stroke: none; stroke-width: 0; }
  }
  .nucleus-flash { animation: nucleusFlash 1s ease; }
  .card-glow { box-shadow: 0 0 40px 8px #a3ff98 !important; animation: nucleusFlash 1s ease; }
  /* Discount Applied Sticker */
  .discount-sticker {
    position: absolute;
    top: -10px;
    right: -10px;
    background: linear-gradient(120deg, gold, orange);
    color: #333;
    font-size: 0.75rem;
    padding: 0.25rem 0.5rem;
    border-radius: 12px;
    font-weight: bold;
    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    overflow: hidden;
  }

  /* ---------- Fade & Layout ---------- */
  .fade-in { animation: fadeIn 1s forwards; }
  .fade-out { animation: fadeOut 1s forwards; }
  @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
  @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }

  .billing-controls {
    display: flex; justify-content: space-between; align-items: center;
    flex-wrap: wrap; margin: 1rem auto; max-width: 800px; padding: 0 1rem;
    position: relative; overflow: hidden;
  }
  .billing-toggle {
    display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap;
    flex: 1; position: static; transform: none;
  }
  .billing-toggle button {
    padding: 0.4rem 0.8rem; border: 1px solid #ccc; background: white;
    border-radius: 0; cursor: pointer; transition: background 0.2s;
    flex-shrink: 1; white-space: nowrap;
  }
  .billing-toggle button.active {
    background: black; color: white; border-color: black;
  }
  .currency-select {
    margin-left: auto; display: flex; align-items: center; gap: 0.5rem;
    font-size: 0.9rem; flex-shrink: 0;
  }
  .billing-four-months .short-text {
    display: none;
  }
  /* On mobile, stack label on top of input */
  @media (max-width: 600px) {
    .currency-select,
    .discount-input {
      flex-direction: column;
      align-items: stretch;
    }
    .currency-select label,
    .discount-input label {
      margin-bottom: 0.3rem;
    }
      .billing-four-months .full-text {
      display: none;
    }
    .billing-four-months .short-text {
      display: inline;
    }
  }

  /* ---------- Plan Card Layout ---------- */
  #plan-cards {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(249px, 1fr));
    font-family: system-ui, sans-serif;
    max-width: 95vw;
    margin: auto;
    padding: 1rem;
  }
  .plan-wrapper {
    transform: translateY(30px);
    background-color: white;
  }
  @keyframes fadeSlide { to { opacity: 1; transform: translateY(0); } }
  .plan {
    width: 100%; /* Now fills the entire plan-wrapper */
    height: 100%;
    border: 1px solid black;
    border-radius: 0;
    padding: 1.5rem;
    box-shadow: 0 4px 10px rgba(0,0,0,0.05);
    position: relative;
    transition: transform 0.2s;
    display: flex;
    flex-direction: column;
    height: 100%; /* ensures card fills its container height */
  }
  .plan-title { font-size: 1.25rem; font-weight: bold; margin-bottom: 0.5rem; }
  .plan-price { font-size: 1.5rem; color: black; margin-bottom: 1rem; }
  .plan-price small { display: block; font-size: 0.75rem; color: #555; }
  .plan-desc { font-size: 0.95rem; color: black; margin-bottom: 1rem; }
  .plan-features {
    list-style: none;
    padding: 0;
    margin: 1rem 0;
    text-align: center;      /* center text for features */
    flex-grow: 1;            /* take remaining space */
    display: flex;
    flex-direction: column;
    align-items: center;     /* center list items */
    justify-content: center;
  }
  .plan-features li {
    text-align: center;
  }
  .plan-features li::before { content: "✓ "; color: green; }
  .plan-button {
    background: black;
    color: white;
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 0;
    cursor: pointer;
    font-size: 1rem;
    margin-top: auto;        /* pushes button to bottom */
    align-self: center; /* Centers the button horizontally */
    box-shadow: 8px 8px 10px rgba(0, 0, 0, 0.6);
  }
  .plan-button:hover { background: #333; }
  .secondary-button {
    background: black;
    margin-left: 0.5rem;
    border-radius: 0;
    color: white;
    padding: 0.5rem 1rem;
    border: none;
    cursor: pointer;
    font-size: 1rem;
  }
  .secondary-button:hover { background: #333; }
  .best-deal {
    position: absolute;
    top: -10px;
    right: -10px;
    background: linear-gradient(120deg, gold, orange);
    color: #333;
    font-size: 0.75rem;
    padding: 0.25rem 0.5rem;
    border-radius: 12px;
    font-weight: bold;
    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    overflow: hidden;
  }
  /* ---------- Selection & Atom Styles ---------- */
  .selection-container { padding: 0; font-family: system-ui, sans-serif; position: relative; }
  /* ---------- Fixed Header & Footer ---------- */
  .header-divider, .footer-divider {
    width: 100%; padding: 1rem 2.1rem; background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: height 0.3s ease;
    z-index: 10;
  }
  .header-divider { position: fixed; top: 0; left: 0; right: 0; height: 27vh; display: flex; align-items: center; }
  .footer-divider {
    position: fixed; bottom: 0; left: 0; right: 0; height: 8vh; display: flex; align-items: center; justify-content: flex-end;
    box-sizing: border-box; background: #a3ff98;
  }
  .header-left, .header-center, .header-right {
    flex: 1; display: flex; align-items: center; justify-content: center;
  }
  .header-center {
    height: 100%;
  }
  .header-left { justify-content: flex-start; }
  .header-right { justify-content: flex-end; }
  #atom-svg {
    width: auto; max-height: 200px; cursor: pointer;
  }
  @media (max-width: 600px) {
    .header-divider, .footer-divider { padding: 1rem; }
    .header-divider { height: 17vh; }
    .footer-divider { height: 10vh; }
    .body-divider { top: calc(18vh + 1rem); bottom: calc(10vh + 0.5rem); }
    .header-left, .header-center, .header-right { justify-content: center; width: 100%; }
    #atom-svg { width: 150px; height: 150px; }
    /* Make navbar items stack vertically on mobile */
    #navbar ul { flex-direction: column; align-items: flex-start; }
  }
  .back-button {
    background: black; border: none; padding: 0.5rem 1rem;
    border-radius: 0; cursor: pointer; font-size: 1rem; color: white;
  }
  .back-button:hover { background: #333; }
  /* ---------- Scrolling Body Section ---------- */
  .body-divider {
    scroll-behavior: smooth;
    position: fixed;
    top: calc(27vh);
    bottom: calc(8vh);
    left: 0; right: 0;
    overflow-y: auto;
    padding-bottom: 1rem;
  }
  .discount-message {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-overflow: ellipsis;
    white-space: nowrap;
    margin: 0;
    font-size: 24px;
    font-weight: bold;
    animation: tilt-n-move-shaking 8.3s linear infinite;
    text-shadow: 4px 4px 7px rgba(0, 0, 0, 0.6);
  }

@keyframes tilt-n-move-shaking {
  /* Shake Segment 1 (0%–8%) */
  0% {
    transform: translate(-50%, -50%) rotate(0deg);
  }
  4% {
    transform: translate(calc(-50% + 5px), calc(-50% + 5px)) rotate(5deg);
  }
  8% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  /* First Pause (8%–22%) */
  22% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  /* Shake Segment 2 (22%–30%) */
  26% {
    transform: translate(calc(-50% - 5px), calc(-50% + 5px)) rotate(-5deg);
  }
  30% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  /* Second Pause (30%–55%) */
  55% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  /* Shake Segment 3 (55%–63%) */
  59% {
    transform: translate(calc(-50% + 5px), calc(-50% + 5px)) rotate(5deg);
  }
  63% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  /* Third Pause (63%–75%) */
  75% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  /* Shake Segment 4 (75%–80%) */
  77.5% {
    transform: translate(calc(-50% - 5px), calc(-50% + 5px)) rotate(-5deg);
  }
  80% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  /* Fourth Pause (80%–100%) */
  100% {
    transform: translate(-50%, -50%) rotate(0deg);
  }
}

  /* ---------- Selection Cards Styles ---------- */
  .selection-section { margin-bottom: 2rem; }
  .selection-section h2 { text-align: center; margin-bottom: 1rem; color: white; }
  .selection-cards {
    padding: 0 1rem; box-sizing: border-box;
    display: grid; gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(249px, 1fr));
  }
  @keyframes swipeIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
  .swipe-in { animation: swipeIn 0.5s forwards; }
  .selection-card * { pointer-events: none; }
  .selection-card {
    z-index: 1; pointer-events: auto;
    border: 1px solid black; border-radius: 16px; padding: 1rem;
    box-shadow: 0 4px 10px rgba(0,0,0,0.05); cursor: pointer;
    transition: border 0.2s, box-shadow 0.2s, background-color 0.2s;
    position: relative; width: 100%; box-sizing: border-box;
    background: white;
  }
  .selection-card.selected {
    background-color: transparent;
    color: white;
    border: 2px solid white;
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  }
  .selection-card:hover:not(.selected) {
    border: 4px solid #a3ff98;
  }
  .selection-card:hover:.selected {
    border: 4px solid #fff;
  }
  .selection-card img { width: 100%; border-radius: 8px; margin-bottom: 0.5rem; }
  .selection-card h3 { font-size: 1.1rem; margin: 0.5rem 0; }
  .selection-card p { font-size: 0.9rem; margin: 0.5rem 0; color: white; }
  .selection-card .price { font-size: 1.2rem; color: inherit; margin-bottom: 0.5rem; }
  .electron-count { font-size: 0.85rem; color: #ccc; margin-bottom: 0.5rem; }

  /* Quiz Options Styling – using divs for clarity */
  .quiz-option {
    background: white;
    color: black;
    border: 2px solid #333;
    border-radius: 4px;
    padding: 4px 8px;  /* Reduced padding */
    margin: 4px;       /* Reduced margin */
    font-size: 1rem; /* Smaller text */
    text-align: center;
    cursor: pointer;
    min-width: 80px;   /* Ensure they fit within the header */
  }
  .quiz-option:hover {
    background: #eee;
  }
  .quiz-timer {
    font-size: 1.2rem;
    font-weight: bold;
    margin-bottom: 0.5rem;
  }
  .quiz-question {
    font-size: 0.8rem; /* Smaller text */
  }

  /* ---------- Electron & Photon Animations ---------- */
  .flying-electron {
    width: 10px; height: 10px; border-radius: 50%;
    background: black; position: fixed; z-index: 2000;
    border: 1px solid white;
    pointer-events: none; transition: left 0.8s ease, top 0.8s ease;
  }
  .flying-photon {
    position: fixed; z-index: 2000; pointer-events: none;
    border: 1px solid white;
    width: 36px; height: 18px; transition: left 0.8s ease, top 0.8s ease, opacity 0.8s ease;
  }

  /* Checkout Button Gradient */
  .checkout-btn {
    z-index: 10000;
    background-size: cover;
    color: white;
    border-color: none;
    background-color: black;
    padding: 0rem 1.2rem;
    cursor: pointer;
    box-sizing: border-box;
    white-space: nowrap;
    flex: 0 0 auto;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    background-image: linear-gradient(100deg, #000, #fff 50%, #000);
    background-size: 400% 200%;
    animation: shimmer 7s infinite;
    box-shadow: 8px 8px 10px rgba(0, 0, 0, 0.6);
  }

  @keyframes shimmer {
    0% {
      background-position: 0% 0%;
    }
    100% {
      background-position: -275% 0%;
    }
  }

#starfield {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;         /* Behind the content */
  pointer-events: none; /* Let clicks pass through to underlying elements */
  width: 100%;
  height: 200vh;
}

/* Default styling for the burger button and mobile navbar */
#burger-menu {
  font-size: 1.5rem;
  background: none;
  border: none;
  cursor: pointer;
  display: none; /* hidden on desktop */
}

/* Mobile adjustments */
@media (max-width: 600px) {
  /* Show the burger menu button */
  #burger-menu {
    display: block;
  }
  /* Hide the navbar by default */
  #navbar {
    display: none;
    width: 100%;
    background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  }
  /* Style the mobile navbar ul */
  #navbar ul {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  #navbar ul li {
    border-bottom: 1px solid #eee;
  }
  #navbar ul li a {
    display: block;
    padding: 0.75rem 1rem;
    color: black;
    text-decoration: none;
  }
  .quiz-timer {
    font-size: 4rem;
  }
  .quiz-question {
    font-size: 1.4rem; /* Smaller text */
  }
  .quiz-option {
    font-size: 1.4rem; /* Smaller text */
  }
  .scroll-container {
    position: relative;
    overflow: hidden; /* Hide anything outside this container */
    width: 100%;     /* Adjust container width as needed */
    left: 0;
    background: #a3ff98; /* Match background to the gradient start */
    height: 100%;
    margin-right: 10%;
  }
  .discount-message {
    position: absolute;
    top: 50%;
    /* Start the text fully off-screen to the right */
    left: 100%;
    transform: translateY(-50%);
    text-overflow: ellipsis;
    white-space: nowrap;
    margin: 0;
    font-size: 16px;
    font-weight: bold;
    animation: scroll-left 6s linear infinite;
  }
  /* Gradient overlay on the left edge */
  .scroll-container::before {
    z-index: 1000;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 50px; /* Adjust width to control fade distance */
    background: linear-gradient(to right, #a3ff98, rgba(255, 255, 255, 0));
    pointer-events: none; /* Allow clicks to pass through */
  }
  /* Gradient overlay on the right edge */
  .scroll-container::after {
    z-index: 1000;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 50px; /* Adjust fade distance */
    background: linear-gradient(to left, #a3ff98, rgba(255, 255, 255, 0));
    pointer-events: none;
  }

  @keyframes scroll-left {
    0% {
      /* Start at the right edge of the container */
      transform: translateX(0%) translateY(-50%);
    }
    100% {
      /* End past the left edge of the container */
      transform: translateX(-200%) translateY(-50%);
    }
  }
}

#mobile-logo {
  position: fixed;
  top: 0.5rem;      /* Adjust spacing as needed */
  left: 0.5rem;     /* Adjust spacing as needed */
  width: 30px;      /* Make the icon tiny */
  height: auto;
  cursor: pointer;
  z-index: 1000;    /* Ensure it's above other content */
}

/* Hide the mobile logo by default */
#mobile-logo {
  display: none;
}

/* Back button: tiny and fixed at top left */
#mobile-back {
  position: fixed;
  top: 0.5rem;
  left: 0.5rem;
  width: 30px;         /* Adjust size as needed */
  height: auto;
  cursor: pointer;
  z-index: 1000;
  display: none;       /* Hide by default on desktop */
}

/* Burger menu button: fixed at top right */
#burger-menu {
  position: fixed;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 1000;
  font-size: 1.5rem;
  background: none;
  border: none;
  cursor: pointer;
  display: none;       /* Hide by default on desktop */
}

/* Mobile styles */
@media (max-width: 600px) {
  #mobile-back,
  #burger-menu {
    display: block;
  }
  #navbar {
    display: none;
    position: absolute;
  }
  /* You can further style the nav menu for mobile here */
  #navbar ul {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  #navbar ul li {
    border-bottom: 1px solid #eee;
  }
  #navbar ul li a {
    display: block;
    padding: 0.75rem 1rem;
    color: black;
    text-decoration: none;
  }
}

/* On mobile, hide the default logo and show the mobile logo */
@media (max-width: 600px) {
  .logo {
    display: none;
  }
  #mobile-logo {
    display: block;
  }
}

.has-submenu .submenu {
  display: none;
}

/* When the submenu should be open (via JS toggle or hover) */
.has-submenu.active .submenu {
  display: block;
}

/* Alternatively, if you want to open on hover (desktop only), you can add: */
@media (min-width: 601px) {
  .has-submenu:hover .submenu {
    display: block;
  }
}

@media (max-width: 600px) {
  #navbar ul li a {
    display: block;
    width: 100%;
    padding: 0.75rem 1rem;
    color: black;
    text-decoration: none;
  }
}

/* Group Plan User Input Styles */
.user-input {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 1rem 0; /* Provides spacing from surrounding elements */
}
.user-input label {
  font-size: 0.9rem;
  font-weight: bold;
  color: inherit;
}
.user-input span {
  font-size: 0.9rem;
  min-width: 20px;
  text-align: center;
}
.user-input input[type="range"] {
  display: block;     /* Hidden on desktop */
  width: 100%;
}

main { background: none; } /* fix starfield creeping through */
</style>

<script src="https://js.stripe.com/v3/"></script>
<script>
  /* ------------------ GLOBAL STATE & DEBOUNCE UTILS ------------------ */
  const stripe = Stripe("pk_live_51OY9gGGxWcYgHR5Tap4m8YP4YD1z6hGYrnHs9JZEv7bH1sGt1tYLCuqBptcdp5F8orIWnAgMJM5WxaX34pA4yeRq00T4QhtSn6");
  let discountSpecificCourseType = ""; // When set, only courses of this type get the extra discount.
  let isProcessing = false;
  let currentDiscountCode = "";
  const originalPrices = {};
  const discountThresholds = { mentoring: 2, consulting: 2, product: 10, course: 18 };
  let discountUsed = { mentoring: false, consulting: false, product: false, course: false };
  let selectedPlan = null;
  let discountMentoringAvailable = false;
  let discountConsultingAvailable = false;
  let discountProductsAvailable = false;
  let discountCoursesAvailable = false;
  let discountAdditionalCoursesUnlocked = false;
  let discountPrompted = { mentoring: false, consulting: false, product: false, course: false };
  let selectionList = [];
  let additionalProductsVisible = false;
  const orbitalCapacities = [2, 8, 8, 18];
  const orbitalRadii = [20, 40, 60, 80];
  const exchangeRates = {
    GBP: 1,
    USD: 1.2821,   // 1 GBP ≈ 1.2821 USD
    EUR: 1.1667,   // 1 GBP ≈ 1.1667 EUR
    JPY: 188.4615, // 1 GBP ≈ 188.46 JPY
    INR: 106.5385, // 1 GBP ≈ 106.54 INR
    CAD: 1.7308,   // 1 GBP ≈ 1.7308 CAD
    AUD: 1.9487    // 1 GBP ≈ 1.9487 AUD
  };
  // Detect the user's locale as before, but fallback to GBP if the detected currency isn't in our rates
  const browserLocale = navigator.language || 'en-GB';
  const defaultCurrency = new Intl.NumberFormat(browserLocale, { style: 'currency', currency: 'GBP' })
                              .resolvedOptions().currency || 'GBP';
  const userCurrency = defaultCurrency in exchangeRates ? defaultCurrency : 'GBP';
  let selectedCurrency = userCurrency;
  // Make yearly the default billing option
  let currentBilling = "yearly";
  let enterpriseUsers = 1;
  let discountCodeActive = false;

  // Quiz
  let quizCompleted = false;  // Track if the quiz has been completed

  // Debounce utility to limit rapid function calls
  function debounce(func, delay) {
    let timeout;
    return function(...args) {
      clearTimeout(timeout);
      timeout = setTimeout(() => { func.apply(this, args); }, delay);
    };
  }

  /* ------------------ BASE DATA ------------------ */
const basePlans = [
  {
    name: "Student",
    description: "Establish your online presence.",
    features: ["Build your Website!", "Private Personal Email", "CV Hosting", "Integrated Note-Taking", "Secure Cloud Data & Code Hosting", "Protect your data from AI", "Donation Portal to Support You"],
    bestDeal: true,
    pricingGBP: {
      monthly: 10,
      four_months: 9.5,
      yearly: 9
    },
    stripePriceIds: {
      monthly: "price_1REoA3GxWcYgHR5Tsm8YrHBY",  // Updated
      four_months: "price_1REoA3GxWcYgHR5TVjOXDDIr",  // Updated
      yearly: "price_1REoA3GxWcYgHR5TzY1OxgKv"  // Updated
    },
  },
  {
    name: "Professional",
    description: "Distinguish yourself as the first search result.",
    features: ["Custom Domain Website", "Unlimited Email Aliases", "All-in-One System for Notes", "Secure & Private", "Bespoke Web-Design", "Donation Portal", "Integrated Payments System for your Digital Books"],
    pricingGBP: { monthly: 49, four_months: 45, yearly: 39 },
    stripePriceIds: {
      monthly: "price_1REoA0GxWcYgHR5TlDUsvAJN",  // Updated
      four_months: "price_1REoA0GxWcYgHR5TrwuUJgcY",  // Updated
      yearly: "price_1REoA0GxWcYgHR5TWtYqu18a"  // Updated
    }
  },
  {
    name: "Group",
    description: "Form your network, accelerate your research, and be at the cutting edge.",
    features: ["Organisational Tools", "All-in-One Collaborative & Secure System", "Unlimited Group Email Accounts", "Bespoke Group Websites", "We Promote your Group via Social Platforms", "Donation Portal", "Integrated Payments Solutions for your Courses & Digital Books"],
    pricingGBP: { monthly: 60, four_months: 56, yearly: 50 },
    stripePriceIds: {
      monthly: "price_1REoAGGxWcYgHR5TbQVfsVx4",  // Updated
      four_months: "price_1REoAGGxWcYgHR5Te4NrzpxX",  // Updated
      yearly: "price_1REoAHGxWcYgHR5ThzTomcpf"  // Updated
    },
    perUserGBP: 9,
  }
];

  const billingOptions = { monthly: "Monthly", four_months: "Four mo", yearly: "Yearly" };

const baseProducts = [
  {
    name: "AI Assistant",
    category: "product",
    priceGBP: 10,
    get electronCount() { return 1; },
    stripePriceIds: {
      monthly: 'price_1REoAdGxWcYgHR5TdoxcvhME',  // Updated
      four_months: 'price_1REoAdGxWcYgHR5T0DCUVXZO',  // Updated
      yearly: 'price_1REoAdGxWcYgHR5T47TqQjO2',  // Updated
    },
    discountPriceIds: {
      monthly: 'price_1REoAdGxWcYgHR5TV7rK7EBf',  // Updated
      four_months: 'price_1REoAdGxWcYgHR5T2vdvmlKO',  // Updated
      yearly: 'price_1REoAdGxWcYgHR5T1iFKajvt'  // Updated
    }
  },
  {
    name: "Website Analytics",
    category: "product",
    priceGBP: 10,
    get electronCount() { return 1; },
    stripePriceIds: {
      monthly: 'price_1REoAWGxWcYgHR5TjTmLJ81G',  // Updated
      four_months: 'price_1REoAWGxWcYgHR5TyROubMIz',  // Updated
      yearly: 'price_1REoAWGxWcYgHR5TklbC1nKP',  // Updated
    },
    discountPriceIds: {
      monthly: 'price_1REoAWGxWcYgHR5TNU4Zyg32',  // Updated
      four_months: 'price_1REoAVGxWcYgHR5TmanBxYTj',  // Updated
      yearly: 'price_1REoAVGxWcYgHR5TChyl5Eax'  // Updated
    }
  }
];

const baseCourses = [
  {
    name: "Physics",
    category: "course",
    priceGBP: 249,
    courseType: "Basic",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoAkGxWcYgHR5Titmg2WWn"  // Updated
  },
  {
    name: "Biology",
    category: "course",
    priceGBP: 249,
    courseType: "Basic",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoAfGxWcYgHR5TweoeYxdg"  // Updated
  },
  {
    name: "Coding for Scientists",
    category: "course",
    priceGBP: 299,
    courseType: "Advanced",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoA9GxWcYgHR5TKskzDwb7"  // Updated
  },
  {
    name: "Linux for Scientists",
    category: "course",
    priceGBP: 299,
    courseType: "University",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoA7GxWcYgHR5TTRxyTiLM"  // Updated
  },
  {
    name: "Design",
    category: "course",
    priceGBP: 299,
    courseType: "Advanced",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoACGxWcYgHR5TKHrgNu0S"  // Updated
  },
  {
    name: "Mathematics Course",
    category: "course",
    priceGBP: 249,
    courseType: "Basic",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoAFGxWcYgHR5TBB2HuX1j"  // Updated
  },
  {
    name: "Chemistry Course",
    category: "course",
    priceGBP: 249,
    courseType: "Basic",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoAhGxWcYgHR5TJqQ7VYcv"  // Updated
  },
  {
    name: "Entrepreneurship Dragon",
    category: "course",
    priceGBP: 299,
    courseType: "Entrepreneurship",
    get electronCount() { return this.priceGBP < 50 ? 3 : 4; },
    stripePriceId: "price_1REoA5GxWcYgHR5Ta1xSFjS6"  // Updated
  }
];

const planAddons = {
  Student: {
    name: "Mentoring",
    category: "mentoring",
    priceGBP: 20,
    get electronCount() { return 4; },
    stripePriceIds: {
      monthly: 'price_1REo9xGxWcYgHR5TxjgMPfEC',  // Updated
      four_months: 'price_1REo9xGxWcYgHR5TlItilby4',  // Updated
      yearly: 'price_1REo9xGxWcYgHR5ThLDS1WGJ',  // Updated
    }
  },
  Professional: {
    name: "Consulting",
    category: "consulting",
    priceGBP: 20,
    get electronCount() { return 5; },
    stripePriceIds: {
      monthly: 'price_1REo9uGxWcYgHR5TRa16ycNn',  // Updated
      four_months: 'price_1REo9uGxWcYgHR5TepnX31Gh',  // Updated
      yearly: 'price_1REo9uGxWcYgHR5TE2lfAHdS',  // Updated
    }
  },
  Group: {
    name: "Consulting",
    category: "consulting",
    priceGBP: 20,
    get electronCount() { return 5; },
    stripePriceIds: {
      monthly: 'price_1REo9uGxWcYgHR5TRa16ycNn',  // Updated
      four_months: 'price_1REo9uGxWcYgHR5TepnX31Gh',  // Updated
      yearly: 'price_1REo9uGxWcYgHR5TE2lfAHdS',  // Updated
    }
  }
};

  function getMentoringPlusStudent() {
    const basicPlan = basePlans.find(p => p.name === "Student");
    const mentoringAddon = planAddons["Student"];
    return {
      name: "Mentoring + Student",
      category: "mentoring",
      priceGBP: basicPlan.pricingGBP[currentBilling] + mentoringAddon.priceGBP,
      electronCount: mentoringAddon.electronCount
    };
  }

  /* ------------------ PAYMENT TABLE FUNCTIONS ------------------ */
// DRY pricing helper for all plans
function getPlanPricing(plan, billingCycle) {
  let basePrice;
  if (plan.name === "Group") {
    // For Group plans add per-user cost based on enterpriseUsers
    basePrice = plan.pricingGBP[billingCycle] + enterpriseUsers * (plan.perUserGBP || 0);
  } else {
    basePrice = plan.pricingGBP[billingCycle];
  }
  // Apply discount if active
  if (discountCodeActive) basePrice *= 0.5;
  // Convert price into selected currency
  const convertedPrice = convertToCurrency(basePrice);

  let monthlyRate = convertedPrice;
  let fullBillingText = "";
  if (billingCycle === "four_months") {
    fullBillingText = `${formatPrice(convertedPrice * 4)} billed every 4 months`;
  } else if (billingCycle === "yearly") {
    fullBillingText = `${formatPrice(convertedPrice * 12)} billed annually`;
  }
  // For monthly, the monthlyRate is already the converted per-month price.
  return { monthlyRate, fullBillingText };
}
  function convertToCurrency(usd) { return usd * exchangeRates[selectedCurrency]; }
  function formatPrice(amount) {
    const rounded = Math.round(amount * 2) / 2;
    // Determine if the rounded value has a fractional part.
    const fractionDigits = (rounded % 1 === 0) ? 0 : 1;
    return new Intl.NumberFormat(browserLocale, {
      style: "currency",
      currency: selectedCurrency,
      minimumFractionDigits: fractionDigits,
      maximumFractionDigits: fractionDigits
    }).format(rounded);
  }
  function updateGroupUsers(val) {
    enterpriseUsers = parseInt(val) || 1;
    updateGroupPriceOnly();
  }
function updateGroupPriceOnly() {
  const enterprisePriceElem = document.querySelector('[data-enterprise-price]');
  if (!enterprisePriceElem) return;
  const { monthlyRate, fullBillingText } = getPlanPricing(basePlans[2], currentBilling);
  const monthlyText = `${formatPrice(monthlyRate)}/mo`;
  enterprisePriceElem.innerHTML = currentBilling === "monthly"
    ? monthlyText
    : `${monthlyText} <small>${fullBillingText}</small>`;

  const input = document.querySelector('[data-enterprise-input]');
  if (input) input.value = enterpriseUsers;
}
  /* ------------------ INITIALIZE PAYMENT TABLE ------------------ */
  function createPaymentTable() {
    document.body.style.overflow = "";
    const container = document.getElementById("payment-table");
    container.innerHTML = `
      <div class="billing-controls">
        <!-- Currency and Discount Controls on top -->
        <div class="billing-extra">
          <div class="currency-select">
            <label for="currency">Currency:</label>
            <select id="currency" onchange="updateCurrency(this.value)">
              ${Object.keys(exchangeRates).map(cur => `
                <option value="${cur}" ${cur === selectedCurrency ? "selected" : ""}>${cur}</option>
              `).join("")}
            </select>
          </div>
          <div class="discount-input">
            <label for="discount-code">Discount:</label>
            <input
              type="text"
              id="discount-code"
              name="discount-code"
              autocomplete="off"
              placeholder="Enter code"
              value="${currentDiscountCode}"
              onkeyup="debouncedApplyDiscountCode(event)"
            />
          </div>
        </div>
        <!-- Billing Courses Button -->
        <div class="billing-courses">
          <button class="plan-button" onclick="jumpToCourses()">
            <i class="icon-courses"></i> Jump to Courses
          </button>
        </div>
        <!-- Billing Toggle now only contains the websites buttons -->
        <div class="billing-toggle">
          <div class="billing-websites">
            <span class="billing-icon"><i class="icon-website"></i></span>
            ${Object.entries(billingOptions).slice(0, 3).map(([key, label]) => `
              <button onclick="updateBilling('${key}')" class="${key === currentBilling ? 'active' : ''}">
                ${label}
              </button>
            `).join("")}
          </div>
        </div>
      </div>
      <div id="plan-cards">
${basePlans.map(plan => {
  const { monthlyRate, fullBillingText } = getPlanPricing(plan, currentBilling);
  const monthlyText = `${formatPrice(monthlyRate)}/mo`;
  return `
    <div class="plan-wrapper">
      <div class="plan">
        ${plan.bestDeal ? `<div class="best-deal">Best Deal</div>` : ""}
        <div class="plan-title">${plan.name}</div>
        <div class="plan-price" ${plan.name === "Group" ? 'data-enterprise-price' : ''}>
          ${currentBilling === "monthly"
            ? monthlyText
            : `${monthlyText} <small>${fullBillingText}</small>`}
        </div>
        <div class="plan-desc">${plan.description}</div>
        <ul class="plan-features">
          ${plan.features.map(f => `<li>${f}</li>`).join("")}
        </ul>
        ${
        plan.name === "Group" ? `
          <div class="user-input">
            <label for="enterprise-users">Users:</label>
            <span id="user-count-display">${enterpriseUsers}</span>
            <input type="range" id="enterprise-users-slider" min="1" max="100" value="${enterpriseUsers}"
                   oninput="updateGroupUsers(this.value); document.getElementById('user-count-display').textContent = this.value;"
                   data-enterprise-slider />
          </div>
        ` : ""}
        <button class="plan-button" onclick="choosePlan('${plan.name}')">Choose Plan</button>
      </div>
    </div>
  `;
}).join("")}
      </div>
    `;
    setTimeout(updateGroupPriceOnly, 50);
  }
  function updateBilling(type) {
    if (type === currentBilling) return;
    const billingToggle = document.querySelector(".billing-toggle");
    if (billingToggle) {
      billingToggle.classList.add('slide-out');
      setTimeout(() => {
        currentBilling = type;
        createPaymentTable();
        const newBillingToggle = document.querySelector(".billing-toggle");
        if (newBillingToggle) {
          newBillingToggle.classList.add('slide-in');
          setTimeout(() => { newBillingToggle.classList.remove('slide-in'); }, 300);
        }
      }, 300);
    }
  }
  function updateCurrency(newCurrency) {
    selectedCurrency = newCurrency;
    createPaymentTable();
  }

  const debouncedApplyDiscountCode = debounce(function(e) {
    applyDiscountCode(e);
  }, 500);

  function applyDiscountCode(e) {
    const code = e.target.value.trim().toUpperCase();
    currentDiscountCode = code; // Save the entered code globally
    discountCodeActive = (code === "QUANTUM50");

    // Only re-render when the user presses Enter
    if (e.key === "Enter") {
      createPaymentTable();
      e.preventDefault();
    }
  }
  function choosePlan(planName) {
    selectedPlan = planName;
    selectionList = [];
    discountMentoringAvailable = false;
    discountConsultingAvailable = false;
    discountProductsAvailable = false;
    discountCoursesAvailable = false;
    discountPrompted = { mentoring: false, consulting: false, product: false, course: false };
    discountUsed = { mentoring: false, consulting: false, product: false, course: false };
    additionalProductsVisible = true;
    showSelection(true);
  }
  function jumpToCourses() {
    selectedPlan = "Student";
    selectionList = [];
    discountMentoringAvailable = false;
    discountConsultingAvailable = false;
    discountProductsAvailable = false;
    discountCoursesAvailable = false;
    discountPrompted = { mentoring: false, consulting: false, product: false, course: false };
    discountUsed = { mentoring: false, consulting: false, product: false, course: false };
    planAddons["Student"] = getMentoringPlusStudent();
    showSelection(false);
  }

  /* ------------------ LOGO FUNCTIONS ------------------ */
  function toggleBurgerMenu() {
  const mobileNav = document.getElementById("navbar");
  if (!mobileNav) return;
  if (mobileNav.style.display === "block") {
    mobileNav.style.display = "none";
  } else {
    mobileNav.style.display = "block";
  }
}

function moveLogoToHeader() {
  // Select the logo inside the anchor (using a descendant selector)
  const logoWrapper = document.querySelector('a.logo > #logo-wrapper');
  const headerLeft = document.querySelector('.header-left');
  if (logoWrapper && headerLeft) {
    // Remove the logo from its current parent so it doesn't get duplicated
    logoWrapper.parentNode.removeChild(logoWrapper);
    // Clear any existing content in header-left to avoid duplicates
    headerLeft.innerHTML = '';
    // Append the detached logo element to the header
    headerLeft.appendChild(logoWrapper);
    logoWrapper.style.cursor = "pointer";
    logoWrapper.onclick = handleLogoBack;
  }
}

function moveLogoBack() {
  // Now select the logo from within the header-left
  const logoWrapper = document.querySelector('.header-left > #logo-wrapper');
  const originalContainer = document.querySelector('a.logo');
  if (logoWrapper && originalContainer) {
    // Remove the logo from the header to avoid duplication
    logoWrapper.parentNode.removeChild(logoWrapper);
    // Clear the anchor's content (if necessary) and reinsert the logo
    originalContainer.innerHTML = '';
    originalContainer.appendChild(logoWrapper);
    logoWrapper.style.cursor = "default";
    logoWrapper.onclick = null;
  }
}
  function handleLogoBack() {
    backToPayment();
  }
function setMainPadding(paddingValue) {
  const mainEl = document.querySelector("main");
  if (mainEl) {
    mainEl.style.padding = paddingValue;
  }
}
  /* ------------------ SELECTION & ATOM VIEW ------------------ */
function showSelection(includeAdditional) {
  setMainPadding("0"); // Set padding to 0 when opening the second table
  // Hide the footer when entering the selection view
  const footer = document.querySelector('footer');
  if (footer) {
    footer.style.display = 'none';
  }
  document.body.style.overflow = "hidden";
  const container = document.getElementById("payment-table");
  container.classList.add("fade-out");
  setTimeout(() => {
    container.innerHTML = buildSelectionHTML(includeAdditional);
    container.classList.remove("fade-out");
    container.classList.add("fade-in");
    setTimeout(() => { container.classList.remove("fade-in"); }, 500);
    moveLogoToHeader();
    updateAtomSVG();
    updateDiscountMessage();
    scrollToDiscountedItem();
    attachAtomTripleClick();
    attachAtomSingleClick();
  }, 1000);
}

function backToPayment() {
  setMainPadding(""); // Restore original padding when returning
  // Display the footer again when leaving the selection view
  const footer = document.querySelector('footer');
  if (footer) {
    footer.style.display = 'block';
  }
  document.body.style.overflow = "";
  const container = document.getElementById("payment-table");
  container.classList.add("fade-out");
  moveLogoBack();
  setTimeout(() => {
    createPaymentTable();
    container.classList.remove("fade-out");
    container.classList.add("fade-in");
    setTimeout(() => { container.classList.remove("fade-in"); }, 500);
  }, 500);
}

const additionalProductsByPlan = {
  "Student": [
    {
      name: "Operating System",
      category: "product",
      priceGBP: 10,
      electronCount: 2,
      stripePriceIds: {
        monthly:     'price_1REo9nGxWcYgHR5TXi8qas6X',  // Updated
        four_months: 'price_1REo9nGxWcYgHR5TKQOCdIQv',  // Updated
        yearly:      'price_1REo9nGxWcYgHR5T0fffC74r',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REo9nGxWcYgHR5T49FF3aB8',  // Updated
        four_months: 'price_1REo9nGxWcYgHR5TblsUJ63e',  // Updated
        yearly:      'price_1REo9nGxWcYgHR5T4bAiYIDy',  // Updated
      }
    },
    {
      name: "AI Assistant",
      category: "product",
      priceGBP: 10,
      electronCount: 1,
      stripePriceIds: {
        monthly:     'price_1QifhQGxWcYgHR5Thw2GRDdy',  // Updated
        four_months: 'price_1QifhQGxWcYgHR5TiJTfVYpX',  // Updated
        yearly:      'price_1QifhQGxWcYgHR5T0B5ai9kV',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REoAdGxWcYgHR5TV7rK7EBf',  // Updated
        four_months: 'price_1REoAdGxWcYgHR5T2vdvmlKO',  // Updated
        yearly:      'price_1REoAdGxWcYgHR5T1iFKajvt',  // Updated
      }
    }
  ],
  "Professional": [
    {
      name: "Website Analytics",
      category: "product",
      priceGBP: 10,
      electronCount: 1,
      stripePriceIds: {
        monthly:     'price_1QifmFGxWcYgHR5TOB1zkEis',  // Updated
        four_months: 'price_1QifmFGxWcYgHR5TvFhR8g9I',  // Updated
        yearly:      'price_1QifmFGxWcYgHR5TR5kBcN5J',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REoAWGxWcYgHR5TNU4Zyg32',  // Updated
        four_months: 'price_1REoAVGxWcYgHR5TmanBxYTj',  // Updated
        yearly:      'price_1REoAVGxWcYgHR5TChyl5Eax',  // Updated
      }
    },
    {
      name: "Operating System",
      category: "product",
      priceGBP: 10,
      electronCount: 2,
      stripePriceIds: {
        monthly:     'price_1REo9nGxWcYgHR5TXi8qas6X',  // Updated
        four_months: 'price_1REo9nGxWcYgHR5TKQOCdIQv',  // Updated
        yearly:      'price_1REo9nGxWcYgHR5T0fffC74r',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REo9nGxWcYgHR5T49FF3aB8',  // Updated
        four_months: 'price_1REo9nGxWcYgHR5TblsUJ63e',  // Updated
        yearly:      'price_1REo9nGxWcYgHR5T4bAiYIDy',  // Updated
      }
    },
    {
      name: "AI Assistant",
      category: "product",
      priceGBP: 20,
      electronCount: 2,
      stripePriceIds: {
        monthly:     'price_1REiVRGxWcYgHR5TgpRb4ic9',  // Updated
        four_months: 'price_1REiyGGxWcYgHR5T9dk1afLL',  // Updated
        yearly:      'price_1REiyGGxWcYgHR5TSQf8kCVR',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REoAdGxWcYgHR5TV7rK7EBf',  // Updated
        four_months: 'price_1REoAdGxWcYgHR5T2vdvmlKO',  // Updated
        yearly:      'price_1REoAdGxWcYgHR5T1iFKajvt',  // Updated
      }
    }
  ],
  "Group": [
    {
      name: "Website Analytics",
      category: "product",
      priceGBP: 10,
      electronCount: 1,
      stripePriceIds: {
        monthly:     'price_1REoAWGxWcYgHR5TjTmLJ81G',  // Updated
        four_months: 'price_1REoAWGxWcYgHR5TyROubMIz',  // Updated
        yearly:      'price_1REoAWGxWcYgHR5TklbC1nKP',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REoAWGxWcYgHR5TNU4Zyg32',  // Updated
        four_months: 'price_1REoAVGxWcYgHR5TmanBxYTj',  // Updated
        yearly:      'price_1REoAVGxWcYgHR5TChyl5Eax',  // Updated
      }
    },
    {
      name: "Operating System",
      category: "product",
      priceGBP: 10,
      electronCount: 2,
      stripePriceIds: {
        monthly:     'price_1REo9nGxWcYgHR5TXi8qas6X',  // Updated
        four_months: 'price_1REo9nGxWcYgHR5TKQOCdIQv',  // Updated
        yearly:      'price_1REo9nGxWcYgHR5T0fffC74r',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REo9nGxWcYgHR5T49FF3aB8',  // Updated
        four_months: 'price_1REo9nGxWcYgHR5TblsUJ63e',  // Updated
        yearly:      'price_1REo9nGxWcYgHR5T4bAiYIDy',  // Updated
      }
    },
    {
      name: "Advanced AI",
      category: "product",
      priceGBP: 20,
      electronCount: 2,
      stripePriceIds: {
        monthly:     'price_1REo9rGxWcYgHR5T5XT1ntbF',  // Updated
        four_months: 'price_1REo9rGxWcYgHR5TLbCRMNL9',  // Updated
        yearly:      'price_1REo9rGxWcYgHR5THL9e4Hwd',  // Updated
      },
      discountPriceIds: {
        monthly:     'price_1REo9rGxWcYgHR5TpsXLdwcj',  // Updated
        four_months: 'price_1REo9rGxWcYgHR5TYWqZ2qiT',  // Updated
        yearly:      'price_1REo9rGxWcYgHR5TKJ0hveJ5',  // Updated
      }
    }
  ]
};

function buildSelectionHTML(includeAdditional) {
  const courseCategoriesSet = new Set(baseCourses.map(c => c.courseType));
  const courseCategories = Array.from(courseCategoriesSet);

  let additionalProductsHTML = "";
  if (includeAdditional) {
    const addProds = additionalProductsByPlan[selectedPlan] || [];
    if (addProds.length) {
      additionalProductsHTML = `
         <div class="selection-section" id="product">
           <h2>Additional Products</h2>
           <div class="selection-cards swipe-in">
             ${addProds.map(p => buildSelectionCard(p, true)).join("")}
           </div>
         </div>
      `;
    }
  }

  let coursesHTML = "";
  courseCategories.forEach(cat => {
    const courses = baseCourses.filter(c => c.courseType === cat);
    if (courses.length) {
      coursesHTML += `
        <div class="selection-section" id="${cat.toLowerCase()}-courses">
          <h2>${cat} Courses</h2>
          <div class="selection-cards">
            ${courses.map(c => buildSelectionCard(c)).join("")}
          </div>
        </div>
      `;
    }
  });

  const planAddonData = planAddons[selectedPlan] || null;
  // Build submenu for courses with an indicator; clicking toggles submenu visibility
  const coursesSubmenuHTML = courseCategories.map(cat => `
    <li><a href="#${cat.toLowerCase()}-courses" style="color: black;">${cat}</a></li>
  `).join("");

const headerHTML = `
  <div class="header-divider" id="header-divider">
    <div class="header-left" id="logo-wrapper">
      <img src="/favicon/icon.svg" alt="Back" id="mobile-logo" onclick="handleLogoBack()" style="cursor: pointer;">
    </div>
    <div class="header-center">
      <svg id="atom-svg" viewBox="-85 -85 170 170" preserveAspectRatio="xMidYMid meet" style="overflow: visible;">
        <circle cx="0" cy="0" r="10" fill="#a3ff98">
          <animate attributeName="fill" values="#ebff00;#00ffff;#ebff00" dur="10s" repeatCount="indefinite" />
        </circle>
        <circle cx="0" cy="0" r="20" stroke="#aaa" fill="none"/>
        <circle cx="0" cy="0" r="40" stroke="#aaa" fill="none"/>
        <circle cx="0" cy="0" r="60" stroke="#aaa" fill="none"/>
        <circle cx="0" cy="0" r="80" stroke="#aaa" fill="none"/>
      </svg>
    </div>
    <div class="header-right">
      <button id="burger-menu" onclick="toggleBurgerMenu()">&#9776;</button>
      <nav id="navbar">
        <ul>
          <li>
            <a href="#products">🛒 Products</a>
          </li>
          <li class="has-submenu" onclick="toggleCoursesSubmenu()">
            <a href="javascript:void(0);" style="color: black; display: block;">
              🎓 Courses <span id="courses-indicator">▾</span>
            </a>
            <ul class="submenu" id="courses-submenu" style="display: none;">
              ${coursesSubmenuHTML}
            </ul>
          </li>
          <li>
            <a href="#plan-addon">
              ${selectedPlan === "Student" ? "🤝 Mentoring" : "💼 Consulting"}
            </a>
          </li>
        </ul>
      </nav>
    </div>
  </div>
`;

  return `
    <div class="selection-container">
      ${headerHTML}
      <div class="body-divider">
        ${additionalProductsHTML}
        ${coursesHTML}
        ${
          planAddonData
            ? `<div class="selection-section" id="plan-addon">
                 <h2>Plan-Specific Add-on</h2>
                 <div class="selection-cards">
                   ${buildSelectionCard(planAddonData, true)}
                 </div>
               </div>`
            : ""
        }
      </div>
    </div>
    <div class="footer-divider">
      <div class="scroll-container">
        <span id="discount-message" class="discount-message"></span>
      </div>
      <button class="checkout-btn" onclick="finalizeCheckout()">Checkout</button>
    </div>
  `;
}

function buildSelectionCard(item, isAddOn=false) {
  const isSelected = selectionList.some(sel => sel.name === item.name);
  const selectedItem = selectionList.find(sel => sel.name === item.name);
  let priceText = formatPrice(convertToCurrency(item.priceGBP));
  if (isAddOn || item.category === "product") { priceText += "/mo"; }
  return `
      <div class="selection-card ${isSelected ? 'selected' : ''}" data-name="${item.name}" onclick="toggleItem(event, '${item.name}')">
        <img src="https://via.placeholder.com/150" alt="${item.name}">
        <h3>${item.name}</h3>
        <p>${item.category === "course" ? "Expand your skills." : "Boost your plan."}</p>
        <div class="price">${priceText}</div>
        <div class="electron-count">⚛ ${item.electronCount}</div>
        ${isSelected && selectedItem && selectedItem.discountApplied ? `<div class="discount-sticker">Discount Applied!</div>` : ""}
      </div>
    `;
}

function toggleItem(event, itemName) {
  event.stopPropagation();
  const svg = document.getElementById("atom-svg");
  if (svg && svg.querySelector("foreignObject") && itemName && isCourse(itemName)) {
    updateAtomSVG();
    attachAtomTripleClick();
  }
  if (isProcessing) return;
  isProcessing = true;
  const allItems = [...baseCourses, ...baseProducts];
  if (planAddons[selectedPlan]) allItems.push(planAddons[selectedPlan]);
  if (additionalProductsVisible && additionalProductsByPlan[selectedPlan]) {
    allItems.push(...additionalProductsByPlan[selectedPlan]);
  }
  const itemData = allItems.find(x => x.name === itemName);
  if (!itemData) { isProcessing = false; return; }
  let discountAvailable = false;
  if (itemData.category === "course") {
    // 1) quiz‑unlocked Entrepreneurship
    if (discountAdditionalCoursesUnlocked && itemData.courseType === "Entrepreneurship") {
      discountAvailable = true;
    }
    // 2) any other “specific” course code you might have set
    else if (discountSpecificCourseType && itemData.courseType === discountSpecificCourseType) {
      discountAvailable = true;
    }
    // 3) the generic courses‑over‑18‑electron bonus
    else {
      discountAvailable = discountCoursesAvailable;
    }
  } else {
  // existing branches for mentoring, consulting, products
  if (itemData.category === "mentoring") discountAvailable = discountMentoringAvailable;
  if (itemData.category === "consulting") discountAvailable = discountConsultingAvailable;
  if (itemData.category === "product") discountAvailable = discountProductsAvailable;
}
  const currentlySelected = selectionList.find(x => x.name === itemName);
  if (currentlySelected) {
    if (discountAvailable && !currentlySelected.discountApplied) {
      if (!originalPrices[itemName]) originalPrices[itemName] = currentlySelected.priceGBP;
      currentlySelected.priceGBP *= 0.5;
      currentlySelected.discountApplied = true;
      if (itemData.category === "mentoring") { discountMentoringAvailable = false; discountUsed.mentoring = true; }
      else if (itemData.category === "consulting") { discountConsultingAvailable = false; discountUsed.consulting = true; }
      else if (itemData.category === "product") { discountProductsAvailable = false; discountUsed.product = true; }
      else if (itemData.category === "course") { discountCoursesAvailable = false; discountUsed.course = true; }
      updateSelectionCard(itemName);
      checkDiscounts().then(() => { isProcessing = false; });
      return;
    }
    removeItem(currentlySelected).then(() => {
      if (itemName === "Mentoring + Student") {
        additionalProductsVisible = false;
        showSelection(additionalProductsVisible);
      }
      checkDiscounts().then(() => { isProcessing = false; });
    });
  } else {
    const newItem = {
      name: itemData.name,
      category: itemData.category,
      priceGBP: itemData.priceGBP,
      electronCount: itemData.electronCount,
      stripePriceIds:   itemData.stripePriceIds   || null, // ← add this
      stripePriceId:    itemData.stripePriceId    || null, // keep for courses
      discountApplied: false,
      courseType: itemData.courseType || ""
    };
    originalPrices[newItem.name] = newItem.priceGBP;
    selectionList.push(newItem);
    if (discountAvailable) {
      newItem.priceGBP *= 0.5;
      newItem.discountApplied = true;
      if (itemData.category === "mentoring") { discountMentoringAvailable = false; discountUsed.mentoring = true; }
      else if (itemData.category === "consulting") { discountConsultingAvailable = false; discountUsed.consulting = true; }
      else if (itemData.category === "product") { discountProductsAvailable = false; discountUsed.product = true; }
      else if (itemData.category === "course") { discountCoursesAvailable = false; discountUsed.course = true; }
    }
    animateAddItem(newItem).then(() => {
      updateSelectionCard(itemName);
      if (itemName === "Mentoring + Student") {
        additionalProductsVisible = true;
        const bodyDiv = document.querySelector('.body-divider');
        if (bodyDiv) { bodyDiv.scrollTop = bodyDiv.scrollHeight - 100; }
        showSelection(additionalProductsVisible);
      }
      checkDiscounts().then(() => { isProcessing = false; });
    });
  }
}
function isCourse(itemName) {
  const allCourses = baseCourses.map(c => c.name);
  return allCourses.includes(itemName);
}
function updateSelectionCard(itemName) {
  const cardElement = document.querySelector(`.selection-card[data-name="${itemName}"]`);
  if (!cardElement) return;
  const selectedItem = selectionList.find(x => x.name === itemName);
  const existingSticker = cardElement.querySelector(".discount-sticker");
  if (selectedItem && selectedItem.discountApplied) {
    if (!existingSticker) {
      const newSticker = document.createElement("div");
      newSticker.className = "discount-sticker";
      newSticker.textContent = "Discount Applied!";
      cardElement.appendChild(newSticker);
    }
  } else {
    if (existingSticker) { existingSticker.remove(); }
  }
}
function removeItem(item) {
  return new Promise(resolve => {
    const idx = selectionList.findIndex(i => i.name === item.name);
    if (idx < 0) { resolve(); return; }
    const cardElement = document.querySelector(`.selection-card[data-name="${item.name}"]`);
    if (cardElement) {
      cardElement.classList.remove("selected");
      const sticker = cardElement.querySelector(".discount-sticker");
      if (sticker) { sticker.remove(); }
    }
    if (item.discountApplied) {
      if (item.category === "mentoring") discountUsed.mentoring = false;
      if (item.category === "consulting") discountUsed.consulting = false;
      if (item.category === "product") discountUsed.product = false;
      if (item.category === "course") discountUsed.course = false;
    }
    const baseIndex = selectionList.slice(0, idx).reduce((sum, it) => sum + it.electronCount, 0);
    const count = item.electronCount;
    const tasks = [];
    for (let i = 0; i < count; i++) {
      const reversedIndex = count - 1 - i;
      const globalIndex = baseIndex + reversedIndex;
      tasks.push(() => animateElectronOut(cardElement, globalIndex, i * 150));
    }
    Promise.all(tasks.map(fn => fn())).then(() => {
      selectionList.splice(idx, 1);
      updateAtomSVG();
      resolve();
    });
  });
}
function animateAddItem(item) {
  return new Promise(resolve => {
    const cardElement = document.querySelector(`.selection-card[data-name="${item.name}"]`);
    if (!cardElement) { resolve(); return; }
    cardElement.classList.add("selected");
    if (item.discountApplied) {
      const sticker = document.createElement("div");
      sticker.className = "discount-sticker";
      sticker.textContent = "Discount Applied!";
      cardElement.appendChild(sticker);
    }
    const idx = selectionList.findIndex(x => x.name === item.name);
    const baseIndex = selectionList.slice(0, idx).reduce((sum, it) => sum + it.electronCount, 0);
    const tasks = [];
    for (let i = 0; i < item.electronCount; i++) {
      tasks.push(() => animateElectronIn(cardElement, baseIndex + i, i * 150));
    }
    Promise.all(tasks.map(fn => fn())).then(() => {
      updateAtomSVG();
      resolve();
    });
  });
}
function distributeElectrons(total) {
  let remaining = total;
  const out = [];
  for (let i = 0; i < orbitalCapacities.length; i++) {
    const used = Math.min(remaining, orbitalCapacities[i]);
    out.push(used);
    remaining -= used;
  }
  return out;
}
function getElectronCoordinates(shellIndex, indexInShell, shellCount) {
  const r = orbitalRadii[shellIndex];
  if (shellCount === 0) return { x: 0, y: 0 };
  const angleStep = 360 / shellCount;
  const angle = angleStep * indexInShell;
  const rad = angle * Math.PI / 180;
  return { x: r * Math.cos(rad), y: r * Math.sin(rad) };
}
function globalIndexToShell(globalIndex, distribution) {
  let accum = 0;
  for (let s = 0; s < distribution.length; s++) {
    const c = distribution[s];
    if (globalIndex < accum + c) { return { shellIndex: s, indexInShell: globalIndex - accum }; }
    accum += c;
  }
  return { shellIndex: distribution.length - 1, indexInShell: 0 };
}
function updateAtomSVG() {
  const svg = document.getElementById("atom-svg");
  if (!svg) return;
  svg.querySelectorAll("foreignObject").forEach(el => el.remove());
  const header = document.getElementById("header-divider");
  if (header) {
    header.style.height = "25vh";
    const bodyDivider = document.querySelector(".body-divider");
    if (bodyDivider) { bodyDivider.style.top =  "25vh"; }
  }
  svg.innerHTML = `
    <circle cx="0" cy="0" r="10" fill="#a3ff98">
      <animate attributeName="fill" values="#ebff00;#00ffff;#ebff00" dur="10s" repeatCount="indefinite" />
    </circle>
    <circle cx="0" cy="0" r="20" stroke="#aaa" fill="none"/>
    <circle cx="0" cy="0" r="40" stroke="#aaa" fill="none"/>
    <circle cx="0" cy="0" r="60" stroke="#aaa" fill="none"/>
    <circle cx="0" cy="0" r="80" stroke="#aaa" fill="none"/>
  `;
  const total = selectionList.reduce((sum, it) => sum + it.electronCount, 0);
  const dist = distributeElectrons(total);
  dist.forEach((count, s) => {
    const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
    g.id = "orbital-" + (s + 1);
    svg.appendChild(g);
    for (let i = 0; i < count; i++) {
      const { x, y } = getElectronCoordinates(s, i, count);
      const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
      circle.setAttribute("cx", x);
      circle.setAttribute("cy", y);
      circle.setAttribute("r", s === 0 ? 3 : 4);
      circle.setAttribute("fill", "black");
      g.appendChild(circle);
    }
  });
  svg.classList.add("orbit-rotation");
  const nucleus = svg.querySelector("circle");
  nucleus.classList.remove("nucleus-filled");
  if (dist[0] === orbitalCapacities[0]) { nucleus.classList.add("nucleus-filled"); }
  applyGlowIfDiscount();
}
function animateElectronIn(sourceEl, globalIndex, delayMs = 0) {
  return new Promise(resolve => {
    setTimeout(() => {
      const total = selectionList.reduce((s, it) => s + it.electronCount, 0);
      const dist = distributeElectrons(total);
      const { shellIndex, indexInShell } = globalIndexToShell(globalIndex, dist);
      const { x, y } = getElectronCoordinates(shellIndex, indexInShell, dist[shellIndex]);
      const svg = document.getElementById("atom-svg");
      const pt = svg.createSVGPoint();
      pt.x = x; pt.y = y;
      const screenPt = pt.matrixTransform(svg.getScreenCTM());
      const [tx, ty] = [screenPt.x, screenPt.y];
      const rect = sourceEl.getBoundingClientRect();
      const sx = rect.left + rect.width / 2;
      const sy = rect.top + rect.height / 2;
      const electron = document.createElement("div");
      electron.className = "flying-electron";
      electron.style.left = sx + "px";
      electron.style.top = sy + "px";
      document.body.appendChild(electron);
      electron.getBoundingClientRect();
      electron.style.left = tx + "px";
      electron.style.top = ty + "px";
      electron.addEventListener("transitionend", () => { electron.remove(); resolve(); });
    }, delayMs);
  });
}
function animateElectronOut(targetEl, globalIndex, delayMs = 0) {
  return new Promise(resolve => {
    setTimeout(() => {
      const total = selectionList.reduce((s, it) => s + it.electronCount, 0) + 1;
      const dist = distributeElectrons(total);
      const { shellIndex, indexInShell } = globalIndexToShell(globalIndex, dist);
      const { x, y } = getElectronCoordinates(shellIndex, indexInShell, dist[shellIndex]);
      const svg = document.getElementById("atom-svg");
      const pt = svg.createSVGPoint();
      pt.x = x; pt.y = y;
      const sp = pt.matrixTransform(svg.getScreenCTM());
      const rect = targetEl.getBoundingClientRect();
      const tx = rect.left + rect.width / 2;
      const ty = rect.top + rect.height / 2;
      const angleDeg = Math.atan2(ty - sp.y, tx - sp.x) * (180 / Math.PI);
      const photon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      photon.classList.add("flying-photon");
      photon.setAttribute("viewBox", "0 0 10 10");
      photon.innerHTML = `<path d="M0,5 Q2.5,0 5,5 T10,5" stroke="black" fill="none" stroke-width="1"/>`;
      photon.style.position = "fixed";
      photon.style.left = sp.x + "px";
      photon.style.top = sp.y + "px";
      photon.style.transform = `rotate(${angleDeg}deg)`;
      document.body.appendChild(photon);
      photon.getBoundingClientRect();
      photon.style.left = tx + "px";
      photon.style.top = ty + "px";
      photon.style.opacity = "0";
      photon.addEventListener("transitionend", () => { photon.remove(); resolve(); });
    }, delayMs);
  });
}
function applyGlowIfDiscount() {
  let discountGlowing = false;

  // 1) pull in every item you ever render as a <.selection-card>
  const allItems = [
    ...baseCourses,
    ...baseProducts,
    // only if we’re showing them
    ...(additionalProductsVisible && additionalProductsByPlan[selectedPlan]
      ? additionalProductsByPlan[selectedPlan]
      : []),
    ...(planAddons[selectedPlan] ? [planAddons[selectedPlan]] : [])
  ];

  // 2) now loop cards and match by name
  document.querySelectorAll(".selection-card").forEach(card => {
    const name  = card.getAttribute("data-name");
    const found = allItems.find(i => i.name === name);
    if (!found) {
      // this card isn’t one of ours
      card.classList.remove("card-glow");
      return;
    }

    // 3) same logic as before for “should this glow?”
    let glow = false;
    if (found.category === "mentoring"   && discountMentoringAvailable)   glow = true;
    if (found.category === "consulting"   && discountConsultingAvailable)  glow = true;
    if (found.category === "product"      && discountProductsAvailable)    glow = true;
    if (found.category === "course"       && discountCoursesAvailable)     glow = true;
    if (found.category === "course"
     && found.courseType === "Entrepreneurship"
     && discountAdditionalCoursesUnlocked)                              glow = true;

    const selected = selectionList.some(x => x.name === name && x.discountApplied);
    if (selected) {
      card.classList.remove("card-glow");
    } else if (glow) {
      card.classList.add("card-glow");
      discountGlowing = true;
    } else {
      card.classList.remove("card-glow");
    }
  });

  // 4) nucleus flash if *any* card was glowing
  if (discountGlowing) {
    const svg = document.getElementById("atom-svg");
    if (svg) {
      const nucleus = svg.querySelector("circle");
      nucleus.classList.add("nucleus-flash");
      setTimeout(() => nucleus.classList.remove("nucleus-flash"), 1000);
    }
  }
}
function updateDiscountMessage() {
  const msgElem = document.getElementById("discount-message");
  if (!msgElem) return;

  // Clear the message if the discount on courses has been applied (as before)
  if (discountSpecificCourseType && discountUsed.course) {
    msgElem.textContent = "";
    return;
  }

  let discountCategories = [];
  if (discountMentoringAvailable) discountCategories.push("mentoring");
  if (discountConsultingAvailable) discountCategories.push("consulting");
  if (discountProductsAvailable) discountCategories.push("product");

  // Show a specific label if a specific course discount is active.
  if (discountSpecificCourseType) {
    discountCategories.push(discountSpecificCourseType + " courses");
  } else if (discountCoursesAvailable) {
    discountCategories.push("courses");
  }

  if (discountCategories.length > 0) {
    if (discountCategories.length === 1) {
      msgElem.textContent = "Discount unlocked for " + discountCategories[0] + "!";
    } else if (discountCategories.length === 2) {
      msgElem.textContent = "Discount unlocked for " + discountCategories.join(" and ") + "!";
    } else {
      msgElem.textContent = "Don't miss your discounts for " + discountCategories.slice(0, -1).join(", ") + " and " + discountCategories.slice(-1) + "!";
    }
    return;
  }

  const totalElectrons = selectionList.reduce((sum, it) => sum + it.electronCount, 0);
  if (totalElectrons === 0) {
    msgElem.textContent = "Select items to unlock more electrons!";
    return;
  }
  const needed = nextOrbitalNeed(totalElectrons);
  const allItems = [...baseCourses, ...baseProducts];
  if (planAddons[selectedPlan]) {
    allItems.push(planAddons[selectedPlan]);
  }
  const availableElectrons = allItems.filter(item => !selectionList.find(sel => sel.name === item.name))
                                     .reduce((sum, item) => sum + item.electronCount, 0);
  if (needed > 0 && availableElectrons >= needed) {
    msgElem.textContent = `You need ${needed} more electron${needed === 1 ? '' : 's'} to fill the next orbital.`;
  } else if (needed === 0) {
    msgElem.textContent = "All current orbitals are filled! Checkout when you're ready.";
  } else if  (!quizCompleted && !discountAdditionalCoursesUnlocked) {
    msgElem.textContent = "Can you split the atom?";
  } else {
    msgElem.textContent = "";
  }
}
function nextOrbitalNeed(total) {
  const dist = distributeElectrons(total);
  for (let i = 0; i < dist.length; i++) {
    if (dist[i] < orbitalCapacities[i]) { return orbitalCapacities[i] - dist[i]; }
  }
  return 0;
}
function checkDiscounts() {
  return new Promise(resolve => {
    const totalElectrons = selectionList.reduce((sum, it) => sum + it.electronCount, 0);
    selectionList.forEach(item => {
      const threshold = discountThresholds[item.category] || 0;
      if (item.discountApplied && totalElectrons < threshold) {
        if (originalPrices[item.name] !== undefined) { item.priceGBP = originalPrices[item.name]; }
        item.discountApplied = false;
        discountUsed[item.category] = false;
        updateSelectionCard(item.name);
      }
    });
    discountMentoringAvailable = false;
    discountConsultingAvailable = false;
    discountProductsAvailable = false;
    discountCoursesAvailable = false;
    if (totalElectrons >= 18 && !discountUsed.course) {
      discountCoursesAvailable = true;
      discountPrompted.course = true;
    }
    if (totalElectrons >= 10 && !discountUsed.product) {
      discountProductsAvailable = true;
      discountPrompted.product = true;
    }
    if (totalElectrons >= 2) {
      if (selectedPlan === "Student" && !discountUsed.mentoring) {
        discountMentoringAvailable = true;
        discountPrompted.mentoring = true;
      } else if (selectedPlan !== "Student" && !discountUsed.consulting) {
        discountConsultingAvailable = true;
        discountPrompted.consulting = true;
      }
    }
    applyGlowIfDiscount();
    updateDiscountMessage();

    // Delay the scroll a bit to ensure the discount element is rendered.
    setTimeout(() => {
     scrollToDiscountedItem();
    }, 50);

    resolve();
  });
}
function scrollToDiscountedItem() {
  const container = document.querySelector('.body-divider');
  // Find the first selection card that has a discount sticker
  const discountedCard = document.querySelector('.card-glow');
  if (!container || !discountedCard) {
    console.log('No discounted item or container found');
    return;
  }
  // Get the parent selection card element (the discounted item)
  const card = discountedCard.closest('.selection-card');
  if (!card) return;

  // Calculate the card's position relative to the container
  const containerRect = container.getBoundingClientRect();
  const cardRect = card.getBoundingClientRect();
  const relativeOffset = cardRect.top - containerRect.top;

  // Adjust scroll so that the card is centered
  const scrollTarget = relativeOffset + container.scrollTop - container.clientHeight / 2 + cardRect.height / 2;

  container.scrollTo({
    top: scrollTarget,
    behavior: 'smooth'
  });
}
async function finalizeCheckout() {
  // Show the loading spinner
  document.getElementById("loading-spinner").style.display = "block";

  // 1) Build one‑off items only
  const oneOffs = selectionList.map(item => {
    const priceId = item.stripePriceIds
      ? item.stripePriceIds[currentBilling]
      : item.stripePriceId;       // fallback for pure one‑time items
    return { priceId, quantity: 1 };
  });

  // 2) Send plan _separately_
  const body = {
    plan:            selectedPlan,             // "Group" / "Student" / "Professional"
    billingInterval: currentBilling,           // "monthly" / "four_months" / "yearly"
    quantity:        enterpriseUsers,          // number of seats (only for Group)
    items:           oneOffs,                  // <— no plan in here
    discountCode:    currentDiscountCode
  };

  try {
    const res = await fetch('https://secure.quantalumin.com/api/v1/create-checkout-session.php', {
      method:  'POST',
      headers: { 'Content-Type': 'application/json' },
      body:    JSON.stringify(body)
    });
    const text = await res.text();
    const { sessionId, error } = JSON.parse(text);
    if (error) {
      alert('Checkout failed: ' + error);
      return;
    }

    // Redirect to Stripe Checkout
    const { error: stripeError } = await stripe.redirectToCheckout({ sessionId });
    if (stripeError) {
      alert(stripeError.message);
    }
  } catch (err) {
    alert('Error occurred during checkout: ' + err.message);
  } finally {
    // Hide the loading spinner after checkout is complete or failed
    document.getElementById("loading-spinner").style.display = "none";
  }
}

function attachAtomSingleClick() {
  const svg = document.getElementById("atom-svg");
  if (!svg) return;
  svg.addEventListener("click", function(e) {
    if (e.detail === 1) { enableRapidElectronSpin(); }
  });
}
function enableRapidElectronSpin() {
  const svg = document.getElementById("atom-svg");
  if (!svg) return;
  const orbitals = svg.querySelectorAll("g[id^='orbital-']");
  orbitals.forEach((orbital, index) => {
    if (!orbital.dataset.origDuration) { const durations = [20,25,30,35]; orbital.dataset.origDuration = durations[index] || 20; }
    orbital.style.animationDuration = "0.2s";
  });
  setTimeout(() => { orbitals.forEach(orbital => { orbital.style.animationDuration = orbital.dataset.origDuration + "s"; }); }, 1000);
}
let quizTimer;
let quizInterval;
function attachAtomTripleClick() {
  const svg = document.getElementById("atom-svg");
  if (!svg) return;

  // If the quiz has already been completed, do not reattach the triple-click listener
  if (quizCompleted) return;

  let clickCount = 0;
  let clickTimer;
  svg.addEventListener("click", function(e) {
    clickCount++;
    clearTimeout(clickTimer);
    clickTimer = setTimeout(() => { clickCount = 0; }, 600);
    if (clickCount === 3) {
      clickCount = 0;
      handleAtomTripleClick();
    }
  });
}
function handleAtomTripleClick() {
  // If the quiz has already been attempted, do nothing.
  if (quizCompleted) return;

  // Mark quiz as attempted (regardless of outcome)
  quizCompleted = true;

  const svg = document.getElementById("atom-svg");
  if (!svg) return;
  const totalElectrons = selectionList.reduce((sum, it) => sum + it.electronCount, 0);
  if (totalElectrons === 0) return;

  // Increase header size for quiz view
  const header = document.getElementById("header-divider");
  if (header) {
    header.style.height = "35vh";
    const bodyDivider = document.querySelector(".body-divider");
    if (bodyDivider) {
      bodyDivider.style.top = (header.offsetHeight + 16) + "px";
    }
  }

  // Animate electrons flying off
  const randomAngle = () => Math.random() * 360;
  svg.querySelectorAll("g[id^='orbital-']").forEach(orbital => {
    orbital.querySelectorAll("circle").forEach(circle => {
      const rect = circle.getBoundingClientRect();
      const startX = rect.left + rect.width/2;
      const startY = rect.top + rect.height/2;
      const electron = document.createElement("div");
      electron.className = "flying-electron";
      electron.style.left = startX + "px";
      electron.style.top = startY + "px";
      document.body.appendChild(electron);
      const angle = randomAngle();
      const distance = 200 + Math.random() * 100;
      const destX = startX + distance * Math.cos(angle * Math.PI/180);
      const destY = startY + distance * Math.sin(angle * Math.PI/180);
      setTimeout(() => {
        electron.style.left = destX + "px";
        electron.style.top = destY + "px";
        electron.addEventListener("transitionend", () => electron.remove());
      }, 50);
      const photon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      photon.classList.add("flying-photon");
      photon.setAttribute("viewBox", "0 0 10 10");
      photon.innerHTML = `<path d="M0,5 Q2.5,0 5,5 T10,5" stroke="black" fill="none" stroke-width="1"/>`;
      photon.style.position = "fixed";
      photon.style.left = startX + "px";
      photon.style.top = startY + "px";
      photon.style.transform = `rotate(${angle}deg)`;
      document.body.appendChild(photon);
      setTimeout(() => {
        photon.style.left = destX + "px";
        photon.style.top = destY + "px";
        photon.style.opacity = "0";
        photon.addEventListener("transitionend", () => photon.remove());
      }, 50);
    });
  });

  // After a short delay, show the quiz
  setTimeout(() => {
    svg.innerHTML = `
      <foreignObject x="-160" y="-160" width="320" height="320">
        <div xmlns="http://www.w3.org/1999/xhtml" style="display:flex; flex-direction:column; align-items:center; justify-content:center; height:100%; padding:0.5rem;">
          <div id="quiz-timer" class="quiz-timer">05:00</div>
          <p style="font-weight:bold; text-align:center; margin:4px;" class="quiz-question">Who split the atom?</p>
          <div class="quiz-option" onclick="handleQuizAnswer('Rutherford')">Rutherford</div>
          <div class="quiz-option" onclick="handleQuizAnswer('Einstein')">Einstein</div>
          <div class="quiz-option" onclick="handleQuizAnswer('M. Curie')">M. Curie</div>
        </div>
      </foreignObject>
    `;
    startQuizTimer();
  }, 1000);
}
function startQuizTimer() {
  let timeLeft = 300;
  const timerElem = document.getElementById("quiz-timer");
  if (!timerElem) return;
  quizInterval = setInterval(() => {
    timeLeft--;
    const minutes = String(Math.floor(timeLeft / 60)).padStart(2, '0');
    const seconds = String(timeLeft % 60).padStart(2, '0');
    timerElem.textContent = `${minutes}:${seconds}`;
    if (timeLeft <= 0) {
      clearInterval(quizInterval);
      timerElem.textContent = "Time expired!";
      setTimeout(() => {
        timerElem.parentElement.innerHTML = `<p style="font-size:1rem; font-weight:bold; text-align:center;">False!</p>`;
      }, 1000);
    }
  }, 1000);
}
function handleQuizAnswer(answer) {
  clearInterval(quizInterval);
  const svg = document.getElementById("atom-svg");
  if (!svg) return;
  let resultMsg = "";
  if (answer === "Rutherford") {
    // Only unlock the discount if the quiz is passed.
    discountAdditionalCoursesUnlocked = true;
    quizCompleted = true;  // Prevent further quiz attempts
    discountSpecificCourseType = "Entrepreneurship";
    resultMsg = "Correct! Discount unlocked on Entrepreneurship courses.";
  } else {
    resultMsg = "False!";
  }
  svg.innerHTML = `<foreignObject x="-80" y="-80" width="160" height="160">
        <div xmlns="http://www.w3.org/1999/xhtml" style="display:flex; flex-direction:column; align-items:center; justify-content:center; height:100%; background:#fff; padding:0.5rem;">
          <p style="font-size:1rem; font-weight:bold; text-align:center;">${resultMsg}</p>
        </div>
      </foreignObject>`;
  setTimeout(() => {
    // Reset header size, update the SVG, and update the discount message.
    const header = document.getElementById("header-divider");
    if (header) header.style.height = "25vh";
    const bodyDivider = document.querySelector(".body-divider");
    if (bodyDivider && header) bodyDivider.style.top = "25vh";
    updateAtomSVG();
    updateDiscountMessage();
  }, 2000);
}
document.addEventListener("DOMContentLoaded", () => {
  const header = document.querySelector('.header-divider');
  const footer = document.querySelector('.footer-divider');
  const bodyDivider = document.querySelector('.body-divider');
  if (header) {
    header.addEventListener('wheel', function(e) {
      e.preventDefault();
      if (bodyDivider) bodyDivider.scrollTop += e.deltaY;
    });
  }
  if (footer) {
    footer.addEventListener('wheel', function(e) {
      e.preventDefault();
      if (bodyDivider) bodyDivider.scrollTop += e.deltaY;
    });
  }
  const paymentTable = document.getElementById("payment-table");
if (paymentTable) {
  // Set initial opacity to 0
  paymentTable.style.opacity = 0;

  // Duration of the fade-in in milliseconds
  const duration = 1500;
  let startTime = null;

  // Animation function using requestAnimationFrame
  function fadeIn(timestamp) {
    if (!startTime) startTime = timestamp;
    const elapsed = timestamp - startTime;
    // Calculate the new opacity based on elapsed time
    const newOpacity = Math.min(elapsed / duration, 1);
    paymentTable.style.opacity = newOpacity;

    if (elapsed < duration) {
      requestAnimationFrame(fadeIn);
    }
  }

  // Start the fade-in animation after a 0.5s delay
  setTimeout(() => {
    requestAnimationFrame(fadeIn);
  }, 500);

  // Scroll into view after a short delay (if needed)
  setTimeout(() => {
    paymentTable.scrollIntoView({ behavior: "smooth" });
  }, 100);
}
});
document.addEventListener("DOMContentLoaded", () => {
  createPaymentTable();
  const starfield = document.getElementById('starfield');
  if (starfield) {
    // Move the canvas to the body (if needed) so it's not confined to .body-divider
    document.body.appendChild(starfield);

    // Change its style to cover the full viewport
    starfield.style.position = 'absolute';
    starfield.style.top = '0';
    starfield.style.left = '0';
    const fullPageHeight = document.documentElement.scrollHeight;
    const footerHeight = document.querySelector('footer').offsetHeight;
    starfield.style.height = (fullPageHeight - footerHeight) + 'px';
    starfield.style.width = '100%';
    starfield.style.zIndex = '-1';

  }
});

/**
 * Sum plan + all selected items, convert to selectedCurrency,
 * and return in the smallest unit (e.g. cents for USD/EUR, pence for GBP).
 */
function calculateTotalAmountInCents() {
  // 1) Plan base price
  const plan = basePlans.find(p => p.name === selectedPlan);
  let planGBP = 0;
  if (plan) {
    // base GBP price depending on billing cycle + per‑user for Groups
    planGBP = (plan.name === "Group")
      ? plan.pricingGBP[currentBilling] + enterpriseUsers * (plan.perUserGBP || 0)
      : plan.pricingGBP[currentBilling];

    // apply half‑off code if active
    if (discountCodeActive) planGBP *= 0.5;
  }

  // 2) Sum all selected items (their .priceGBP already reflects any per‑item discount)
  const itemsGBP = selectionList.reduce((sum, item) => sum + item.priceGBP, 0);

  // 3) Total in GBP
  const totalGBP = planGBP + itemsGBP;

  // 4) Convert into selectedCurrency smallest unit
  //    convertToCurrency: GBP → selectedCurrency
  const totalInCurrency = convertToCurrency(totalGBP);

  // 5) Round to nearest cent/pence and return integer
  return Math.round(totalInCurrency * 100);
}

/* ---------- Toggle Courses Submenu ---------- */

function toggleCoursesSubmenu() {
  const submenu = document.getElementById("courses-submenu");
  const indicator = document.getElementById("courses-indicator");
  if (!submenu || !indicator) return;
  if (submenu.style.display === "block") {
    submenu.style.display = "none";
    indicator.textContent = "▾";
  } else {
    submenu.style.display = "block";
    indicator.textContent = "▴";
  }
}
document.addEventListener("click", function(e) {
  const clickedLink = e.target.closest('#navbar a');
  if (clickedLink && window.innerWidth <= 600) {
    // If this link is inside a "has-submenu" li and it's the toggle (not one of its submenu items), skip closing
    const parentLI = clickedLink.closest("li.has-submenu");
    if (parentLI && clickedLink.getAttribute("href") === "javascript:void(0);") {
      return; // Don't close the menu for the Courses toggle
    }
    // Otherwise, close the mobile navbar
    document.getElementById("navbar").style.display = "none";
  }
});
</script>

<canvas id="starfield" width="1137" height="1924" data-engine="three.js r167dev"></canvas>
<script type="module" src="/js/starfield.js"></script>
Restore Page Scroll to top
    • Contact
    • Instagram
    • About
    • Members' Portal
    • Toggle Source-Code
    • Operating System
    • Code Repository
    • Websites Tutorial
    • Search Engine
Accelerating the Future
© Test Copyright 2024–2025
View copyright notice