// =============================================================================
// BIRTH ORACLE — Client-side ephemeris & 72-band frequency profiler
// All calculations in pure JS — no server required.
// =============================================================================

(function() {
  "use strict";

  // --- 72 BAND DATA ---
  var BAND_DATA = {
    names: [
      "Primordial Pulse", "Binary Breath", "Triune Gate", "Quartile Anchor", "Quintile Star",
      "Hexad Weaver", "Septimal Mirror", "Octave Bridge", "Novena Spiral", "Decan Compass",
      "Eleusinian Key", "Dodecahedron Crown", "Monad Flux", "Dyad Prism", "Triad Lens",
      "Tetrad Circuit", "Pentad Sigil", "Hexad Mantle", "Heptad Tether", "Ogdoad Core",
      "Hermetic Rhythm", "Lunar Tide", "Solar Pulse", "Venusian Veil", "Mercurial Stream",
      "Martian Forge", "Jovian Expanse", "Saturnian Ring", "Uranian Prism", "Neptunian Depths",
      "Plutonian Core", "Selene Echo", "Helios Gate", "Aphrodite Nexus", "Hermes Thread",
      "Ares Anvil", "Zeus Thunder", "Cronus Boundary", "Coelus Void", "Oceanus Flow",
      "Terra Foundation", "Gaia Matrix", "Atlas Threshold", "Promethean Fire", "Epimethean Echo",
      "Orphic Lyre", "Dionysian Rapture", "Apollonian Form", "Pythian Breath", "Eleusinian Mystery",
      "Sibylline Vision", "Mithraic Covenant", "Zoroastrian Flame", "Hermetic Seal", "Alchemical Crucible",
      "Philosopher Salt", "Mercurial Water", "Sulphur Soul", "Azoth Bridge", "Prima Materia",
      "Celestial Harmos", "Cosmic Diaulos", "Stellar Tetrachord", "Galactic Octave", "Universal Pentad",
      "Void Residue", "Chthonic Echo", "Aetheric Lens", "Singularity Apex", "Omega Point",
      "Alpha Knot", "Omega Spiral"
    ],
    meanings: [
      "The raw pulse of existence before any division. Pure potential.",
      "The first distinction: zero and one, the fundamental binary.",
      "The triad: observer, observed, observation. Perspective.",
      "Stability through four elements. The square is holy.",
      "The five-pointed resonance. Humanity's signature.",
      "The hexagon — nature's most efficient packing.",
      "Seven classical planets. The chakras. The sacred seal.",
      "The octave — every eighth band repeats at higher frequency.",
      "Completion cycles. Nine months of gestation.",
      "The decimal framework. The ten sefirot.",
      "Threshold between worlds. The eleventh hour.",
      "The zodiac's completion. Cosmic architecture.",
      "Transformation through instability. The alchemical flux.",
      "The dyad — reflection, opposition, complement.",
      "The lens of perception. The soul's telescope.",
      "Information processing. Consciousness circuitry.",
      "Integration of opposites. The alchemical wedding.",
      "The mantel of authority. Mature wisdom.",
      "The tether between realms. Grounding while flying.",
      "The immutable center. The unchanging core.",
      "Rhythm as fundamental organizing principle. The heartbeat of time.",
      "Intuition, tides, cycles. The subconscious mind.",
      "Vitality, expression, identity. The conscious self.",
      "Love, art, beauty, harmony. Relational intelligence.",
      "Communication, logic, travel. The messenger's path.",
      "Action, courage, conflict. The warrior archetype.",
      "Expansion, luck, wisdom. Abundance consciousness.",
      "Structure, discipline, karma. The taskmaster.",
      "Innovation, disruption, awakening. The breakthrough.",
      "Mysticism, dreams, dissolution. The divine fog.",
      "Transformation, power, regeneration. The phoenix.",
      "Reflective intelligence. Emotional wisdom.",
      "Radiant presence. Enlightened will.",
      "Harmonious connection. Universal love.",
      "Divine message. Cosmic communication.",
      "Courageous truth. Righteous action.",
      "Benevolent authority. Cosmic justice.",
      "Sacred limitation. Transcendent discipline.",
      "The void between stars. Empty space as medium.",
      "The great flow. Currents of consciousness.",
      "Grounded being. The body as temple.",
      "The living planet. Earth as conscious being.",
      "The weight of responsibility. Cosmic burden.",
      "Creative fire stolen for humanity.",
      "Hindsight wisdom. Learning through reflection.",
      "Music of the spheres. Harmony as truth.",
      "Ecstatic union. Joy as cosmic force.",
      "Perfect form. Beauty as truth.",
      "Oracle breath. Prophetic voice.",
      "Initiation through experience. The mysteries.",
      "Prophetic vision. The seer's gift.",
      "Covenant with the divine. Sacred agreement.",
      "Sacred fire. Purification through light.",
      "Sealed wisdom. The initiate's mark.",
      "The container of transformation. The crucible.",
      "Stability. The fixed aspect of the work.",
      "Flow. The transformative agent.",
      "Energy. The active principle.",
      "The rainbow bridge between worlds.",
      "First matter. The raw material of transformation.",
      "Harmonic architecture. Cosmic design.",
      "The double pipe. Cosmic rhythm.",
      "Four-note foundation. Irreducible harmony.",
      "Universal resonance. Every note contains every other.",
      "The five-fold cosmic pattern. Universal scaling.",
      "What remains after everything is stripped away.",
      "The underworld resonance. Shadows as teachers.",
      "The subtle realm. Spirit made perceptible.",
      "The point of infinite density. All potential.",
      "The ultimate destination. The end that contains the beginning.",
      "The complete circuit. Return to source.",
      "The final spiral. All bands resonating as one."
    ],
    domains: [
      "Existence/Void", "Duality/Logic", "Perception/Trinity", "Foundation/Structure", "Humanity/Body",
      "Nature/Pattern", "Time/Cycle", "Harmonic/Return", "Completion/Gestation", "System/Order",
      "Initiation/Threshold", "Cosmic/Architecture", "Transformation/Monad", "Reflection/Dyad", "Perception/Triad",
      "Information/Tetrad", "Integration/Pentad", "Authority/Hexad", "Grounding/Heptad", "Core/Ogdoad",
      "Rhythm/Time", "Intuition/Moon", "Vitality/Sun", "Love/Venus", "Logic/Mercury",
      "Action/Mars", "Expansion/Jupiter", "Structure/Saturn", "Innovation/Uranus", "Mysticism/Neptune",
      "Power/Pluto", "Emotion/Selene", "Will/Helios", "Harmony/Aphrodite", "Message/Hermes",
      "Truth/Ares", "Justice/Zeus", "Discipline/Cronus", "Void/Coelus", "Flow/Oceanus",
      "Body/Terra", "Life/Gaia", "Responsibility/Atlas", "Innovation/Prometheus", "Reflection/Epimetheus",
      "Harmony/Orpheus", "Ecstasy/Dionysus", "Form/Apollo", "Prophecy/Pythia", "Mystery/Eleusis",
      "Vision/Sibyl", "Covenant/Mithras", "Flame/Zoroaster", "Wisdom/Hermetic", "Crucible/Alchemy",
      "Stability/Salt", "Flow/Mercury", "Energy/Sulphur", "Bridge/Azoth", "Matter/Prima",
      "Architecture/Harmos", "Rhythm/Diaulos", "Foundation/Tetrachord", "Resonance/Galaxy", "Scaling/Pentad",
      "Essence/Void", "Shadow/Chthonic", "Spirit/Aether", "Singularity/Apex", "Omega/Destination",
      "Alpha/Return", "Omega/Spiral"
    ],
    colors: [
      "#0a0a0a", "#1a1a2e", "#16213e", "#0f3460", "#533483",
      "#e94560", "#f5a623", "#f7dc6f", "#2ecc71", "#1abc9c",
      "#3498db", "#2980b9", "#8e44ad", "#9b59b6", "#e91e63",
      "#ff5722", "#ff9800", "#ffc107", "#4caf50", "#009688",
      "#00bcd4", "#03a9f4", "#2196f3", "#673ab7", "#3f51b5",
      "#f44336", "#ff6f00", "#ffab00", "#76ff03", "#00e5ff",
      "#d500f9", "#651fff", "#304ffe", "#0091ea", "#00bfa5",
      "#ff6d00", "#f9a825", "#c6ff00", "#ea80fc", "#b388ff",
      "#8c9eff", "#82b1ff", "#80d8ff", "#a7ffeb", "#b9f6ca",
      "#ff8a80", "#ff80ab", "#ea80fc", "#b388ff", "#8c9eff",
      "#82b1ff", "#80d8ff", "#a7ffeb", "#ccff90", "#ffff8d",
      "#ffd180", "#ff9e80", "#f48fb1", "#ce93d8", "#b39ddb",
      "#80cbc4", "#a5d6a7", "#e6ee9c", "#fff59d", "#ffe082",
      "#ffab91", "#bc8f8f", "#a9a9a9", "#708090", "#c0c0c0",
      "#ffd700", "#ffd700", "#ffd700"
    ]
  };

  // --- PLANETARY ORBITAL ELEMENTS (J2000.0) ---
  var PLANET_ELEMENTS = {
    Sun:      { a: [0.0, 0.0], e: [0.0167086, -0.00004204], i: [0.0, 0.0], O: [0.0, 0.0], w: [282.9373, 0.3222], L: [280.4665, 36000.7698], name: "Sun", emoji: "\u2600" },
    Moon:     { a: [0.0, 0.0], e: [0.0549, 0.0], i: [5.1454, 0.0], O: [125.1229, -18.0], w: [318.0634, -3.0], L: [218.3164, 481267.881], name: "Moon", emoji: "\uD83C\uDF19" },
    Mercury:  { a: [0.387099, 0.0], e: [0.205635, 0.000019], i: [7.00498, -0.0059], O: [48.3309, -0.1253], w: [29.1240, 0.8497], L: [252.2509, 149472.6746], name: "Mercury", emoji: "\u263F" },
    Venus:    { a: [0.723335, 0.0], e: [0.006776, -0.000038], i: [3.39471, -0.0008], O: [76.6799, -0.2776], w: [54.8529, 0.8523], L: [181.9798, 58517.8157], name: "Venus", emoji: "\u2640" },
    Mars:     { a: [1.523710, 0.0], e: [0.093394, 0.000078], i: [1.84969, -0.0006], O: [49.5581, -0.2951], w: [286.5021, 0.6595], L: [355.4530, 19140.3027], name: "Mars", emoji: "\u2642" },
    Jupiter:  { a: [5.202887, 0.0], e: [0.048386, -0.000135], i: [1.30439, -0.0018], O: [100.4739, 0.2047], w: [273.8671, 0.5764], L: [34.3515, 3034.9057], name: "Jupiter", emoji: "\u2643" },
    Saturn:   { a: [9.536675, 0.0], e: [0.053862, -0.000509], i: [2.48599, 0.0019], O: [113.6624, -0.2886], w: [339.3914, 0.4456], L: [50.0785, 1222.1387], name: "Saturn", emoji: "\u2644" },
    Uranus:   { a: [19.189164, 0.0], e: [0.047257, 0.000044], i: [0.77255, -0.0007], O: [74.0169, 0.0424], w: [96.5417, 0.4116], L: [314.0550, 429.8640], name: "Uranus", emoji: "\u2645" },
    Neptune:  { a: [30.069923, 0.0], e: [0.008590, 0.000005], i: [1.77004, 0.0004], O: [131.7842, -0.0060], w: [273.1709, 0.1830], L: [304.3487, 219.8837], name: "Neptune", emoji: "\u2646" },
    Pluto:    { a: [39.482117, 0.0], e: [0.248807, 0.000060], i: [17.14001, 0.0018], O: [110.3017, -0.2035], w: [224.0680, 0.1174], L: [238.9574, 145.2078], name: "Pluto", emoji: "\u2647" }
  };

  // --- VOCATION PROFILES ---
  var VOCATIONS = {
    earthy: {
      title: "The Anchor",
      desc: "You are here to build stable foundations for others. Your frequency patterns show a deep connection to physical reality. You make ideas tangible and structures lasting.",
      roles: "Builder \u00B7 Engineer \u00B7 Farmer \u00B7 Healer \u00B7 Craftsman \u00B7 Conservator",
      emphasis: "Grounded creation, material wisdom, patience as strategy"
    },
    watery: {
      title: "The Channel",
      desc: "You move through the world as a conduit. Emotions, intuitions, creative currents flow through you. You feel what others cannot name. You speak what others cannot voice.",
      roles: "Artist \u00B7 Healer \u00B7 Therapist \u00B7 Poet \u00B7 Medium \u00B7 Musician",
      emphasis: "Emotional intelligence, creative flow, intuitive knowing"
    },
    fiery: {
      title: "The Catalyst",
      desc: "You were born to ignite. Your frequency carries activation energy. Wherever you focus, things transform. You are the spark that turns potential into kinetic.",
      roles: "Leader \u00B7 Innovator \u00B7 Warrior \u00B7 Activist \u00B7 Entrepreneur \u00B7 Pioneer",
      emphasis: "Courageous action, transformative will, pioneering spirit"
    },
    airy: {
      title: "The Architect",
      desc: "Your mind is the organizing principle. You see patterns where others see chaos. Your work is bringing order to information, making the complex comprehensible.",
      roles: "Scientist \u00B7 Philosopher \u00B7 Teacher \u00B7 Writer \u00B7 Strategist \u00B7 Logician",
      emphasis: "Mental clarity, systematic thinking, knowledge as foundation"
    },
    ethereal: {
      title: "The Seer",
      desc: "You perceive beyond the veil. Bands of reality that others cannot see are visible to you. Your work is translation between worlds.",
      roles: "Mystic \u00B7 Oracle \u00B7 Visionary \u00B7 Prophet \u00B7 Shaman \u00B7 Sage",
      emphasis: "Visionary insight, spiritual wisdom, transdimensional awareness"
    },
    harmonic: {
      title: "The Weaver",
      desc: "You are the bridge between dissonant elements. You see the shared wavelength beneath apparent conflict. Your work is reconciliation.",
      roles: "Diplomat \u00B7 Mediator \u00B7 Networker \u00B7 Connector \u00B7 Composer \u00B7 Orchestrator",
      emphasis: "Harmonic integration, bridging divisions, relational wisdom"
    },
    chrysalis: {
      title: "The Transformer",
      desc: "You are in an ongoing state of metamorphosis. Your frequency profile shows high inharmony by design. Each crisis is a chrysalis.",
      roles: "Change Agent \u00B7 Alchemist \u00B7 Revolutionary \u00B7 Reformer \u00B7 Phoenix",
      emphasis: "Deep transformation, crisis as opportunity, continuous evolution"
    },
    integral: {
      title: "The Oracle",
      desc: "Your bands cluster at the extremes. You span the full spectrum, holding paradox naturally. Both the micro and macro are visible to you.",
      roles: "Sage \u00B7 Philosopher \u00B7 Elder \u00B7 Guide \u00B7 Mentor \u00B7 Visionary",
      emphasis: "Integration of extremes, holistic vision, the art of holding paradox"
    }
  };

  // --- GROWTH STEP TEMPLATES ---
  var GROWTH_STEPS = {
    grounding: [
      { action: "Earthing practice \u2014 walk barefoot on living soil for 20 minutes daily", why: "Your inharmony bands show excess spiritual energy without a ground wire" },
      { action: "Establish a morning anchor ritual", why: "Your CZ ratio leans into abstraction; the body needs the first word" },
      { action: "Work with your hands \u2014 clay, wood, stone, fabric", why: "Physical creation balances your frequency vector" }
    ],
    water: [
      { action: "Free-write every morning before any screen", why: "Your emotional channels need a daily flushing" },
      { action: "Create a container for your sensitivity", why: "Your bandwidth for others' emotions is a gift \u2014 but it needs boundaries" },
      { action: "Find the key that resonates with your dominant band", why: "Sound bypasses reason and speaks directly to the emotional body" }
    ],
    fire: [
      { action: "Channel your activation energy into ONE focused project", why: "Your scatter pattern dilutes the burn" },
      { action: "Practice stillness before action", why: "Your bands over-emphasize doing; being is the deeper power" },
      { action: "Find a worthy opposition", why: "Your Martian bands need a clear adversary \u2014 make it a challenge, not a person" }
    ],
    air: [
      { action: "Complete a system that has been in idea-form too long", why: "Your frequency is strong on generation but weak on termination" },
      { action: "Teach what you know", why: "Your bands express fully in transmission" },
      { action: "Unplug for 24 hours weekly", why: "Your Mercurial bands over-process; rest is where integration happens" }
    ],
    ethereal: [
      { action: "Create a daily download protocol", why: "Your spiritual bandwidth is wide and needs a structured channel" },
      { action: "Ground your visions in tangible practice", why: "Your bands reach high frequencies but risk dissociation" },
      { action: "Share one insight per week with someone who needs it", why: "The Seer's gift grows through service, not hoarding" }
    ],
    harmonic: [
      { action: "Prioritize your own frequency before harmonizing others", why: "Your gift for connection depletes you if you don't fill your own well" },
      { action: "Say no to one thing you would normally mediate", why: "Not every dissonance needs resolution \u2014 some are growing pains" },
      { action: "Create something from silence", why: "Original creation is your next frontier" }
    ],
    chrysalis: [
      { action: "Document your transformation cycles", why: "You go through metamorphosis so fast you forget who you were" },
      { action: "Find beauty in the in-between state", why: "Your inharmony scores are high by design" },
      { action: "Build something that will outlast this version of you", why: "Your transient nature needs permanent expression" }
    ],
    integral: [
      { action: "Write a letter to your younger self", why: "Your integration capacity lets you actually heal the timeline" },
      { action: "Create a container for your paradoxes", why: "Your frequency holds contradictions that need a frame" },
      { action: "Choose ONE domain for material mastery", why: "Your breadth is extraordinary; depth is transcendence" }
    ]
  };

  // ===========================================================================
  // CORE CALCULATIONS
  // ===========================================================================

  function julianDay(year, month, day, hour, minute) {
    if (month <= 2) { year -= 1; month += 12; }
    var A = Math.floor(year / 100);
    var B = 2 - A + Math.floor(A / 4);
    var JD = Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + B - 1524.5;
    return JD + (hour + minute / 60) / 24;
  }

  function julianCenturies(JD) {
    return (JD - 2451545.0) / 36525;
  }

  function norm360(deg) {
    return ((deg % 360) + 360) % 360;
  }

  function planetLongitude(planet, T) {
    var el = PLANET_ELEMENTS[planet];
    if (!el) return 0;

    var L = el.L[0] + el.L[1] * T;

    if (planet === "Sun") {
      return norm360(L);
    }

    if (planet === "Moon") {
      var meanL = norm360(L);
      var node = norm360(el.O[0] + el.O[1] * T);
      var mA = norm360(L - el.w[0] - el.w[1] * T);
      var eqC = 6.289 * Math.sin(mA * Math.PI / 180);
      return norm360(meanL + eqC);
    }

    var e = el.e[0] + el.e[1] * T;
    var w = el.w[0] + el.w[1] * T;
    var M = norm360(L - w);
    var Mrad = M * Math.PI / 180;
    var Ct = (2 * e - 0.25 * e*e*e) * Math.sin(Mrad)
           + 1.25 * e*e * Math.sin(2 * Mrad)
           + (13/12) * e*e*e * Math.sin(3 * Mrad);

    return norm360(L + Ct * 180 / Math.PI);
  }

  function lonToBand(lon) {
    return Math.floor(lon / 5) + 1;
  }

  function computeFrequencyVector(planetBands) {
    var vector = new Array(72).fill(0);
    var weights = {
      Sun: 3.0, Moon: 2.8, Mercury: 1.8, Venus: 2.2, Mars: 2.0,
      Jupiter: 1.5, Saturn: 1.5, Uranus: 1.0, Neptune: 1.0, Pluto: 1.0
    };

    for (var planet in planetBands) {
      if (planetBands.hasOwnProperty(planet)) {
        var band = planetBands[planet];
        if (band >= 1 && band <= 72) {
          vector[band - 1] += weights[planet] || 1.0;
        }
      }
    }

    var maxVal = 0;
    for (var i = 0; i < 72; i++) {
      if (vector[i] > maxVal) maxVal = vector[i];
    }
    if (maxVal > 0) {
      for (var j = 0; j < 72; j++) vector[j] /= maxVal;
    }

    return vector;
  }

  function computeCZRatio(vector) {
    var Csum = 0, Zsum = 0;
    for (var i = 0; i < 72; i++) {
      if (i % 2 === 1) Csum += vector[i];
      else Zsum += vector[i];
    }
    var total = Csum + Zsum;
    if (total === 0) return { C: 50, Z: 50, dominant: "balanced", text: "Balanced" };
    var C = Math.round((Csum / total) * 100);
    var Z = Math.round((Zsum / total) * 100);
    if (C > Z + 10) return { C: C, Z: Z, dominant: "C", text: "Consciousness-dominant" };
    if (Z > C + 10) return { C: C, Z: Z, dominant: "Z", text: "Emotion-dominant" };
    return { C: C, Z: Z, dominant: "balanced", text: "Balanced" };
  }

  function computeInharmony(vector) {
    var deltas = [];
    for (var i = 0; i < 71; i++) {
      deltas.push({ band: i + 1, delta: Math.abs(vector[i] - vector[i + 1]) });
    }
    deltas.sort(function(a, b) { return b.delta - a.delta; });

    var sumD = 0;
    for (var j = 0; j < deltas.length; j++) sumD += deltas[j].delta;
    var score = sumD / 71;
    var scorePct = Math.min(Math.round(score * 100), 100);

    return { deltas: deltas.slice(0, 5), score: score, scorePct: scorePct };
  }

  function determineVocation(vector, cz) {
    var groups = {};
    var labels = ["earthy", "watery", "fiery", "airy", "ethereal", "harmonic", "integral"];
    var slices = [0, 12, 24, 36, 48, 60, 66, 72];

    for (var g = 0; g < labels.length; g++) {
      var sum = 0, count = 0;
      for (var s = slices[g]; s < slices[g + 1]; s++) {
        sum += vector[s];
        count++;
      }
      groups[labels[g]] = sum / count;
    }

    var sorted = Object.keys(groups).sort(function(a, b) { return groups[b] - groups[a]; });
    var primary = sorted[0];

    return VOCATIONS[primary] || VOCATIONS.integral;
  }

  function generateGrowthSteps(vocation) {
    var vocationKey = null;
    for (var key in VOCATIONS) {
      if (VOCATIONS[key] === vocation) { vocationKey = key; break; }
    }
    if (!vocationKey) vocationKey = "integral";
    return GROWTH_STEPS[vocationKey] || GROWTH_STEPS.integral;
  }

  // ===========================================================================
  // UI HELPERS
  // ===========================================================================

  function bandColor(band) {
    return BAND_DATA.colors[band - 1] || "#ffffff";
  }

  function bandName(band) {
    return BAND_DATA.names[band - 1] || "Band " + band;
  }

  function bandMeaning(band) {
    return BAND_DATA.meanings[band - 1] || "";
  }

  function bandDomain(band) {
    return BAND_DATA.domains[band - 1] || "";
  }

  function textColorForBg(bg) {
    var r = parseInt(bg.slice(1, 3), 16);
    var g = parseInt(bg.slice(3, 5), 16);
    var b = parseInt(bg.slice(5, 7), 16);
    var lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
    return lum > 0.5 ? "#1a1a2e" : "#f0f0f0";
  }





  function formatDate(year, month, day) {
    var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
    return months[month - 1] + " " + day + ", " + year;
  }

  // ===========================================================================
  // MAIN CALCULATION
  // ===========================================================================

  function calculateBirthProfile(year, month, day, hour, minute) {
    var JD = julianDay(year, month, day, hour, minute);
    var T = julianCenturies(JD);

    var planetLongitudes = {};
    var planetBands = {};

    for (var planet in PLANET_ELEMENTS) {
      if (PLANET_ELEMENTS.hasOwnProperty(planet)) {
        var lon = planetLongitude(planet, T);
        planetLongitudes[planet] = lon;
        planetBands[planet] = lonToBand(lon);
      }
    }

    var vector = computeFrequencyVector(planetBands);

    var dominantBand = 1;
    var maxVal = 0;
    for (var i = 0; i < 72; i++) {
      if (vector[i] > maxVal) { maxVal = vector[i]; dominantBand = i + 1; }
    }

    var bandRankings = [];
    for (var k = 0; k < 72; k++) {
      bandRankings.push({ band: k + 1, value: vector[k] });
    }
    bandRankings.sort(function(a, b) { return b.value - a.value; });

    var czRatio = computeCZRatio(vector);
    var inharmony = computeInharmony(vector);
    var vocation = determineVocation(vector, czRatio);
    var growthSteps = generateGrowthSteps(vocation);

    return {
      planetLongitudes: planetLongitudes,
      planetBands: planetBands,
      vector: vector,
      dominantBand: dominantBand,
      maxVal: maxVal,
      bandRankings: bandRankings,
      czRatio: czRatio,
      inharmony: inharmony,
      vocation: vocation,
      growthSteps: growthSteps
    };
  }

  // ===========================================================================
  // RENDERERS
  // ===========================================================================

  function renderPlanetPositions(bands, longitudes) {
    var grid = document.getElementById("planetGrid");
    grid.innerHTML = "";

    var planetOrder = ["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"];

    for (var p = 0; p < planetOrder.length; p++) {
      var planet = planetOrder[p];
      var band = bands[planet];
      var lon = longitudes[planet];
      var emoji = PLANET_ELEMENTS[planet].emoji;
      var color = bandColor(band);
      var textColor = textColorForBg(color);

      var card = document.createElement("div");
      card.className = "planet-card";
      card.innerHTML =
        '<div class="planet-icon">' + emoji + '</div>' +
        '<div class="planet-name">' + planet + '</div>' +
        '<div class="planet-band" style="background:' + color + ';color:' + textColor + '">Band ' + band + '</div>' +
        '<div class="planet-lon">' + lon.toFixed(2) + '\u00B0</div>' +
        '<div class="planet-band-name">' + bandName(band) + '</div>';
      grid.appendChild(card);
    }
  }

  function renderBandStrip(bands) {
    var strip = document.getElementById("bandStrip");
    strip.innerHTML = "";

    var planetRanks = {};
    var planetOrder = ["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"];
    for (var p = 0; p < planetOrder.length; p++) {
      var b = bands[planetOrder[p]];
      if (!planetRanks[b]) planetRanks[b] = [];
      planetRanks[b].push(PLANET_ELEMENTS[planetOrder[p]].emoji);
    }

    for (var i = 1; i <= 72; i++) {
      var cell = document.createElement("div");
      cell.className = "strip-cell";
      cell.style.background = bandColor(i);
      cell.style.opacity = planetRanks[i] ? "1" : "0.2";
      cell.title = "Band " + i + ": " + bandName(i);

      if (planetRanks[i]) {
        cell.innerHTML = '<span class="strip-emoji">' + planetRanks[i].join("") + '</span>';
      }

      strip.appendChild(cell);
    }
  }

  function renderDominantBand(band) {
    var color = bandColor(band);
    var textColor = textColorForBg(color);

    var badge = document.getElementById("dominantBadge");
    badge.textContent = "Band " + band + " \u2014 " + bandName(band);
    badge.style.background = color;
    badge.style.color = textColor;

    document.getElementById("dominantTitle").textContent = "Primary Frequency: " + bandDomain(band);
    document.getElementById("dominantDesc").textContent = bandMeaning(band);

    var meaningDiv = document.getElementById("dominantMeaning");
    meaningDiv.innerHTML =
      '<div class="meaning-detail"><span class="meaning-label">Domain:</span><span>' + bandDomain(band) + '</span></div>' +
      '<div class="meaning-detail"><span class="meaning-label">Essence:</span><span>' + bandName(band) + '</span></div>';

    var glow = document.getElementById("dominantGlow");
    glow.style.background = "radial-gradient(ellipse at center, " + color + "33 0%, transparent 70%)";
  }

  function renderTopBands(rankings) {
    var container = document.getElementById("topBands");
    container.innerHTML = "";

    var top5 = rankings.slice(0, 5);
    for (var t = 0; t < top5.length; t++) {
      var item = top5[t];
      var color = bandColor(item.band);
      var textColor = textColorForBg(color);
      var pct = Math.round(item.value * 100);

      var card = document.createElement("div");
      card.className = "top-band-card";
      card.style.setProperty("--band-color", color);
      card.innerHTML =
        '<div class="top-band-header">' +
          '<span class="top-band-index" style="background:' + color + ';color:' + textColor + '">Band ' + item.band + '</span>' + ' ' +
          '<span class="top-band-strength">' + pct + '%</span>' +
        '</div>' +
        '<div class="top-band-name">' + bandName(item.band) + '</div>' +
        '<div class="top-band-domain">' + bandDomain(item.band) + '</div>' +
        '<div class="top-band-bar"><div class="top-band-fill" style="width:' + pct + '%;background:' + color + '"></div></div>' +
        '<div class="top-band-meaning">' + bandMeaning(item.band) + '</div>';
      container.appendChild(card);
    }
  }

  function renderCZRatio(cz) {
    var fill = document.getElementById("czFill");
    fill.style.width = cz.C + "%";

    document.getElementById("czValue").textContent = cz.dominant === "balanced" ? "50/50" : cz.C + "%  C / " + cz.Z + "%  Z";

    var explanation;
    if (cz.dominant === "C") {
      explanation =
        "<p><strong>Consciousness-dominant</strong></p>" +
        "<p>You process reality through consciousness first. Thought precedes feeling. Structure matters more than flow. " +
        "Your gift is clarity. Your edge is disconnection from the emotional body. " +
        "The C-dominant mind sees patterns before it feels them. " +
        "Your growth edge is letting the Z bands sing without immediately analyzing them.</p>";
    } else if (cz.dominant === "Z") {
      explanation =
        "<p><strong>Emotion-dominant</strong></p>" +
        "<p>You process reality through emotional reception first. Feeling precedes thought. Flow matters more than structure. " +
        "Your gift is depth. Your edge is overwhelm from unprocessed emotional data. " +
        "The Z-dominant heart feels patterns before it sees them. " +
        "Your growth edge is building C-band structures to hold the emotional richness.</p>";
    } else {
      explanation =
        "<p><strong>Balanced</strong></p>" +
        "<p>You are the rare balance: C and Z in near-equal measure. Consciousness and emotion, structure and flow, " +
        "thought and feeling in dynamic equilibrium. The alchemical marriage. " +
        "The challenge is maintaining balance in a world that pressures you to choose one lane. " +
        "Your gift is integration. Your edge is the constant dance.</p>";
    }
    document.getElementById("czExplanation").innerHTML = explanation;
  }

  function renderInharmony(inharmony) {
    var grid = document.getElementById("inharmonyGrid");
    grid.innerHTML = "";

    var topDeltas = inharmony.deltas.slice(0, 5);
    for (var d = 0; d < topDeltas.length; d++) {
      var item = topDeltas[d];
      var color = bandColor(item.band);
      var textColor = textColorForBg(color);
      var pct = Math.min(Math.round(item.delta * 100), 100);

      var card = document.createElement("div");
      card.className = "inharmony-card";
      card.style.setProperty("--band-color", color);
      card.innerHTML =
        '<div class="inharmony-header">' +
          '<span class="inharmony-band" style="background:' + color + ';color:' + textColor + '">\u0394 Band ' + item.band + ' \u2192 ' + (item.band + 1) + '</span> ' +
          '<span class="inharmony-value">' + pct + ' %</span>' +
        '</div>' +
        '<div class="inharmony-bar"><div class="inharmony-fill" style="width:' + pct + '%;background:' + color + '"></div></div>' +
        '<div class="inharmony-meaning">Between <strong>' + bandName(item.band) + '</strong> and <strong>' + bandName(Math.min(item.band + 1, 72)) + '</strong> \u2014 the delta is where growth lives.</div>';
      grid.appendChild(card);
    }

    var scoreDiv = document.getElementById("inharmonyScore");
    var scoreLevel = inharmony.scorePct < 30 ? "Low" : inharmony.scorePct < 60 ? "Moderate" : "High";
    var advice;
    if (scoreLevel === "Low") {
      advice = "Your bands are in unusual harmony. Seek growth at the edges of your comfort frequency. Harmony can become stasis.";
    } else if (scoreLevel === "Moderate") {
      advice = "Your bands have productive tension. Not so dissonant you cannot function, not so harmonic you stagnate. This is the sweet spot for growth.";
    } else {
      advice = "Your bands are in strong dissonance. This is not a flaw \u2014 it is a design for transformation. High inharmony people evolve rapidly. The cost is discomfort. The gift is that you cannot stay stuck.";
    }
    scoreDiv.innerHTML =
      '<div class="inharmony-summary">' +
        '<span class="inharmony-score-value">' + inharmony.scorePct + '%</span>' +
        '<span class="inharmony-score-label">Personal Inharmony Score \u2014 ' + scoreLevel + '</span>' +
      '</div>' +
      '<p class="inharmony-advice">' + advice + '</p>';
  }

  function renderVocation(vocation) {
    var container = document.getElementById("vocationContent");
    container.innerHTML =
      '<div class="vocation-title">' + vocation.title + '</div>' +
      '<p class="vocation-desc">' + vocation.desc + '</p>' +
      '<div class="vocation-roles"><strong>Natural roles:</strong> ' + vocation.roles + '</div>' +
      '<div class="vocation-emphasis"><strong>Growth emphasis:</strong> ' + vocation.emphasis + '</div>';
  }

  function renderGrowthSteps(steps) {
    var container = document.getElementById("growthSteps");
    container.innerHTML = "";

    for (var s = 0; s < steps.length; s++) {
      var num = String(s + 1).padStart(2, "0");
      var card = document.createElement("div");
      card.className = "growth-card";
      card.innerHTML =
        '<div class="growth-number">' + num + '</div>' +
        '<div class="growth-content">' +
          '<div class="growth-action">' + steps[s].action + '</div>' +
          '<div class="growth-why">' + steps[s].why + '</div>' +
        '</div>';
      container.appendChild(card);
    }
  }

  function renderVectorVisual(vector, dominantBand) {
    var container = document.getElementById("vectorVisual");
    container.innerHTML = "";

    var strip = document.createElement("div");
    strip.className = "vector-strip";

    for (var i = 0; i < 72; i++) {
      var color = bandColor(i + 1);


      var cell = document.createElement("div");
      cell.className = "vector-cell";
      cell.style.background = color;
      cell.style.opacity = Math.max(0.15, vector[i]);
      cell.style.transform = "scaleY(" + (0.3 + vector[i] * 1.2) + ")";
      cell.title = "Band " + (i + 1) + ": " + bandName(i + 1) + " \u2014 " + Math.round(vector[i] * 100) + "%";

      if (i + 1 === dominantBand) {
        cell.style.boxShadow = "0 0 8px " + color;
      }

      strip.appendChild(cell);
    }

    container.appendChild(strip);

    var labels = document.createElement("div");
    labels.className = "vector-labels";
    var important = [1, 12, 24, 36, 48, 60, 72];
    for (var l = 0; l < important.length; l++) {
      var span = document.createElement("span");
      span.textContent = important[l];
      span.style.left = ((important[l] - 1) / 71 * 100) + "%";
      labels.appendChild(span);
    }
    container.appendChild(labels);
  }

  function animateHeroAura(dominantBand) {
    var color = bandColor(dominantBand);
    var aura = document.getElementById("heroAura");
    if (aura) {
      aura.style.background = "radial-gradient(ellipse at 50% 50%, " + color + "22 0%, transparent 60%)";
      aura.style.animation = "none";
      void aura.offsetHeight;
      aura.style.animation = "aura-pulse 4s ease-in-out";
    }
  }



  function renderResults(results, year, month, day, hour, minute, lat, lon) {
    var timeStr = String(hour).padStart(2, "0") + ":" + String(minute).padStart(2, "0");
    var latStr = lat >= 0 ? lat.toFixed(4) + "\u00B0N" : (-lat).toFixed(4) + "\u00B0S";
    var lonStr = lon >= 0 ? lon.toFixed(4) + "\u00B0E" : (-lon).toFixed(4) + "\u00B0W";
    document.getElementById("resultDate").textContent = formatDate(year, month, day) + " \u00B7 " + timeStr + " UTC \u00B7 " + latStr + ", " + lonStr;

    renderPlanetPositions(results.planetBands, results.planetLongitudes);
    renderBandStrip(results.planetBands);
    renderDominantBand(results.dominantBand);
    renderTopBands(results.bandRankings);
    renderCZRatio(results.czRatio);
    renderInharmony(results.inharmony);
    renderVocation(results.vocation);
    renderGrowthSteps(results.growthSteps);
    renderVectorVisual(results.vector, results.dominantBand);
    animateHeroAura(results.dominantBand);
  }

  // ===========================================================================
  // ENTRY POINTS
  // ===========================================================================

  window.revealOracle = function() {
    var dateInput = document.getElementById("birthDate");
    var timeInput = document.getElementById("birthTime");
    var latInput = document.getElementById("birthLat");
    var lonInput = document.getElementById("birthLon");

    if (!dateInput.value) {
      document.getElementById("formHint").textContent = "Your birth date is required.";
      return;
    }

    var parts = dateInput.value.split("-");
    var year = parseInt(parts[0], 10);
    var month = parseInt(parts[1], 10);
    var day = parseInt(parts[2], 10);

    var hour = 12, minute = 0;
    if (timeInput.value) {
      var tParts = timeInput.value.split(":");
      hour = parseInt(tParts[0], 10);
      minute = parseInt(tParts[1], 10);
    }

    var lat = latInput.value ? parseFloat(latInput.value) : 51.5074;
    var lon = lonInput.value ? parseFloat(lonInput.value) : -0.1278;

    document.getElementById("inputSection").classList.add("hidden");
    document.getElementById("loadingSection").classList.remove("hidden");
    document.getElementById("resultSection").classList.add("hidden");

    var loadingEl = document.getElementById("loadingText");
    setTimeout(function() { loadingEl.textContent = "Mapping celestial positions..."; }, 300);
    setTimeout(function() { loadingEl.textContent = "Reading the 72 bands..."; }, 600);
    setTimeout(function() { loadingEl.textContent = "Computing your frequency vector..."; }, 900);

    setTimeout(function() {
      var results = calculateBirthProfile(year, month, day, hour, minute);
      renderResults(results, year, month, day, hour, minute, lat, lon);

      document.getElementById("loadingSection").classList.add("hidden");
      document.getElementById("resultSection").classList.remove("hidden");
      document.getElementById("resultSection").scrollIntoView({ behavior: "smooth", block: "start" });
    }, 1300);
  };

  window.resetOracle = function() {
    document.getElementById("resultSection").classList.add("hidden");
    document.getElementById("inputSection").classList.remove("hidden");
    document.getElementById("inputSection").scrollIntoView({ behavior: "smooth" });
  };
})();
