slack status without the slack status.zzstoatzz.io/
quickslice

Simplify picker layout and styling

Changed files
+25 -141
templates
+25 -141
templates/status.html
··· 200 200 </div> 201 201 <button type="button" class="emoji-picker-close" id="emoji-picker-close" aria-label="close emoji picker">โœ•</button> 202 202 </div> 203 - <div class="emoji-picker-preview"> 204 - <div class="emoji-preview-block"> 205 - <span class="emoji-preview-label">current</span> 206 - <div class="emoji-preview-emoji" id="emoji-preview-current"> 207 - {% if let Some(current) = current_status.as_ref() %} 208 - {% if current.status.starts_with("custom:") %} 209 - {% let emoji_name = current.status.strip_prefix("custom:").unwrap() %} 210 - <img src="/emojis/{{emoji_name}}.png" alt="{{emoji_name}}" title="{{emoji_name}}" 211 - onerror="this.onerror=null; this.src='/emojis/{{emoji_name}}.gif';"> 212 - {% else %} 213 - <span title="{{ current.status }}">{{ current.status }}</span> 214 - {% endif %} 215 - {% else %} 216 - <span title="happy">๐Ÿ˜Š</span> 217 - {% endif %} 218 - </div> 219 - </div> 220 - <div class="emoji-preview-block"> 221 - <span class="emoji-preview-label">next</span> 222 - <div class="emoji-preview-emoji" id="emoji-preview-next"> 223 - {% if let Some(current) = current_status.as_ref() %} 224 - {% if current.status.starts_with("custom:") %} 225 - {% let emoji_name = current.status.strip_prefix("custom:").unwrap() %} 226 - <img src="/emojis/{{emoji_name}}.png" alt="{{emoji_name}}" title="{{emoji_name}}" 227 - onerror="this.onerror=null; this.src='/emojis/{{emoji_name}}.gif';"> 228 - {% else %} 229 - <span title="{{ current.status }}">{{ current.status }}</span> 230 - {% endif %} 231 - {% else %} 232 - <span title="happy">๐Ÿ˜Š</span> 233 - {% endif %} 234 - </div> 235 - </div> 236 - </div> 237 203 <div class="emoji-search-container"> 238 204 <input type="text" 239 205 id="emoji-search" ··· 1115 1081 } 1116 1082 1117 1083 .emoji-picker { 1118 - width: min(720px, 100%); 1119 - max-height: min(90vh, 720px); 1084 + width: min(960px, 94vw); 1085 + height: min(90vh, 820px); 1120 1086 background: var(--bg-secondary); 1121 1087 border: 1px solid var(--border-color); 1122 1088 border-radius: clamp(var(--radius), 2vw, 24px); 1123 1089 box-shadow: 0 32px 80px rgba(0, 0, 0, 0.45); 1124 1090 display: flex; 1125 1091 flex-direction: column; 1126 - gap: 1rem; 1127 - padding: clamp(1.25rem, 5vw, 2rem); 1092 + gap: 1.25rem; 1093 + padding: clamp(1.25rem, 5vw, 2.5rem); 1128 1094 overflow: hidden; 1129 1095 } 1096 + 1130 1097 1131 1098 .emoji-picker-header { 1132 1099 display: flex; ··· 1169 1136 outline: none; 1170 1137 } 1171 1138 1172 - .emoji-picker-preview { 1173 - display: flex; 1174 - gap: 1rem; 1175 - background: var(--bg-primary); 1176 - border-radius: var(--radius); 1177 - border: 1px solid var(--border-color); 1178 - padding: 1rem; 1179 - } 1180 - 1181 - .emoji-preview-block { 1182 - flex: 1; 1183 - display: flex; 1184 - flex-direction: column; 1185 - align-items: center; 1186 - gap: 0.5rem; 1187 - } 1188 - 1189 - .emoji-preview-label { 1190 - font-size: 0.75rem; 1191 - text-transform: uppercase; 1192 - letter-spacing: 0.08em; 1193 - color: var(--text-tertiary); 1194 - } 1195 - 1196 - .emoji-preview-emoji { 1197 - width: clamp(3.25rem, 16vw, 4.5rem); 1198 - height: clamp(3.25rem, 16vw, 4.5rem); 1199 - display: flex; 1200 - align-items: center; 1201 - justify-content: center; 1202 - font-size: clamp(2rem, 10vw, 3rem); 1203 - border-radius: var(--radius); 1204 - background: var(--bg-secondary); 1205 - border: 1px solid rgba(255, 255, 255, 0.05); 1206 - overflow: hidden; 1207 - } 1208 - 1209 - .emoji-preview-emoji img { 1210 - width: 100%; 1211 - height: 100%; 1212 - object-fit: contain; 1213 - } 1214 - 1215 - .emoji-preview-emoji span { 1216 - display: block; 1217 - } 1218 - 1219 1139 .emoji-search-container { 1220 1140 margin: 0; 1221 1141 } ··· 1251 1171 1252 1172 .emoji-categories { 1253 1173 display: flex; 1254 - gap: 0.5rem; 1174 + gap: 0.75rem; 1255 1175 overflow-x: auto; 1256 1176 padding-bottom: 0.5rem; 1257 1177 border-bottom: 1px solid rgba(255, 255, 255, 0.06); ··· 1289 1209 .emoji-grid { 1290 1210 flex: 1; 1291 1211 display: grid; 1292 - grid-template-columns: repeat(auto-fill, minmax(56px, 1fr)); 1293 - gap: 0.5rem; 1212 + grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); 1213 + gap: 0.75rem; 1294 1214 padding-right: 0.25rem; 1295 1215 overflow-y: auto; 1296 1216 } 1297 1217 1298 1218 .emoji-option { 1299 - background: var(--bg-primary); 1300 - border: 1px solid transparent; 1301 - font-size: 2rem; 1219 + background: transparent; 1220 + border: none; 1221 + font-size: 2.4rem; 1302 1222 cursor: pointer; 1303 - border-radius: 16px; 1304 - transition: transform 0.15s ease, border-color 0.2s ease, background 0.2s ease; 1223 + transition: transform 0.15s ease; 1305 1224 display: flex; 1306 1225 align-items: center; 1307 1226 justify-content: center; 1308 1227 width: 100%; 1309 1228 aspect-ratio: 1; 1310 - position: relative; 1229 + } 1230 + 1231 + .emoji-option:hover { 1232 + transform: translateY(-3px) scale(1.05); 1311 1233 } 1312 1234 1313 - .emoji-option:hover, 1314 1235 .emoji-option:focus-visible { 1315 - background: var(--bg-tertiary); 1316 - border-color: var(--accent); 1317 - transform: translateY(-2px); 1318 - outline: none; 1236 + outline: 2px solid var(--accent); 1237 + outline-offset: 6px; 1238 + border-radius: 16px; 1319 1239 } 1320 1240 1321 1241 .emoji-option.custom-emoji img { 1322 - width: 70%; 1323 - height: 70%; 1242 + width: 75%; 1243 + height: 75%; 1324 1244 object-fit: contain; 1325 1245 } 1326 1246 1327 - .emoji-option.custom-emoji::after { 1328 - content: ''; 1329 - position: absolute; 1330 - inset: 8%; 1331 - border-radius: 12px; 1332 - pointer-events: none; 1333 - } 1334 - 1335 1247 @media (max-width: 640px) { 1336 1248 .emoji-picker-overlay { 1337 1249 padding: 0; ··· 1343 1255 height: 100%; 1344 1256 max-height: none; 1345 1257 border-radius: 0; 1346 - padding: 1.25rem 1rem 1rem; 1347 - gap: 0.75rem; 1348 - } 1349 - 1350 - .emoji-picker-preview { 1351 - padding: 0.75rem; 1258 + padding: 1.5rem 1rem; 1259 + gap: 1rem; 1352 1260 } 1353 1261 1354 1262 .emoji-grid { 1355 - grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); 1263 + grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); 1264 + gap: 0.5rem; 1356 1265 } 1357 1266 } 1358 1267 ··· 2142 2051 const emojiGrid = document.getElementById('emoji-grid'); 2143 2052 const selectedEmoji = document.getElementById('selected-emoji'); 2144 2053 const statusInput = document.getElementById('status-input'); 2145 - const emojiPreviewCurrent = document.getElementById('emoji-preview-current'); 2146 - const emojiPreviewNext = document.getElementById('emoji-preview-next'); 2147 2054 let lastFocusBeforeEmojiPicker = null; 2148 2055 2149 2056 // Clear time picker ··· 2153 2060 const expiresSelect = document.getElementById('expires_in'); 2154 2061 2155 2062 const isEmojiPickerOpen = () => emojiPickerOverlay && !emojiPickerOverlay.classList.contains('hidden'); 2156 - 2157 - const syncPreviewWithSelection = () => { 2158 - if (emojiPreviewNext && selectedEmoji) { 2159 - emojiPreviewNext.innerHTML = selectedEmoji.innerHTML; 2160 - } 2161 - }; 2162 - 2163 - syncPreviewWithSelection(); 2164 2063 2165 2064 const openEmojiPicker = () => { 2166 2065 if (!emojiPickerOverlay || !emojiPicker) return; ··· 2181 2080 if (emojiSearch) emojiSearch.focus(); 2182 2081 }, 60); 2183 2082 } 2184 - 2185 - if (emojiPreviewCurrent) { 2186 - const currentDisplay = document.querySelector('.current-status .status-emoji'); 2187 - if (currentDisplay) { 2188 - emojiPreviewCurrent.innerHTML = currentDisplay.innerHTML; 2189 - } else if (selectedEmoji) { 2190 - emojiPreviewCurrent.innerHTML = selectedEmoji.innerHTML; 2191 - } 2192 - } 2193 - 2194 - syncPreviewWithSelection(); 2195 2083 2196 2084 loadCustomEmojis().then(() => { 2197 2085 loadEmojiCategory('frequent'); ··· 2314 2202 } 2315 2203 2316 2204 statusInput.value = emoji; 2317 - syncPreviewWithSelection(); 2318 2205 closeEmojiPicker(); 2319 2206 checkForChanges(); 2320 2207 }); ··· 2342 2229 // Display the image in the selected emoji area 2343 2230 selectedEmoji.innerHTML = `<img src="${img.src}" alt="${img.alt}" style="width: 100%; height: 100%; object-fit: contain;">`; 2344 2231 statusInput.value = emojiValue; 2345 - syncPreviewWithSelection(); 2346 2232 closeEmojiPicker(); 2347 2233 checkForChanges(); 2348 2234 }); ··· 2361 2247 const emoji = e.target.getAttribute('data-emoji'); 2362 2248 selectedEmoji.textContent = emoji; 2363 2249 statusInput.value = emoji; 2364 - syncPreviewWithSelection(); 2365 2250 closeEmojiPicker(); 2366 2251 checkForChanges(); 2367 2252 }); ··· 2595 2480 } 2596 2481 2597 2482 statusInput.value = emojiValue; 2598 - syncPreviewWithSelection(); 2599 2483 closeEmojiPicker(); 2600 2484 checkForChanges(); 2601 2485 // Clear search when emoji is selected