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> 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 & 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 & 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 & 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.