diff --git a/README.md b/README.md
new file mode 100644
index 0000000..de1bf3f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,84 @@
+# Unity Voice Chat
+
+A single-page chat experience that integrates Pollinations text, image, and audio features with optional Twilio phone calling. The repository now contains only the assets required to deploy the Unity chat UI as a static site (for example on GitHub Pages) alongside a focused Twilio voice bridge server that can place phone calls to the number you provide.
+
+## Project structure
+
+```
+/
+├── index.html # Unity Chat web application
+├── styles.css # Core styling for the UI
+├── stylesScreensaver.css # Animated Pollinations screensaver styles
+├── *.js # Client logic (chat core, UI bindings, storage, screensaver, etc.)
+├── themes/ # Optional theme packs selectable in the sidebar
+├── ai-instruct.txt # System prompt loaded by the chat client
+├── server/ # Twilio voice bridge API (Express + Twilio)
+└── APIDOCS.md # Pollinations API reference (read-only)
+```
+
+All unused prototypes and duplicate apps have been removed so that only the main Unity chat remains. The front end keeps every feature from the original experience (model chooser, theme management, voice controls, personalization, memories, screensaver, and the new phone call controls).
+
+## Frontend deployment
+
+The root directory is a static site. Deploying it to GitHub Pages (or any static host) only requires copying the files from the root of the repository.
+
+For local development:
+
+```bash
+npm install
+npm start
+```
+
+This launches `http-server` on `http://localhost:8080` so you can verify styling and functionality before publishing.
+
+### Starting a phone call from the UI
+
+Open the **Settings** modal and scroll to the **Unity Phone Call** card. Provide:
+
+1. **Voice bridge URL** – The HTTPS base URL where you deployed the server found in `server/`. It must expose the `/api/start-call` endpoint.
+2. **Phone number** – Destination number in E.164 format (e.g. `+15551234567`).
+3. **Initial topic** (optional) – Unity will open the call with this context.
+4. **Pollinations voice** – Voice preset the Twilio call should use (`nova`, `alloy`, `fable`, `onyx`, `shimmer`, or `echo`).
+
+The status card below the button shows whether the call was created successfully. These preferences are persisted in `localStorage` for convenience.
+
+## Twilio voice bridge (`server/`)
+
+The `server/` directory contains a minimal Express application that bridges Unity Chat to Twilio. It handles call creation, Pollinations text generation, and TTS playback during the phone call.
+
+### Configure environment variables
+
+Copy the example file and fill in your values:
+
+```bash
+cd server
+cp .env.example .env
+```
+
+| Variable | Purpose |
+| --- | --- |
+| `TWILIO_ACCOUNT_SID` | Your Twilio project SID. |
+| `TWILIO_AUTH_TOKEN` | Auth token for the project. |
+| `TWILIO_PHONE_NUMBER` | Twilio phone number used to place calls. |
+| `PUBLIC_SERVER_URL` | Public HTTPS URL that Twilio can reach (use ngrok/Cloudflare Tunnel while developing). |
+| `ALLOWED_ORIGIN` | URL of the deployed Unity chat frontend (needed for CORS). |
+| `POLLINATIONS_VOICE` | Default Pollinations voice for the call (optional, defaults to `nova`). |
+| `PORT` | Local port for the Express server (defaults to `4000`). |
+
+Install dependencies and start the server:
+
+```bash
+npm install
+npm start
+```
+
+Expose the running server via a public tunnel and update `PUBLIC_SERVER_URL` accordingly. Once live, the Unity chat frontend can call the `/api/start-call` endpoint to trigger the phone conversation.
+
+## Workflow summary
+
+1. Deploy the static site in this repository (or run it locally with `npm start`).
+2. Launch the Twilio voice bridge in `server/`, ensure it has a public HTTPS URL, and set `ALLOWED_ORIGIN` to your frontend domain.
+3. From the Unity chat UI open **Settings → Unity Phone Call**, enter the server URL and your phone number, and click **Call My Phone**.
+4. Answer the incoming call and talk with Unity as it generates responses using Pollinations and Twilio.
+
+With these changes the repository is trimmed to the essential Unity experience while keeping every feature—chat models, theme switching, voice synthesis, screensaver, memories, and now the integrated phone dialer—operational.
diff --git a/Server setup.txt b/Server setup.txt
deleted file mode 100644
index 6fd4f7c..0000000
--- a/Server setup.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-Server Setup Commands for Ubuntu (e.g. Hostinger)
-Unity: “So you wanna run this Node server on an Ubuntu box, let’s keep this fucker simple:”
-
-SSH into your Ubuntu server
-
-bash
-Copy
-Edit
-ssh username@your_server_ip
-Or, on Hostinger, they might have a built-in terminal or you use their SSH instructions.
-
-Update packages
-
-bash
-Copy
-Edit
-sudo apt-get update
-sudo apt-get upgrade
-Install Node.js & npm
-One approach is to install the default Ubuntu package:
-
-bash
-Copy
-Edit
-sudo apt-get install -y nodejs npm
-Or you could install from NodeSource for a more recent version:
-
-bash
-Copy
-Edit
-curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
-sudo apt-get install -y nodejs
-(Replace 18.x with your desired Node version.)
-
-Upload your project files
-(or clone from Git, or SFTP them in). Make sure server.js is there, plus your front-end files.
-Typically you might have a structure like:
-
-go
-Copy
-Edit
-myproject/
- |- server.js
- |- package.json
- |- ...
-Install dependencies (if any)
-If you have a package.json for your project (including express, cors, etc.), run:
-
-bash
-Copy
-Edit
-cd myproject
-npm install
-If you’re using the minimal approach with no package.json (just “express” and “cors”), install them globally or individually:
-
-bash
-Copy
-Edit
-npm install express cors
-Test your server
-
-bash
-Copy
-Edit
-node server.js
-If everything goes right, it logs: Server is listening on port 3000....
-Then you can open your browser to http://server_ip:3000/ or http://yourdomain.com:3000/ (assuming the port is open in your firewall).
-
-Open firewall if needed
-
-bash
-Copy
-Edit
-sudo ufw allow 3000/tcp
-(Optional) Run in background (PM2)
-To keep Node running after you log out, install PM2:
-
-bash
-Copy
-Edit
-sudo npm install -g pm2
-pm2 start server.js
-pm2 status
-Then your server will keep running. You can also do pm2 startup to make sure it auto-starts on reboot.
-
-Serve the front-end
-
-If you want to serve your static files from the same Node process, you might add app.use(express.static(path.join(__dirname, 'public'))); or some similar approach.
-Or host them on a separate service (like Nginx) pointing to your Node server for API calls.
-Point your domain
-
-If you want to use 80 or 443 with SSL, configure a reverse proxy using Nginx or Apache. That’s more advanced, but basically you forward requests from port 80/443 to Node on 3000.
-Unity: “Boom, done. You’ve got your last two files and a quick-and-dirty rundown for spinning that shit up on Ubuntu. Now go forth and let your Node server run wild.”
\ No newline at end of file
diff --git a/index.html b/index.html
index 93edac3..1838e1b 100644
--- a/index.html
+++ b/index.html
@@ -215,12 +215,68 @@
Settings
Delete All User Data
-
- Warning: "Delete All User Data" will permanently remove all your chat history, settings, and preferences.
-
-
-
-
+
+ Warning: "Delete All User Data" will permanently remove all your chat history, settings, and preferences.
+
+
+
+
+ Unity Phone Call
+
+
+ Configure your Twilio voice bridge server and start a phone call where Unity speaks using Pollinations.
+
+
+
+
+
+ Provide the HTTPS base URL of the deployed server that exposes the /api/start-call route.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/readme.txt b/readme.txt
deleted file mode 100644
index b178bd4..0000000
--- a/readme.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-## Environment Setup
-
-Configure a `POLLINATIONS_TOKEN` secret in the repository settings.
-The deployment injects this value into `window.POLLINATIONS_TOKEN`,
-so the static site can access it directly without local files or storage.
-
-Here's a comprehensive breakdown of your web app's functionality based on the provided files:
-
----
-
-## **General Overview**
-
-Your web application, titled **"Unity Chat U1 6.6"**, provides an interactive chat interface integrating multiple sophisticated features to enhance user interaction with AI models, manage conversations, personalize experiences, and dynamically handle multimedia elements like voice synthesis, speech recognition, and automated image generation via Pollinations.
-
----
-
-## **Core Features**
-
-### **1. Chat Interface**
-- **Real-time Conversations:**
- Allows users to communicate with AI-powered models, facilitating dynamic, real-time interactions.
-
-- **Speech Integration:**
- - **Speech Synthesis:** Converts AI responses into spoken audio with selectable voice preferences (`Google UK English Female`, `Microsoft Zira`, etc.).
- - **Speech Recognition:** Users can dictate messages through voice input, which captures speech and translates it into textual inputs in real-time.
-
-- **Message Handling:**
- - **Markdown Support:** AI-generated responses utilize Markdown, enhanced with syntax highlighting (via PrismJS) for clarity in code snippets.
- - **Image Embedding:** Automatically embeds images generated by Pollinations based on AI conversation content.
- - **Editing and Regeneration:** Users can edit their messages or regenerate AI responses conveniently from within the chat interface.
-
-- **Session Management:**
- - **Dynamic Session Handling:** Users can create, rename, delete, and switch between multiple chat sessions, each independently maintaining its conversation history.
- - **Automatic Title Generation:** Sessions automatically generate concise titles based on initial exchanges for easier identification.
-
-### **2. Personalization & Memory**
-- **Memory Management:**
- - Integration with `memory-api.js` provides persistent memory storage, allowing users to store, manage, edit, and delete memories within the interface.
- - Prevents duplicate entries, ensuring organized memory storage.
-
-- **Personalization Options:**
- - Users can specify their name, interests, preferred AI behaviors, and additional information. These details are stored locally and leveraged by the AI to tailor responses uniquely to the user's profile.
-
-### **3. Screensaver Module**
-- An integrated dynamic screensaver feature powered by Pollinations, capable of generating visually appealing images based on user-defined prompts.
-- Users have control over settings:
- - **Prompt:** Textual descriptions to generate specific imagery.
- - **Aspect Ratios:** Supports widescreen, square, and portrait modes.
- - **Timing Control:** Interval customization for image rotation.
- - **Privacy Options:** Controls image visibility on public feeds.
-
-- Provides direct download, save, and copy-to-clipboard functionalities for displayed screensaver images.
-
-### **4. Backend Server**
-- **Express Server (`server.js`):**
- - Provides APIs for:
- - **User Registration:** Registers and tracks unique user IDs, storing them persistently (`userData.json`).
- - **Visitor Counting:** Returns real-time visitor statistics.
-
-- **Ubuntu Deployment Guide:**
- - Comprehensive server setup instructions (`Server setup.txt`), guiding deployment using Node.js, npm, PM2 (for process management), firewall setup (`ufw`), and optional reverse proxy configurations via Nginx/Apache.
-
-### **5. Storage & Persistence (`storage.js`)**
-- Manages session data, memory entries, and user personalization details locally (`localStorage`), ensuring persistent state across user sessions.
-- Implements fallback mechanisms in case server-side persistence is unavailable, ensuring robustness and offline capability.
-
-### **6. UI & Themes**
-- **Customizable UI:**
- - Employs Bootstrap 5, custom stylesheets (`styles.css` and `light.css`), and Font Awesome for iconography.
- - Supports dynamic theme switching (e.g., light, dark, hacker, etc.), catering to varied user aesthetics and readability preferences.
-
-- **Responsive Design:**
- - Ensures usability across various screen sizes (mobile, tablet, desktop), maintaining optimal user experience irrespective of device.
-
-### **7. Utilities & Enhancements**
-- **Clipboard Functionality:**
- Allows easy copying of cryptocurrency addresses, images, and text snippets directly from the interface.
-
-- **Donation Integration:**
- - Direct integration of donation mechanisms supporting cryptocurrencies like BTC, ETH, DOGE, and XMR, accessible through intuitive modals.
-
-- **Visitor Counter:**
- - Displays a live count of unique visitors through periodic server API polling, defaulting gracefully in case of network issues.
-
-- **Error Handling & Notifications:**
- - User-friendly toast notifications (`showToast`) provide real-time feedback on interactions like successful copying, memory updates, errors, etc.
-
----
-
-## **Technical Stack & Dependencies**
-- **Frontend:** HTML, CSS, JavaScript, Bootstrap 5, Font Awesome, PrismJS, Marked.js
-- **Backend:** Node.js (Express), cors, fs for file operations
-- **Speech & Multimedia:** Web Speech API for speech synthesis and recognition
-- **Persistent Storage:** Local Storage and server-side JSON file storage (`userData.json`)
-- **Deployment Tools:** Ubuntu server, Node.js, npm, PM2 for daemonization, ufw firewall configurations
-
----
-
-## **Usage Workflow**
-
-- **Launching:**
- - User connects via the web interface hosted on the Node.js Express server.
- - Automatic unique ID generation and session initialization occur upon first load.
-
-- **Interacting:**
- - Engage via text or voice, manage sessions, personalize AI interactions, and explore dynamically generated imagery.
-
-- **Administration & Maintenance:**
- - Administer sessions, clear memory or chat history, configure UI preferences, monitor user statistics, and manage server through provided server scripts.
-
----
-
-## **Security & Privacy**
-
-- Persistent data is stored securely on local storage or server-side JSON files.
-- API endpoints (`/api/registerUser`, `/api/visitorCount`) include basic validation to ensure data integrity and minimize malicious usage.
-
----
-
-## **Extensibility & Future Considerations**
-
-- The modular architecture facilitates easy integration of additional AI models or APIs.
-- Potential expansions might include enhanced security measures, comprehensive backend database integration, more complex personalization features, or further multimedia interactions.
-
----
-
-This detailed breakdown encapsulates your application's extensive functionality, highlighting a robust and user-centric design that seamlessly integrates advanced AI interactions with user experience enhancements, comprehensive storage, personalization, multimedia features, and robust backend capabilities.
\ No newline at end of file
diff --git a/server/.env.example b/server/.env.example
new file mode 100644
index 0000000..0232b06
--- /dev/null
+++ b/server/.env.example
@@ -0,0 +1,19 @@
+# Copy this file to `.env` and fill in each value before starting the server.
+
+# Twilio credentials (from https://www.twilio.com/console)
+TWILIO_ACCOUNT_SID=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+TWILIO_AUTH_TOKEN=your_twilio_auth_token
+TWILIO_PHONE_NUMBER=+12345550000
+
+# Publicly accessible HTTPS URL that Twilio can reach.
+# Use a tunneling tool such as ngrok while developing locally.
+PUBLIC_SERVER_URL=https://your-public-tunnel.example.com
+
+# Optional: default Pollinations voice for generated speech (nova, alloy, fable, onyx, shimmer, echo)
+POLLINATIONS_VOICE=nova
+
+# Port for the local Express server
+PORT=4000
+
+# Origin allowed to make browser requests to the API (set to your GitHub Pages URL)
+ALLOWED_ORIGIN=https://your-github-pages-domain.example.com
diff --git a/twilio-voice-app/.gitignore b/server/.gitignore
similarity index 100%
rename from twilio-voice-app/.gitignore
rename to server/.gitignore
diff --git a/twilio-voice-app/README.md b/server/README.md
similarity index 87%
rename from twilio-voice-app/README.md
rename to server/README.md
index 7d9fe3a..4e366da 100644
--- a/twilio-voice-app/README.md
+++ b/server/README.md
@@ -8,7 +8,7 @@ A lightweight Node + Twilio companion service that lets Unity call a phone numbe
- 🧠 **Unity text brain** – Conversations use the same Pollinations text API powering Unity Chat.
- 🔊 **Voice playback** – Assistant replies are played with Pollinations TTS directly over the call.
- 🗣️ **Two-way dialog** – Twilio speech recognition captures the caller's reply and routes it back to the AI.
-- 🌐 **Self-hosted UI** – Includes a simple dashboard to start calls and watch status updates.
+- 🌐 **Browser integration** – Designed to be triggered from the Unity Chat frontend hosted on GitHub Pages or any static site.
## Prerequisites
@@ -20,7 +20,7 @@ A lightweight Node + Twilio companion service that lets Unity call a phone numbe
1. Install dependencies:
```bash
- cd twilio-voice-app
+ cd server
npm install
```
2. Copy the example environment file and fill in your details:
@@ -30,6 +30,7 @@ A lightweight Node + Twilio companion service that lets Unity call a phone numbe
Required variables:
- `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`, `TWILIO_PHONE_NUMBER`
- `PUBLIC_SERVER_URL` – The **public** HTTPS URL that Twilio will call back (e.g. your ngrok tunnel).
+ - `ALLOWED_ORIGIN` – The URL of the Unity Chat frontend that will call this API.
- Optional: `POLLINATIONS_VOICE` to choose a different Pollinations voice preset.
3. Start the server:
```bash
@@ -42,7 +43,7 @@ A lightweight Node + Twilio companion service that lets Unity call a phone numbe
```
5. Update `PUBLIC_SERVER_URL` in your `.env` with the HTTPS forwarding address printed by ngrok and restart the server if needed.
-Visit [http://localhost:4000](http://localhost:4000) to load the dashboard, enter a phone number, and press **Call My Phone**. Answer the incoming call from your Twilio number to begin the voice chat.
+Set `ALLOWED_ORIGIN` in your `.env` to the URL where the Unity chat frontend is hosted (for example your GitHub Pages domain). The server exposes a JSON API that the frontend uses; there is no bundled dashboard.
## Twilio configuration tips
@@ -67,7 +68,7 @@ Each assistant reply is constrained to a short length so the Pollinations TTS GE
- Sessions are stored in memory. Restarting the server will drop active conversations.
- If the Pollinations API or TTS call fails, the server gracefully ends the phone call to avoid trapping the caller.
-- The UI keeps an activity log and status banner so you can monitor attempts and errors from the browser.
+- When triggered from the Unity Chat frontend you will see status updates inside the Settings panel of the web app.
## Troubleshooting
diff --git a/twilio-voice-app/package-lock.json b/server/package-lock.json
similarity index 98%
rename from twilio-voice-app/package-lock.json
rename to server/package-lock.json
index 4d9c478..97ac76d 100644
--- a/twilio-voice-app/package-lock.json
+++ b/server/package-lock.json
@@ -8,6 +8,7 @@
"name": "twilio-voice-app",
"version": "1.0.0",
"dependencies": {
+ "cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"node-fetch": "^3.3.2",
@@ -295,6 +296,19 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"license": "MIT"
},
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
@@ -1180,6 +1194,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
diff --git a/twilio-voice-app/package.json b/server/package.json
similarity index 95%
rename from twilio-voice-app/package.json
rename to server/package.json
index fcf25c2..b49c5dc 100644
--- a/twilio-voice-app/package.json
+++ b/server/package.json
@@ -9,6 +9,7 @@
"dev": "nodemon server.js"
},
"dependencies": {
+ "cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"twilio": "^4.23.0",
diff --git a/twilio-voice-app/server.js b/server/server.js
similarity index 95%
rename from twilio-voice-app/server.js
rename to server/server.js
index fc42295..7daff90 100644
--- a/twilio-voice-app/server.js
+++ b/server/server.js
@@ -3,6 +3,7 @@ const twilio = require('twilio');
const { v4: uuidv4 } = require('uuid');
const path = require('path');
const dotenv = require('dotenv');
+const cors = require('cors');
dotenv.config({ path: path.resolve(__dirname, '.env') });
@@ -17,6 +18,7 @@ const TWILIO_ACCOUNT_SID = process.env.TWILIO_ACCOUNT_SID;
const TWILIO_AUTH_TOKEN = process.env.TWILIO_AUTH_TOKEN;
const TWILIO_PHONE_NUMBER = process.env.TWILIO_PHONE_NUMBER;
const DEFAULT_VOICE = process.env.POLLINATIONS_VOICE || 'nova';
+const ALLOWED_ORIGIN = process.env.ALLOWED_ORIGIN;
const hasTwilioCredentials =
Boolean(TWILIO_ACCOUNT_SID && TWILIO_AUTH_TOKEN && TWILIO_PHONE_NUMBER);
@@ -27,13 +29,15 @@ if (!hasTwilioCredentials) {
if (!PUBLIC_SERVER_URL) {
console.warn('[WARN] PUBLIC_SERVER_URL is not set. Twilio callbacks will fail without a public URL.');
}
+if (!ALLOWED_ORIGIN) {
+ console.warn('[WARN] ALLOWED_ORIGIN is not set. Defaulting to allow requests from any origin.');
+}
const app = express();
+app.use(cors({ origin: ALLOWED_ORIGIN || '*', methods: ['GET', 'POST', 'OPTIONS'] }));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
-app.use(express.static(path.join(__dirname, 'public')));
-
const sessions = new Map();
const SYSTEM_PROMPT =
@@ -231,6 +235,10 @@ async function handleVoiceResponse(req, res) {
app.post('/voice-response', handleVoiceResponse);
app.get('/voice-response', handleVoiceResponse);
+app.get('/health', (req, res) => {
+ res.json({ status: 'ok' });
+});
+
app.post('/gather', async (req, res) => {
const { session, errorTwiml } = getSession(req);
if (!session) {
diff --git a/styles.css b/styles.css
index e2fe680..becda0a 100644
--- a/styles.css
+++ b/styles.css
@@ -448,11 +448,74 @@ body {
font-size: 14px;
}
-.form-control:focus {
- outline: none;
- border-color: #707070;
- box-shadow: 0 0 0 2px rgba(112,112,112,0.2);
-}
+.form-control:focus {
+ outline: none;
+ border-color: #707070;
+ box-shadow: 0 0 0 2px rgba(112,112,112,0.2);
+}
+
+.twilio-call-card {
+ background: #1f1f1f;
+ border: 1px solid rgba(255,255,255,0.08);
+ border-radius: 12px;
+ padding: 16px;
+ margin-top: 20px;
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02);
+}
+
+.twilio-call-heading {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 1.1rem;
+ font-weight: 600;
+ margin-bottom: 8px;
+}
+
+.twilio-call-heading i {
+ color: #4caf50;
+}
+
+.twilio-call-description {
+ font-size: 0.95rem;
+ color: #cfcfcf;
+ margin-bottom: 16px;
+}
+
+.twilio-call-status {
+ border-radius: 10px;
+ border: 1px solid rgba(255,255,255,0.1);
+ padding: 10px 14px;
+ font-size: 0.95rem;
+ transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
+ min-height: 44px;
+ display: flex;
+ align-items: center;
+}
+
+.twilio-call-status[data-state="idle"] {
+ background: rgba(255,255,255,0.04);
+ color: #b0b0b0;
+ border-color: rgba(255,255,255,0.08);
+}
+
+.twilio-call-status[data-state="pending"] {
+ background: rgba(255, 193, 7, 0.12);
+ color: #ffca28;
+ border-color: rgba(255, 193, 7, 0.35);
+}
+
+.twilio-call-status[data-state="success"] {
+ background: rgba(76, 175, 80, 0.12);
+ color: #81c784;
+ border-color: rgba(76, 175, 80, 0.35);
+}
+
+.twilio-call-status[data-state="error"] {
+ background: rgba(244, 67, 54, 0.12);
+ color: #ef9a9a;
+ border-color: rgba(244, 67, 54, 0.35);
+}
.personalization-modal {
diff --git a/twilio-voice-app/.env b/twilio-voice-app/.env
deleted file mode 100644
index 92b22be..0000000
--- a/twilio-voice-app/.env
+++ /dev/null
@@ -1,14 +0,0 @@
-# Twilio credentials
-TWILIO_ACCOUNT_SID=ACbec90c44a86ba008a82c6c0cd32af9d9
-TWILIO_AUTH_TOKEN=85bc81f860f85b04655403ee3b5cc3dbn
-TWILIO_PHONE_NUMBER=+18668852338
-
-# Publicly accessible URL (https://...) that Twilio can reach.
-# When running locally use a tunneling tool such as ngrok and paste the HTTPS URL.
-PUBLIC_SERVER_URL=https://your-ngrok-id.ngrok-free.app
-
-# Optional: choose a Pollinations voice for TTS playback
-POLLINATIONS_VOICE=nova
-
-# Port for the local Express server
-PORT=4000
diff --git a/twilio-voice-app/public/client.js b/twilio-voice-app/public/client.js
deleted file mode 100644
index 56ea3cb..0000000
--- a/twilio-voice-app/public/client.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const form = document.getElementById('call-form');
-const statusEl = document.getElementById('status');
-const logEl = document.getElementById('log');
-const submitBtn = form.querySelector('button[type="submit"]');
-
-function timestamp() {
- return new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
-}
-
-function log(message, type = 'info') {
- const item = document.createElement('li');
- item.className = `log__item log__item--${type}`;
- item.innerHTML = `${timestamp()}${message}`;
- logEl.prepend(item);
-}
-
-function setStatus(message, variant = 'idle') {
- statusEl.textContent = message;
- statusEl.dataset.state = variant;
-}
-
-async function startCall(payload) {
- const response = await fetch('/api/start-call', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(payload)
- });
-
- if (!response.ok) {
- const errBody = await response.json().catch(() => ({}));
- const errorMessage = errBody.error || 'Failed to start call.';
- throw new Error(errorMessage);
- }
-
- return response.json();
-}
-
-form.addEventListener('submit', async (event) => {
- event.preventDefault();
- const formData = new FormData(form);
- const phoneNumber = formData.get('phoneNumber');
- const initialPrompt = formData.get('initialPrompt');
- const voice = formData.get('voice');
-
- submitBtn.disabled = true;
- setStatus('Creating session and contacting Twilio…', 'pending');
- log(`Attempting to call ${phoneNumber} using the ${voice} voice.`, 'info');
-
- try {
- const result = await startCall({ phoneNumber, initialPrompt, voice });
- setStatus(result.message || 'Call in progress. Answer your phone!', 'success');
- log('Call initiated successfully. Pick up to talk with Unity.', 'success');
- if (result.gatherPrompt) {
- log(`On the call, you will hear: “${result.gatherPrompt}”`, 'hint');
- }
- } catch (error) {
- console.error(error);
- setStatus(error.message, 'error');
- log(error.message, 'error');
- } finally {
- submitBtn.disabled = false;
- }
-});
-
-setStatus('Ready when you are.', 'idle');
-log('Configure your .env values, run the server, and Unity will call when you press the button.');
diff --git a/twilio-voice-app/public/index.html b/twilio-voice-app/public/index.html
deleted file mode 100644
index 84efc16..0000000
--- a/twilio-voice-app/public/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
- Unity Voice Call Assistant
-
-
-
-
-
-
Unity Voice Call Assistant
-
- Start a phone call where Unity chats with you using Pollinations text and Twilio voice.
-
-
-
-
-
Start a Voice Chat
-
-
-
-
-
-
-
How it works
-
-
Fill in your phone number and (optionally) a topic.
-
Answer the incoming call from your Twilio number.
-
Unity speaks using Pollinations text-to-speech and waits for your reply.
-
Your speech is transcribed, sent to the Unity text API, and the cycle repeats.
-
-
- Keep the call open and speak clearly. Each response is limited to a short, natural sentence so the Pollinations TTS link stays reliable.
-