Lexicon-driven ATProto AppView in Gleam — port of HappyView
0

Configure Feed

Select the types of activity you want to include in your feed.

gleamview / priv / public / styles.css
9.6 kB 583 lines
1:root { 2 color-scheme: dark light; 3 --bg: #0a0f0e; 4 --bg-elev: #121a18; 5 --bg-card: #15201d; 6 --border: #243330; 7 --border-strong: #35524a; 8 --text: #e8f0ed; 9 --muted: #8aa399; 10 --accent: #5eead4; 11 --accent-dim: #2dd4bf33; 12 --accent-text: #042f2e; 13 --warn: #fbbf24; 14 --danger: #f87171; 15 --ok: #4ade80; 16 --shadow: 0 18px 50px #00000066; 17 --radius: 14px; 18 --font: "Segoe UI", ui-sans-serif, system-ui, -apple-system, sans-serif; 19 --mono: "JetBrains Mono", "SF Mono", ui-monospace, Menlo, Consolas, monospace; 20 --max: 52rem; 21} 22 23@media (prefers-color-scheme: light) { 24 :root { 25 --bg: #f4f7f6; 26 --bg-elev: #ffffff; 27 --bg-card: #ffffff; 28 --border: #d5e0dc; 29 --border-strong: #a8c0b8; 30 --text: #10211c; 31 --muted: #5b726a; 32 --accent: #0f766e; 33 --accent-dim: #14b8a633; 34 --accent-text: #ecfdf5; 35 --shadow: 0 12px 40px #0f172a14; 36 } 37} 38 39* { 40 box-sizing: border-box; 41} 42 43html, 44body { 45 margin: 0; 46 min-height: 100%; 47 background: var(--bg); 48 color: var(--text); 49 font-family: var(--font); 50 line-height: 1.5; 51} 52 53body { 54 position: relative; 55 overflow-x: hidden; 56} 57 58a { 59 color: var(--accent); 60 text-decoration: none; 61} 62 63a:hover { 64 text-decoration: underline; 65} 66 67code, 68pre, 69.mono { 70 font-family: var(--mono); 71} 72 73code { 74 font-size: 0.88em; 75 background: var(--accent-dim); 76 color: var(--accent); 77 padding: 0.1em 0.35em; 78 border-radius: 6px; 79} 80 81.bg-glow { 82 pointer-events: none; 83 position: fixed; 84 inset: -20% -10% auto; 85 height: 55vh; 86 background: 87 radial-gradient(ellipse 50% 60% at 20% 20%, #14b8a622, transparent 60%), 88 radial-gradient(ellipse 40% 50% at 80% 10%, #fbbf2414, transparent 55%); 89 z-index: 0; 90} 91 92.shell { 93 position: relative; 94 z-index: 1; 95 max-width: var(--max); 96 margin: 0 auto; 97 padding: 1.5rem 1.15rem 3rem; 98} 99 100.top { 101 display: flex; 102 align-items: flex-start; 103 justify-content: space-between; 104 gap: 1rem; 105 margin-bottom: 1.25rem; 106} 107 108.brand { 109 display: flex; 110 gap: 0.85rem; 111 align-items: center; 112} 113 114.logo { 115 width: 2.6rem; 116 height: 2.6rem; 117 border-radius: 0.85rem; 118 background: 119 linear-gradient(145deg, #134e4a, #0c1210 55%), 120 linear-gradient(145deg, transparent 40%, #5eead455); 121 border: 1px solid var(--border-strong); 122 box-shadow: inset 0 1px 0 #ffffff18, var(--shadow); 123 position: relative; 124} 125 126.logo::after { 127 content: ""; 128 position: absolute; 129 inset: 28% 30% 24%; 130 border: 2px solid var(--accent); 131 border-radius: 2px 2px 40% 40%; 132 border-bottom: none; 133 transform: rotate(180deg); 134} 135 136.brand h1 { 137 margin: 0; 138 font-size: 1.45rem; 139 letter-spacing: -0.02em; 140 font-weight: 700; 141} 142 143.tagline { 144 margin: 0.1rem 0 0; 145 color: var(--muted); 146 font-size: 0.9rem; 147} 148 149.top-meta { 150 display: flex; 151 align-items: center; 152 gap: 0.5rem; 153} 154 155.pill { 156 display: inline-flex; 157 align-items: center; 158 gap: 0.35rem; 159 font-size: 0.78rem; 160 font-weight: 600; 161 padding: 0.28rem 0.65rem; 162 border-radius: 999px; 163 border: 1px solid var(--border); 164 background: var(--bg-elev); 165 color: var(--muted); 166 white-space: nowrap; 167} 168 169.pill.sm { 170 font-size: 0.72rem; 171 padding: 0.12rem 0.45rem; 172 vertical-align: middle; 173} 174 175.pill.ok { 176 color: var(--ok); 177 border-color: #4ade8044; 178 background: #4ade8014; 179} 180 181.pill.warn { 182 color: var(--warn); 183 border-color: #fbbf2444; 184 background: #fbbf2414; 185} 186 187.pill.err { 188 color: var(--danger); 189 border-color: #f8717144; 190 background: #f8717114; 191} 192 193.tabs { 194 display: flex; 195 gap: 0.35rem; 196 overflow-x: auto; 197 padding: 0.25rem; 198 margin-bottom: 1.25rem; 199 border: 1px solid var(--border); 200 border-radius: 999px; 201 background: color-mix(in srgb, var(--bg-elev) 90%, transparent); 202 backdrop-filter: blur(10px); 203} 204 205.tab { 206 appearance: none; 207 border: 0; 208 background: transparent; 209 color: var(--muted); 210 font: inherit; 211 font-size: 0.92rem; 212 font-weight: 600; 213 padding: 0.55rem 0.95rem; 214 border-radius: 999px; 215 cursor: pointer; 216 white-space: nowrap; 217 transition: 0.15s ease; 218} 219 220.tab:hover { 221 color: var(--text); 222 background: #ffffff08; 223} 224 225.tab.active { 226 color: var(--accent-text); 227 background: var(--accent); 228} 229 230.main { 231 min-height: 22rem; 232} 233 234.panel { 235 animation: fade 0.18s ease; 236} 237 238.panel[hidden] { 239 display: none !important; 240} 241 242@keyframes fade { 243 from { 244 opacity: 0; 245 transform: translateY(4px); 246 } 247 to { 248 opacity: 1; 249 transform: none; 250 } 251} 252 253.panel-head { 254 display: flex; 255 align-items: flex-start; 256 justify-content: space-between; 257 gap: 1rem; 258 margin-bottom: 1rem; 259} 260 261.panel-head h2 { 262 margin: 0; 263 font-size: 1.2rem; 264 letter-spacing: -0.02em; 265} 266 267.panel-head p { 268 margin: 0.2rem 0 0; 269} 270 271.muted { 272 color: var(--muted); 273} 274 275h3 { 276 margin: 1.5rem 0 0.65rem; 277 font-size: 0.95rem; 278 text-transform: uppercase; 279 letter-spacing: 0.06em; 280 color: var(--muted); 281 font-weight: 700; 282} 283 284.stack { 285 display: flex; 286 flex-direction: column; 287 gap: 0.9rem; 288} 289 290label { 291 display: flex; 292 flex-direction: column; 293 gap: 0.35rem; 294 font-size: 0.9rem; 295 font-weight: 600; 296} 297 298label.check { 299 flex-direction: row; 300 align-items: center; 301 gap: 0.55rem; 302 font-weight: 500; 303 color: var(--muted); 304} 305 306input[type="text"], 307input[type="password"], 308textarea { 309 width: 100%; 310 font: inherit; 311 color: var(--text); 312 background: var(--bg); 313 border: 1px solid var(--border); 314 border-radius: 10px; 315 padding: 0.7rem 0.85rem; 316 outline: none; 317 transition: border-color 0.15s ease, box-shadow 0.15s ease; 318} 319 320textarea { 321 resize: vertical; 322 min-height: 6rem; 323 line-height: 1.45; 324} 325 326input:focus, 327textarea:focus { 328 border-color: var(--accent); 329 box-shadow: 0 0 0 3px var(--accent-dim); 330} 331 332.row { 333 display: flex; 334 flex-wrap: wrap; 335 align-items: center; 336 gap: 0.65rem; 337} 338 339.btn { 340 appearance: none; 341 border: 1px solid var(--border-strong); 342 background: var(--bg-elev); 343 color: var(--text); 344 font: inherit; 345 font-weight: 650; 346 font-size: 0.92rem; 347 padding: 0.55rem 0.95rem; 348 border-radius: 10px; 349 cursor: pointer; 350 transition: 0.15s ease; 351} 352 353.btn:hover { 354 border-color: var(--accent); 355 color: var(--accent); 356} 357 358.btn:active { 359 transform: translateY(1px); 360} 361 362.btn.primary { 363 background: var(--accent); 364 border-color: transparent; 365 color: var(--accent-text); 366} 367 368.btn.primary:hover { 369 filter: brightness(1.05); 370 color: var(--accent-text); 371} 372 373.btn.ghost { 374 background: transparent; 375} 376 377.btn.danger:hover { 378 border-color: var(--danger); 379 color: var(--danger); 380} 381 382.btn:disabled { 383 opacity: 0.5; 384 cursor: not-allowed; 385} 386 387.inline-form { 388 display: flex; 389 flex-wrap: wrap; 390 gap: 0.55rem; 391 margin-bottom: 0.75rem; 392} 393 394.inline-form input { 395 flex: 1 1 12rem; 396} 397 398.card-list { 399 display: flex; 400 flex-direction: column; 401 gap: 0.7rem; 402} 403 404.card { 405 background: var(--bg-card); 406 border: 1px solid var(--border); 407 border-radius: var(--radius); 408 padding: 0.95rem 1.05rem; 409 box-shadow: var(--shadow); 410} 411 412.card.post .meta { 413 display: flex; 414 flex-wrap: wrap; 415 gap: 0.5rem 0.85rem; 416 margin-bottom: 0.55rem; 417 font-size: 0.82rem; 418 color: var(--muted); 419 font-family: var(--mono); 420} 421 422.card.post .body { 423 white-space: pre-wrap; 424 word-break: break-word; 425 font-size: 1.02rem; 426} 427 428.card .title { 429 font-weight: 700; 430 margin-bottom: 0.25rem; 431} 432 433.card .sub { 434 color: var(--muted); 435 font-size: 0.88rem; 436 font-family: var(--mono); 437 word-break: break-all; 438} 439 440.empty { 441 border: 1px dashed var(--border-strong); 442 border-radius: var(--radius); 443 padding: 2rem 1.25rem; 444 text-align: center; 445 color: var(--muted); 446 background: color-mix(in srgb, var(--bg-elev) 70%, transparent); 447} 448 449.stats { 450 display: grid; 451 grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); 452 gap: 0.75rem; 453 margin-bottom: 0.5rem; 454} 455 456.stat { 457 background: var(--bg-card); 458 border: 1px solid var(--border); 459 border-radius: var(--radius); 460 padding: 1rem 1.1rem; 461 display: flex; 462 flex-direction: column; 463 gap: 0.15rem; 464} 465 466.stat-n { 467 font-size: 1.75rem; 468 font-weight: 750; 469 letter-spacing: -0.03em; 470 color: var(--accent); 471 font-variant-numeric: tabular-nums; 472} 473 474.stat-l { 475 color: var(--muted); 476 font-size: 0.85rem; 477 text-transform: uppercase; 478 letter-spacing: 0.05em; 479 font-weight: 650; 480} 481 482.code-block { 483 margin: 0; 484 padding: 0.9rem 1rem; 485 background: #00000055; 486 border: 1px solid var(--border); 487 border-radius: 12px; 488 overflow: auto; 489 font-size: 0.82rem; 490 line-height: 1.45; 491 color: var(--muted); 492 white-space: pre-wrap; 493 word-break: break-word; 494} 495 496.callout { 497 margin: 0.5rem 0 0.85rem; 498 padding: 0.85rem 1rem; 499 border-radius: 12px; 500 border: 1px solid #fbbf2455; 501 background: #fbbf2414; 502 color: var(--text); 503 font-size: 0.9rem; 504} 505 506.callout strong { 507 color: var(--warn); 508} 509 510.callout code { 511 user-select: all; 512} 513 514.hint { 515 margin-top: 1.25rem; 516 font-size: 0.9rem; 517} 518 519.muted-card { 520 margin-top: 1.5rem; 521} 522 523.muted-card h3 { 524 margin-top: 0; 525} 526 527.foot { 528 margin-top: 2.5rem; 529 padding-top: 1rem; 530 border-top: 1px solid var(--border); 531 color: var(--muted); 532 font-size: 0.85rem; 533 display: flex; 534 flex-wrap: wrap; 535 gap: 0.35rem 0.5rem; 536 align-items: center; 537} 538 539.foot .sep { 540 opacity: 0.5; 541} 542 543.toast { 544 position: fixed; 545 left: 50%; 546 bottom: 1.25rem; 547 transform: translateX(-50%); 548 z-index: 50; 549 max-width: min(32rem, calc(100vw - 2rem)); 550 padding: 0.75rem 1rem; 551 border-radius: 12px; 552 background: var(--bg-elev); 553 border: 1px solid var(--border-strong); 554 box-shadow: var(--shadow); 555 font-size: 0.92rem; 556 animation: fade 0.15s ease; 557} 558 559.toast.err { 560 border-color: #f8717166; 561} 562 563.toast.ok { 564 border-color: #4ade8066; 565} 566 567@media (max-width: 560px) { 568 .shell { 569 padding: 1rem 0.85rem 2.5rem; 570 } 571 572 .top { 573 flex-direction: column; 574 } 575 576 .panel-head { 577 flex-direction: column; 578 } 579 580 .tabs { 581 border-radius: 16px; 582 } 583}