Something went wrong. Try again.
mobile bluesky & blacksky app made with flutter lazurite.stormlightlabs.org
mobile bluesky blacksky flutter android ios
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>Thread - Lazurite</title> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Lora:wght@400;500;600;700&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet" /> <link rel="stylesheet" href="styles.css" /> <style> .thread-container { padding-bottom: 88px; }
/* Thread line connecting parent posts to the focused post */ .thread-line-wrapper { position: relative; }
.thread-line-wrapper::after { content: ""; position: absolute; left: 39px; /* center of avatar (16px pad + 24px half of 48px avatar) - 1px */ top: 0; bottom: 0; width: 2px; background-color: var(--border); }
.thread-line-wrapper .post-card { position: relative; z-index: 1; }
/* Parent post: smaller, muted, with thread line below */ .thread-parent { border-bottom: none; padding-bottom: 0; }
.thread-parent .post-content { color: var(--text-secondary); }
.thread-parent .post-actions { display: none; }
.thread-parent-connector { padding: 0 16px 0 39px; height: 16px; position: relative; }
.thread-parent-connector::before { content: ""; position: absolute; left: 39px; top: 0; bottom: 0; width: 2px; background-color: var(--border); }
/* Focused post: the main post in the thread */ .thread-focused { padding: 16px; border-bottom: 1px solid var(--border); background-color: var(--bg); }
.thread-focused .post-header { display: flex; gap: 12px; margin-bottom: 16px; }
.thread-focused .post-content { font-size: 17px; line-height: 1.6; color: var(--text-primary); margin-bottom: 16px; }
.thread-focused-timestamp { font-size: 14px; color: var(--text-muted); padding-bottom: 16px; border-bottom: 1px solid var(--border); margin-bottom: 12px; }
.thread-focused-stats { display: flex; gap: 20px; padding-bottom: 12px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.thread-stat { font-size: 14px; color: var(--text-secondary); }
.thread-stat strong { font-weight: 600; color: var(--text-primary); }
.thread-focused .post-actions { padding-top: 8px; justify-content: space-around; }
.thread-focused .post-action svg { width: 22px; height: 22px; }
.thread-focused .post-action { font-size: 0; /* hide counts in focused action bar, they're shown in stats */ }
/* Active action states */ .post-action.active-like { color: var(--accent-error); }
.post-action.active-repost { color: var(--accent-success); }
.post-action.active-bookmark { color: var(--accent-primary); }
/* Replies section */ .thread-replies-header { padding: 12px 16px 8px; font-size: 13px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; border-bottom: 1px solid var(--border); }
/* Nested reply indentation via thread line */ .thread-reply { position: relative; }
.thread-reply-nested { padding-left: 32px; position: relative; }
.thread-reply-nested::before { content: ""; position: absolute; left: 39px; top: 0; height: 28px; width: 2px; background-color: var(--border); }
/* Reply composer fixed at bottom, above nav */ .thread-reply-bar { position: fixed; bottom: 76px; left: 50%; transform: translateX(-50%); width: 100%; max-width: 414px; background-color: var(--surface); border-top: 1px solid var(--border); padding: 10px 16px; display: flex; align-items: center; gap: 12px; z-index: 90; }
.thread-reply-bar .avatar { width: 32px; height: 32px; font-size: 12px; }
.thread-reply-input { flex: 1; border: 1px solid var(--border); border-radius: 20px; padding: 8px 16px; font-size: 14px; background-color: var(--bg); color: var(--text-primary); outline: none; font-family: inherit; }
.thread-reply-input::placeholder { color: var(--text-muted); }
.thread-reply-input:focus { border-color: var(--accent-primary); }
.thread-reply-send { width: 36px; height: 36px; border-radius: 50%; border: none; background-color: var(--accent-primary); color: white; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background-color 0.2s ease; flex-shrink: 0; }
.thread-reply-send:hover { background-color: var(--accent-primary-hover); }
.thread-reply-send svg { width: 18px; height: 18px; }
/* Quoted post embed */ .thread-quote { margin-top: 12px; border: 1px solid var(--border); border-radius: 12px; padding: 12px; }
.thread-quote-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.thread-quote-avatar { width: 20px; height: 20px; border-radius: 50%; background-color: var(--surface-variant); display: flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 600; color: var(--text-secondary); }
.thread-quote-author { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.thread-quote-text { font-size: 13px; color: var(--text-secondary); line-height: 1.4; }
/* Loading & error states */ .thread-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 64px 24px; gap: 16px; }
.thread-spinner { width: 32px; height: 32px; border: 3px solid var(--border); border-top-color: var(--accent-primary); border-radius: 50%; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.thread-error { display: flex; flex-direction: column; align-items: center; padding: 64px 24px; text-align: center; gap: 12px; }
.thread-error-icon { width: 48px; height: 48px; color: var(--text-muted); }
.thread-error-title { font-size: 16px; font-weight: 600; color: var(--text-primary); }
.thread-error-text { font-size: 14px; color: var(--text-secondary); max-width: 260px; }
/* Extra bottom padding to account for reply bar */ .thread-container { padding-bottom: 140px; }
/* Back button */ .header-back { background: none; border: none; color: var(--text-primary); cursor: pointer; padding: 8px; margin-left: -8px; display: flex; align-items: center; }
.header-back svg { width: 24px; height: 24px; }
.header-left { display: flex; align-items: center; gap: 8px; } </style> </head> <body> <div class="mobile-container"> <!-- Header --> <header class="header"> <div class="header-left"> <button class="header-back" title="Back"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="19" y1="12" x2="5" y2="12" /> <polyline points="12 19 5 12 12 5" /> </svg> </button> <h1 class="header-title" style="font-family: var(--font-heading)">Thread</h1> </div> <button class="header-action"> <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="1" /> <circle cx="19" cy="12" r="1" /> <circle cx="5" cy="12" r="1" /> </svg> </button> </header>
<div class="thread-container"> <!-- Parent Post (with thread line) --> <div class="thread-line-wrapper"> <article class="post-card thread-parent"> <div class="post-header"> <div class="avatar">BJ</div> <div class="post-author"> <div class="post-author-name">Bob Johnson</div> <div class="post-author-handle">@bob.bsky.social · <span class="post-timestamp">6h</span></div> </div> </div> <div class="post-content"> What are everyone's thoughts on the latest changes to the AT Protocol? Particularly interested in how federation is being handled. </div> </article>
<div class="thread-parent-connector"></div> </div>
<!-- Focused Post (the main post being viewed) --> <article class="thread-focused"> <div class="post-header"> <div class="avatar">AS</div> <div class="post-author"> <div class="post-author-name">Alice Smith</div> <div class="post-author-handle">@alice.bsky.social</div> </div> </div>
<div class="post-content"> The federation work has been really impressive! The PDS model means you truly own your data. I've been running my own server for a week now and it's been rock solid. <br /><br /> Key things I've noticed:<br /> • Identity is portable across servers<br /> • The relay infrastructure scales well<br /> • App views make custom feeds possible </div>
<!-- Quoted post embed --> <div class="thread-quote"> <div class="thread-quote-header"> <div class="thread-quote-avatar">AT</div> <span class="thread-quote-author">AT Protocol · @atproto.com</span> </div> <div class="thread-quote-text"> Federation is now live! Self-host your PDS and take control of your social data. Read more at atproto.com/blog/federation </div> </div>
<div style="height: 16px"></div>
<div class="thread-focused-timestamp">2:34 PM · Mar 17, 2026</div>
<div class="thread-focused-stats"> <span class="thread-stat"><strong>24</strong> replies</span> <span class="thread-stat"><strong>12</strong> reposts</span> <span class="thread-stat"><strong>156</strong> likes</span> <span class="thread-stat"><strong>8</strong> saves</span> </div>
<div class="post-actions"> <!-- Reply --> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" /> </svg> </button> <!-- Repost (active) --> <button class="post-action active-repost"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="17 1 21 5 17 9" /> <path d="M3 11V9a4 4 0 0 1 4-4h14" /> <polyline points="7 23 3 19 7 15" /> <path d="M21 13v2a4 4 0 0 1-4 4H3" /> </svg> </button> <!-- Like (active) --> <button class="post-action active-like"> <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" /> </svg> </button> <!-- Bookmark (active) --> <button class="post-action active-bookmark"> <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"> <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z" /> </svg> </button> <!-- Share --> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" /> <polyline points="16 6 12 2 8 6" /> <line x1="12" y1="2" x2="12" y2="15" /> </svg> </button> </div> </article>
<!-- Replies --> <div class="thread-replies-header">Replies</div>
<!-- Reply 1 --> <article class="post-card thread-reply"> <div class="post-header"> <div class="avatar">CW</div> <div class="post-author"> <div class="post-author-name">Carol White</div> <div class="post-author-handle">@carol.dev · <span class="post-timestamp">4h</span></div> </div> </div> <div class="post-content"> This is spot on! The portability aspect is what sold me. Being able to migrate my entire social presence without losing followers is a game changer. </div> <div class="post-actions"> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" /> </svg> 3 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="17 1 21 5 17 9" /> <path d="M3 11V9a4 4 0 0 1 4-4h14" /> <polyline points="7 23 3 19 7 15" /> <path d="M21 13v2a4 4 0 0 1-4 4H3" /> </svg> 1 </button> <button class="post-action active-like"> <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" /> </svg> 18 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" /> <polyline points="16 6 12 2 8 6" /> <line x1="12" y1="2" x2="12" y2="15" /> </svg> </button> </div> </article>
<!-- Reply 2 (with nested sub-reply) --> <article class="post-card thread-reply"> <div class="post-header"> <div class="avatar">DM</div> <div class="post-author"> <div class="post-author-name">David Miller</div> <div class="post-author-handle">@davidm.bsky.social · <span class="post-timestamp">3h</span></div> </div> </div> <div class="post-content"> Have you run into any performance issues with your PDS? I'm considering self-hosting but worried about the resource requirements. </div> <div class="post-actions"> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" /> </svg> 1 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="17 1 21 5 17 9" /> <path d="M3 11V9a4 4 0 0 1 4-4h14" /> <polyline points="7 23 3 19 7 15" /> <path d="M21 13v2a4 4 0 0 1-4 4H3" /> </svg> </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" /> </svg> 5 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" /> <polyline points="16 6 12 2 8 6" /> <line x1="12" y1="2" x2="12" y2="15" /> </svg> </button> </div> </article>
<!-- Reply 3: Author's own reply in thread --> <article class="post-card thread-reply thread-reply-nested"> <div class="post-header"> <div class="avatar">AS</div> <div class="post-author"> <div class="post-author-name">Alice Smith</div> <div class="post-author-handle">@alice.bsky.social · <span class="post-timestamp">2h</span></div> </div> </div> <div class="post-content"> Runs great on a small VPS! I'm using a 2GB instance and it handles everything smoothly. The docs have a good guide on minimal setups. </div> <div class="post-actions"> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" /> </svg> </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="17 1 21 5 17 9" /> <path d="M3 11V9a4 4 0 0 1 4-4h14" /> <polyline points="7 23 3 19 7 15" /> <path d="M21 13v2a4 4 0 0 1-4 4H3" /> </svg> </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" /> </svg> 12 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" /> <polyline points="16 6 12 2 8 6" /> <line x1="12" y1="2" x2="12" y2="15" /> </svg> </button> </div> </article>
<!-- Reply 4 --> <article class="post-card thread-reply"> <div class="post-header"> <div class="avatar">EL</div> <div class="post-author"> <div class="post-author-name">Eva Lee</div> <div class="post-author-handle">@eva.bsky.social · <span class="post-timestamp">1h</span></div> </div> </div> <div class="post-content"> The custom feeds through app views are my favourite part. Being able to build your own algorithmic timeline without depending on the platform is so empowering. <a href="#" class="post-facet-hashtag">#atproto</a> <a href="#" class="post-facet-hashtag">#openweb</a> </div> <div class="post-actions"> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" /> </svg> 2 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="17 1 21 5 17 9" /> <path d="M3 11V9a4 4 0 0 1 4-4h14" /> <polyline points="7 23 3 19 7 15" /> <path d="M21 13v2a4 4 0 0 1-4 4H3" /> </svg> 4 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" /> </svg> 31 </button> <button class="post-action"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" /> <polyline points="16 6 12 2 8 6" /> <line x1="12" y1="2" x2="12" y2="15" /> </svg> </button> </div> </article> </div>
<!-- Reply Composer Bar --> <div class="thread-reply-bar"> <div class="avatar" style="width: 32px; height: 32px; font-size: 12px">JD</div> <input type="text" class="thread-reply-input" placeholder="Reply to Alice..." /> <button class="thread-reply-send" title="Send reply"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="22" y1="2" x2="11" y2="13" /> <polygon points="22 2 15 22 11 13 2 9 22 2" /> </svg> </button> </div>
<!-- Bottom Navigation --> <nav class="nav-bar"> <a href="home.html" class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /> <polyline points="9 22 9 12 15 12 15 22" /> </svg> <span>Home</span> </a>
<a href="search.html" class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="11" cy="11" r="8" /> <line x1="21" y1="21" x2="16.65" y2="16.65" /> </svg> <span>Search</span> </a>
<a href="notifications.html" class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" /> <path d="M13.73 21a2 2 0 0 1-3.46 0" /> </svg> <span>Alerts</span> </a>
<a href="messages.html" class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /> </svg> <span>Chat</span> </a>
<a href="profile.html" class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /> <circle cx="12" cy="7" r="4" /> </svg> <span>Profile</span> </a> </nav> </div>
<script> if (localStorage.getItem("theme")) { const t = localStorage.getItem("theme"); if (t !== "light") document.documentElement.setAttribute("data-theme", t); } </script> </body></html>