aboutsummaryrefslogtreecommitdiffstats
path: root/src/style.css
Commit message (Collapse)AuthorAgeFilesLines
* Desktop feed scrolls like a phone: a mouse-wheel notch coasts and slows ↵Adam Soltys9 days1-0/+2
| | | | | | (quick turns stack, a reverse turn brakes, trackpads left alone), and a mouse can grab the feed and flick it (a sideways drag still selects text, a drag doesn't click what it started on) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Profile public key: solid border instead of dashed, a copy icon beside the ↵Adam Soltys9 days1-0/+8
| | | | | | key, and a slightly larger font (13px) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Chip strips drag sideways with a mouse (a drag doesn't click the chip it ↵Adam Soltys9 days1-0/+8
| | | | | | started on) and show a thin scrollbar on mouse devices, so the feed chips that run past the card are reachable on desktop Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Amethyst's feed model: an Everything feed (your follows, everyone on your ↵Adam Soltys9 days1-1/+1
| | | | | | lists and packs, and posts from anyone on a hashtag you follow: your topic feeds' tags and your NIP-51 interests, kind 10015) and a Follows + lists feed beside Following, built from your feeds and offered once there's something to add. Long names in search results end in an ellipsis instead of running off the card Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Desktop layout: from 900px the bottom nav is a left rail (your profile first ↵Adam Soltys9 days1-0/+53
| | | | | | with a bigger face and name, Settings last) beside a 600px page column, and from 1220px the wallet (balance, Receive/Send, latest payments) rides in a right column; search is a full field in the header there. Floaters re-centred on the page column, open chats still fill the window, phones unchanged Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A tapped lightning:lnurl (NFC at a till) waits on the paying shell for the ↵Adam Soltys9 days1-0/+3
| | | | | | feature that pays it instead of sitting as raw text in the recipient field; Paste and Scan stay one line tall as a long address grows the field Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Feed videos before they play: the picture fills the box with only the play ↵Adam Soltys11 days1-0/+6
| | | | | | button and size (no seek bar or sound button until playing); hovering the cover no longer paints it over with the app's button grey; upright phone clips (stored sideways with a quarter-turn matrix) paint upright, v1 size caches dropped; a clip the probe found HEVC switches to the copy before fetching the original Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Videos: posters for clips that came without one, and an H.264 copy for a ↵Adam Soltys11 days1-0/+8
| | | | | | clip this browser can't picture (an iPhone's HEVC on Chrome for Linux played sound over black) — vmedia container on cs (bun + ffmpeg, /vmedia/), switch on zero-width metadata or an HEVC header from the probe, a line saying why if the copy fails too Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Setup wizard: a cover behind the avatar — twelve nature covers ↵Adam Soltys11 days1-0/+12
| | | | | | (self-hosted, Unsplash) cycled with arrows or a swipe, or upload your own; untouched, each pubkey gets its own default, published as the kind-0 banner beside the punk Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A quote inside a quote shows as a one-line preview (author + start of the ↵Adam Soltys12 days1-0/+5
| | | | | | | text) instead of a bare 'view note' link Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
* Chat: a long attachment name truncates instead of scrolling the log sidewaysAdam Soltys12 days1-1/+1
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
* Audio links (mp3/m4a/ogg/opus/wav/flac/aac) render as a player, like AmethystAdam Soltys13 days1-0/+6
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
* Feed Articles view: long-form posts (NIP-23) from the feed's ↵Adam Soltys13 days1-0/+2
| | | | | | | people/topics/relays as cards, own cursor + index; Popular keeps articles two others engaged with Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
* nostr:naddr renders: article cards (cover, title, summary) that open to read ↵Adam Soltys13 days1-0/+10
| | | | | | | with headings, list/pack cards that open as feeds Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
* Feed pictures: a height-capped one's frame narrows with it (no empty bands)Adam Soltys14 days1-3/+4
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
* Feed pictures uncropped: the column's width at their own shape, height-cappedAdam Soltys14 days1-3/+3
| | | | | | | | | The 3:4 crop for tall pictures cut the top and bottom off comics. Now nothing is cropped; a picture is as wide as the column allows up to min(560px, 70vh) tall, and only one taller than that narrows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
* Feed: a tall picture fills a 3:4 frame as wide as the column, not a skinny stripAdam Soltys2026-10-031-0/+2
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
* Video tiles: a frame even when the size check fails; retry it laterAdam Soltys2026-10-031-1/+1
| | | | | | | | | | | | | | | | | | | | Efrat's clip (blossom.primal.net → r2a.primal.net) showed a blank tile on a phone: the 64 KB probe failed there (slow connection), the failure was kept for good, and a tile with a failed probe never tried for a frame. - A failed probe is dated and asked again after an hour (it was kept forever; old 'failed: true' entries are retried). The probe waits 10 s. - A tile whose probe failed still tries for a first frame, giving up and letting go of the file after 8 s. - Primal's CDN lets scripts read the bytes but not Content-Range, so the size was unknown: a HEAD's Content-Length (readable by any page) fills it in. - No size in imeta but a bitrate and duration (Primal posts those): the size is estimated from them. 'dim 1080.0x1920.0' is understood. - A tile with nothing to show is dark, like a video, not a pale gap. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
* Videos opens on a grid of thumbnails; the pager waits for a tapAdam Soltys2026-10-031-0/+4
| | | | | | | | | | | | | | Choosing Videos no longer jumps into the full-screen pager: it shows the vertical clips as a grid, like Images, and a tile opens the pager on that clip. Every tile gets a first frame when that costs only the start of the file (the index leads, or the server serves ranges), whatever the clip's size; a clip over budget wears its cost as a badge. Only an index-last file from a server without ranges shows its cost instead. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
* Videos: know what a clip costs before fetching it; vertical clips onlyAdam Soltys2026-10-031-0/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | - What a clip costs is learned up front: the post's imeta (size, dim, image) when it says, else one 64 KB ranged request — the total from Content-Range, whether ranges are served, whether the MP4's index (moov) comes before its data, and the picture size from the track header. Up to three at a time; remembered across sessions. It also replaces the player-based shape probe the feed ran on every clip. - Clips over 25 MB (8 MB on 2G/3G, 3 MB with data saver), above 1080p, index-last files over 8 MB from servers without ranges, or clips that couldn't be measured wait for a tap: a cover saying what they cost ("50 MB", "4K"). Settings → Nostr → Videos: Autoplay large videos. - The pager loads only the clip on screen in full; the next gets its opening if within budget; everything else holds nothing. Sizes are asked three slides ahead. - Feed clips fetch nothing until they're about to play (preload none), with the post's still as a poster. - Video grid tiles show a first frame only for small clips that start quickly; others show their cost. - Videos lists only clips known to stand taller than wide; one of unknown shape is measured and joins when it qualifies; choosing Videos with none known yet opens the pager on the first that turns up. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
* Feed media views: a grid of pictures, videos to flip throughAdam Soltys2026-10-031-1/+78
| | | | | | | | | | | | | | | | | | | | | | | All / Images / Videos sits under the feed chips (remembered). - Images lays the feed's pictures out as a three-column grid. - Videos opens straight into a full-screen pager: one clip per screen, snapping, the one on screen playing with sound (muted with an Unmute button when the browser refuses), the next a flick or ↓ away. Closing it leaves a grid of the clips. - The pager shows only the media until tapped; a tap shows the author (tap for their profile), the post's words as a caption without the media links (tap to expand), and likes and sats in the bottom right, which also like and zap. - It is a place: Back or Escape closes it. Built outside the morph, so a repaint never restarts a clip; off-screen clips let go of their media. - Near the end of the grid or the pager the feed fetches older posts and new slides are appended. - Toasts now sit above full-screen viewers. tools/feed-media-views-test.js Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
* Align chat composer controls at a shared 44px heightAdam Soltys2026-10-021-2/+8
|
* Send: the recipient field grows to show it all; history steps aside while ↵Adam Soltys2026-10-021-2/+9
| | | | | | | | | | | | | | | | | | sending - The recipient is a one-line textarea that wraps and grows (rows from the text's length over the field's measured width), so a whole address is in view in the field itself — no second copy in small type below. Enter doesn't break it and pasted line breaks are dropped. Empty, it is as tall as its hint (measured in the hint's own face), so that's whole too. - Past the recipient — the amount, a review, a Lightning/Ark confirmation, a raw tx to broadcast — the history list below the send pane is left out. - tools/send-dest-test.js (390px and 1280px). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Recovery words stay inside the cardAdam Soltys2026-10-021-5/+14
| | | | | | | | | | The grid's 1fr columns wouldn't shrink below their words, so an eight-letter word pushed the third column out past the card's padding. minmax(0, 1fr) columns, slightly tighter cells, and two columns up to 480px wide (was 420). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Feed form: relays and an every-post firehose; its Back works; a stronger ↵Adam Soltys2026-10-021-1/+4
| | | | | | | | | | | | | | | | | | | new-post tint - The new/edit feed form gets a Relays field (read this feed from these relays only) and "Every post on these relays", which saves a firehose feed (optionally curated) named after its relay and hides the people, packs and topics it doesn't need. It used to take a hand-typed /feed/all?r= link. - The form's Back did nothing visible: opening it made no history entry, so Back went to the page behind the feed and left the form up. The editor (and the gear page's Spending/Savings view) are now part of the navigation state. - New-post tint 9% -> 16% green in light mode; dark mode unchanged. - tools/feed-editor-relays-test.js. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* New-post tint fades the moment any of the post is on screenAdam Soltys2026-10-021-4/+4
| | | | | | | | | | | It waited for half the row to sit in view for two seconds; scrolling reset the clock and a replaced node lost it, so a tall post read in passing or one the window remounted could stay green for good. Now the first visible pixel starts a 3s fade (the row's background transition), marked seen by id, whether the reader stays or scrolls on. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Pictures paint with the page: column-sized copies, and CORS that worksAdam Soltys2026-10-021-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | Measured in the live tab (screencast frames): back from a profile, the feed's text was on screen ~200ms before its photo. The <img> was loaded and complete on the first frame — a 3024px, 12-megapixel original that Chrome re-decodes whenever the page is rebuilt. - Post photos wider than the column at 2x are painted from an 1100px WebP copy made once (fetch, createImageBitmap, OffscreenCanvas) and kept in Cache Storage; it decodes in a few ms, decoding=sync, inside the same frame as the text. GIFs and small pictures keep the original; the lightbox opens the original. Profile banners use the same copies, warmed on prefetch. - corsFetch: primal's CDN caches its no-Origin answer without Vary: Origin, so a CORS fetch after the <img> got that header-less copy and failed — which had written blossom.primal.net, m.primal.net and coinos.io off as 'no CORS', so their avatars never got local thumbnails and painted late from the originals. A refusal is now retried once past the cache before a host is blamed; the old list is dropped (nocors-v2). - DM list: the unread dot sits centred at the row's end, like the communities' below, instead of beside the time. - Balance card gear: the icon alone, no circle. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Profile npub: full and monospace again, behind a Public key linkAdam Soltys2026-10-021-11/+1
| | | | | | | | | The truncated key button took a whole row on every profile. A "Public key" link now ends the Following/Followers line; it reveals the npub in full, monospace, tap to copy, and hides it again. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Balance card gear replaces Accounts; Spending's coins live behind itAdam Soltys2026-10-021-0/+2
| | | | | | | | | | | | | | | | | | | | - The "Accounts" pill on each balance face is now a gear. It opens that face's settings: Spending leads with its coins (renewal, the co-operative move to Savings, unilateral exit), then Security (lock, change password), the recovery phrase, auto-logout; Savings adds its public key. A wallet with no nostr identity also gets sign-in and log-out there, since it has no profile page to hold them. - The exit cost is no longer said under the balance; the Spending settings state it, always, not only when coin chains run deep. - The lone Manage link under the balance is gone (the gear is the way in); warning notices that are about the coins link to the same page. - The Accounts list, Add wallet and Delete all are no longer reached from the wallet (Delete all stays behind profile > Log out > forget). - Tests follow the gear: padlock-ask, lock-wallet and account-access pass again; cooperative-exit-ui clicks the Spending gear. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Profiles show Following and Followers, each a list you can openAdam Soltys2026-10-021-0/+10
| | | | | | | | | | | | | | | | | | Under the bio: "116 Following · 572 Followers". Tapping either opens the people below it (50 at a time); tapping a person opens their profile. Follows are the person's kind 3, now read from Primal's cache alongside the relays (a list kept only on their outbox relays used to read as nobody). Followers, which no relay counts, come from Primal: the count from user_profile, the list from user_followers, a first screenful fast and the rest after, without reordering what is on screen. Every event taken from Primal is signature-checked in the verify worker first, and the profiles among them fill names and faces the relays lacked. Also translates the post-zap "no address" message. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Composer hint goes away on focus, so the caret sits at the leftAdam Soltys2026-10-021-0/+2
| | | | | | | The placeholder is ::before text in the flow, and the caret blinked after it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Bigger new-posts pill that swipes awayAdam Soltys2026-10-011-2/+7
| | | | | | | | | | The pill is thumb-sized now (16px, 12/24 padding) and rides above the Post button on a phone. Drag it sideways or down and let go: it flies off and stays away until more posts arrive than it was showing. A short drag springs back and is not a tap. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Tall videos fill the column with no side bars, up to the screen's heightAdam Soltys2026-10-011-1/+1
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Videos in posts span the column instead of a narrow strip at the leftAdam Soltys2026-10-011-1/+1
| | | | | | | | | A tall clip was 360px high at most (profile, thread) or sized to its own width (feed), leaving most of the post blank. Now every inline video is the column's width, up to three quarters of the screen tall, letterboxed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Preview in the thread reply box is the size of Cancel and ReplyAdam Soltys2026-10-011-1/+2
| | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Use a two-tone paper and green pen icon for new postsAdam Soltys2026-10-011-0/+3
|
* Add cooperative coin exits and clarify profile, preview and zap controlsAdam Soltys2026-10-011-1/+12
|
* Clear abandoned payments, reset profile Pay and restore native messaging BackAdam Soltys2026-10-011-3/+9
|
* The reply box in dark mode is dark with light text instead of white.Adam Soltys2026-10-011-1/+1
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
* "Post" floats at the feed's bottom right instead of sitting in the header.Adam Soltys2026-09-301-0/+10
| | | | | | | | | | A pill with the pencil and "Post", fixed above the bottom nav inside the page column, wherever the reader is in the feed; the tap scrolls to the top, opens the composer and focuses it. Hidden while the composer is open (it has its own Post button) and for visitors. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
* A picture or video on its way shows a bar with its percentage — shrinking, ↵Adam Soltys2026-09-301-0/+5
| | | | | | | | | | | | | | | | then uploading; the pencil reads "New post". ui.mediaProgress { stage, pct } (a render per whole percent) drawn as a labelled bar under the reply and post composers, instead of only the paperclip turning into a spinner. Upload progress comes from XMLHttpRequest upload events (fetch() has none) in uploadPublicMedia's new onProgress; injected fetchers (tests) keep the fetch path. upload-progress-test: 1.2 MB at 400 KB/s climbs 0→100 in steps. video-compress-test: the bar counts the shrink, then the upload. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
* Composers take pictures from the keyboard: the reply, post and chat fields ↵Adam Soltys2026-09-291-0/+10
| | | | | | | | | | | | | | | | | | | are contenteditable. Android keyboards (Gboard GIFs, stickers) only offer images to fields that accept them, and Chrome says so for contenteditable, never <textarea> — hence the greyed-out GIF key and "This app does not support images here". <coinos-text> (src/rich-text.js) is a contenteditable that acts like a textarea to the code around it (value, selectionStart/End, setSelection- Range, placeholder), keeps text plain, and hands any pasted/dropped/ keyboard picture to onMedia — the paperclip's upload. The morph syncs its value like a field's and leaves its own editing attributes alone. composer-media-test: types like a textarea, strips pasted formatting, a pasted GIF uploads and lands in the reply, still editable after repaint. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
* Polls (NIP-88): options with each one's share of the vote, votable from the ↵Adam Soltys2026-09-281-0/+18
| | | | | | | | | | | | | | feed and the thread. A kind 1068 poll showed as "an event this app doesn't show". Now its options are rows with the vote share behind them (kind 1018 votes, each person's latest counts, single/multiple choice, endsAt honored); a tap votes, marked as yours at once. A quoted poll is pictured in its card. Feeds and profiles list polls alongside notes, and a thread's root is looked up by id with any kind, so replies to a poll find it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
* Pinch to zoom a full-screen picture.Adam Soltys2026-09-281-0/+2
| | | | | | | | | Pinch zooms around the fingers (up to 5x), one finger pans a zoomed picture within its edges, double-tap zooms in at a spot and again to reset, and the wheel zooms on a desktop. A tap still closes an unzoomed picture (after a beat, so it can be the first half of a double-tap); a gesture never does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* New posts: the pill lands on the oldest one, and each wears a tint until ↵Adam Soltys2026-09-281-0/+9
| | | | | | | | | | | you've seen it. The new-posts pill used to glide to the top of the feed; now it stops at the oldest post that came in, right above where you were reading, so you read on upward. Posts that arrive while you read are tinted until they've been in view about two seconds, then fade to the plain page (like Amethyst). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The post action bar spans the post's full width, like its body.Adam Soltys2026-09-281-1/+1
| | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The bottom nav spans the window; the chat list is just conversations.Adam Soltys2026-09-281-5/+8
| | | | | | | | | Feed and Notifications leave the chat list (the nav reaches both; the bell carries the notifications dot now). On a wide screen the bar runs edge to edge with its buttons over the page column; quiet muted tabs, a pill for the current one. Feed gets a newspaper icon instead of a house. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The bottom nav rides every page: Feed, Messages, Notifications, Wallet.Adam Soltys2026-09-281-4/+9
| | | | | | | | | It now shows across the signed-in app and a visitor's public pages (never over sign-in, onboarding or the lock prompt), marks the current page, and carries the unread dot. Home is renamed Feed, and the Messages button leaves the header. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep feed navigation visible and add a wallet shortcutAdam Soltys2026-09-281-4/+3
|
* Add scrolling feed navigation for home, messages and notificationsAdam Soltys2026-09-281-0/+18
|