|
129
|
1 <!DOCTYPE html>
|
|
|
2 <html lang="en">
|
|
|
3 <head>
|
|
|
4 <meta charset="UTF-8">
|
|
|
5 <title>Talk!</title>
|
|
|
6 <meta charset="UTF-8">
|
|
|
7 <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
8 <link rel="icon" type="image/svg+xml" href="/public/epi_all_colors.svg">
|
|
|
9
|
|
|
10 <link rel="preload" href="/public/fonts/Roboto-Regular.ttf" as="font" crossorigin>
|
|
|
11 <link rel="preload" href="/public/fonts/Roboto-Thin.ttf"as="font" crossorigin>
|
|
|
12
|
|
|
13 <!-- <link rel="preload" href="/public/fonts/atkinson-regular.woff" as="font" type="font/woff" crossorigin> -->
|
|
|
14 <!-- <link rel="preload" href="/public/fonts/atkinson-bold.woff" as="font" type="font/woff" crossorigin> -->
|
|
|
15
|
|
|
16 <!-- <link rel="preload" href="/public/fonts/more-sugar.extras.otf" as="font" type="font/otf" crossorigin> -->
|
|
|
17 <link rel="preload" href="/public/fonts/more-sugar.regular.otf" as="font" type="font/otf" crossorigin>
|
|
|
18 <link rel="preload" href="/public/fonts/more-sugar.thin.otf" as="font" type="font/otf" crossorigin>
|
|
|
19
|
|
|
20 <link rel="preload" href="/base.css" as="style" />
|
|
|
21 <link rel="stylesheet" href="/base.css" />
|
|
|
22
|
|
|
23
|
|
|
24 <style>
|
|
|
25 body { font-family: sans-serif; padding: 20px; }
|
|
|
26 #messages { height: 200px; border: 1px solid #ccc; overflow-y: scroll; margin-bottom: 10px; padding: 10px; }
|
|
|
27 #chat { display: flex; gap: 10px; }
|
|
|
28 input { flex-grow: 1; }
|
|
|
29 </style>
|
|
|
30 </head>
|
|
|
31 <body>
|
|
|
32 <style>
|
|
|
33 :root {
|
|
|
34 --header-background: var(--white);
|
|
|
35 --header-color: rgb(var(--black));
|
|
|
36 --link-hover-accent: var(--awesome);
|
|
|
37 }
|
|
|
38
|
|
|
39 /* Fixed icon in top left corner */
|
|
|
40 #themeToggle {
|
|
|
41 position: fixed;
|
|
|
42 top: 20px;
|
|
|
43 left: 20px;
|
|
|
44 background: var(--header-background);
|
|
|
45 display: flex;
|
|
|
46 align-items: center;
|
|
|
47 border-radius: 50%;
|
|
|
48 cursor: pointer;
|
|
|
49 z-index: 1000;
|
|
|
50 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
51 transition: transform 0.2s ease;
|
|
|
52 }
|
|
|
53
|
|
|
54 #themeToggle:hover {
|
|
|
55 transform: scale(1.05);
|
|
|
56 }
|
|
|
57
|
|
|
58 /* Professional header */
|
|
|
59 header {
|
|
|
60 margin: auto;
|
|
|
61 padding: 1.5em 1em;
|
|
|
62 font-family: "More", sans-serif;
|
|
|
63 box-shadow: 0 2px 8px rgba(var(--black), 5%);
|
|
|
64 width: 720px;
|
|
|
65 max-width: calc(100% - 2em);
|
|
|
66 text-align: center;
|
|
|
67 }
|
|
|
68
|
|
|
69 header h1 {
|
|
|
70 margin: 0;
|
|
|
71 font-size: 1.8em;
|
|
|
72 font-weight: 700;
|
|
|
73 letter-spacing: -0.5px;
|
|
|
74 }
|
|
|
75
|
|
|
76 header h1 a {
|
|
|
77 text-decoration: none;
|
|
|
78 color: var(--header-color);
|
|
|
79 }
|
|
|
80
|
|
|
81 header h1 a::before {
|
|
|
82 display: none;
|
|
|
83 }
|
|
|
84
|
|
|
85 /* Mobile responsiveness */
|
|
|
86 @media (max-width: 720px) {
|
|
|
87 #themeToggle {
|
|
|
88 top: 15px;
|
|
|
89 left: 15px;
|
|
|
90 }
|
|
|
91
|
|
|
92 header {
|
|
|
93 padding: 1em;
|
|
|
94 }
|
|
|
95
|
|
|
96 header h1 {
|
|
|
97 font-size: 1.5em;
|
|
|
98 }
|
|
|
99 }
|
|
|
100
|
|
|
101 @media (max-width: 480px) {
|
|
|
102 #themeToggle {
|
|
|
103 top: 10px;
|
|
|
104 left: 10px;
|
|
|
105 }
|
|
|
106
|
|
|
107 #themeToggle img {
|
|
|
108 height: 40px;
|
|
|
109 width: 40px;
|
|
|
110 }
|
|
|
111
|
|
|
112 header h1 {
|
|
|
113 font-size: 1.3em;
|
|
|
114 }
|
|
|
115 }
|
|
|
116
|
|
|
117 #logo {
|
|
|
118 width: 300px;
|
|
|
119 }
|
|
|
120
|
|
|
121 /* 1. DEFINE THE DEFAULTS (Light Mode) */
|
|
|
122 :root {
|
|
|
123 --logo-invert: invert(0);
|
|
|
124 --epi-grayscale: grayscale(0) brightness(1);
|
|
|
125 }
|
|
|
126
|
|
|
127 /* 2. MANUAL DARK OVERRIDE */
|
|
|
128 html.dark {
|
|
|
129 --logo-invert: invert(1);
|
|
|
130 --epi-grayscale: grayscale(1);
|
|
|
131 }
|
|
|
132
|
|
|
133 /* 3. MANUAL LIGHT OVERRIDE */
|
|
|
134 html.light-mode {
|
|
|
135 --logo-invert: invert(0);
|
|
|
136 --epi-grayscale: brightness(2.9) grayscale(1);
|
|
|
137 }
|
|
|
138
|
|
|
139 /* 4. SYSTEM PREFERENCE */
|
|
|
140 @media (prefers-color-scheme: dark) {
|
|
|
141 :root:not(.light-mode) {
|
|
|
142 --logo-invert: invert(1);
|
|
|
143 }
|
|
|
144 }
|
|
|
145
|
|
|
146 /* 5. APPLY TO ELEMENTS */
|
|
|
147 #logo {
|
|
|
148 -webkit-filter: var(--logo-invert);
|
|
|
149 filter: var(--logo-invert);
|
|
|
150 transition: filter 0.3s ease;
|
|
|
151 }
|
|
|
152
|
|
|
153 .epi-logo {
|
|
|
154 -webkit-filter: var(--epi-grayscale);
|
|
|
155 filter: var(--epi-grayscale);
|
|
|
156 transition: filter 0.3s ease;
|
|
|
157 }
|
|
|
158 </style>
|
|
|
159
|
|
|
160 <div id="themeToggle">
|
|
|
161 <img id="epiChan" class="epi-logo" aria-label="Toggle dark mode" src="/public/epi_all_colors.svg" height="50" width="50">
|
|
|
162 </div>
|
|
|
163
|
|
|
164 <header>
|
|
|
165 <h1><a href="/">MrJuneJune</a></h1>
|
|
|
166 </header>
|
|
|
167 <script src="/index.js"></script>
|
|
|
168
|
|
|
169
|
|
|
170 <h1>Talks</h1>
|
|
|
171
|
|
|
172 <div id="messages"></div>
|
|
|
173
|
|
|
174 <div id="chat">
|
|
|
175 <input type="text" id="messageInput" placeholder="Type a message...">
|
|
|
176 <button id="sendBtn">Send</button>
|
|
|
177 </div>
|
|
|
178 <div style="display: flex; align-items: center; justify-content: center; margin: 30px 0px;">
|
|
|
179 <small>© 2026 June Park</small>
|
|
|
180 </div>
|
|
|
181
|
|
|
182 <script>
|
|
|
183 const ws = new WebSocket('ws://localhost:6969/echo');
|
|
|
184 const messagesDiv = document.getElementById('messages');
|
|
|
185
|
|
|
186 ws.onopen = () => {
|
|
|
187 console.log('Connected!');
|
|
|
188 appendMessage('System: Connected to server');
|
|
|
189 };
|
|
|
190
|
|
|
191 ws.onmessage = (event) => {
|
|
|
192 console.log('Received:', event.data);
|
|
|
193 appendMessage('Server: ' + event.data);
|
|
|
194 };
|
|
|
195
|
|
|
196 // Function to send message
|
|
|
197 sendBtn.onclick = () => {
|
|
|
198 const message = messageInput.value;
|
|
|
199 if (message) {
|
|
|
200 ws.send(message);
|
|
|
201 appendMessage('You: ' + message);
|
|
|
202 messageInput.value = ''; // Clear input
|
|
|
203 }
|
|
|
204 };
|
|
|
205
|
|
|
206 // Helper to show messages on screen
|
|
|
207 function appendMessage(text) {
|
|
|
208 const msg = document.createElement('p');
|
|
|
209 msg.textContent = text;
|
|
|
210 messagesDiv.appendChild(msg);
|
|
|
211 messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
|
|
212 }
|
|
|
213
|
|
|
214 messageInput.addEventListener('keydown', (event) => {
|
|
|
215 if (event.key === 'Enter' && !event.shiftKey)
|
|
|
216 {
|
|
|
217 event.preventDefault();
|
|
|
218 sendBtn.click();
|
|
|
219 }
|
|
|
220 });
|
|
|
221 </script>
|
|
|
222 </body>
|
|
|
223 </html>
|