PageSourceSearch

https://forever-safe-home.vercel.app/community.html

html forever-safe-home.vercel.app collected 2026-10-03 06:57:38 UTC 98,683 bytes, 1,657 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width,initial-scale=1.0">
6<title>Haven Ridge — The Safe Home Chronicles: Forever Home</title>
7<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700;800;900&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
8<style>
9*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
10:root{
11--black:#0a0a0a;--navy:#0d1b2a;--purple:#7b2d8b;--purple-light:#9b59b6;
12--orange:#c0542a;--orange-light:#e07b39;--gold:#c9a84c;
13--glass:rgba(13,27,42,0.6);--glass-border:rgba(123,45,139,0.3);
14--text:#e0e0e0;--text-dim:#888;--text-bright:#fff;
15}
16html{scroll-behavior:smooth}
17body{font-family:'Inter',sans-serif;background:var(--black);color:var(--text);line-height:1.6;overflow-x:hidden}
18h1,h2,h3,h4,h5{font-family:'Playfair Display',serif;color:var(--text-bright)}
19a{color:var(--purple-light);text-decoration:none;transition:color .3s}
20a:hover{color:var(--orange-light)}
21::selection{background:var(--purple);color:#fff}
22::-webkit-scrollbar{width:8px}
23::-webkit-scrollbar-track{background:var(--black)}
24::-webkit-scrollbar-thumb{background:var(--purple);border-radius:4px}
25
26/* TRIGGER WARNING GATE */
27.tw-gate{position:fixed;inset:0;z-index:10000;background:rgba(0,0,0,0.97);display:flex;align-items:center;justify-content:center;backdrop-filter:blur(20px)}
28.tw-gate.hidden{display:none}
29.tw-inner{max-width:620px;padding:40px;text-align:center}
30.tw-inner h1{font-size:2rem;margin-bottom:10px;color:#fff}
31.tw-inner .tw-subtitle{color:var(--orange-light);font-size:.95rem;text-transform:uppercase;letter-spacing:3px;margin-bottom:30px}
32.tw-themes{background:rgba(123,45,139,0.1);border:1px solid var(--glass-border);border-radius:12px;padding:20px;margin-bottom:25px;text-align:left}
33.tw-themes p{font-size:.85rem;color:var(--text-dim);line-height:1.8}
34.tw-themes strong{color:var(--orange-light)}
35.tw-quote{font-family:'Playfair Display',serif;font-style:italic;font-size:1.1rem;color:var(--gold);margin:25px 0;padding:15px 20px;border-left:3px solid var(--gold)}
36.tw-check{display:flex;align-items:flex-start;gap:10px;margin:25px 0;text-align:left;cursor:pointer}
37.tw-check input[type="checkbox"]{width:18px;height:18px;accent-color:var(--purple);margin-top:3px;flex-shrink:0}
38.tw-check label{font-size:.85rem;color:var(--text-dim);cursor:pointer}
39.tw-buttons{display:flex;gap:15px;justify-content:center;flex-wrap:wrap;margin-top:25px}
40.btn{padding:12px 28px;border:none;border-radius:8px;font-family:'Inter',sans-serif;font-weight:600;font-size:.9rem;cursor:pointer;transition:all .3s;text-transform:uppercase;letter-spacing:1px}
41.btn:disabled{opacity:0.3;cursor:not-allowed}
42.btn-primary{background:linear-gradient(135deg,var(--purple),var(--purple-light));color:#fff;box-shadow:0 4px 20px rgba(123,45,139,0.4)}
43.btn-primary:not(:disabled):hover{transform:translateY(-2px);box-shadow:0 6px 30px rgba(123,45,139,0.6)}
44.btn-secondary{background:transparent;border:1px solid var(--text-dim);color:var(--text-dim)}
45.btn-secondary:hover{border-color:var(--text);color:var(--text)}
46.btn-gold{background:linear-gradient(135deg,var(--gold),#d4a843);color:var(--black)}
47.btn-orange{background:linear-gradient(135deg,var(--orange),var(--orange-light));color:#fff}
48
49/* NAV */
50.nav{position:fixed;top:0;left:0;right:0;z-index:9000;background:rgba(10,10,10,0.9);backdrop-filter:blur(15px);border-bottom:1px solid var(--glass-border);padding:0 20px;transition:transform .3s}
51.nav-inner{max-width:1200px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;height:60px}
52.nav-logo{font-family:'Playfair Display',serif;font-size:1.2rem;color:var(--text-bright);font-weight:700}
53.nav-logo span{color:var(--purple-light)}
54.nav-links{display:flex;gap:5px;align-items:center}
55.nav-links a{padding:8px 14px;font-size:.8rem;color:var(--text-dim);border-radius:6px;transition:all .3s;white-space:nowrap}
56.nav-links a:hover,.nav-links a.active{color:var(--text-bright);background:rgba(123,45,139,0.2)}
57.nav-back{font-size:.8rem;color:var(--text-dim);margin-right:15px;border-right:1px solid rgba(255,255,255,0.1);padding-right:15px}
58.hamburger{display:none;flex-direction:column;gap:5px;cursor:pointer;padding:5px}
59.hamburger span{width:24px;height:2px;background:var(--text);transition:all .3s}
60.mobile-menu{display:none;position:fixed;top:60px;left:0;right:0;bottom:0;background:rgba(10,10,10,0.98);z-index:8999;flex-direction:column;padding:20px;gap:5px}
61.mobile-menu.open{display:flex}
62.mobile-menu a{padding:15px;font-size:1rem;color:var(--text-dim);border-bottom:1px solid rgba(255,255,255,0.05)}
63
64/* SECTIONS */
65section{padding:100px 20px;max-width:1200px;margin:0 auto}
66.section-label{text-transform:uppercase;letter-spacing:4px;font-size:.75rem;color:var(--purple-light);margin-bottom:10px}
67.section-title{font-size:2.2rem;margin-bottom:15px}
68.section-desc{color:var(--text-dim);max-width:600px;margin-bottom:40px;font-size:.95rem}
69
70/* HERO */
71.hero{min-height:70vh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;position:relative;padding-top:80px}
72.hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at center,rgba(123,45,139,0.15) 0%,transparent 70%);pointer-events:none}
73.hero h1{font-size:3.5rem;margin-bottom:15px;background:linear-gradient(135deg,#fff,var(--purple-light));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
74.hero .subtitle{color:var(--text-dim);font-size:1.1rem;margin-bottom:30px}
75.citizen-counter{display:flex;align-items:center;gap:10px;font-size:1rem;color:var(--gold)}
76.gate-dot{width:10px;height:10px;background:#00c853;border-radius:50%;animation:pulse 2s infinite}
77@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(0,200,83,0.4)}50%{box-shadow:0 0 0 10px rgba(0,200,83,0)}}
78.hero-quote{font-family:'Playfair Display',serif;font-style:italic;color:var(--text-dim);margin-top:30px;font-size:1rem;max-width:500px}
79
80/* CARDS */
81.card{background:var(--glass);border:1px solid var(--glass-border);border-radius:16px;padding:25px;transition:all .3s;position:relative;overflow:hidden}
82.card:hover{transform:translateY(-3px);border-color:var(--purple-light);box-shadow:0 10px 40px rgba(123,45,139,0.2)}
83.card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--purple),var(--orange));opacity:0;transition:opacity .3s}
84.card:hover::before{opacity:1}
85
86/* CHAPTER CARDS */
87.chapters-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:20px}
88.chapter-card{position:relative}
89.chapter-num{font-size:.75rem;color:var(--purple-light);text-transform:uppercase;letter-spacing:2px}
90.chapter-title{font-family:'Playfair Display',serif;font-size:1.3rem;margin:8px 0;color:#fff}
91.chapter-excerpt{font-size:.85rem;color:var(--text-dim);margin-bottom:15px}
92.badge{display:inline-block;padding:3px 10px;border-radius:20px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:1px}
93.badge-new{background:var(--orange);color:#fff;animation:glow-badge 2s infinite}
94@keyframes glow-badge{0%,100%{box-shadow:0 0 5px rgba(192,84,42,0.5)}50%{box-shadow:0 0 15px rgba(192,84,42,0.8)}}
95.badge-free{background:rgba(255,255,255,0.1);color:var(--text-dim)}
96.badge-dreamer{background:rgba(123,45,139,0.3);color:var(--purple-light)}
97.badge-storyteller{background:rgba(192,84,42,0.3);color:var(--orange-light)}
98.badge-architect{background:rgba(201,168,76,0.3);color:var(--gold)}
99.chapter-locked{position:absolute;inset:0;background:rgba(10,10,10,0.8);border-radius:16px;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:8px;backdrop-filter:blur(3px)}
100.chapter-locked span{font-size:1.5rem}
101.chapter-locked p{font-size:.8rem;color:var(--text-dim)}
102
103/* TIER BADGES */
104.tier-badge{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;border-radius:20px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:1px}
105.tier-free{background:rgba(255,255,255,0.08);color:var(--text-dim)}
106.tier-dreamer{background:rgba(123,45,139,0.2);color:var(--purple-light);border:1px solid rgba(123,45,139,0.3)}
107.tier-storyteller{background:rgba(192,84,42,0.2);color:var(--orange-light);border:1px solid rgba(192,84,42,0.3)}
108.tier-architect{background:rgba(201,168,76,0.2);color:var(--gold);border:1px solid rgba(201,168,76,0.3)}
109
110/* CHARACTER WIZARD */
111.wizard-container{background:var(--glass);border:1px solid var(--glass-border);border-radius:20px;padding:30px;max-width:800px;margin:0 auto}
112.wizard-progress{display:flex;justify-content:space-between;margin-bottom:40px;position:relative}
113.wizard-progress::before{content:'';position:absolute;top:18px;left:40px;right:40px;height:2px;background:rgba(255,255,255,0.1)}
114.wizard-progress-fill{position:absolute;top:18px;left:40px;height:2px;background:linear-gradient(90deg,var(--purple),var(--orange));transition:width .5s}
115.wizard-step-dot{width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,0.1);border:2px solid rgba(255,255,255,0.1);display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:600;color:var(--text-dim);position:relative;z-index:2;transition:all .3s}
116.wizard-step-dot.active{background:var(--purple);border-color:var(--purple);color:#fff;box-shadow:0 0 20px rgba(123,45,139,0.5)}
117.wizard-step-dot.done{background:var(--orange);border-color:var(--orange);color:#fff}
118.wizard-step-label{position:absolute;top:42px;font-size:.65rem;color:var(--text-dim);white-space:nowrap}
119.wizard-panel{display:none}
120.wizard-panel.active{display:block;animation:fadeIn .4s}
121@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
122.wizard-nav{display:flex;justify-content:space-between;margin-top:30px;padding-top:20px;border-top:1px solid rgba(255,255,255,0.05)}
123
124/* FORM ELEMENTS */
125.form-group{margin-bottom:20px}
126.form-group label{display:block;font-size:.85rem;color:var(--text);margin-bottom:8px;font-weight:500}
127.form-group label .required{color:var(--orange)}
128.form-input{width:100%;padding:12px 16px;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);border-radius:10px;color:#fff;font-family:'Inter',sans-serif;font-size:.9rem;transition:all .3s;outline:none}
129.form-input:focus{border-color:var(--purple);box-shadow:0 0 0 3px rgba(123,45,139,0.2)}
130.form-input::placeholder{color:var(--text-dim)}
131select.form-input{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23888' fill='none' stroke-width='1.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 16px center;cursor:pointer}
132select.form-input option{background:var(--navy);color:#fff}
133textarea.form-input{resize:vertical;min-height:100px}
134
135/* SELECTION GRIDS */
136.select-grid{display:flex;flex-wrap:wrap;gap:8px}
137.select-option{padding:8px 16px;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);border-radius:8px;cursor:pointer;font-size:.8rem;color:var(--text-dim);transition:all .3s;user-select:none}
138.select-option:hover{border-color:var(--purple-light);color:var(--text)}
139.select-option.selected{background:rgba(123,45,139,0.3);border-color:var(--purple);color:#fff}
140.select-option.selected-orange{background:rgba(192,84,42,0.3);border-color:var(--orange);color:#fff}
141
142/* SKIN TONE PICKER */
143.skin-tones{display:flex;gap:10px;flex-wrap:wrap}
144.skin-tone{width:40px;height:40px;border-radius:50%;cursor:pointer;border:3px solid transparent;transition:all .3s;box-shadow:0 2px 8px rgba(0,0,0,0.3)}
145.skin-tone:hover{transform:scale(1.1)}
146.skin-tone.selected{border-color:var(--purple-light);transform:scale(1.15);box-shadow:0 0 15px rgba(123,45,139,0.5)}
147
148/* AVATAR PREVIEW */
149.avatar-preview-container{display:flex;justify-content:center;margin:20px 0}
150.avatar-builder{width:180px;height:180px;border-radius:50%;position:relative;overflow:hidden;border:3px solid var(--glass-border);box-shadow:0 0 30px rgba(123,45,139,0.3);background:#222}
151.avatar-skin{position:absolute;inset:0;border-radius:50%;transition:background .3s}
152.avatar-hair{position:absolute;top:0;left:0;right:0;height:50%;z-index:3;transition:all .3s;pointer-events:none}
153.avatar-face{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:4;font-size:.9rem;text-align:center;color:rgba(0,0,0,0.6);font-weight:700}
154.avatar-clothing{position:absolute;bottom:0;left:0;right:0;height:30%;z-index:2;transition:background .3s}
155.avatar-eyes{position:absolute;top:40%;left:50%;transform:translateX(-50%);z-index:5;display:flex;gap:16px}
156.avatar-eye{width:8px;height:8px;background:rgba(0,0,0,0.7);border-radius:50%}
157.avatar-mouth{position:absolute;top:58%;left:50%;transform:translateX(-50%);z-index:5;width:14px;height:7px;border-bottom:2px solid rgba(0,0,0,0.5);border-radius:0 0 10px 10px}
158
159/* Hair Styles */
160.hair-fade{background:currentColor;height:25%;border-radius:50% 50% 0 0;top:5%}
161.hair-locs{height:65%;top:0;display:flex;flex-wrap:wrap;justify-content:center;gap:2px;padding:5px 20px}
162.hair-locs::before{content:'';position:absolute;top:0;left:15%;right:15%;height:20%;background:currentColor;border-radius:50% 50% 0 0}
163.hair-locs::after{content:'';position:absolute;top:15%;left:10%;right:10%;bottom:10%;background:repeating-linear-gradient(90deg,currentColor 0px,currentColor 4px,transparent 4px,transparent 8px);opacity:0.8}
164.hair-braids{height:55%;top:0}
165.hair-braids::before{content:'';position:absolute;top:0;left:15%;right:15%;height:30%;background:currentColor;border-radius:50% 50% 0 0}
166.hair-braids::after{content:'';position:absolute;top:20%;left:10%;right:10%;bottom:0;background:repeating-linear-gradient(180deg,currentColor 0px,currentColor 3px,transparent 3px,transparent 6px);opacity:0.7}
167.hair-afro{height:70%;width:120%;left:-10%;top:-10%;border-radius:50%;background:currentColor;box-shadow:0 0 15px rgba(0,0,0,0.3)}
168.hair-buzz{background:currentColor;height:18%;border-radius:50% 50% 0 0;top:5%;opacity:0.7}
169.hair-curly{height:55%;top:0;border-radius:50% 50% 30% 30%;background:currentColor}
170.hair-curly::after{content:'';position:absolute;top:30%;left:5%;right:5%;bottom:10%;background:radial-gradient(circle at 20% 40%,transparent 8px,currentColor 8px,currentColor 10px,transparent 10px),radial-gradient(circle at 50% 30%,transparent 8px,currentColor 8px,currentColor 10px,transparent 10px),radial-gradient(circle at 80% 45%,transparent 8px,currentColor 8px,currentColor 10px,transparent 10px);opacity:0.4}
171.hair-straight{height:65%;top:0;background:linear-gradient(180deg,currentColor 0%,currentColor 60%,transparent 100%);border-radius:10% 10% 40% 40%}
172.hair-mohawk::before{content:'';position:absolute;top:-5%;left:35%;right:35%;height:45%;background:currentColor;border-radius:30% 30% 0 0}
173.hair-mohawk::after{content:'';position:absolute;top:0;left:30%;right:30%;height:15%;background:currentColor;border-radius:50%}
174.hair-twists{height:55%;top:0}
175.hair-twists::before{content:'';position:absolute;top:0;left:15%;right:15%;height:35%;background:currentColor;border-radius:50% 50% 0 0}
176.hair-twists::after{content:'';position:absolute;top:25%;left:8%;right:8%;bottom:0;background:repeating-linear-gradient(160deg,currentColor 0px,currentColor 3px,transparent 3px,transparent 7px);opacity:0.6}
177.hair-bangs{height:40%;top:0;background:currentColor;border-radius:5% 50% 20% 40%;clip-path:polygon(10% 0,90% 0,100% 60%,85% 80%,60% 45%,0% 70%)}
178.hair-shaved-sides::before{content:'';position:absolute;top:0;left:25%;right:25%;height:35%;background:currentColor;border-radius:30% 30% 0 0}
179.hair-shaved-sides::after{content:'';position:absolute;top:20%;left:15%;right:15%;height:10%;background:currentColor;opacity:0.3;border-radius:0 0 50% 50%}
180.hair-bald{display:none}
181
182/* Clothing styles */
183.clothing-streetwear{background:linear-gradient(135deg,#333,#555);border-top:2px solid var(--orange)}
184.clothing-preppy{background:linear-gradient(135deg,#1a3a5c,#2a5a8c);border-top:2px solid #4a90d9}
185.clothing-goth{background:linear-gradient(135deg,#1a0a1a,#2d1033);border-top:2px solid #8b00ff}
186.clothing-artistic{background:linear-gradient(135deg,#4a2040,#2a4060);border-top:2px solid var(--gold)}
187.clothing-athletic{background:linear-gradient(135deg,#1a2a1a,#2a4a2a);border-top:2px solid #00c853}
188.clothing-minimalist{background:linear-gradient(135deg,#222,#333);border-top:2px solid #888}
189
190/* PROFILE */
191.profile-card{background:var(--glass);border:1px solid var(--glass-border);border-radius:20px;padding:30px;max-width:500px;margin:0 auto}
192.profile-id{font-family:'Courier New',monospace;font-size:.75rem;color:var(--text-dim);letter-spacing:2px;text-align:center;margin-bottom:15px}
193.profile-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:15px;margin-top:20px}
194.profile-stat{text-align:center;padding:10px;background:rgba(255,255,255,0.03);border-radius:10px}
195.profile-stat-num{font-size:1.5rem;font-weight:700;color:var(--gold)}
196.profile-stat-label{font-size:.7rem;color:var(--text-dim);text-transform:uppercase;letter-spacing:1px}
197
198/* WORLD MAP */
199.map-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:20px}
200.map-card{cursor:default}
201.map-card .map-icon{font-size:2rem;margin-bottom:10px}
202.map-card h3{font-size:1.1rem;margin-bottom:8px;color:var(--gold)}
203.map-card p{font-size:.85rem;color:var(--text-dim)}
204.map-card .map-activity{font-size:.75rem;color:var(--purple-light);margin-top:8px;font-style:italic}
205
206/* SUBMISSIONS */
207.submission-form{max-width:700px;margin:0 auto}
208.word-count{font-size:.75rem;color:var(--text-dim);text-align:right;margin-top:5px}
209
210/* FORUM */
211.forum-categories{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:20px}
212.forum-cat{padding:6px 14px;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);border-radius:20px;font-size:.8rem;color:var(--text-dim);cursor:pointer;transition:all .3s}
213.forum-cat:hover,.forum-cat.active{background:rgba(123,45,139,0.2);border-color:var(--purple);color:var(--purple-light)}
214.forum-threads{display:flex;flex-direction:column;gap:10px}
215.forum-thread{display:flex;justify-content:space-between;align-items:center;padding:18px 20px;background:var(--glass);border:1px solid rgba(255,255,255,0.05);border-radius:12px;transition:all .3s;cursor:pointer}
216.forum-thread:hover{border-color:var(--glass-border);transform:translateX(3px)}
217.forum-thread-info h4{font-size:.95rem;color:var(--text);margin-bottom:4px;font-family:'Inter',sans-serif;font-weight:500}
218.forum-thread-info p{font-size:.75rem;color:var(--text-dim)}
219.forum-thread-meta{text-align:right;flex-shrink:0}
220.forum-thread-meta .replies{font-size:.85rem;color:var(--purple-light);font-weight:600}
221.forum-thread-meta .time{font-size:.7rem;color:var(--text-dim)}
222
223/* FOOTER */
224.footer{padding:60px 20px;text-align:center;border-top:1px solid rgba(255,255,255,0.05);margin-top:40px}
225.footer p{font-size:.8rem;color:var(--text-dim);margin-bottom:8px}
226
227/* ANIMATIONS */
228.fade-in{opacity:0;transform:translateY(20px);transition:all .6s ease}
229.fade-in.visible{opacity:1;transform:translateY(0)}
230
231/* CHARACTER SHOWCASE */
232.showcase-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:20px;margin-top:30px}
233.showcase-card{background:var(--glass);border:1px solid var(--glass-border);border-radius:16px;padding:20px;text-align:center;transition:all .3s}
234.showcase-card:hover{transform:translateY(-3px);box-shadow:0 10px 30px rgba(123,45,139,0.2)}
235.mini-avatar{width:80px;height:80px;border-radius:50%;margin:0 auto 12px;position:relative;overflow:hidden;border:2px solid var(--glass-border)}
236.mini-avatar .avatar-skin{position:absolute;inset:0}
237.mini-avatar .avatar-hair{position:absolute;top:0;left:0;right:0;height:50%}
238.mini-avatar .avatar-clothing{position:absolute;bottom:0;left:0;right:0;height:30%}
239.mini-avatar .avatar-eyes{position:absolute;top:40%;left:50%;transform:translateX(-50%);display:flex;gap:10px}
240.mini-avatar .avatar-eye{width:5px;height:5px;background:rgba(0,0,0,0.7);border-radius:50%}
241
242/* RESPONSIVE */
243@media(max-width:768px){
244.nav-links{display:none}
245.hamburger{display:flex}
246.hero h1{font-size:2.2rem}
247.section-title{font-size:1.8rem}
248.wizard-progress{overflow-x:auto;padding-bottom:30px}
249.wizard-step-label{font-size:.55rem}
250.map-grid{grid-template-columns:1fr}
251.chapters-grid{grid-template-columns:1fr}
252.profile-stats{grid-template-columns:1fr}
253.tw-inner{padding:20px}
254.tw-inner h1{font-size:1.5rem}
255}
256</style>
257</head>
258<body>
259
260<!-- TRIGGER WARNING GATE -->
261<div class="tw-gate" id="twGate">
262<div class="tw-inner">
263<h1>⚠️ Content Warning</h1>
264<div class="tw-subtitle">
264Haven Ridge — The Safe Home Chronicles</div>
265<div class="tw-themes">
266<p>This experience explores <strong>heavy and potentially triggering themes</strong> including but not limited to:</p>
267<p style="margin-top:10px"><strong>Foster care, abuse, abandonment, trafficking, addiction, trauma, violence, self-harm, mental health crises, neglect, homelessness, sexual assault, and systemic failure.</strong></p>
268</div>
269<div class="tw-quote">"This isn't a safe space. This is a real space. The stories here reflect what thousands of kids actually live through."</div>
270<div class="tw-check">
271<input type="checkbox" id="twCheck">
272<label for="twCheck">I acknowledge this content contains mature themes including abuse, trauma, and violence. I am choosing to enter this space willingly.</label>
273</div>
274<div class="tw-buttons">
275<button class="btn btn-secondary" onclick="window.location.href='index.html'">Take Me Back</button>
276<button class="btn btn-primary" id="twEnter" disabled onclick="enterHavenRidge()">I Understand — Let Me In</button>
277</div>
278</div>
279</div>
280
281<!-- NAVIGATION -->
282<nav class="nav" id="mainNav">
283<div class="nav-inner">
284<a href="#hero" class="nav-logo">Haven <span>Ridge</span></a>
285<div class="nav-links" id="navLinks">
286<a href="index.html" class="nav-back">← Back to Main</a>
287<a href="#stories" class="nav-link">Story Updates</a>
288<a href="#tiers" class="nav-link">Membership</a>
289<a href="#creator" class="nav-link">Create Character</a>
290<a href="#profile" class="nav-link">Your Profile</a>
291<a href="#worldmap" class="nav-link">World Map</a>
292<a href="#submissions" class="nav-link">Submissions</a>
293<a href="#forum" class="nav-link">Forum</a>
294</div>
295<div class="hamburger" id="hamburger" onclick="toggleMobile()">
296<span></span><span></span><span></span>
297</div>
298</div>
299</nav>
300<div class="mobile-menu" id="mobileMenu">
301<a href="index.html" onclick="closeMobile()">← Back to Main Site</a>
302<a href="#stories" onclick="closeMobile()">Story Updates</a>
303<a href="#creator" onclick="closeMobile()">Create Character</a>
304<a href="#profile" onclick="closeMobile()">Your Profile</a>
305<a href="#worldmap" onclick="closeMobile()">World Map</a>
306<a href="#submissions" onclick="closeMobile()">Submissions</a>
307<a href="#forum" onclick="closeMobile()">Forum</a>
308</div>
309
310<!-- HERO -->
311<section class="hero" id="hero">
312<div class="section-label">You've crossed the gate</div>
313<h1>Welcome to Haven Ridge</h1>
314<p class="subtitle">A city built by the forgotten. A home for those who never had one.</p>
315<div class="citizen-counter">
316<span class="gate-dot"></span>
317Gate Status: OPEN — <strong id="citizenCount">0</strong>&nbsp;Citizens Registered
318</div>
319<p class="hero-quote">"Everyone who walks through The Gate has a story. Some are whispered. Some are screamed. All of them matter."</p>
320</section>
321
322<!-- WEEKLY STORY UPDATES -->
323<section id="stories" class="fade-in">
324<div class="section-label">Weekly Drops</div>
325<h2 class="section-title">Story Updates</h2>
326<p class="section-desc">New episodes drop every two weeks. Episode 1 is free for everyone. Subscribe to unlock the full Haven Ridge story.</p>
327<div class="chapters-grid">
328<div class="card chapter-card" style="cursor:pointer" onclick="openEpisode1()">
329<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
330<span class="chapter-num">Episode 01</span>
331<span class="badge badge-free">Free</span>
332</div>
333<h3 class="chapter-title">The Arrival</h3>
334<p class="chapter-excerpt">The bus rolls in slow. No music. No talking. Just the sound of tires dragging across pavement. Jordyn sits by the window. Arms crossed. Jaw tight. Watching everything...</p>
335<div style="margin-top:12px;display:flex;align-items:center;gap:10px"><span class="tier-badge tier-free">🔓 All Access</span><span style="font-size:.75rem;color:var(--orange-light)">▶ Read Episode →</span></div>
336</div>
337<div class="card chapter-card">
338<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
339<span class="chapter-num">Chapter 02</span>
340<span class="badge badge-new">NEW</span>
341</div>
342<h3 class="chapter-title">Building A — The Foundation</h3>
343<p class="chapter-excerpt">The walls here have heard more confessions than any church. Your room is small. Your roommate is quiet. The silence is deafening...</p>
344<div style="margin-top:12px"><span class="tier-badge tier-dreamer">🟣 Dreamer+</span></div>
345<div class="chapter-locked" id="ch2Lock"><span>🔒</span>
345<p>Dreamer tier required</p></div>
346</div>
347<div class="card chapter-card">
348<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
349<span class="chapter-num">Chapter 03</span>
350<span class="badge badge-dreamer" style="background:rgba(123,45,139,0.3);color:var(--purple-light)">Coming Soon</span>
351</div>
352<h3 class="chapter-title">First Day at Haven Ridge High</h3>
353<p class="chapter-excerpt">Every hallway has its hierarchy. Every classroom has its ghosts. You're the new kid — again...</p>
354<div style="margin-top:12px"><span class="tier-badge tier-dreamer">🟣 Dreamer+</span></div>
355<div class="chapter-locked"><span>🔒</span><p>Releases next week</p></div>
356</div>
357<div class="card chapter-card">
358<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
359<span class="chapter-num">Chapter 04</span>
360<span class="badge" style="background:rgba(201,168,76,0.3);color:var(--gold)">Upcoming</span>
361</div>
362<h3 class="chapter-title">The Wall Speaks</h3>
363<p class="chapter-excerpt">They say if you write your truth on The Wall, Haven Ridge listens. But some truths are better left unwritten...</p>
364<div style="margin-top:12px"><span class="tier-badge tier-storyteller">🟠 Storyteller+</span></div>
365<div class="chapter-locked"><span>🔒</span><p>Storyteller tier required</p></div>
366</div>
367</div>
368</section>
369
370<!-- EPISODE 1 MODAL -->
371<div id="ep1Modal" style="display:none;position:fixed;inset:0;z-index:9500;background:rgba(0,0,0,0.95);overflow-y:auto;backdrop-filter:blur(10px)">
372<div style="max-width:720px;margin:0 auto;padding:60px 30px 80px">
373<button onclick="closeEpisode1()" style="background:transparent;border:1px solid rgba(255,255,255,0.2);color:var(--text-dim);padding:8px 16px;border-radius:6px;cursor:pointer;font-size:.8rem;margin-bottom:40px">← Close</button>
374<div style="text-align:center;margin-bottom:40px">
375<div style="font-size:.7rem;text-transform:uppercase;letter-spacing:4px;color:var(--orange-light);margin-bottom:10px">Haven Ridge — Episode 01</div>
376<h1 style="font-family:'Playfair Display',serif;font-size:2.5rem;color:#fff;margin-bottom:10px">"The Arrival"</h1>
377<div style="width:60px;height:2px;background:linear-gradient(90deg,var(--purple),var(--orange));margin:0 auto"></div>
378</div>
379<div style="font-family:'Playfair Display',serif;font-style:italic;color:var(--text-dim);text-align:center;padding:20px 0 30px;font-size:1rem;border-bottom:1px solid rgba(255,255,255,0.05);margin-bottom:40px">The gates don't look like what you expect.<br>They're not locked.<br>They're open.</div>
380<div class="ep1-text" style="line-height:2;color:var(--text);font-size:.95rem">
381<div style="color:var(--gold);font-size:.7rem;text-transform:uppercase;letter-spacing:3px;margin-bottom:20px">Scene 1 — The Arrival</div>
382<p>The bus rolls in slow.</p><br>
383<p>No music.</p><br><p>No talking.</p><br><p>Just the sound of tires dragging across pavement.</p><br><br>
384<p>Jordyn sits by the window.</p><br><p>Arms crossed.</p><br><p>Jaw tight.</p><br><p>Watching everything.</p><br><br>
385<p>He doesn't trust places like this.</p><br><p>Not places that look clean.</p><br><p>Not places that say they're here to help.</p><br><br>
386<p style="font-family:'Playfair Display',serif;font-size:1.3rem;color:#fff;text-align:center;padding:20px 0">"Haven Ridge"</p><br>
387<p>The name sits on the gate in bold letters.</p><br><p>Too clean.</p><br><p>Too perfect.</p><br><br>
388<p>Jordyn exhales through his nose.</p><br><p>Low.</p><br><p>Controlled.</p><br><p>He's already irritated.</p><br><br>
389<div style="padding:20px;background:rgba(123,45,139,0.1);border-left:3px solid var(--purple);border-radius:0 8px 8px 0;margin:20px 0;font-style:italic">
390<p style="color:var(--purple-light)">"This ain't real."</p><br><p style="color:var(--purple-light)">"Nothing like this is real."</p>
391</div><br>
392<p>But the bus keeps moving.</p><br><br>
393<p>And for the first time…</p><br><p>Nobody's yelling.</p><br><p>Nobody's fighting.</p><br><p>Nobody's telling him to move.</p><br><br>
394<p style="color:var(--orange-light)">That alone feels wrong.</p><br><br>
395<div style="color:var(--gold);font-size:.7rem;text-transform:uppercase;letter-spacing:3px;margin:30px 0 20px">Scene 2 — Intake</div>
396<p>The building is quiet.</p><br><p>Too quiet.</p><br><br>
397<p>A woman sits across from him.</p><br><p>Tablet in hand.</p><br><p>Calm.</p><br><p>Too calm.</p><br><br>
398<p>"Jordyn."</p><br><p>She doesn't ask.</p><br><p>She already knows.</p><br><br>
399<p>He leans back in the chair.</p><br><p>Tilts his head.</p><br><p>Looks her dead in the eyes.</p><br><br>
400<p style="font-family:'Playfair Display',serif;font-style:italic;color:#fff;font-size:1.1rem">"Depends who's asking."</p><br><br>
401<p>She doesn't react.</p><br><p>Just writes something down.</p><br><br>
402<p style="color:var(--orange-light)">That pisses him off more than anything.</p><br><br>
403<p>"Anger response," she says quietly.</p><br><p>"Deflection. Guarded."</p><br><br>
404<p>Jordyn leans forward now.</p><br><p>Voice sharper.</p><br><br>
405<p style="font-family:'Playfair Display',serif;font-style:italic;color:#fff;font-size:1.1rem">"You writing a book or something?"</p><br><br>
406<p>Still no reaction.</p><br><br>
407<p>"Just trying to understand you."</p><br><br>
408<p>That word hits wrong.</p><br><p style="font-style:italic;color:var(--purple-light)">Understand.</p><br><br>
409<p style="font-family:'Playfair Display',serif;font-style:italic;color:#fff;font-size:1.1rem">"You don't."</p><br><br>
410<p>Silence.</p><br><br>
411<p>Then she finally looks up.</p><br><p>Really looks at him.</p><br><br>
412<p>"Maybe not yet."</p><br><br>
413<p>Pause.</p><br><br>
414<p style="color:var(--gold);font-style:italic">"…but you're here now."</p><br><br>
415<p>That line sits in the room longer than it should.</p><br><br>
416<div style="color:var(--gold);font-size:.7rem;text-transform:uppercase;letter-spacing:3px;margin:30px 0 20px">Scene 3 — The Room</div>
417<p>Door unlocks.</p><br><p>Soft click.</p><br><br>
418<p>Jordyn steps inside.</p><br><p>Stops.</p><br><br>
419<p>The place is… finished.</p><br><br>
420<p>Bed.</p><br><p>Desk.</p><br><p>Closet.</p><br><p>Couch.</p><br><p>No stains.</p><br><p>No broken pieces.</p><br><p>No smell.</p><br><br>
421<p style="color:var(--orange-light)">That's what throws him off the most.</p><br><br>
422<p>He walks in slow.</p><br><p>Touches the table.</p><br><p style="font-style:italic;color:var(--text-dim)">Like it might disappear.</p><br><br>
423<p>Then—</p><br><br>
424<p>He drops his bag.</p><br><p>Hard.</p><br><p>Sits on the edge of the bed.</p><br><p>Hands on his face.</p><br><br>
425<p>Not crying.</p><br><p>Not soft.</p><br><p>Just… processing.</p><br><br>
426<div style="color:var(--gold);font-size:.7rem;text-transform:uppercase;letter-spacing:3px;margin:30px 0 20px">Scene 4 — Outside</div>
427<p>Later.</p><br><br>
428<p>He steps outside.</p><br><p>Sun hitting different out here.</p><br><br>
429<p>Kids walking around.</p><br><p>Talking.</p><br><p>Laughing.</p><br><p style="font-style:italic;color:var(--text-dim)">Like they belong.</p><br><br>
430<p>A football field in the distance.</p><br><p>Lights.</p><br><p>Goalposts.</p><br><br>
431<p>His eyes lock in.</p><br><br>
432<p style="font-family:'Playfair Display',serif;font-style:italic;color:var(--gold);font-size:1.2rem">"I can work with that."</p><br><br>
433<div style="color:var(--gold);font-size:.7rem;text-transform:uppercase;letter-spacing:3px;margin:30px 0 20px">Final Scene — The Hook</div>
434<p>A voice behind him:</p><br><br>
435<p>"New?"</p><br><br>
436<p>Jordyn doesn't turn around right away.</p><br><br>
437<p>"Yeah."</p><br><br>
438<p>"Good luck."</p><br><br>
439<p style="font-style:italic;color:var(--text-dim)">That tone? Not friendly. Not threatening. Just real.</p><br><br>
440<p>Jordyn turns now.</p><br><p>Eyes sharp.</p><br><br>
441<p style="font-family:'Playfair Display',serif;font-style:italic;color:#fff;font-size:1.3rem">"I don't need luck."</p><br><br>
442<p>Pause.</p><br><br>
443<p style="font-family:'Playfair Display',serif;font-style:italic;color:var(--gold);font-size:1.3rem">"…I need a reason."</p>
444</div>
445<div style="margin-top:60px;padding:30px;background:rgba(123,45,139,0.1);border:1px solid rgba(123,45,139,0.3);border-radius:16px;text-align:center">
446<p style="color:var(--gold);font-size:1.1rem;font-family:'Playfair Display',serif;margin-bottom:10px">You just arrived at Haven Ridge.</p>
447<p style="color:var(--text-dim);font-size:.9rem;margin-bottom:25px">Who do you see yourself as in this story? Drop your character below 👇 Episode 2 drops in 2 weeks.</p>
448<button onclick="closeEpisode1();document.getElementById('creator').scrollIntoView({behavior:'smooth'})" class="btn btn-primary" style="font-size:1rem;padding:15px 30px">Create My Character →</button>
449</div>
450</div>
451</div>
452
453<!-- SUBSCRIPTION TIERS -->
454<section id="tiers" class="fade-in">
455<div class="section-label">Choose Your Role</div>
456<h2 class="section-title">Haven Ridge Membership</h2>
457<p class="section-desc">Everyone creates a character. Your tier determines how deep your story goes.</p>
458<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:20px;max-width:900px;margin:0 auto">
459<div class="card" style="text-align:center;padding:30px">
460<div style="font-size:1.5rem;margin-bottom:10px">🌙</div>
461<div class="tier-badge tier-dreamer" style="margin-bottom:15px">Dreamer</div>
462<div style="font-size:2rem;font-weight:700;color:#fff;margin-bottom:5px">$2.99<span style="font-size:.9rem;color:var(--text-dim)">/mo</span></div>
463<ul style="text-align:left;font-size:.85rem;color:var(--text-dim);list-style:none;margin:20px 0;line-height:2">
464<li>✅ Create your Haven Ridge character</li>
465<li>✅ Access to Episodes 1-3</li>
466<li>✅ Character appears in community feed</li>
467<li>
467✅ Background presence in episodes</li>
468<li>✅ Forum access</li>
469</ul>
470<a href="https://buy.stripe.com/00wcN43DHao77su1Osbsc03" target="_blank" class="btn btn-primary" style="width:100%;text-align:center;display:block">Join as Dreamer</a>
471</div>
472<div class="card" style="text-align:center;padding:30px;border-color:var(--orange-light);box-shadow:0 0 30px rgba(192,84,42,0.2)">
473<div style="font-size:1.5rem;margin-bottom:10px">🔥</div>
474<div class="tier-badge tier-storyteller" style="margin-bottom:10px">Storyteller</div>
475<div style="font-size:.7rem;color:var(--orange-light);text-transform:uppercase;letter-spacing:2px;margin-bottom:10px">Most Popular</div>
476<div style="font-size:2rem;font-weight:700;color:#fff;margin-bottom:5px">$5.99<span style="font-size:.9rem;color:var(--text-dim)">/mo</span></div>
477<ul style="text-align:left;font-size:.85rem;color:var(--text-dim);list-style:none;margin:20px 0;line-height:2">
478<li>✅ Everything in Dreamer</li>
479<li>✅ Submit scenes for official episodes</li>
480<li>✅ Character gets speaking lines</li>
481<li>✅ Interact with Jordyn's storyline</li>
482<li>✅ Access all episodes</li>
483<li>✅ Episode credits</li>
484</ul>
485<a href="https://buy.stripe.com/4gM9AS5LPao7eUWgJmbsc04" target="_blank" class="btn btn-orange" style="width:100%;text-align:center;display:block">Join as Storyteller</a>
486</div>
487<div class="card" style="text-align:center;padding:30px;border-color:var(--gold);box-shadow:0 0 30px rgba(201,168,76,0.2)">
488<div style="font-size:1.5rem;margin-bottom:10px">🏛️</div>
489<div class="tier-badge tier-architect" style="margin-bottom:15px">Architect</div>
490<div style="font-size:2rem;font-weight:700;color:#fff;margin-bottom:5px">$7.99<span style="font-size:.9rem;color:var(--text-dim)">/mo</span></div>
491<ul style="text-align:left;font-size:.85rem;color:var(--text-dim);list-style:none;margin:20px 0;line-height:2">
492<li>✅ Everything in Storyteller</li>
493<li>✅ Recurring character in main arc</li>
494<li>✅ Help shape Haven Ridge's future</li>
495<li>✅ Named co-author credits</li>
496<li>✅ Early episode access</li>
497<li>✅ Direct input on story direction</li>
498</ul>
499<a href="https://buy.stripe.com/aFa5kC2zD2VFfZ0fFibsc05" target="_blank" class="btn btn-gold" style="width:100%;text-align:center;display:block">Become an Architect</a>
500</div>
501</div>
502</section>
503
504<!-- CHARACTER CREATOR -->
505<section id="creator" class="fade-in">
506<div class="section-label">Build Your Resident</div>
507<h2 class="section-title">Character Creator</h2>
508<p class="section-desc">Every citizen of Haven Ridge has a story. Create yours. Be honest — there's no judgment behind The Gate.</p>
509
510<div class="wizard-container">
511<!-- Progress Bar -->
512<div class="wizard-progress">
513<div class="wizard-progress-fill" id="progressFill" style="width:0%"></div>
514<div class="wizard-step-dot active" data-step="0" id="dot0">1<span class="wizard-step-label">Identity</span></div>
515<div class="wizard-step-dot" data-step="1" id="dot1">2<span class="wizard-step-label">Appearance</span></div>
516<div class="wizard-step-dot" data-step="2" id="dot2">3<span class="wizard-step-label">Psyche</span></div>
517<div class="wizard-step-dot" data-step="3" id="dot3">4<span class="wizard-step-label">Life</span></div>
518<div class="wizard-step-dot" data-step="4" id="dot4">5<span class="wizard-step-label">Review</span></div>
519</div>
520
521<!-- STEP 1: IDENTITY -->
522<div class="wizard-panel active" id="panel0">
523<h3 style="margin-bottom:20px;color:var(--purple-light)">Step 1: Identity</h3>
524<div class="form-group">
525<label>Your Email <span class="required">*</span> <span style="font-size:.7rem;color:var(--text-dim);font-weight:400">(to link your character to your subscription)</span></label>
526<input type="email" class="form-input" id="charEmail" placeholder="[email protected]">
527</div>
528<div class="form-group">
529<label>Character Name <span class="required">*</span></label>
530<input type="text" class="form-input" id="charName" maxlength="30" placeholder="What do they call you?">
531<div style="font-size:.7rem;color:var(--text-dim);margin-top:4px"><span id="nameCount">0</span>/30</div>
532</div>
533<div class="form-group">
534<label>Age Range <span class="required">*</span></label>
535<div class="select-grid" id="ageGrid">
536<div class="select-option" data-value="13-15" data-group="age">13-15 <span style="font-size:.7rem;opacity:.6">Just arrived</span></div>
537<div class="select-option" data-value="16-17" data-group="age">16-17 <span style="font-size:.7rem;opacity:.6">Finding your footing</span></div>
538<div class="select-option" data-value="18-21" data-group="age">
53818-21 <span style="font-size:.7rem;opacity:.6">Aging out</span></div>
539<div class="select-option" data-value="22+" data-group="age">22+ <span style="font-size:.7rem;opacity:.6">Made it through</span></div>
540</div>
541</div>
542<div class="form-group">
543<label>Gender</label>
544<div class="select-grid" id="genderGrid">
545<div class="select-option" data-value="Male" data-group="gender">Male</div>
546<div class="select-option" data-value="Female" data-group="gender">Female</div>
547<div class="select-option" data-value="Non-binary" data-group="gender">Non-binary</div>
548<div class="select-option" data-value="Prefer not to say" data-group="gender">Prefer not to say</div>
549</div>
550</div>
551<div class="form-group">
552<label>Pronouns</label>
553<div class="select-grid" id="pronounGrid">
554<div class="select-option" data-value="He/Him" data-group="pronoun">He/Him</div>
555<div class="select-option" data-value="She/Her" data-group="pronoun">She/Her</div>
556<div class="select-option" data-value="They/Them" data-group="pronoun">They/Them</div>
557<div class="select-option" data-value="Custom" data-group="pronoun">Custom</div>
558</div>
559<input type="text" class="form-input" id="customPronoun" placeholder="Enter custom pronouns" style="display:none;margin-top:8px">
560</div>
561<div class="wizard-nav">
562<div></div>
563<button class="btn btn-primary" onclick="wizardNext()">Next → Appearance</button>
564</div>
565</div>
566
567<!-- STEP 2: APPEARANCE -->
568<div class="wizard-panel" id="panel1">
569<h3 style="margin-bottom:20px;color:var(--purple-light)">Step 2: Appearance</h3>
570<div class="avatar-preview-container">
571<div class="avatar-builder" id="avatarPreview">
572<div class="avatar-skin" id="avSkin"></div>
573<div class="avatar-hair" id="avHair"></div>
574<div class="avatar-eyes"><div class="avatar-eye"></div><div class="avatar-eye"></div></div>
575<div class="avatar-mouth" id="avMouth"></div>
576<div class="avatar-face" id="avFace"></div>
577<div class="avatar-clothing" id="avClothing"></div>
578</div>
579</div>
580<div class="form-group">
581<label>Skin Tone</label>
582<div class="skin-tones" id="skinTones">
583<div class="skin-tone" data-color="#FDEBD0" style="background:#FDEBD0" title="Very Light"></div>
584<div class="skin-tone" data-color="#F5CBA7" style="background:#F5CBA7" title="Light"></div>
585<div class="skin-tone" data-color="#EDBB99" style="background:#EDBB99" title="Medium Light"></div>
586<div class="skin-tone" data-color="#D4A574" style="background:#D4A574" title="Medium"></div>
587<div class="skin-tone" data-color="#C68642" style="background:#C68642" title="Medium Tan"></div>
588<div class="skin-tone" data-color="#8D5524" style="background:#8D5524" title="Tan"></div>
589<div class="skin-tone" data-color="#5C3317" style="background:#5C3317" title="Dark"></div>
590<div class="skin-tone" data-color="#3B1E08" style="background:#3B1E08" title="Very Dark"></div>
591</div>
592</div>
593<div class="form-group">
594<label>Hair Style</label>
595<div class="select-grid" id="hairStyleGrid">
596<div class="select-option" data-value="fade">✂️ Short Fade</div>
597<div class="select-option" data-value="locs">🔗 Locs/Dreads</div>
598<div class="select-option" data-value="braids">🪢 Braids</div>
599<div class="select-option" data-value="afro">🌀 Afro</div>
600<div class="select-option" data-value="buzz">💈 Buzz Cut</div>
601<div class="select-option" data-value="curly">〰️ Curly Natural</div>
602<div class="select-option" data-value="straight">📏 Straight Long</div>
603<div class="select-option" data-value="mohawk">⬆️ Mohawk</div>
604<div class="select-option" data-value="twists">🌀 Twists</div>
605<div class="select-option" data-value="bangs">💇 Bangs</div>
606<div class="select-option" data-value="shaved-sides">🔪 Shaved Sides</div>
607<div class="select-option" data-value="bald">🪨 Bald</div>
608</div>
609</div>
610<div class="form-group">
611<label>Hair Color</label>
612<div class="skin-tones" id="hairColorGrid">
613<div class="skin-tone" data-color="#1a1a1a" style="background:#1a1a1a" title="Black"></div>
614<div class="skin-tone" data-color="#8B4513" style="background:#8B4513" title="Brown"></div>
615<div class="skin-tone" data-color="#4a2a0a" style="background:#4a2a0a" title="Dark Brown"></div>
616<div class="skin-tone" data-color="#DAA520" style="background:#DAA520" title="Blonde"></div>
617<div class="skin-tone" data-color="#CC3333" style="background:#CC3333" title="Red"></div>
618<div class="skin-tone" data-color="#2266CC" style="background:#2266CC" title="Blue"></div>
619<div class="skin-tone" data-color="#9933CC" style="background:#9933CC" title="Purple"></div>
620<div class="skin-tone" data-color="#FF69B4" style="background:#FF69B4" title="Pink"></div>
621<div class="skin-tone" data-color="#888888" style="background:#888888" title="Gray"></div>
622<div class="skin-tone" data-color="#EEEEEE" style="background:#EEEEEE" title="White"></div>
623</div>
624</div>
625<div class="form-group">
626<label>Face Shape</label>
627<div class="select-grid" id="faceGrid">
628<div class="select-option" data-value="Round" data-group="face">Round</div>
629<div class="select-option" data-value="Oval" data-group="face">Oval</div>
630<div class="select-option" data-value="Square" data-group="face">Square</div>
631<div class="select-option" data-value="Heart" data-group="face">Heart</div>
632<div class="select-option" data-value="Diamond" data-group="face">Diamond</div>
633</div>
634</div>
635<div class="form-group">
636<label>Build / Body Type</label>
637<div class="select-grid" id="buildGrid">
638<div class="select-option" data-value="Slim" data-group="build">Slim</div>
639<div class="select-option" data-value="Average" data-group="build">Average</div>
640<div class="select-option" data-value="Athletic" data-group="build">Athletic</div>
641<div class="select-option" data-value="Stocky" data-group="build">Stocky</div>
642<div class="select-option" data-value="Tall & Lean" data-group="build">Tall & Lean</div>
643</div>
644</div>
645<div class="form-group">
646<label>Clothing Style</label>
647<div class="select-grid" id="clothingGrid">
648<div class="select-option" data-value="streetwear" data-group="clothing">🧥 Streetwear</div>
649<div class="select-option" data-value="preppy" data-group="clothing">👔 Preppy</div>
650<div class="select-option" data-value="goth" data-group="clothing">
650🖤 Goth/Dark</div>
651<div class="select-option" data-value="artistic" data-group="clothing">🎨 Artistic/Eclectic</div>
652<div class="select-option" data-value="athletic" data-group="clothing">🏃 Athletic</div>
653<div class="select-option" data-value="minimalist" data-group="clothing">⬜ Minimalist</div>
654</div>
655</div>
656<div class="wizard-nav">
657<button class="btn btn-secondary" onclick="wizardPrev()">← Back</button>
658<button class="btn btn-primary" onclick="wizardNext()">Next → Psyche</button>
659</div>
660</div>
661
662<!-- STEP 3: PSYCHE & TRAUMA -->
663<div class="wizard-panel" id="panel2">
664<h3 style="margin-bottom:5px;color:var(--purple-light)">Step 3: Psyche &amp; Trauma</h3>
665<p style="font-size:.8rem;color:var(--text-dim);margin-bottom:20px">This is the hardest part. Be honest with your character's story.</p>
666<div class="form-group">
667<label>Primary Trauma <span class="required">*</span></label>
668<select class="form-input" id="primaryTrauma">
669<option value="">— Select primary trauma —</option>
670<option value="Abandonment by parent(s)">Abandonment by parent(s)</option>
671<option value="Physical abuse by caregiver">Physical abuse by caregiver</option>
672<option value="Emotional/psychological abuse">Emotional/psychological abuse</option>
673<option value="Sexual abuse or assault">Sexual abuse or assault</option>
674<option value="Severe neglect">Severe neglect</option>
675<option value="Witnessing domestic violence">Witnessing domestic violence</option>
676<option value="Parent incarceration">Parent incarceration</option>
677<option value="Parent/caregiver substance abuse">Parent/caregiver substance abuse</option>
678<option value="Death of parent or sibling">Death of parent or sibling</option>
679<option value="Multiple foster placement disruptions">Multiple foster placement disruptions</option>
680<option value="Aging out of system with no support">Aging out of system with no support</option>
681<option value="Homelessness">Homelessness</option>
682<option value="Human trafficking/exploitation">Human trafficking/exploitation</option>
683<option value="Severe bullying/peer violence">Severe bullying/peer violence</option>
684<option value="Racial trauma & discrimination">Racial trauma &amp; discrimination</option>
685<option value="Identity rejection (LGBTQ+)">Identity rejection (LGBTQ+)</option>
686<option value="Self-harm">Self-harm</option>
687<option value="Eating disorder">Eating disorder</option>
688<option value="Substance abuse (self)">Substance abuse (self)</option>
689<option value="Gang pressure/involvement">Gang pressure/involvement</option>
690<option value="Mental health crisis/hospitalization">Mental health crisis/hospitalization</option>
691<option value="Educational neglect/denied schooling">Educational neglect/denied schooling</option>
692<option value="Medical neglect">Medical neglect</option>
693<option value="Sibling separation">Sibling separation</option>
694<option value="Parental deportation/immigration crisis">Parental deportation/immigration crisis</option>
695<option value="Wrongful juvenile detention">Wrongful juvenile detention</option>
696<option value="Caregiver hoarding/unsafe living conditions">Caregiver hoarding/unsafe living conditions</option>
697<option value="Forced religious practices/spiritual abuse">Forced religious practices/spiritual abuse</option>
698<option value="Parentification (forced to raise siblings)">Parentification (forced to raise siblings)</option>
699<option value="Cyberbullying/online exploitation">Cyberbullying/online exploitation</option>
700</select>
701</div>
702<div class="form-group">
703<label>Secondary Trauma <span style="font-size:.7rem;color:var(--text-dim)">(optional)</span></label>
704<select class="form-input" id="secondaryTrauma">
705<option value="">— None —</option>
706<option value="Abandonment by parent(s)">Abandonment by parent(s)</option>
707<option value="Physical abuse by caregiver">Physical abuse by caregiver</option>
708<option value="Emotional/psychological abuse">Emotional/psychological abuse</option>
709<option value="Sexual abuse or assault">Sexual abuse or assault</option>
710<option value="Severe neglect">Severe neglect</option>
711<option value="Witnessing domestic violence">Witnessing domestic violence</option>
712<option value="Parent incarceration">Parent incarceration</option>
713<option value="Parent/caregiver substance abuse">Parent/caregiver substance abuse</option>
714<option value="Death of parent or sibling">Death of parent or sibling</option>
715<option value="Multiple foster placement disruptions">Multiple foster placement disruptions</option>
716<option value="Aging out of system with no support">Aging out of system with no support</option>
717<option value="Homelessness">Homelessness</option>
718<option value="Human trafficking/exploitation">Human trafficking/exploitation</option>
719<option value="Severe bullying/peer violence">Severe bullying/peer violence</option>
720<option value="Racial trauma & discrimination">Racial trauma &amp; discrimination</option>
721<option value="Identity rejection (LGBTQ+)">Identity rejection (LGBTQ+)</option>
722<option value="Self-harm">Self-harm</option>
723<option value="Eating disorder">Eating disorder</option>
724<option value="Substance abuse (self)">Substance abuse (self)</option>
725<option value="Gang pressure/involvement">Gang pressure/involvement</option>
726<option value="Mental health crisis/hospitalization">Mental health crisis/hospitalization</option>
727<option value="Educational neglect/denied schooling">Educational neglect/denied schooling</option>
728<option value="Medical neglect">Medical neglect</option>
729<option value="Sibling separation">Sibling separation</option>
730<option value="Parental deportation/immigration crisis">Parental deportation/immigration crisis</option>
731<option value="Wrongful juvenile detention">Wrongful juvenile detention</option>
732<option value="Caregiver hoarding/unsafe living conditions">Caregiver hoarding/unsafe living conditions</option>
733<option value="Forced religious practices/spiritual abuse">Forced religious practices/spiritual abuse</option>
734<option value="Parentification (forced to raise siblings)">Parentification (forced to raise siblings)</option>
735<option value="Cyberbullying/online exploitation">Cyberbullying/online exploitation</option>
736</select>
737</div>
738<div class="form-group">
739<label>Coping Mechanisms <span style="font-size:.7rem;color:var(--text-dim)">(pick up to 2)</span></label>
740<div class="select-grid" id="copingGrid">
741<div class="select-option" data-value="Art & creativity" data-group="coping">🎨 Art & creativity</div>
742<div class="select-option" data-value="Music" data-group="coping">🎵 Music</div>
743<div class="select-option" data-value="Writing/journaling" data-group="coping">📝 Writing/journaling</div>
744<div class="select-option" data-value="Sports/physical activity" data-group="coping">🏃 Sports</div>
745<div class="select-option" data-value="Isolation/withdrawal" data-group="coping">🚪 Isolation</div>
746<div class="select-option" data-value="Humor & deflection" data-group="coping">😂 Humor</div>
747<div class="select-option" data-value="Anger/fighting" data-group="coping">👊 Anger/fighting</div>
748<div class="select-option" data-value="People-pleasing/masking" data-group="coping">🎭 People-pleasing</div>
749<div class="select-option" data-value="Substance use" data-group="coping">💊 Substance use</div>
750<div class="select-option" data-value="Hyper-independence" data-group="coping">🛡️ Hyper-independence</div>
751<div class="select-option" data-value="Religion/spirituality" data-group="coping">🙏 Religion</div>
752<div class="select-option" data-value="Animals/nature" data-group="coping">🌿 Animals/nature</div>
753<div class="select-option" data-value="Gaming/escapism" data-group="coping">🎮 Gaming/escapism</div>
754<div class="select-option" data-value="Talking to a therapist" data-group="coping">💬 Therapy</div>
755<div class="select-option" data-value="Shutting down/dissociation" data-group="coping">🫥 Dissociation</div>
756</div>
757</div>
758<div class="form-group">
759<label>Personality Traits <span style="font-size:.7rem;color:var(--text-dim)">(pick up to 3)</span></label>
760<div class="select-grid" id="traitsGrid">
761<div class="select-option" data-value="Loyal" data-group="trait">Loyal</div>
762<div class="select-option" data-value="Guarded" data-group="trait">Guarded</div>
763<div class="select-option" data-value="Reckless" data-group="trait">Reckless</div>
764<div class="select-option" data-value="Quiet" data-group="trait">Quiet</div>
765<div class="select-option" data-value="Fearless" data-group="trait">Fearless</div>
766<div class="select-option" data-value="Broken" data-group="trait">Broken</div>
767<div class="select-option" data-value="Funny" data-group="trait">Funny</div>
768<div class="select-option" data-value="Angry" data-group="trait">Angry</div>
769<div class="select-option" data-value="Hopeful" data-group="trait">Hopeful</div>
770<div class="select-option" data-value="Kind" data-group="trait">Kind</div>
771<div class="select-option" data-value="Street Smart" data-group="trait">Street Smart</div>
772<div class="select-option" data-value="Creative" data-group="trait">Creative</div>
773<div class="select-option" data-value="Manipulative" data-group="trait">Manipulative</div>
774<div class="select-option" data-value="Paranoid" data-group="trait">Paranoid</div>
775<div class="select-option" data-value="Protective" data-group="trait">Protective</div>
776<div class="select-option" data-value="Stubborn" data-group="trait">Stubborn</div>
777<div class="select-option" data-value="Empathetic" data-group="trait">Empathetic</div>
778<div class="select-option" data-value="Numb" data-group="trait">Numb</div>
779<div class="select-option" data-value="Charismatic" data-group="trait">Charismatic</div>
780<div class="select-option" data-value="Observant" data-group="trait">Observant</div>
781</div>
782</div>
783<div class="form-group">
784<label>Emotional State Right Now <span class="required">*</span></label>
785<div class="select-grid" id="emotionGrid">
786<div class="select-option" data-value="Scared but hopeful" data-group="emotion">😰 Scared but hopeful</div>
787<div class="select-option" data-value="Angry at everything" data-group="emotion">😡 Angry at everything</div>
788<div class="select-option" data-value="Numb/checked out" data-group="emotion">😶 Numb/checked out</div>
789<div class="select-option" data-value="Cautiously optimistic" data-group="emotion">🤔 Cautiously optimistic</div>
790<div class="select-option" data-value="Ready to fight" data-group="emotion">✊ Ready to fight</div>
791<div class="select-option" data-value="Just tired" data-group="emotion">😔 Just tired</div>
792<div class="select-option" data-value="Pretending to be fine" data-group="emotion">🙂 Pretending to be fine</div>
793<div class="select-option" data-value="Actually okay for once" data-group="emotion">😊 Actually okay for once</div>
794<div class="select-option" data-value="Heartbroken" data-group="emotion">💔 Heartbroken</div>
795<div class="select-option" data-value="Determined" data-group="emotion">🔥 Determined</div>
796</div>
797</div>
798<div class="wizard-nav">
799<button class="btn btn-secondary" onclick="wizardPrev()">← Back</button>
800<button class="btn btn-primary" onclick="wizardNext()">Next → Life</button>
801</div>
802</div>
803
804<!-- STEP 4: LIFE IN HAVEN RIDGE -->
805<div class="wizard-panel" id="panel3">
806<h3 style="margin-bottom:5px;color:var(--purple-light)">Step 4: Life in Haven Ridge</h3>
807<p style="font-size:.8rem;color:var(--text-dim);margin-bottom:20px">What does your life look like inside the walls?</p>
808<div class="form-group">
809<label>School Focus <span class="required">*</span></label>
810<div class="select-grid" id="schoolGrid">
811<div class="select-option" data-value="Arts & Music" data-group="school">🎨 Arts & Music</div>
812<div class="select-option" data-value="STEM & Technology" data-group="school">💻 STEM & Technology</div>
813<div class="select-option" data-value="Sports & Athletics" data-group="school">🏆 Sports & Athletics</div>
814<div class="select-option" data-value="Business & Leadership" data-group="school">📈 Business & Leadership</div>
815<div class="select-option" data-value="Culinary Arts" data-group="school">🍳 Culinary Arts</div>
816<div class="select-option" data-value="Trades & Mechanics" data-group="school">🔧 Trades & Mechanics</div>
817<div class="select-option" data-value="General Studies" data-group="school">📚 General Studies</div>
818</div>
819</div>
820<div class="form-group">
821<label>Extracurricular Activities <span style="font-size:.7rem;color:var(--text-dim)">(pick 1-2)</span></label>
822<div class="select-grid" id="activityGrid">
823<div class="select-option" data-value="Basketball" data-group="activity" data-sport="true">🏀 Basketball</div>
824<div class="select-option" data-value="Football" data-group="activity" data-sport="true">🏈 Football</div>
825<div class="select-option" data-value="Soccer" data-group="activity" data-sport="true">⚽ Soccer</div>
826<div class="select-option" data-value="Track & Field" data-group="activity" data-sport="true">🏃 Track & Field</div>
827<div class="select-option" data-value="Art Club" data-group="activity">🎨 Art Club</div>
828<div class="select-option" data-value="Music Program" data-group="activity">🎵 Music Program</div>
829<div class="select-option" data-value="Photography Club" data-group="activity">📸 Photography</div>
830<div class="select-option" data-value="Coding & Robotics" data-group="activity">💻 Coding & Robotics</div>
831<div class="select-option" data-value="Theater/Drama" data-group="activity">🎭 Theater/Drama</div>
832<div class="select-option" data-value="Community Garden" data-group="activity">🌱 Community Garden</div>
833<div class="select-option" data-value="Student Council" data-group="activity">🗳️ Student Council</div>
834<div class="select-option" data-value="Book Club" data-group="activity">📚 Book Club</div>
835<div class="select-option" data-value="Boxing/MMA" data-group="activity">🥊 Boxing/MMA</div>
836<div class="select-option" data-value="Yoga & Meditation" data-group="activity">🧘 Yoga & Meditation</div>
837<div class="select-option" data-value="Gaming Club" data-group="activity">🎮 Gaming Club</div>
838</div>
839</div>
840<!-- Sport sub-dropdowns -->
841<div id="sportDetails" style="display:none;margin-top:10px;padding:15px;background:rgba(255,255,255,0.03);border-radius:10px;border:1px solid rgba(255,255,255,0.05)">
842<div class="form-group" id="sportPositionGroup">
843<label>Position</label>
844<select class="form-input" id="sportPosition">
845<option value="">— Select position —</option>
846</select>
847</div>
848<div class="form-group">
849<label>Level</label>
850<div class="select-grid" id="sportLevelGrid">
851<div class="select-option" data-value="Bench" data-group="sportLevel">Bench</div>
852<div class="select-option" data-value="Rotation" data-group="sportLevel">Rotation</div>
853<div class="select-option" data-value="Starter" data-group="sportLevel">Starter</div>
854<div class="select-option" data-value="Star" data-group="sportLevel">Star</div>
855</div>
856</div>
857</div>
858<div class="form-group">
859<label>Living Situation</label>
860<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:10px">
861<div>
862<label style="font-size:.75rem;color:var(--text-dim);margin-bottom:5px">Building</label>
863<select class="form-input" id="building">
864<option value="">— Select —</option>
865<option value="Building A — The Foundation">A: The Foundation</option>
866<option value="Building B — New Horizons">B: New Horizons</option>
867<option value="Building C — Second Chances">C: Second Chances</option>
868</select>
869</div>
870<div>
871<label style="font-size:.75rem;color:var(--text-dim);margin-bottom:5px">Floor</label>
872<select class="form-input" id="floor">
873<option value="">— Select —</option>
874<option value="1st">1st Floor</option>
875<option value="2nd">2nd Floor</option>
876<option value="3rd">3rd Floor</option>
877</select>
878</div>
879<div>
880<label style="font-size:.75rem;color:var(--text-dim);margin-bottom:5px">Roommate</label>
881<select class="form-input" id="roommate">
882<option value="Solo">Solo</option>
883<option value="Shared (random)">Shared (random)</option>
884<option value="Shared (request)">Shared (request)</option>
885</select>
886</div>
887</div>
888</div>
889<div class="wizard-nav">
890<button class="btn btn-secondary" onclick="wizardPrev()">← Back</button>
891<button class="btn btn-primary" onclick="wizardNext()">Next → Review</button>
892</div>
893</div>
894
895<!-- STEP 5: REVIEW -->
896<div class="wizard-panel" id="panel4">
897<h3 style="margin-bottom:5px;color:var(--purple-light)">Step 5: Review Your Character</h3>
898<p style="font-size:.8rem;color:var(--text-dim);margin-bottom:20px">Make sure everything looks right before you walk through The Gate.</p>
899<div id="reviewCard" style="background:rgba(255,255,255,0.03);border:1px solid var(--glass-border);border-radius:16px;padding:25px">
900<div style="display:flex;align-items:center;gap:20px;margin-bottom:20px;flex-wrap:wrap">
901<div class="avatar-builder" id="reviewAvatar" style="width:120px;height:120px;flex-shrink:0">
902<div class="avatar-skin" id="revSkin"></div>
903<div class="avatar-hair" id="revHair"></div>
904<div class="avatar-eyes" style="top:40%;gap:12px"><div class="avatar-eye" style="width:6px;height:6px"></div><div class="avatar-eye" style="width:6px;height:6px"></div></div>
905<div class="avatar-clothing" id="revClothing"></div>
906</div>
907<div>
908<h2 id="revName" style="margin-bottom:5px">—</h2>
909<p style="color:var(--text-dim);font-size:.85rem"><span id="revAge">—</span> · <span id="revGender">—</span> · <span id="revPronouns">—</span></p>
910<p style="color:var(--text-dim);font-size:.8rem;margin-top:3px"><span id="revBuild">—</span> · <span id="revFace">— face</span></p>
911</div>
912</div>
913<div style="display:grid;grid-template-columns:1fr 1fr;gap:15px;font-size:.85rem">
914<div><strong style="color:var(--purple-light)">Primary Trauma:</strong><br><span id="revTrauma1" class="review-val">—</span></div>
915<div><strong style="color:var(--purple-light)">Secondary Trauma:</strong><br><span id="revTrauma2" class="review-val">—</span></div>
916<div><strong style="color:var(--orange-light)">Coping:</strong><br><span id="revCoping" class="review-val">—</span></div>
917<div><strong style="color:var(--orange-light)">Traits:</strong><br><span id="revTraits" class="review-val">—</span></div>
918<div><strong style="color:var(--gold)">Emotional State:</strong><br><span id="revEmotion" class="review-val">—</span></div>
919<div><strong style="color:var(--gold)">School Focus:</strong><br><span id="revSchool" class="review-val">—</span></div>
920<div><strong style="color:var(--text)">Activities:</strong><br><span id="revActivities" class="review-val">—</span></div>
921<div><strong style="color:var(--text)">Housing:</strong><br><span id="revHousing" class="review-val">—</span></div>
922</div>
923</div>
924<div class="wizard-nav">
925<button class="btn btn-secondary" onclick="wizardPrev()">← Back</button>
926<button class="btn btn-gold" onclick="createCharacter()" style="font-size:1rem;padding:15px 40px">🏠 Welcome to Haven Ridge</button>
927</div>
928</div>
929</div><!-- end wizard-container -->
930
931<!-- Character Showcase -->
932<div id="showcaseSection" style="margin-top:50px;display:none">
933<h3 style="margin-bottom:5px;color:var(--gold)">Haven Ridge Citizens</h3>
934<p style="font-size:.85rem;color:var(--text-dim);margin-bottom:15px">The people who call this place home.</p>
935<div class="showcase-grid" id="showcaseGrid"></div>
936</div>
937</section>
938
939<!-- YOUR PROFILE -->
940<section id="profile" class="fade-in">
941<div class="section-label">Your Identity</div>
942<h2 class="section-title">Your Profile</h2>
943<div id="profileEmpty" style="text-align:center;padding:40px">
944<p style="font-size:3rem;margin-bottom:15px">👤</p>
945<p style="color:var(--text-dim)">No character created yet.</p>
946<a href="#creator" style="color:var(--purple-light)">Create your Haven Ridge citizen →</a>
947</div>
948<div id="profileCard" class="profile-card" style="display:none">
949<div class="profile-id">HAVEN RIDGE CITIZEN ID — <span id="profileId">HR-0000</span></div>
950<div style="display:flex;align-items:center;gap:20px;justify-content:center;flex-wrap:wrap">
951<div class="avatar-builder" id="profileAvatar" style="width:100px;height:100px;flex-shrink:0">
952<div class="avatar-skin" id="profSkin"></div>
953<div class="avatar-hair" id="profHair"></div>
954<div class="avatar-eyes" style="top:40%;gap:10px"><div class="avatar-eye" style="width:5px;height:5px"></div><div class="avatar-eye" style="width:5px;height:5px"></div></div>
955<div class="avatar-clothing" id="profClothing"></div>
956</div>
957<div>
958<h3 id="profileName" style="margin-bottom:3px">—</h3>
959<p style="font-size:.85rem;color:var(--text-dim)" id="profileMeta">—</p>
960<span class="tier-badge tier-free" id="profileTier">Free Citizen</span>
961</div>
962</div>
963<div class="profile-stats">
964<div class="profile-stat"><div class="profile-stat-num" id="statDays">1</div><div class="profile-stat-label">Days as Resident</div></div>
965<div class="profile-stat"><div class="profile-stat-num" id="statSubs">0</div><div class="profile-stat-label">Submissions</div></div>
966<div class="profile-stat"><div class="profile-stat-num" id="statThreads">0</div><div class="profile-stat-label">Forum Posts</div></div>
967</div>
968<div style="text-align:center;margin-top:20px">
969<button class="btn btn-secondary" onclick="editCharacter()" style="font-size:.8rem">✏️ Edit Character</button>
970<button class="btn btn-secondary" onclick="deleteCharacter()" style="font-size:.8rem;margin-left:8px;border-color:var(--orange);color:var(--orange)">🗑️ Delete</button>
971</div>
972</div>
973</section>
974
975<!-- WORLD MAP -->
976<section id="worldmap" class="fade-in">
977<div class="section-label">Explore the City</div>
978<h2 class="section-title">Haven Ridge World Map</h2>
979<p class="section-desc">Every corner of Haven Ridge has a purpose. Every building holds stories.</p>
980<div class="map-grid">
981<div class="card map-card">
982<div class="map-icon">🚪</div>
983<h3>The Gate</h3>
984<p>Where everyone enters Haven Ridge. You don't choose to come here — you're chosen, usually when every other door has been slammed in your face.</p>
985<div class="map-activity">Processing new arrivals • Orientation • First assessments</div>
986</div>
987<div class="card map-card">
988<div class="map-icon">🏫</div>
989<h3>Haven Ridge High</h3>
990<p>Seven tracks, one mission: give you the education the system denied. Classes run different here — teachers actually see you.</p>
991<div class="map-activity">Classes • Sports • Academic support • College prep</div>
992</div>
993<div class="card map-card">
994<div class="map-icon">🏢</div>
995<h3>The Apartments</h3>
996<p>Three buildings. Three philosophies. Building A (The Foundation) for new arrivals, B (New Horizons) for those progressing, C (Second Chances) for those rebuilding.</p>
997<div class="map-activity">Transitional living • Room assignments • Community dinners</div>
998</div>
999<div class="card map-card">
1000<div class="map-icon">🏛️</div>
1001<h3>The Plaza</h3>
1002<p>The heart of Haven Ridge. Town halls, celebrations, arguments, and the occasional midnight conversation that changes everything.</p>
1003<div class="map-activity">Community events • Gatherings • Announcements</div>
1004</div>
1005<div class="card map-card">
1006<div class="map-icon">🔬</div>
1007<h3>The STEM Dome</h3>
1008<p>Where the future is built. Coding bootcamps, robotics, 3D printing, and the kind of resources most foster kids never get access to.</p>
1009<div class="map-activity">Tech labs • Innovation challenges • Mentorship</div>
1010</div>
1011<div class="card map-card">
1012<div class="map-icon">🎨</div>
1013<h3>The Art District</h3>
1014<p>Paint your pain. Sculpt your rage. Photograph your truth. The Art District doesn't ask you to explain — just express.</p>
1015<div class="map-activity">Studios • Galleries • Open mics • Exhibitions</div>
1016</div>
1017<div class="card map-card">
1018<div class="map-icon">🌿</div>
1019<h3>The Garden</h3>
1020<p>The quietest place in Haven Ridge. Where residents go when the noise gets too loud — inside and out.</p>
1021<div class="map-activity">Reflection • Meditation • Community gardening</div>
1022</div>
1023<div class="card map-card">
1024<div class="map-icon">🧱</div>
1025<h3>The Wall</h3>
1026<p>The graffiti wall where stories are written. Some are beautiful. Some are brutal. All of them are real. If you write your truth on The Wall, Haven Ridge listens.</p>
1027<div class="map-activity">Graffiti • Storytelling • Anonymous confessions</div>
1028</div>
1029<div class="card map-card">
1030<div class="map-icon">🌙</div>
1031<h3>Night Market</h3>
1032<p>After dark, Haven Ridge transforms. Music, food, underground poetry slams, and the kind of honesty that only comes out when the sun goes down.</p>
1033<div class="map-activity">Events • Food • Music • Late-night community</div>
1034</div>
1035<div class="card map-card">
1036<div class="map-icon">🧠</div>
1037<h3>Therapy Center</h3>
1038<p>No one forces you to go. But everyone who does says the same thing: "I wish I went sooner." Trauma-informed care by people who actually get it.</p>
1039<div class="map-activity">Individual therapy • Group sessions • Crisis support</div>
1040</div>
1041<div class="card map-card">
1042<div class="map-icon">⚡</div>
1043<h3>The Edge</h3>
1044<p>The border of Haven Ridge, where it meets the outside world. Some look over it with fear. Some with hope. Some aren't sure they ever want to cross back.</p>
1045<div class="map-activity">Transition planning • Real-world prep • The unknown</div>
1046</div>
1047</div>
1048</section>
1049
1050<!-- STORY SUBMISSIONS -->
1051<section id="submissions" class="fade-in">
1052<div class="section-label">Tell Your Story</div>
1053<h2 class="section-title">Story Submissions</h2>
1054<p class="section-desc">Storyteller and Architect tier members can submit scenes that may become part of the official Haven Ridge narrative.</p>
1055<div class="submission-form">
1056<div style="padding:15px;background:rgba(192,84,42,0.1);border:1px solid rgba(192,84,42,0.3);border-radius:10px;margin-bottom:20px;font-size:.85rem;color:var(--orange-light)">
1057🟠 Requires Storyteller ($5.99/mo) or Architect ($7.99/mo) tier. Don't have one? <a href="https://buy.stripe.com/4gM9AS5LPao7eUWgJmbsc04" target="_blank" style="color:var(--gold)">Join as Storyteller →</a>
1058</div>
1059<div class="form-group">
1060<label>Your Email <span class="required">*</span></label>
1061<input type="email" class="form-input" id="subEmail" placeholder="[email protected]">
1062</div>
1063<div class="form-group">
1064<label>Your Citizen ID <span style="font-size:.7rem;color:var(--text-dim);font-weight:400">(optional — shown on your profile after character creation)</span></label>
1065<input type="text" class="form-input" id="subCitizenId" placeholder="HR-XXXX">
1066</div>
1067<div class="form-group">
1068<label>Your Subscription Tier <span class="required">*</span></label>
1069<select class="form-input" id="subTier">
1070<option value="">— Select your tier —</option>
1071<option value="Storyteller">Storyteller ($5.99/mo)</option>
1072<option value="Architect">Architect ($7.99/mo)</option>
1073</select>
1074</div>
1075<div class="form-group">
1076<label>Scene Title <span class="required">*</span></label>
1077<input type="text" class="form-input" id="subTitle" placeholder="Title of your scene">
1078</div>
1079<div class="form-group">
1080<label>Location <span class="required">*</span></label>
1081<select class="form-input" id="subLocation">
1082<option value="">
1082— Where does this scene take place? —</option>
1083<option>The Gate</option>
1084<option>Haven Ridge High</option>
1085<option>The Apartments — Building A</option>
1086<option>The Apartments — Building B</option>
1087<option>The Apartments — Building C</option>
1088<option>The Plaza</option>
1089<option>The STEM Dome</option>
1090<option>The Art District</option>
1091<option>The Garden</option>
1092<option>The Wall</option>
1093<option>Night Market</option>
1094<option>Therapy Center</option>
1095<option>The Edge</option>
1096</select>
1097</div>
1098<div class="form-group">
1099<label>Soundtrack Match <span style="font-size:.7rem;color:var(--text-dim)">(optional — what song plays during this scene?)</span></label>
1100<input type="text" class="form-input" id="subSoundtrack" placeholder="Artist — Song Title">
1101</div>
1102<div class="form-group">
1103<label>Your Scene <span class="required">*</span></label>
1104<textarea class="form-input" id="subContent" rows="10" placeholder="Write your scene... Be raw. Be real. Be you." oninput="updateWordCount()"></textarea>
1105<div class="word-count"><span id="wordCount">0</span> words</div>
1106</div>
1107<button class="btn btn-orange" onclick="submitStory()">Submit Scene for Review</button>
1108</div>
1109</section>
1110
1111<!-- COMMUNITY FORUM -->
1112<section id="forum" class="fade-in">
1113<div class="section-label">Community Voices</div>
1114<h2 class="section-title">Forum</h2>
1115<p class="section-desc">Speak. Listen. Argue. Heal. This is your space.</p>
1116<div class="forum-categories">
1117<div class="forum-cat active" data-cat="all">All</div>
1118<div class="forum-cat" data-cat="introductions">Introductions</div>
1119<div class="forum-cat" data-cat="stories">Story Discussion</div>
1120<div class="forum-cat" data-cat="characters">Characters</div>
1121<div class="forum-cat" data-cat="real-talk">Real Talk</div>
1122<div class="forum-cat" data-cat="creative">Creative Corner</div>
1123<div class="forum-cat" data-cat="support">Support</div>
1124</div>
1125<button class="btn btn-primary" onclick="startThread()" style="margin-bottom:20px;font-size:.8rem">+ Start a Thread</button>
1126<div class="forum-threads" id="forumThreads">
1127<div class="forum-thread" data-cat="introductions">
1128<div class="forum-thread-info">
1129<h4>👋 New here — just walked through The Gate</h4>
1130<p>by <span style="color:var(--purple-light)">Anonymous_Resident</span> in <span style="color:var(--gold)">Introductions</span></p>
1131</div>
1132<div class="forum-thread-meta"><div class="replies">23 replies</div><div class="time">2 hours ago</div></div>
1133</div>
1134<div class="forum-thread" data-cat="stories">
1135<div class="forum-thread-info">
1136<h4>Chapter 1 Discussion — The Gate (SPOILERS)</h4>
1137<p>by <span style="color:var(--purple-light)">StoryKeeper</span> in <span style="color:var(--gold)">Story Discussion</span></p>
1138</div>
1139<div class="forum-thread-meta"><div class="replies">47 replies</div><div class="time">5 hours ago</div></div>
1140</div>
1141<div class="forum-thread" data-cat="characters">
1142<div class="forum-thread-info">
1143<h4>Share your character — who did you create?</h4>
1144<p>by <span style="color:var(--purple-light)">HR_Citizen_042</span> in <span style="color:var(--gold)">Characters</span></p>
1145</div>
1146<div class="forum-thread-meta"><div class="replies">31 replies</div><div class="time">1 day ago</div></div>
1147</div>
1148<div class="forum-thread" data-cat="real-talk">
1149<div class="forum-thread-info">
1150<h4>For those who actually aged out — does it get better?</h4>
1151<p>by <span style="color:var(--purple-light)">SurvivorNotVictim</span> in <span style="color:var(--gold)">Real Talk</span></p>
1152</div>
1153<div class="forum-thread-meta"><div class="replies">89 replies</div><div class="time">3 hours ago</div></div>
1154</div>
1155<div class="forum-thread" data-cat="creative">
1156<div class="forum-thread-info">
1157<h4>🎵 Playlist thread — songs that sound like Haven Ridge</h4>
1158<p>by <span style="color:var(--purple-light)">NightMarketDJ</span> in <span style="color:var(--gold)">Creative Corner</span></p>
1159</div>
1160<div class="forum-thread-meta"><div class="replies">56 replies</div><div class="time">6 hours ago</div></div>
1161</div>
1162<div class="forum-thread" data-cat="support">
1163<div class="forum-thread-info">
1164<h4>Resources for anyone actually going through it right now</h4>
1165<p>by <span style="color:var(--purple-light)">Moderator</span> in <span style="color:var(--gold)">Support</span> — <span style="color:var(--orange)">📌 Pinned</span></p>
1166</div>
1167<div class="forum-thread-meta"><div class="replies">12 replies</div><div class="time">Pinned</div></div>
1168</div>
1169<div class="forum-thread" data-cat="real-talk">
1170<div class="forum-thread-info">
1171<h4>The system failed us. Now what?</h4>
1172<p>by <span style="color:var(--purple-light)">TruthTeller</span> in <span style="color:var(--gold)">Real Talk</span></p>
1173</div>
1174<div class="forum-thread-meta"><div class="replies">67 replies</div><div class="time">12 hours ago</div></div>
1175</div>
1176<div class="forum-thread" data-cat="stories">
1177<div class="forum-thread-info">
1178<h4>Theory: The Edge isn't just a border — it's a metaphor</h4>
1179<p>by <span style="color:var(--purple-light)">DeepReader</span> in <span style="color:var(--gold)">Story Discussion</span></p>
1180</div>
1181<div class="forum-thread-meta"><div class="replies">34 replies</div><div class="time">1 day ago</div></div>
1182</div>
1183</div>
1184</section>
1185
1186<!-- FOOTER -->
1187<footer class="footer">
1188<p><a href="index.html" style="color:var(--purple-light)">← Back to The Safe Home Chronicles: Forever Home</a></p>
1189<p style="margin-top:15px;font-style:italic;color:var(--text-dim);font-size:.75rem">Haven Ridge is a fictional community created for storytelling purposes. The themes explored are inspired by real experiences but all characters and events are fictional.</p>
1190<p style="margin-top:10px;font-size:.75rem">If you or someone you know is in crisis, contact the <strong style="color:var(--text)">988 Suicide & Crisis Lifeline</strong> (call or text 988) or the <strong style="color:var(--text)">Childhelp National Child Abuse Hotline</strong> (1-800-422-4453).</p>
1191<p style="margin-top:20px;font-size:.7rem">© 2026 Blackface Media Publishing. All rights reserved.</p>
1192</footer>
1193
1194<script>
1195// ============ STATE ============
1196let currentStep = 0;
1197const totalSteps = 5;
1198let charData = {
1199  name:'',age:'',gender:'',pronouns:'',
1200  skinTone:'#C68642',hairStyle:'fade',hairColor:'#1a1a1a',
1201  faceShape:'Oval',build:'Average',clothingStyle:'streetwear',
1202  primaryTrauma:'',secondaryTrauma:'',
1203  coping:[],traits:[],emotion:'',
1204  school:'',activities:[],sportPosition:'',sportLevel:'',
1205  building:'',floor:'',roommate:'Solo'
1206};
1207
1208// ============ TRIGGER WARNING ============
1209(function(){
1210  if(localStorage.getItem('hr_gate_passed')==='true'){
1211    document.getElementById('twGate').classList.add('hidden');
1212  }
1213  document.getElementById('twCheck').addEventListener('change',function(){
1214    document.getElementById('twEnter').disabled=!this.checked;
1215  });
1216})();
1217
1218function enterHavenRidge(){
1219  if(!document.getElementById('twCheck').checked)return;
1220  localStorage.setItem('hr_gate_passed','true');
1221  document.getElementById('twGate').style.opacity='0';
1222  document.getElementById('twGate').style.transition='opacity 0.5s';
1223  setTimeout(()=>document.getElementById('twGate').classList.add('hidden'),500);
1224}
1225
1226// ============ MOBILE MENU ============
1227function toggleMobile(){
1228  document.getElementById('mobileMenu').classList.toggle('open');
1229}
1230function closeMobile(){
1231  document.getElementById('mobileMenu').classList.remove('open');
1232}
1233
1234// ============ CITIZEN COUNTER ============
1235function updateCitizenCount(){
1236  let chars=JSON.parse(localStorage.getItem('hr_characters')||'[]');
1237  let base=142;
1238  document.getElementById('citizenCount').textContent=base+chars.length;
1239}
1240updateCitizenCount();
1241
1242// ============ WIZARD NAVIGATION ============
1243function wizardNext(){
1244  if(!validateStep(currentStep))return;
1245  if(currentStep<totalSteps-1){
1246    currentStep++;
1247    updateWizard();
1248    if(currentStep===4)populateReview();
1249  }
1250}
1251function wizardPrev(){
1252  if(currentStep>0){
1253    currentStep--;
1254    updateWizard();
1255  }
1256}
1257function updateWizard(){
1258  document.querySelectorAll('.wizard-panel').forEach((p,i)=>{
1259    p.classList.toggle('active',i===currentStep);
1260  });
1261  document.querySelectorAll('.wizard-step-dot').forEach((d,i)=>{
1262    d.classList.remove('active','done');
1263    if(i===currentStep)d.classList.add('active');
1264    else if(i<currentStep)d.classList.add('done');
1265  });
1266  let pct=(currentStep/(totalSteps-1))*100;
1267  let fillW=document.querySelector('.wizard-progress').offsetWidth-80;
1268  document.getElementById('progressFill').style.width=(pct*fillW/100)+'px';
1269}
1270function validateStep(step){
1271  if(step===0){
1272    charData.name=document.getElementById('charName').value.trim();
1273    if(!charData.name){alert('Please enter a character name.');return false;}
1274    if(!charData.age){alert('Please select an age range.');return false;}
1275    return true;
1276  }
1277  if(step===2){
1278    charData.primaryTrauma=document.getElementById('primaryTrauma').value;
1279    charData.secondaryTrauma=document.getElementById('secondaryTrauma').value;
1280    if(!charData.primaryTrauma){alert('Please select a primary trauma.');return false;}
1281    if(!charData.emotion){alert('Please select an emotional state.');return false;}
1282    return true;
1283  }
1284  if(step===3){
1285    if(!charData.school){alert('Please select a school focus.');return false;}
1286    charData.building=document.getElementById('building').value;
1287    charData.floor=document.getElementById('floor').value;
1288    charData.roommate=document.getElementById('roommate').value;
1289    return true;
1290  }
1291  return true;
1292}
1293
1294// ============ SINGLE-SELECT GRIDS ============
1295document.querySelectorAll('.select-grid').forEach(grid=>{
1296  grid.addEventListener('click',function(e){
1297    let opt=e.target.closest('.select-option');
1298    if(!opt)return;
1299    let group=opt.dataset.group;
1300    let val=opt.dataset.value;
1301    // Multi-select groups
1302    if(group==='coping'){
1303      handleMultiSelect(opt,charData.coping,2,'coping');return;
1304    }
1305    if(group==='trait'){
1306      handleMultiSelect(opt,charData.traits,3,'trait');return;
1307    }
1308    if(group==='activity'){
1309      handleMultiSelect(opt,charData.activities,2,'activity');
1310      updateSportDetails();return;
1311    }
1312    if(group==='sportLevel'){
1313      grid.querySelectorAll('.select-option').forEach(o=>o.classList.remove('selected'));
1314      opt.classList.add('selected');
1315      charData.sportLevel=val;return;
1316    }
1317    // Single select
1318    grid.querySelectorAll('.select-option').forEach(o=>o.classList.remove('selected'));
1319    opt.classList.add('selected');
1320    if(group==='age')charData.age=val;
1321    if(group==='gender')charData.gender=val;
1322    if(group==='pronoun'){
1323      charData.pronouns=val;
1324      document.getElementById('customPronoun').style.display=val==='Custom'?'block':'none';
1325    }
1326    if(group==='face')charData.faceShape=val;
1327    if(group==='build')charData.build=val;
1328    if(group==='clothing'){charData.clothingStyle=val;updateAvatar();}
1329    if(group==='emotion')charData.emotion=val;
1330    if(group==='school')charData.school=val;
1331  });
1332});
1333
1334function handleMultiSelect(opt,arr,max,groupName){
1335  let val=opt.dataset.value;
1336  let idx=arr.indexOf(val);
1337  if(idx>-1){
1338    arr.splice(idx,1);
1339    opt.classList.remove('selected');
1340  }else{
1341    if(arr.length>=max){
1342      // Remove first
1343      let firstOpt=opt.closest('.select-grid').querySelector('.select-option.selected');
1344      if(firstOpt){firstOpt.classList.remove('selected');arr.shift();}
1345    }
1346    arr.push(val);
1347    opt.classList.add('selected');
1348  }
1349}
1350
1351// ============ SKIN TONE ============
1352document.getElementById('skinTones').addEventListener('click',function(e){
1353  let t=e.target.closest('.skin-tone');
1354  if(!t)return;
1355  this.querySelectorAll('.skin-tone').forEach(s=>s.classList.remove('selected'));
1356  t.classList.add('selected');
1357  charData.skinTone=t.dataset.color;
1358  updateAvatar();
1359});
1360
1361// ============ HAIR COLOR ============
1362document.getElementById('hairColorGrid').addEventListener('click',function(e){
1363  let t=e.target.closest('.skin-tone');
1364  if(!t)return;
1365  this.querySelectorAll('.skin-tone').forEach(s=>s.classList.remove('selected'));
1366  t.classList.add('selected');
1367  charData.hairColor=t.dataset.color;
1368  updateAvatar();
1369});
1370
1371// ============ HAIR STYLE ============
1372document.getElementById('hairStyleGrid').addEventListener('click',function(e){
1373  let opt=e.target.closest('.select-option');
1374  if(!opt)return;
1375  document.getElementById('hairStyleGrid').querySelectorAll('.select-option').forEach(o=>o.classList.remove('selected'));
1376  opt.classList.add('selected');
1377  charData.hairStyle=opt.dataset.value;
1378  updateAvatar();
1379});
1380
1381// ============ AVATAR UPDATE ============
1382function updateAvatar(){
1383  // Main preview
1384  applyAvatar('avSkin','avHair','avClothing',charData);
1385  // Review avatar
1386  applyAvatar('revSkin','revHair','revClothing',charData);
1387}
1388function applyAvatar(skinId,hairId,clothId,d){
1389  let skin=document.getElementById(skinId);
1390  let hair=document.getElementById(hairId);
1391  let cloth=document.getElementById(clothId);
1392  if(skin)skin.style.background=d.skinTone;
1393  if(hair){
1394    hair.className='avatar-hair hair-'+d.hairStyle;
1395    hair.style.color=d.hairColor;
1396    hair.style.background='';
1397    // For styles that use background directly
1398    let bgStyles=['fade','afro','buzz','curly','straight'];
1399    if(bgStyles.includes(d.hairStyle)){
1400      hair.style.background=d.hairColor;
1401    }
1402  }
1403  if(cloth){
1404    cloth.className='avatar-clothing clothing-'+d.clothingStyle;
1405  }
1406}
1407
1408// ============ NAME COUNTER ============
1409document.getElementById('charName').addEventListener('input',function(){
1410  document.getElementById('nameCount').textContent=this.value.length;
1411});
1412
1413// ============ SPORT DETAILS ============
1414const sportPositions={
1415  'Basketball':['PG (Point Guard)','SG (Shooting Guard)','SF (Small Forward)','PF (Power Forward)','C (Center)'],
1416  'Football':['QB','RB','WR','TE','OL','DL','LB','CB','S','K'],
1417  'Soccer':['GK','CB','LB','RB','CDM','CM','CAM','LW','RW','ST'],
1418  'Track & Field':['Sprints (100m/200m)','Middle Distance (400m/800m)','Long Distance','Hurdles','Jumps','Throws','Relay']
1419};
1420function updateSportDetails(){
1421  let sportActs=charData.activities.filter(a=>sportPositions[a]);
1422  let detail=document.getElementById('sportDetails');
1423  if(sportActs.length>0){
1424    detail.style.display='block';
1425    let sel=document.getElementById('sportPosition');
1426    sel.innerHTML='<option value="">— Select position —</option>';
1427    sportActs.forEach(sport=>{
1428      sportPositions[sport].forEach(pos=>{
1429        sel.innerHTML+='<option value="'+sport+': '+pos+'">'+sport+' — '+pos+'</option>';
1430      });
1431    });
1432  }else{
1433    detail.style.display='none';
1434  }
1435}
1436document.getElementById('sportPosition').addEventListener('change',function(){
1437  charData.sportPosition=this.value;
1438});
1439
1440// ============ POPULATE REVIEW ============
1441function populateReview(){
1442  // Get custom pronouns if needed
1443  if(charData.pronouns==='Custom'){
1444    charData.pronouns=document.getElementById('customPronoun').value||'Custom';
1445  }
1446  document.getElementById('revName').textContent=charData.name;
1447  document.getElementById('revAge').textContent=charData.age;
1448  document.getElementById('revGender').textContent=charData.gender||'Not specified';
1449  document.getElementById('revPronouns').textContent=charData.pronouns||'Not specified';
1450  document.getElementById('revBuild').textContent=charData.build;
1451  document.getElementById('revFace').textContent=charData.faceShape;
1452  document.getElementById('revTrauma1').textContent=charData.primaryTrauma;
1453  document.getElementById('revTrauma2').textContent=charData.secondaryTrauma||'None';
1454  document.getElementById('revCoping').textContent=charData.coping.join(', ')||'None selected';
1455  document.getElementById('revTraits').textContent=charData.traits.join(', ')||'None selected';
1456  document.getElementById('revEmotion').textContent=charData.emotion;
1457  document.getElementById('revSchool').textContent=charData.school;
1458  let actText=charData.activities.join(', ');
1459  if(charData.sportPosition)actText+=' ('+charData.sportPosition+')';
1460  if(charData.sportLevel)actText+=' — '+charData.sportLevel;
1461  document.getElementById('revActivities').textContent=actText||'None';
1462  let housing='';
1463  if(charData.building)housing=charData.building;
1464  if(charData.floor)housing+=', '+charData.floor+' Floor';
1465  housing+=', '+charData.roommate;
1466  document.getElementById('revHousing').textContent=housing;
1467  updateAvatar();
1468}
1469
1470// ============ WEBHOOK URL ============
1471const WEBHOOK_URL = '__WEBHOOK_URL__';
1472
1473// ============ CREATE CHARACTER ============
1474async function createCharacter(){
1475  let email=document.getElementById('charEmail').value.trim();
1476  if(!email||!email.includes('@')){alert('Please enter a valid email address.');return;}
1477  let id='HR-'+(Math.floor(Math.random()*9000)+1000);
1478  charData.id=id;
1479  charData.createdAt=new Date().toISOString();
1480  charData.email=email;
1481  // Save to localStorage
1482  let chars=JSON.parse(localStorage.getItem('hr_characters')||'[]');
1483  chars.push(JSON.parse(JSON.stringify(charData)));
1484  localStorage.setItem('hr_characters',JSON.stringify(chars));
1485  localStorage.setItem('hr_my_character',JSON.stringify(charData));
1486  // Send to webhook
1487  if(WEBHOOK_URL && WEBHOOK_URL !== '__WEBHOOK_URL__'){
1488    try{
1489      await fetch(WEBHOOK_URL,{
1490        method:'POST',
1491        headers:{'Content-Type':'application/json'},
1492        body:JSON.stringify({type:'character',email:email,character:charData})
1493      });
1494    }catch(e){console.log('Submission logged locally');}
1495  }
1496  // Show success
1497  let wizard=document.querySelector('.wizard-container');
1498  wizard.innerHTML='<div style="text-align:center;padding:60px 20px"><p style="font-size:3rem;margin-bottom:15px">🏠</p><h2 style="color:var(--gold);margin-bottom:10px">Welcome to Haven Ridge, '+charData.name+'</h2><p style="color:var(--text-dim);margin-bottom:5px">Citizen ID: '+id+'</p><p style="color:var(--text-dim);font-size:.85rem;margin-bottom:20px">Your story begins now. Our team reviews all characters — you may appear in an upcoming episode.</p><div style="padding:15px;background:rgba(123,45,139,0.15);border:1px solid rgba(123,45,139,0.3);border-radius:10px;margin-bottom:20px"><p style="font-size:.85rem;color:var(--purple-light);margin-bottom:10px">Want your character to get <strong>speaking lines and a real role</strong> in the story?</p><a href="https://buy.stripe.com/4gM9AS5LPao7eUWgJmbsc04" target="_blank" class="btn btn-orange" style="margin-right:8px">Upgrade to Storyteller →</a><a href="https://buy.stripe.com/aFa5kC2zD2VFfZ0fFibsc05" target="_blank" class="btn btn-gold">Become an Architect →</a></div><button class="btn btn-primary" onclick="location.reload()">View Your Profile</button></div>';
1499  updateCitizenCount();
1500  loadShowcase();
1501  loadProfile();
1502}
1503
1504// ============ PROFILE ============
1505function loadProfile(){
1506  let myChar=JSON.parse(localStorage.getItem('hr_my_character'));
1507  if(!myChar){
1508    document.getElementById('profileEmpty').style.display='block';
1509    document.getElementById('profileCard').style.display='none';
1510    return;
1511  }
1512  document.getElementById('profileEmpty').style.display='none';
1513  document.getElementById('profileCard').style.display='block';
1514  document.getElementById('profileId').textContent=myChar.id||'HR-????';
1515  document.getElementById('profileName').textContent=myChar.name;
1516  document.getElementById('profileMeta').textContent=myChar.age+' · '+myChar.gender+' · '+(myChar.pronouns||'');
1517  applyAvatar('profSkin','profHair','profClothing',myChar);
1518  // Days calc
1519  if(myChar.createdAt){
1520    let days=Math.max(1,Math.floor((Date.now()-new Date(myChar.createdAt).getTime())/(86400000))+1);
1521    document.getElementById('statDays').textContent=days;
1522  }
1523}
1524function editCharacter(){
1525  localStorage.removeItem('hr_my_character');
1526  location.reload();
1527}
1528function deleteCharacter(){
1529  if(!confirm('Are you sure? This will permanently delete your character.'))return;
1530  let myChar=JSON.parse(localStorage.getItem('hr_my_character'));
1531  if(myChar){
1532    let chars=JSON.parse(localStorage.getItem('hr_characters')||'[]');
1533    chars=chars.filter(c=>c.id!==myChar.id);
1534    localStorage.setItem('hr_characters',JSON.stringify(chars));
1535  }
1536  localStorage.removeItem('hr_my_character');
1537  location.reload();
1538}
1539
1540// ============ SHOWCASE ============
1541function loadShowcase(){
1542  let chars=JSON.parse(localStorage.getItem('hr_characters')||'[]');
1543  let section=document.getElementById('showcaseSection');
1544  let grid=document.getElementById('showcaseGrid');
1545  if(chars.length===0){section.style.display='none';return;}
1546  section.style.display='block';
1547  grid.innerHTML='';
1548  chars.forEach(c=>{
1549    let card=document.createElement('div');
1550    card.className='showcase-card';
1551    let hairClass='hair-'+(c.hairStyle||'fade');
1552    let clothClass='clothing-'+(c.clothingStyle||'streetwear');
1553    // Determine if hair needs bg color directly
1554    let bgStyles=['fade','afro','buzz','curly','straight'];
1555    let hairBg=bgStyles.includes(c.hairStyle)?'background:'+c.hairColor:'';
1556    card.innerHTML='<div class="mini-avatar"><div class="avatar-skin" style="position:absolute;inset:0;background:'+(c.skinTone||'#C68642')+'"></div><div class="avatar-hair '+hairClass+'" style="color:'+(c.hairColor||'#1a1a1a')+';'+hairBg+'"></div><div class="avatar-eyes" style="position:absolute;top:40%;left:50%;transform:translateX(-50%);display:flex;gap:10px"><div class="avatar-eye" style="width:5px;height:5px;background:rgba(0,0,0,0.7);border-radius:50%"></div><div class="avatar-eye" style="width:5px;height:5px;background:rgba(0,0,0,0.7);border-radius:50%"></div></div><div class="avatar-clothing '+clothClass+'" style="position:absolute;bottom:0;left:0;right:0;height:30%"></div></div><h4 style="font-size:.9rem;margin-bottom:3px">'+(c.name||'Unknown')+'</h4><p style="font-size:.75rem;color:var(--text-dim)">'+(c.age||'')+' · '+(c.emotion||'')+'</p><div style="margin-top:8px;display:flex;gap:4px;flex-wrap:wrap;justify-content:center">'+(c.traits||[]).map(t=>'<span style="font-size:.65rem;padding:2px 6px;background:rgba(123,45,139,0.2);border-radius:10px;color:var(--purple-light)">'+t+'</span>').join('')+'</div>';
1557    grid.appendChild(card);
1558  });
1559}
1560
1561// ============ SUBMISSIONS ============
1562function updateWordCount(){
1563  let text=document.getElementById('subContent').value;
1564  let words=text.trim()?text.trim().split(/\s+/).length:0;
1565  document.getElementById('wordCount').textContent=words;
1566}
1567async function submitStory(){
1568  let email=document.getElementById('subEmail').value.trim();
1569  let tier=document.getElementById('subTier').value;
1570  let citizenId=document.getElementById('subCitizenId').value.trim();
1571  let title=document.getElementById('subTitle').value.trim();
1572  let loc=document.getElementById('subLocation').value;
1573  let content=document.getElementById('subContent').value.trim();
1574  let soundtrack=document.getElementById('subSoundtrack').value.trim();
1575  if(!email||!email.includes('@')){alert('Please enter your email address.');return;}
1576  if(!tier){alert('Please select your subscription tier.');return;}
1577  if(!title||!loc||!content){alert('Please fill in all required fields.');return;}
1578  let words=content.trim()?content.trim().split(/\s+/).length:0;
1579  if(words<50){alert('Your scene needs at least 50 words. Be real. Be raw. Give us something to work with.');return;}
1580  // Send to webhook
1581  if(WEBHOOK_URL && WEBHOOK_URL !== '__WEBHOOK_URL__'){
1582    try{
1583      await fetch(WEBHOOK_URL,{
1584        method:'POST',
1585        headers:{'Content-Type':'application/json'},
1586        body:JSON.stringify({type:'story',email:email,tier:tier,citizen_id:citizenId,scene_title:title,location:loc,soundtrack:soundtrack,content:content,word_count:words})
1587      });
1588    }catch(e){console.log('Submission logged locally');}
1589  }
1590  alert('Scene submitted. ✅\n\nThe Haven Ridge editorial team reviews all submissions. The best ones get woven into the next episode. Watch for the bi-weekly drop.');
1591  document.getElementById('subEmail').value='';
1592  document.getElementById('subTier').value='';
1593  document.getElementById('subCitizenId').value='';
1594  document.getElementById('subTitle').value='';
1595  document.getElementById('subLocation').value='';
1596  document.getElementById('subContent').value='';
1597  document.getElementById('subSoundtrack').value='';
1598  document.getElementById('wordCount').textContent='0';
1599}
1600
1601// ============ FORUM ============
1602document.querySelectorAll('.forum-cat').forEach(cat=>{
1603  cat.addEventListener('click',function(){
1604    document.querySelectorAll('.forum-cat').forEach(c=>c.classList.remove('active'));
1605    this.classList.add('active');
1606    let filter=this.dataset.cat;
1607    document.querySelectorAll('.forum-thread').forEach(t=>{
1608      t.style.display=(filter==='all'||t.dataset.cat===filter)?'flex':'none';
1609    });
1610  });
1611});
1612function startThread(){
1613  alert('Thread creation coming soon! Forum will be fully interactive in the next update.');
1614}
1615
1616// ============ SCROLL ANIMATIONS ============
1617function handleScrollAnimations(){
1618  document.querySelectorAll('.fade-in').forEach(el=>{
1619    let rect=el.getBoundingClientRect();
1620    if(rect.top<window.innerHeight-50){
1621      el.classList.add('visible');
1622    }
1623  });
1624}
1625window.addEventListener('scroll',handleScrollAnimations);
1626handleScrollAnimations();
1627
1628// ============ NAV HIGHLIGHT ============
1629window.addEventListener('scroll',function(){
1630  let scrollPos=window.scrollY+100;
1631  document.querySelectorAll('section[id]').forEach(sec=>{
1632    if(sec.offsetTop<=scrollPos&&sec.offsetTop+sec.offsetHeight>scrollPos){
1633      let id=sec.getAttribute('id');
1634      document.querySelectorAll('.nav-links a.nav-link').forEach(a=>{
1635        a.classList.toggle('active',a.getAttribute('href')==='#'+id);
1636      });
1637    }
1638  });
1639});
1640
1641// ============ EPISODE 1 MODAL ============
1642function openEpisode1(){
1643  document.getElementById('ep1Modal').style.display='block';
1644  document.body.style.overflow='hidden';
1645}
1646function closeEpisode1(){
1647  document.getElementById('ep1Modal').style.display='none';
1648  document.body.style.overflow='';
1649}
1650
1651// ============ INIT ============
1652loadProfile();
1653loadShowcase();
1654updateAvatar();
1655</script>
1655
1656</body>
1657</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.