<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

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

<title>All About My Child</title>

<!-- Meta Pixel Code -->

<script>

!function(f,b,e,v,n,t,s)

{if(f.fbq)return;n=f.fbq=function(){n.callMethod?

n.callMethod.apply(n,arguments):n.queue.push(arguments)};

if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';

n.queue=[];t=b.createElement(e);t.async=!0;

t.src=v;s=b.getElementsByTagName(e)[0];

s.parentNode.insertBefore(t,s)}(window, document,'script',

'https://connect.facebook.net/en_US/fbevents.js');

fbq('init', '1630656715380377');

fbq('track', 'PageView');

</script>

<noscript><img height="1" width="1" style="display:none"

src="https://www.facebook.com/tr?id=1630656715380377&ev=PageView&noscript=1"

/></noscript>

<!-- End Meta Pixel Code -->

<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@600;700&family=Jost:wght@400;500&display=swap" rel="stylesheet">

<style>

:root {

--cream: #FAF3E9;

--cream-dark: #F0E4D3;

--sage: #8A9A82;

--sage-dark: #5A6B54;

--terracotta: #C97B5F;

--terracotta-dark: #A85C42;

--ink: #3A362F;

--ink-soft: rgba(58,54,47,0.65);

}

* { box-sizing: border-box; }

body {

margin: 0;

background: var(--cream);

color: var(--ink);

font-family: 'Jost', sans-serif;

display: flex;

justify-content: center;

min-height: 100vh;

}

#app {

width: 100%;

max-width: 640px;

padding: 24px;

display: flex;

flex-direction: column;

min-height: 100vh;

}

h1 {

font-family: 'Cormorant Garamond', serif;

font-weight: 700;

color: var(--terracotta-dark);

font-size: 30px;

margin: 8px 0 10px;

text-align: center;

}

.intro {

text-align: center;

color: var(--ink-soft);

font-size: 15px;

line-height: 1.5;

margin: 0 0 14px;

}

#consent-gate {

background: var(--cream-dark);

border: 1px solid rgba(90,107,84,0.3);

border-radius: 14px;

padding: 22px 20px;

margin-bottom: 8px;

}

#consent-gate h2 {

font-family: 'Cormorant Garamond', serif;

font-weight: 700;

color: var(--terracotta-dark);

font-size: 19px;

margin: 0 0 10px;

text-align: center;

}

#consent-gate p {

font-size: 14.5px;

line-height: 1.55;

color: var(--ink);

margin: 0 0 10px;

}

#consent-gate ul {

margin: 0 0 14px;

padding-left: 20px;

font-size: 14.5px;

line-height: 1.5;

}

#consent-gate li { margin-bottom: 4px; }

.consent-check {

display: flex;

align-items: flex-start;

gap: 10px;

background: var(--cream);

border-radius: 10px;

padding: 12px 14px;

margin-bottom: 14px;

}

.consent-check input {

margin-top: 3px;

width: 18px;

height: 18px;

flex-shrink: 0;

accent-color: var(--terracotta);

}

.consent-check label {

font-size: 14px;

line-height: 1.45;

color: var(--ink);

}

#consent-continue {

width: 100%;

background: var(--terracotta);

color: #fff;

border: none;

border-radius: 10px;

padding: 13px;

font-family: 'Jost', sans-serif;

font-weight: 500;

font-size: 15px;

cursor: pointer;

}

#consent-continue:disabled {

background: rgba(201,123,95,0.4);

cursor: not-allowed;

}

#consent-continue:not(:disabled):hover { background: var(--terracotta-dark); }

.site-footer {

text-align: center;

padding-top: 14px;

margin-top: auto;

}

.site-footer a {

color: var(--ink-soft);

font-size: 12.5px;

text-decoration: underline;

}

#chat {

flex: 1;

overflow-y: auto;

display: flex;

flex-direction: column;

gap: 12px;

padding-bottom: 16px;

}

.msg {

padding: 12px 16px;

border-radius: 14px;

max-width: 85%;

line-height: 1.4;

white-space: pre-wrap;

}

.bot {

background: var(--sage);

color: #fff;

align-self: flex-start;

border-bottom-left-radius: 4px;

}

.user {

background: var(--terracotta);

color: #fff;

align-self: flex-end;

border-bottom-right-radius: 4px;

}

.choice-buttons {

display: flex;

gap: 10px;

margin-top: 8px;

}

.choice-btn {

flex: 1;

background: var(--terracotta);

color: #fff;

border: none;

border-radius: 10px;

padding: 12px;

font-family: 'Jost', sans-serif;

font-weight: 500;

cursor: pointer;

}

.choice-btn:hover { background: var(--terracotta-dark); }

#input-row {

display: flex;

gap: 8px;

padding-top: 8px;

border-top: 1px solid rgba(58,54,47,0.15);

}

#input-row input {

flex: 1;

padding: 12px 14px;

border-radius: 10px;

border: 1px solid rgba(90,107,84,0.3);

background: var(--cream-dark);

color: var(--ink);

font-family: 'Jost', sans-serif;

font-size: 15px;

}

#input-row input::placeholder { color: var(--ink-soft); }

#input-row button {

background: var(--terracotta);

color: #fff;

border: none;

border-radius: 10px;

padding: 0 18px;

font-weight: 500;

cursor: pointer;

}

#input-row button:hover { background: var(--terracotta-dark); }

#loading {

align-self: flex-start;

color: var(--ink-soft);

font-style: italic;

padding: 4px 16px;

}

#error-banner {

background: #B8443A;

color: #fff;

padding: 10px 14px;

border-radius: 10px;

margin-bottom: 10px;

display: none;

}

#doc-result {

display: none;

flex-direction: column;

flex: 1;

}

.doc-actions {

display: flex;

gap: 10px;

margin-bottom: 12px;

}

.doc-actions button {

flex: 1;

border: none;

border-radius: 10px;

padding: 12px;

font-family: 'Jost', sans-serif;

font-weight: 500;

font-size: 14.5px;

cursor: pointer;

}

#print-btn {

background: var(--terracotta);

color: #fff;

}

#print-btn:hover { background: var(--terracotta-dark); }

#start-over-btn {

background: var(--cream-dark);

color: var(--ink);

border: 1px solid rgba(58,54,47,0.2) !important;

}

.doc-hint {

text-align: center;

font-size: 12.5px;

color: var(--ink-soft);

margin: 0 0 12px;

}

#doc-frame-wrap {

flex: 1;

overflow: auto;

border-radius: 12px;

background: #ddd;

-webkit-overflow-scrolling: touch;

}

#doc-frame {

display: block;

width: 850px;

min-height: 400px;

border: none;

}

</style>

</head>

<body>

<div id="app">

<h1>All About My Child</h1>

<p class="intro">A short, guided conversation that turns what you know about your child into a one-page reference — for a new teacher, aide, or caregiver meeting them for the first time.</p>



<div id="consent-gate">

<h2>Before we start</h2>

<p>This chat asks about your child, and what you share may include health-related details — medical needs, sensory needs, behavior, medications, and similar. Here's how that's handled:</p>

<ul>

<li>Your messages are sent to Anthropic's Claude API to run this chat and build your document.</li>

<li>Nothing is stored on our end — your conversation lives only in this browser tab and disappears when you close or refresh the page.</li>

<li>It is not used to train Anthropic's AI models, and is automatically deleted from their systems within 30 days.</li>

<li>We don't sell it, share it with advertisers, or use it for anything besides building your document.</li>

</ul>

<div class="consent-check">

<input type="checkbox" id="consent-checkbox" />

<label for="consent-checkbox">I understand and agree to how my information is handled, as described here and in the full <a href="/privacy-policy.html" target="_blank">Privacy Policy</a>.</label>

</div>

<button id="consent-continue" disabled>Continue</button>

</div>



<div id="chat-wrap" style="display:none;">

<div id="error-banner"></div>

<div id="chat"></div>

<div id="input-row" style="display:none;">

<input type="text" id="user-input" placeholder="Type your answer..." />

<button id="send-btn">Send</button>

</div>

</div>



<div id="doc-result">

<div class="doc-actions">

<button id="print-btn">Print / Save as PDF</button>

<button id="start-over-btn">Start Over</button>

</div>

<p class="doc-hint">In the print window, choose "Save as PDF" as the destination to save a copy.</p>

<div id="doc-frame-wrap">

<iframe id="doc-frame" title="Your child's reference document"></iframe>

</div>

</div>



<div class="site-footer"><a href="/privacy-policy.html" target="_blank">Privacy Policy</a></div>

</div>



<script>

// TODO: this should point at your deployed Worker URL.

const WORKER_URL = "https://twilight-fire-243b.cbscodingsuccess.workers.dev/";



const chatEl = document.getElementById('chat');

const chatWrap = document.getElementById('chat-wrap');

const inputRow = document.getElementById('input-row');

const inputEl = document.getElementById('user-input');

const sendBtn = document.getElementById('send-btn');

const errorBanner = document.getElementById('error-banner');

const consentGate = document.getElementById('consent-gate');

const consentCheckbox = document.getElementById('consent-checkbox');

const consentContinue = document.getElementById('consent-continue');

const docResult = document.getElementById('doc-result');

const docFrame = document.getElementById('doc-frame');

const docFrameWrap = document.getElementById('doc-frame-wrap');

const printBtn = document.getElementById('print-btn');

const startOverBtn = document.getElementById('start-over-btn');



let messages = [];

let waitingForModeChoice = true;



function addMessage(role, text) {

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

div.className = 'msg ' + (role === 'user' ? 'user' : 'bot');

div.textContent = text;

chatEl.appendChild(div);

chatEl.scrollTop = chatEl.scrollHeight;

}



function showLoading() {

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

div.id = 'loading';

div.textContent = 'Thinking...';

chatEl.appendChild(div);

chatEl.scrollTop = chatEl.scrollHeight;

}



function hideLoading() {

const el = document.getElementById('loading');

if (el) el.remove();

}



function showError(text) {

errorBanner.textContent = text;

errorBanner.style.display = 'block';

}



function hideError() {

errorBanner.style.display = 'none';

}



async function callWorker() {

showLoading();

hideError();

try {

const res = await fetch(WORKER_URL, {

method: 'POST',

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

body: JSON.stringify({ messages })

});

const data = await res.json();

hideLoading();

if (!res.ok) {

showError(data.error || 'Something went wrong. Please try again.');

return;

}

const reply = data.reply || '';

messages.push({ role: 'assistant', content: reply });



const markerIndex = reply.indexOf('READY_FOR_DOCUMENT:');

if (markerIndex !== -1) {

addMessage('bot', "Thank you — I have everything I need. Building your document now, one moment...");

inputRow.style.display = 'none';

const summaryText = reply.slice(markerIndex + 'READY_FOR_DOCUMENT:'.length).trim();

generateDocument(summaryText);

} else {

addMessage('bot', reply);

}

} catch (err) {

hideLoading();

showError('Could not reach the server. Check your connection and try again.');

}

}



async function generateDocument(summaryText) {

showLoading();

hideError();

try {

const res = await fetch(WORKER_URL, {

method: 'POST',

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

body: JSON.stringify({ action: 'generate_document', summary: summaryText })

});

const data = await res.json();

hideLoading();

if (!res.ok) {

showError(data.error || 'Could not build the document. Please try again.');

addRetryButton(summaryText);

return;

}

showDocument(data.html);

} catch (err) {

hideLoading();

showError('Could not reach the server. Check your connection and try again.');

addRetryButton(summaryText);

}

}



function addRetryButton(summaryText) {

const btn = document.createElement('button');

btn.className = 'choice-btn';

btn.textContent = 'Try building the document again';

btn.style.marginTop = '4px';

btn.onclick = () => {

btn.remove();

generateDocument(summaryText);

};

chatEl.appendChild(btn);

chatEl.scrollTop = chatEl.scrollHeight;

}



function showDocument(html) {

chatWrap.querySelectorAll('#chat, #input-row, #error-banner').forEach(el => {

if (el.id !== 'error-banner') el.style.display = 'none';

});

docResult.style.display = 'flex';

docFrame.srcdoc = html;

docFrame.onload = () => {

try {

const doc = docFrame.contentWindow.document;

docFrame.style.height = doc.documentElement.scrollHeight + 'px';

} catch (e) { /* ignore */ }

fitDocFrame();

};

}



function fitDocFrame() {

const wrapWidth = docFrameWrap.clientWidth;

const nativeWidth = 850;

if (wrapWidth < nativeWidth) {

const scale = wrapWidth / nativeWidth;

docFrame.style.transform = `scale(${scale})`;

docFrame.style.transformOrigin = 'top left';

docFrameWrap.style.height = (docFrame.offsetHeight * scale) + 'px';

} else {

docFrame.style.transform = 'none';

docFrameWrap.style.height = docFrame.offsetHeight + 'px';

}

}



window.addEventListener('resize', fitDocFrame);



printBtn.addEventListener('click', () => {

docFrame.contentWindow.focus();

docFrame.contentWindow.print();

});



startOverBtn.addEventListener('click', () => {

location.reload();

});



function sendUserMessage(text) {

if (!text.trim()) return;

messages.push({ role: 'user', content: text });

addMessage('user', text);

inputEl.value = '';

callWorker();

}



sendBtn.addEventListener('click', () => sendUserMessage(inputEl.value));

inputEl.addEventListener('keydown', (e) => {

if (e.key === 'Enter') sendUserMessage(inputEl.value);

});



// Kick off the conversation with the opening choice message.

function start() {

addMessage('bot', "Let's build your child's document. You can do this two ways:");

const choiceDiv = document.createElement('div');

choiceDiv.className = 'choice-buttons';



const btnA = document.createElement('button');

btnA.className = 'choice-btn';

btnA.textContent = 'A) Brain dump';

btnA.onclick = () => chooseMode('A) Brain dump — I want to just tell you everything about my child freely.');



const btnB = document.createElement('button');

btnB.className = 'choice-btn';

btnB.textContent = 'B) Guided questions';

btnB.onclick = () => chooseMode('B) Guided questions — please ask me one question at a time.');



choiceDiv.appendChild(btnA);

choiceDiv.appendChild(btnB);

chatEl.appendChild(choiceDiv);

}



function chooseMode(choiceText) {

// Remove the choice buttons once picked

document.querySelectorAll('.choice-buttons').forEach(el => el.remove());

addMessage('user', choiceText);

messages.push({ role: 'user', content: choiceText });

inputRow.style.display = 'flex';

callWorker();

}



consentCheckbox.addEventListener('change', () => {

consentContinue.disabled = !consentCheckbox.checked;

});



consentContinue.addEventListener('click', () => {

if (!consentCheckbox.checked) return;

consentGate.style.display = 'none';

chatWrap.style.display = 'block';

start();

});

</script>

</body>

</html>