<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Reclaimed — Intake Pipeline</title>

<style>

  * { box-sizing: border-box; margin: 0; padding: 0; }

  body { background: #0c0a09; color: #e7e5e4; font-family: Georgia, serif; min-height: 100vh; padding: 24px 16px; }

  .container { max-width: 640px; margin: 0 auto; }

  .header { text-align: center; padding: 32px 0 24px; }

  .brand { color: #d97706; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 8px; }

  h1 { font-size: 26px; font-weight: 300; margin-bottom: 6px; }

  .subtitle { color: #78716c; font-size: 14px; }

  .steps { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 24px 0 8px; }

  .step { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 500; transition: all 0.3s; }

  .step.active { background: #b45309; color: white; }

  .step.done { background: #451a03; color: #d97706; }

  .step.pending { background: #292524; color: #57534e; }

  .step-line { width: 32px; height: 1px; background: #292524; }

  .step-line.done { background: #92400e; }

  .step-label { text-align: center; color: #78716c; font-size: 12px; margin-bottom: 24px; }

  .section { background: #1c1917; border-radius: 12px; padding: 20px; margin-bottom: 16px; }

  .section-title { color: #d97706; font-size: 11px; text-transform: uppercase; letter-spacing: 0.15em; margin-bottom: 16px; }

  .field { margin-bottom: 14px; }

  .field:last-child { margin-bottom: 0; }

  label { display: block; font-size: 11px; color: #a8a29e; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 5px; }

  input, select, textarea {

    width: 100%; background: #0c0a09; border: 1px solid #44403c; border-radius: 8px;

    padding: 10px 12px; color: #e7e5e4; font-size: 14px; font-family: Georgia, serif;

    outline: none; transition: border-color 0.2s;

  }

  input:focus, select:focus, textarea:focus { border-color: #b45309; }

  input::placeholder, textarea::placeholder { color: #57534e; }

  textarea { resize: none; }

  .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

  .btn { width: 100%; padding: 14px; border-radius: 12px; border: none; font-size: 14px; font-family: Georgia, serif; font-weight: 500; letter-spacing: 0.05em; cursor: pointer; transition: all 0.2s; }

  .btn-primary { background: #b45309; color: white; }

  .btn-primary:hover { background: #92400e; }

  .btn-primary:disabled { background: #292524; color: #57534e; cursor: not-allowed; }

  .btn-secondary { background: #1c1917; color: #a8a29e; border: 1px solid #44403c; }

  .btn-secondary:hover { border-color: #57534e; }

  .btn-row { display: grid; grid-template-columns: 1fr 2fr; gap: 12px; }

  .btn-copy-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }

  .btn-copy { padding: 10px; border-radius: 10px; border: 1px solid #44403c; background: none; color: #a8a29e; font-size: 12px; font-family: Georgia, serif; cursor: pointer; transition: all 0.2s; }

  .btn-copy:hover { border-color: #57534e; color: #e7e5e4; }

  .status-box { background: #1c1917; border: 1px solid #292524; border-radius: 12px; padding: 20px; margin-bottom: 16px; }

  .status-item { display: flex; gap: 10px; font-size: 14px; margin-bottom: 8px; }

  .status-item.info { color: #a8a29e; }

  .status-item.success { color: #4ade80; }

  .status-item.error { color: #f87171; }

  .error-box { background: #2d0a0a; border: 1px solid #7f1d1d; border-radius: 8px; padding: 14px; color: #f87171; font-size: 14px; margin-top: 12px; }

  .result-header { background: #1c1917; border: 1px solid #451a03; border-radius: 12px; padding: 16px; margin-bottom: 16px; display: flex; justify-content: space-between; align-items: flex-start; }

  .result-name { color: #d97706; font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 4px; }

  .result-client { font-size: 16px; color: #e7e5e4; font-weight: 500; }

  .result-meta { text-align: right; font-size: 12px; color: #78716c; line-height: 1.8; }

  .result-block { background: #1c1917; border: 1px solid #292524; border-radius: 12px; padding: 20px; margin-bottom: 16px; }

  .result-label { color: #d97706; font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 12px; }

  .result-text { color: #d6d3d1; font-size: 14px; line-height: 1.8; white-space: pre-wrap; }

  .pulse { animation: pulse 1.5s infinite; }

  @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }

  .note { color: #78716c; font-size: 12px; line-height: 1.6; margin-top: 8px; }

</style>

</head>

<body>

<div class="container">


  <div class="header">

    <div class="brand">Reclaimed</div>

    <h1>Intake Pipeline</h1>

    <p class="subtitle">Birth data → Chart → Session briefing + Client artifacts</p>

  </div>


  <!-- Steps -->

  <div class="steps" id="steps"></div>

  <div class="step-label" id="stepLabel"></div>


  <!-- STEP 0: API Key -->

  <div id="step0">

    <div class="section">

      <div class="section-title">HumanDesignHub API Key</div>

      <div class="field">

        <label>API Key</label>

        <input type="password" id="hdKey" placeholder="hd_live_..." />

        <p class="note">Only your HumanDesignHub key is needed. Chart calculation runs through your Cloudflare Worker. Briefing and artifacts are generated by Claude — no separate API key required.</p>

      </div>

    </div>

    <button class="btn btn-primary" id="btn0" onclick="goStep(1)" disabled>Continue →</button>

  </div>


  <!-- STEP 1: Intake -->

  <div id="step1" style="display:none">

    <div class="section">

      <div class="section-title">Client Info</div>

      <div class="field">

        <label>Client Name</label>

        <input type="text" id="clientName" placeholder="First name or full name" oninput="checkIntake()" />

      </div>

      <div class="grid2">

        <div class="field">

          <label>Birth Date</label>

          <input type="date" id="birthDate" oninput="checkIntake()" />

        </div>

        <div class="field">

          <label>Birth Time</label>

          <input type="time" id="birthTime" oninput="checkIntake()" />

        </div>

      </div>

      <div class="field">

        <label>Birth City</label>

        <input type="text" id="birthCity" placeholder="City, Country (e.g. St. Louis, US)" oninput="checkIntake()" />

      </div>

    </div>

    <div class="section">

      <div class="section-title">Session Context</div>

      <div class="field">

        <label>Session Type</label>

        <select id="sessionType">

          <option>The Conversation</option>

          <option>The Deep Dive</option>

          <option>Blueprint</option>

        </select>

      </div>

      <div class="field">

        <label>HD Familiarity</label>

        <select id="hdLevel">

          <option>None — complete beginner</option>

          <option>Some — familiar with basics</option>

          <option>Deep — practiced in HD</option>

        </select>

      </div>

    </div>

    <div class="section">

      <div class="section-title">Intake Context</div>

      <div class="field">

        <label>What are you currently navigating?</label>

        <textarea id="navigating" rows="4" placeholder="What's happening in your life right now — relationships, work, decisions, transitions..." oninput="checkIntake()"></textarea>

      </div>

      <div class="field">

        <label>What's alive for you right now?</label>

        <textarea id="alive" rows="4" placeholder="Not what's wrong — what feels present, unresolved, or asking for attention in your body and life..." oninput="checkIntake()"></textarea>

      </div>

      <div class="field">

        <label>Is there anything else you'd like me to know? <span style="color:#57534e;text-transform:none">(optional)</span></label>

        <textarea id="notes" rows="3" placeholder="Any context that feels relevant to bring into our conversation..."></textarea>

      </div>

    </div>

    <div class="btn-row">

      <button class="btn btn-secondary" onclick="goStep(0)">← Back</button>

      <button class="btn btn-primary" id="btn1" onclick="runPipeline()" disabled>Run Pipeline →</button>

    </div>

  </div>


  <!-- STEP 2: Processing -->

  <div id="step2" style="display:none">

    <div class="status-box">

      <div class="section-title">Pipeline Running</div>

      <div id="statusList"></div>

      <div id="processingDot" class="status-item info pulse" style="display:none">→ &nbsp;Processing...</div>

      <div id="errorBox" class="error-box" style="display:none"></div>

    </div>

    <button class="btn btn-secondary" id="backBtn" onclick="goStep(1)" style="display:none">← Back to Intake</button>

  </div>


  <!-- STEP 3: Results -->

  <div id="step3" style="display:none">

    <div class="result-header">

      <div>

        <div class="result-name">Chart Calculated</div>

        <div class="result-client" id="rName"></div>

      </div>

      <div class="result-meta" id="rMeta"></div>

    </div>

    <div class="result-block">

      <div class="result-label">⚡ Session Briefing — Matthew Only</div>

      <div class="result-text" id="rBriefing"></div>

    </div>

    <div class="result-block">

      <div class="result-label">🌿 Client Artifact Package</div>

      <div class="result-text" id="rArtifacts"></div>

    </div>

    <div class="btn-copy-row">

      <button class="btn-copy" onclick="copy('rBriefing', this)">Copy Briefing</button>

      <button class="btn-copy" onclick="copy('rArtifacts', this)">Copy Artifacts</button>

    </div>

    <button class="btn btn-secondary" onclick="newClient()">New Client</button>

  </div>


</div>


<script>

const WORKER_URL = "https://reclaimed-pipeline.matt-budenholzer.workers.dev";


const PROFILES = {

  "1/3":"The Grounded Pathfinder","1/4":"The Rooted Connector",

  "2/4":"The Selective Bridge","2/5":"The Seen Catalyst",

  "3/5":"The Embodied Pathfinder","3/6":"The Alchemist",

  "4/6":"The Trusted Example","4/1":"The Grounded Architect",

  "5/1":"The Practical Authority","5/2":"The Natural Catalyst",

  "6/2":"The Still Flame","6/3":"The Integrated Wanderer"

};


const STEP_LABELS = ["API Key","Client Intake","Processing","Results"];

let currentStep = 0;


function renderSteps(step) {

  const s = document.getElementById("steps");

  const l = document.getElementById("stepLabel");

  s.innerHTML = STEP_LABELS.map((_, i) => {

    const cls = i < step ? "done" : i === step ? "active" : "pending";

    const line = i < STEP_LABELS.length - 1 ? `<div class="step-line ${i < step ? 'done' : ''}"></div>` : "";

    return `<div class="step ${cls}">${i+1}</div>${line}`;

  }).join("");

  l.textContent = STEP_LABELS[step];

}


function goStep(n) {

  ["step0","step1","step2","step3"].forEach((id, i) => {

    document.getElementById(id).style.display = i === n ? "block" : "none";

  });

  currentStep = n;

  renderSteps(n);

}


document.getElementById("hdKey").addEventListener("input", function() {

  document.getElementById("btn0").disabled = this.value.length < 10;

});


function checkIntake() {

  const ok = ["clientName","birthDate","birthTime","birthCity","navigating","alive"]

    .every(id => document.getElementById(id).value.trim());

  document.getElementById("btn1").disabled = !ok;

}


function addStatus(msg, type) {

  const div = document.createElement("div");

  div.className = `status-item ${type}`;

  div.innerHTML = `<span>${type==="success"?"✓":type==="error"?"✗":"→"}</span><span>${msg}</span>`;

  document.getElementById("statusList").appendChild(div);

}


async function callClaude(prompt) {

  const res = await fetch("https://api.anthropic.com/v1/messages", {

    method: "POST",

    headers: { "Content-Type": "application/json" },

    body: JSON.stringify({

      model: "claude-sonnet-4-20250514",

      max_tokens: 1500,

      messages: [{ role: "user", content: prompt }]

    })

  });

  const data = await res.json();

  const text = data?.content?.[0]?.text;

  if (!text) throw new Error("Generation failed: " + JSON.stringify(data));

  return text;

}


async function runPipeline() {

  goStep(2);

  document.getElementById("statusList").innerHTML = "";

  document.getElementById("errorBox").style.display = "none";

  document.getElementById("backBtn").style.display = "none";

  document.getElementById("processingDot").style.display = "flex";


  const hdKey = document.getElementById("hdKey").value.trim();

  const form = {

    clientName: document.getElementById("clientName").value.trim(),

    birthDate: document.getElementById("birthDate").value,

    birthTime: document.getElementById("birthTime").value,

    birthCity: document.getElementById("birthCity").value.trim(),

    sessionType: document.getElementById("sessionType").value,

    hdLevel: document.getElementById("hdLevel").value,

    currentlyNavigating: document.getElementById("navigating").value.trim(),

    whatsAlive: document.getElementById("alive").value.trim(),

    additionalNotes: document.getElementById("notes").value.trim()

  };


  try {

    addStatus("Calculating Human Design chart...", "info");

    const workerRes = await fetch(WORKER_URL, {

      method: "POST",

      headers: { "Content-Type": "application/json" },

      body: JSON.stringify({ hdKey, birthDate: form.birthDate, birthTime: form.birthTime, birthCity: form.birthCity })

    });

    const workerData = await workerRes.json();

    if (!workerData.success) throw new Error(workerData.error || "Worker failed");

    const { chart, location } = workerData;

    const profileName = PROFILES[chart.profile] || chart.profile;

    addStatus(`Chart: ${chart.type} · ${chart.profile} — ${profileName} · ${location}`, "success");


    addStatus("Generating session briefing...", "info");

    const briefing = await callClaude(`You are the pre-session briefing engine for Reclaimed, Matthew Budenholzer's Human Design practice. Generate a focused session briefing in Matthew's voice.


LANGUAGE RULES:

- Profile translations: ${JSON.stringify(PROFILES)}

- Authority: Sacral=The Gut Signal, Splenic=The Whisper, Emotional=The Wave, Self-Projected=The Spoken Truth, Ego=The Will, G Center=The Direction Felt, Mental=The Sounding Board, Lunar=The Moon Cycle

- Not-self: Frustration=The Friction Signal, Bitterness=The Unseen Signal, Anger=The Resistance Signal, Disappointment=The Environment Signal

- Warm, direct, somatic, positively framed. Sessions are Conversations not readings.


CLIENT: ${form.clientName} · ${form.sessionType} · HD familiarity: ${form.hdLevel}


CHART:

Type: ${chart.type} | Strategy: ${chart.strategy} | Authority: ${chart.authority}

Profile: ${chart.profile} — ${profileName} | Definition: ${chart.definition}

Not-Self: ${chart.not_self_theme} | Signature: ${chart.signature}

Defined Centers: ${(chart.centers||[]).join(", ")}

Gates: ${(chart.gates||[]).join(", ")}

Channels: ${(chart.channels||[]).map(c=>c.name).join(", ")}


INTAKE:

Navigating: ${form.currentlyNavigating}

Alive: ${form.whatsAlive}

Notes: ${form.additionalNotes||"None"}


Generate with these exact sections:

## SNAPSHOT

## TOP 3-5 CHART ELEMENTS TO FOCUS ON

## SESSION OPENER

## SHADOW DYNAMICS TO WATCH

## DO NOT GO HERE UNLESS INVITED

## EXPERIMENT SEED


Write as a trusted colleague briefing Matthew before a meaningful conversation.`);

    addStatus("Session briefing generated", "success");


    addStatus("Generating client artifact package...", "info");

    const artifacts = await callClaude(`Generate a personalized client artifact package for Reclaimed, Matthew Budenholzer's Human Design practice.


CLIENT: ${form.clientName}

Type: ${chart.type} | Profile: ${chart.profile} — ${profileName}

Authority: ${chart.authority} | Definition: ${chart.definition}

Not-Self: ${chart.not_self_theme}

Defined Centers: ${(chart.centers||[]).join(", ")}

Navigating: ${form.currentlyNavigating}

Alive: ${form.whatsAlive}


Generate with these exact sections:

## YOUR DESIGN IN PLAIN LANGUAGE

Warm, accessible — written FOR them not AT them. Use their translated profile name (${profileName}). No unexplained jargon.


## SHADOW INQUIRY PROMPTS

4-5 Jungian-framed questions for their not-self pattern and undefined centers. Each starting with →


## SOMATIC EXPERIMENT CARDS

3-4 body-based experiments tied to their design. Labeled Experiment 1:, 2:, etc.


## WHAT TO WATCH FOR

Their conditioning patterns in plain language they can recognize in real time.


## YOUR 2-WEEK EXPERIMENT

One focused experiment tied to their design and what's alive — anchor for the follow-up.


Warm, embodied, accessible. This goes directly to the client.`);

    addStatus("Client artifact package generated", "success");

    addStatus("Pipeline complete ✓", "success");

    document.getElementById("processingDot").style.display = "none";


    document.getElementById("rName").textContent = form.clientName;

    document.getElementById("rMeta").innerHTML = `${chart.type}<br>${profileName}<br>${chart.authority} Authority<br>${chart.definition}`;

    document.getElementById("rBriefing").textContent = briefing;

    document.getElementById("rArtifacts").textContent = artifacts;

    goStep(3);


  } catch(e) {

    document.getElementById("processingDot").style.display = "none";

    addStatus("Error: " + e.message, "error");

    const eb = document.getElementById("errorBox");

    eb.textContent = e.message;

    eb.style.display = "block";

    document.getElementById("backBtn").style.display = "block";

  }

}


function copy(id, btn) {

  const text = document.getElementById(id).textContent;

  navigator.clipboard.writeText(text).then(() => {

    btn.textContent = "Copied ✓";

    setTimeout(() => btn.textContent = id === "rBriefing" ? "Copy Briefing" : "Copy Artifacts", 2000);

  });

}


function newClient() {

  document.getElementById("clientName").value = "";

  document.getElementById("birthDate").value = "";

  document.getElementById("birthTime").value = "";

  document.getElementById("birthCity").value = "";

  document.getElementById("navigating").value = "";

  document.getElementById("alive").value = "";

  document.getElementById("notes").value = "";

  document.getElementById("btn1").disabled = true;

  goStep(1);

}


goStep(0);

renderSteps(0);

</script>

</body>

</html>