# Desktop social tabs
Source: https://docs.aden.space/docs/help/apps-integrations/desktop-social-tabs

The desktop Links surface: socials, artist back-offices and self-added pages in one sidebar, with one feed of their messages, shareable folders, an ad blocker and a cookie banner blocker.
{/* Generated by `bun docs:publish` from docs/features/desktop-social-tabs.md: edit the spec, not this file. */}

## What it is [#what-it-is]

The desktop app has three surfaces in the rail on the left of the window:
**System** (your files and player), **Aden** (the web app) and **Links**.
Members of an organisation also get **Organisations** (the web app's `/org`,
or straight into the one org they are in) and Aden staff get **Admin**
(`/admin`), each lit while you are on that part of the web app.
Links holds every external page: socials (Instagram, TikTok, X, …), artist
back-offices (Spotify for Artists, YouTube Studio, …), and pages you add
yourself. They live in Links' own sidebar.

**The rail is yours.*&#x2A; Under Links, pin whatever your team works in: a Links
page, a network's chats, a System page, an Aden page, a file on this computer
(the team's track sheet in Excel) or any link. Add one from the &#x2A;*+** at the
bottom of the pins (it searches everything), from a page's "…" or right-click
menu (**Pin to rail**, **Pin chats to rail**), or with "Pin to rail" in ⌘K.

* Pages, chats and links open as an app of their own: full width, with the
  Links sidebar out of the way. A chats pin carries a small chat badge and
  opens the inbox with only that network's conversations. Clicking Links,
  System or Aden brings the sidebar back.
* The rail lights the pin while its page is on screen, not the surface it
  opens in: an Aden page pin rather than Aden (and for the pages under it),
  a System page pin rather than System.
* Right-click a pin to rename it, give it an icon and color of its own, or
  unpin it.
* **Websites as tabs:*&#x2A; type an address into the &#x2A;*+** (`artistspace.com`)
  and pick "Open … as a tab": it is pinned and opens at once in its own web
  view, keeping its sign-in, like a browser tab you can rename and recolor.
  It lives on the rail only, not under Your pages in the Links sidebar.
  Every link on one site shares that site's sign-in, so pinning a second
  Claude or ChatGPT conversation never asks you to log in again, and each
  pin keeps a tab of its own, so switching between them never reloads.
  Unpinning the last link on a site removes the page it opened in.
* **Several accounts on one site:** right-click a website pin, on either rail,
  and pick **Add another account*&#x2A;, type the address in the rail's &#x2A;*+** and
  pick **Open claude.ai with another account**, or type "add another Claude
  account" in ⌘K. The site is pinned again beside it ("Claude 2") under a login of its
  own and opens to sign in. Rename it ("Claude work") from its menu, and move
  both to the top rail beside Home to switch with one click.
* **Every account in one sidebar:** with Claude pinned under two logins,
  opening either one also opens the other in the background, and each
  Claude page's own sidebar lists the other account's sessions under its
  name ("Claude 2"), in Claude's own rows with their Running and Unread
  dots. Picking one brings up that account's page on the session, so the
  two read as one Claude. The rows are copies of the page's own
  (`aden-feed-foreign` in `main/social-feed-bridge.js`): a Claude redesign
  can drop them, and each page then shows its own sessions only.
* **T3 Code:** pick **T3 Code*&#x2A; in the rail's &#x2A;*+** (or ⌘K) to pin the T3
  coding-agent app. Nothing runs until then. Its tab starts `t3` on this
  computer (installed, else through npx or bunx, port 3773), or joins a T3
  server already running, and signs the tab in without T3's pairing screen
  (`src/main/t3-code.ts`). The server keeps running behind other pages while
  Aden is open; closing or unpinning the tab, or quitting, stops it.
* A file pin wears the icon the OS shows for that file (Excel's for an
  .xlsx), and a website pin wears the site's own icon, until you choose one.
  The site icon is read by the desktop app from the site's page and kept for
  the session only.
* **Cloud** pages (Google Drive, Google Sheets, Dropbox, OneDrive, Box, iCloud
  Drive) sit in the Links catalog beside the socials, each signed in once in
  its own session, and pin like any page.
* **Folders:*&#x2A; group pins in a folder, and folders in folders. Make one from
  the &#x2A;*+** ("A folder"), from a pin's right-click **Move to folder**, or with
  the folder icon inside an open folder. Hover a folder to see what's in it;
  click it to keep it open and search everything inside, at any depth, by name
  or address. Typing a web address there adds that site to the folder. Each
  row's "…" renames it, moves it to another folder or out, or removes it.
  Right-click a folder to rename it and give it an icon and color, or delete
  it (what it held moves up a level). Pins inside folders are found in ⌘K too.
* **Share a folder by link:** right-click any folder, &#x2A;*Copy link or
  email…**: the same `aden.space/f/…` link a Links folder shares, the folder
  carried in the link (no table). Its sites and Aden pages go, nested ones
  flattened into the one folder; files on this computer stay behind. Type an
  email there to open a new mail with the link. Opening the link adds it as
  a folder on the receiver's rail (`target: 'rail'` in the code).
* **Shared folders:** right-click one of your folders and **Share with** the
  active team or one of your organisations: it leaves your rail and shows on
  everyone's in it, under their own pins, with the team's avatar on its
  corner. Its owners and admins change it; everyone else sees it with the
  editing rows disabled and the reason why. **Stop sharing** brings it back to
  your own rail. Anyone can **Hide from my rail*&#x2A; (this computer only) and
  show it again from the &#x2A;*+**. Files on this computer stay on your rail when
  their folder is shared. Shared folders live in the team's or organisation's
  `sidebar_layouts.desktopRail` (`/api/v1/desktop-rail/shared`), next to the
  sidebar layouts its admins set; no table of their own.
* The rail lives on your account (`users.app_preferences.desktop_rail`), so it
  survives signing out, switching teams and a new computer. A file pin opens
  the same path on every computer; where the file is not, it says so.
* Onboarding has a step to pin the usual ones (Sheets, Drive, Dropbox,
  WhatsApp and Instagram chats, Samples). The rail sits on screen for the
  tour's rail steps, and each pin lands on it as you pick it.

Each page can be open several times, once per account, and every account keeps
its own login session, belonging to the team it was opened under.

## Using it [#using-it]

* **Open a page:** go to Custom, find it in the sidebar (search at the top),
  and click it.
* **Add another account:** hover the page's folder in the "Open" list and
  click the plus. It opens a second session of the same page, signed out, so
  you can log in as another account.
* **Add a page:** **New** at the bottom of the sidebar opens the catalog,
  searchable. Pick a platform to open it (a hidden row comes back this way), or
  paste an address to add it as your own page. "New page with its own name,
  color and icon" leads to the full form. Its chevron also holds **New folder**.
* **The start screen:** with no page or chat open, Links shows the six
  latest conversations from Inbox (hidden ones left out, right-click for the
  same menu as Inbox), then the Start new conversation field, then the pages
  already open as chips, each closable, with Close all.
* **Start new conversation** (`NewChatComposer`, inline there and in the New
  chat dialog from the feed's + and ⌘K): one panel. Type a name and people
  from Aden and every connected app list under the field, with a tab per
  app and its count, each avatar badged with its app and each row a tick
  box. The same contact listed twice on one app shows once. Pick one for a
  chat, several for a group; the first pick settles the app. The bar at the
  bottom takes an optional first message and starts it, and a group gets a
  name field on top. Pressing Links on the rail while already in Links, or the
  home button beside the address, comes back to it. When Beeper isn't
  connected, the step to connect it shows on the screen itself.
* **The sidebar has no headings:** Inbox, the groups, Later and Hidden,
  then the pages. Links settings live in Inbox's own settings; a new group
  starts from a chat's right-click (Add to, New group) and a new page
  from Other or ⌘K. The thread pane's empty state carries the Start new
  conversation field too, and in the list layout search spans the row.
* **Rename a group:** right-click a group chat, Rename group. Beeper chats
  are renamed on their network (`PATCH /v1/chats/{id}`), Aden threads
  through `PATCH /chat/threads/:id`.
* **Several chats at once:** ⌘-click (Ctrl-click on Windows and Linux)
  picks a row, Shift-click a range from the last one picked, ⌘A every row
  on screen while the list has focus. A bar floats over the list with the
  count and what to do with all of them: mark as read or unread, pin or
  unpin, hide from Inbox (show, on Hidden), mark as spam, move to a group,
  and delete. Email goes to the mailbox's own trash and a chat from Beeper
  is deleted as below, after a confirm that names how many. A row its app can't do it on
  is passed over and named in the toast ("Deleted 2. Jay can't be deleted
  from Aden: WhatsApp keeps it."). Escape, the bar's cross, another list or
  filter, or opening a chat lets the rows go.
* **Peek at a chat:** rest the pointer on an unread chat's badge for a
  moment (or focus the row and press Space) and its last few messages show
  beside it, in the
  thread's own bubbles, newest at the bottom, with who wrote each in a
  group and when. Nothing opens and nothing is marked read. It reads the
  chat once and keeps it, so the next look is instant and opening the chat
  paints at once. No peek while a row is dragged or the list scrolls.
* **Group anything:** "New folder" drops a naming row at the top of the
  sidebar. Drag rows onto a folder to file them, back out to unfile. Dropping
  one row on the middle of another folds the two into a folder named after the
  row that was already there; nearer either edge still reorders. An empty
  folder offers "Add a page", where a pasted link becomes a page on the spot.
* **Switch pages:** hold Ctrl and press Tab. The list is ordered by when you
  last looked at each one, so a single Ctrl+Tab flips back to the previous
  page; keep pressing to reach further back, Shift+Tab to walk the other way,
  release to commit, Escape to stay put. It reaches everything the shell has
  open: System, Aden, Links and each open page.
* **Switch rails:** hold Option and press Tab (Mac); it works like ⌘Tab.
  The rail's surfaces: System, Aden, Organisations and Admin for the people
  who have them, Links and every pin under it. A quick tap flips back
  without showing the panel; hold to see it, keep pressing Tab (Shift to go
  back, or the arrow keys), hover to point, and release to switch. Enter or
  a click switches too, Escape stays put. Each open surface shows a preview
  of how you left it; the web app is one page, so of Aden, Organisations
  and Admin only the one it shows has one. Windows and Linux keep Alt+Tab
  for themselves.
* **Close from a switcher:** with either switcher up, W (or the × on a
  card) closes the one selected and the list stays up, as ⌘Tab's Q does.
  Ctrl+Tab closes an open page; Option+Tab closes the pages a pinned app or
  link has open. System, Aden and Links have nothing to close.
* **Moving between views:** opening a chat pushes it in from the right while
  the list steps back and fades; back reverses it. Home, the chats list and a
  page like Instagram crossfade, and another chat in the split view's pane
  eases in over the last.
* **Resize the chats list and a chat:** in the full-width list view, drag
  either edge of the column. The list and an open chat each remember their
  own width; double-click an edge to go back to the default.
* **Resize the sidebar:** drag its right edge. Local's sidebar does the same.
  Double-click the edge to go back to the default width. Each width is
  remembered per surface.
* **Pin to the top:** a page's menu can pin it to a grid of tiles above the
  list, for the handful you open every day.
* **Share a folder:** the folder menu's "Share folder" gives you a link. Send
  it to anyone: the page on aden.space lists what is in the folder, and "Open
  in Aden" hands it to their desktop app, which asks them to confirm before
  adding anything. No account needed to open the link, and your logins never
  travel with it. The raw code is still there under "Or send the raw code",
  for pasting into "Import folder" by hand.
* **Team links are the platform rows.** A link the team saved for Instagram is
  the Instagram row, showing the handle beside the name; opening it lands on
  that profile rather than the platform's home page. A link on a platform the
  catalogs don't carry gets its own row. "Team links" behind the **i** at the
  bottom of the sidebar opens the web app's Links page.
* **China is in the catalog.** Weibo, WeChat, Xiaohongshu (RED), Douyin,
  Bilibili, Kuaishou, Zhihu and Douban under Socials, NetEase Cloud Music and
  QQ Music beside them, and NetEase Cloud Musician, Tencent Musician, Douyin
  Creator, Bilibili Creator, Xiaohongshu Creator and Kuaishou Creator under For
  artists. They start hidden like the rest of the catalog, and the web app's
  Links page carries the same ids, so a link saved there lands on the row.
* **One list, your order.** Catalog platforms, your pages and the team's links
  are all the same kind of row: drag any of them from anywhere on the row, into
  a folder or out of one. A row shows two controls on hover, close and "…";
  opening a new account, hiding the row, detaching it to its own window,
  pinning and renaming are all in that menu. Hidden rows collect behind a
  "N hidden" row at the bottom, and the New button's catalog brings one back.
* **Messaging apps first.** Until you drag rows around, the sidebar leads
  with the apps people message you on (WhatsApp, Instagram, Messenger, X,
  Telegram, Discord, LinkedIn, Snapchat, WeChat), then your own pages, then
  everything else. "Put messaging apps first" behind the **i** forgets your
  dragged order and goes back to that; folders and hidden rows stay.
* **The sidebar starts short.** Before anyone arranges it, it shows Instagram,
  TikTok, Facebook, YouTube, X, SoundCloud, SoundCloud for Artists, YouTube for
  Artists and Apple Music for Artists. The rest of the catalog is hidden, not
  gone: unhide from the "N hidden" row or the New button's catalog. A page you
  are signed into is never hidden, whatever the layout says, or the session
  would have no way back to it.
* **The handle appears on hover.** Sixteen rows each carrying a second string
  is the clutter; which account it is only matters once you are reaching for
  the row.
* **The page's title is in the title bar** whenever a page is on screen,
  beside back and forward. Reload shows while the field is hovered (Stop
  while a page loads), and the magnifier turns into Links home. Click it for the address: paste a deep
  link and hit enter. A page with no title yet shows its short address.
* **Cmd+W closes the page**, not the app: the application menu binds it to
  "Close Tab", with Shift+Cmd+W for the window. With no page open it closes the
  window as before, and in a detached window it closes that window.
* **Detach a page** with the button beside the address, or on the account row
  in the sidebar. It opens in its own window on the same session, so nothing
  asks you to sign in again, and the tab closes: the page moves rather than
  being duplicated.
* **Scale the app:** Cmd/Ctrl with `+`, `-` and `0`. It scales every Aden
  window, including detached pages, and survives a restart.
* **Appearance:** switching the app between light and dark switches the pages
  with it. Sites that keep their own theme setting still win, since that is an
  explicit choice the user made on the site.
* **Add people from their profile:** on someone's profile in Links
  (Instagram, TikTok, X, YouTube, SoundCloud, Facebook, LinkedIn, Threads,
  Bluesky), a pill at the bottom left ties them to Aden. If a contact has
  that handle, it opens the contact. Otherwise it offers a new contact (name
  and handle filled in from the page) or adding the handle to an existing
  one, with contacts of the same name first. The x puts it away for that
  profile. X, YouTube, SoundCloud, Threads and Bluesky have no handle field
  on a contact yet, so those offer a new contact only.
* **Search a platform from ⌘K:** type a platform and a name, "ig
  andrewaofficial", "tt mave", "yt mave trance drums". The palette offers
  "Open @andrewaofficial" (their profile) and "Search Instagram for …", both
  in that platform's Links tab. Aliases: ig/insta, tt, x/twitter, yt, sc, fb,
  li, th/threads, bsky, pin, reddit, sp/spotify (`lib/social-search.ts`).
* **Search (⌘K):** one palette for the whole desktop, opened from the Local
  sidebar's search box or the keyboard. It finds this
  app's screens, your pages and your open sessions. It does not search tracks,
  releases or people: when a query has no local match it says so and offers to
  carry it to the web app, organisations or admin, opening that surface's own
  palette with the query.
* **Extensions:** load your own unpacked Chrome extension into the pages Custom
  opens ("Extensions" behind the **i** at the bottom of the sidebar). Content
  scripts, storage and messaging work; toolbar buttons and most `chrome.tabs`
  calls do not, and Aden's own session never loads them.
* **Pages load when you open them.** Sessions are remembered for every team,
  but a tab only gets a live page once you go to it, and only while its team is
  the active one. Switching team drops the other team's pages; their logins
  stay, and they reload when you go back.
* **Personal is a workspace too:** with Personal picked in the switcher,
  Links lists its pages and inbox like a team's, and pages (and pins) open
  with your own logins, kept apart from every team's.
* **Pages reopen where you left them:** quit and relaunch, and each open
  page (a rail link, Instagram) loads the address it was last on, not the one
  it was opened at (`aden:social-tab-urls`, `lib/tab-last-url.ts`).
* **Audio:** a page playing behind another surface shows up as a pill in the
  title bar naming it. Click it to jump to that page, mute just that one, or
  silence everything at once. Pages also need a click before they may play at
  all, the same rule a browser applies, so a restored session no longer starts
  a sound from nowhere.
* **Feed:** the Feed row at the top of the sidebar collects the messages every
  open page announces (a WhatsApp message, an Instagram DM, a Discord
  mention), newest first. Each row in the sidebar also shows its page's
  unread count. Open a message to go to its conversation; most chat sites
  jump straight to the chat.
* **Two ways to read it:** the toggle in the feed's toolbar switches between
  the feed on its own (opening a message leaves the feed for the page) and the
  feed beside the conversation (the feed stays as a column, the page opens to
  its right). The app remembers your pick.
* **Choose what shows:** the network button in the feed's toolbar (their
  icons stacked, the ones turned off faded) opens a checklist that turns a
  service on or
  off, and so does "Show in feed" in a row's "…" menu. A hidden service keeps
  its unread badge in the sidebar. Search "feed" in ⌘K to open it.
* **Your conversations, not just new messages:** for Instagram, WhatsApp and
  Claude the feed reads the inbox you are signed into and lists every conversation
  with its last message and unread state, merged with Beeper's (when
  connected) and newest first. Opening one takes that page straight to the
  chat. It refreshes every 30 seconds while the page is open in Links. Claude
  lists your Claude Code sessions and chats, so two Claude logins on the rail
  read as one list, each row named for its account.
* **Right-click a chat** for a menu you can type into. A search box on top
  has the cursor; under it a row of icons for the everyday things (Pin, Mark
  as unread, Remind me, Hide from Inbox; hover one for its name and letter);
  then the list: Start a session, Collaborate on a track…, Invite to Aden
  (when they are not on Aden), **Add to** (Collaborators…, Contacts…, a lead,
  and the feed's groups with New group…), **Contact** once they are one
  (open it, email them, their team on Aden, link a team, copy the handle),
  and the chat's own rows. Typing filters all of it, the rows inside Add to
  and Contact included, and brings in the palette's rows about them under
  "From ⌘K": their profile and a search for them on their network, their
  chat, a new track or email with them in mind. The menu looks them up
  first: your team's contacts by handle, email or phone, and any team that
  lists that handle publicly on its profile. Someone not on Aden yet gets an
  invite by email from the session or track you add them to. In your own
  workspace these run for your default team (else your first), and the menu
  names it; only with no team at all does it ask you to join one.
* **Photos, video, voice notes and files** in Beeper chats show in the
  thread: photos inline, videos with Aden's player (first frame, play,
  hover controls, full screen), voice notes and songs with the Aden
  waveform to scrub and a speed button once played, files as a row you
  click to open. Voice messages in Aden chats play there too. One message
  plays at a time.
* **Transcribe a voice note:** the captions button beside it shows the
  network's transcript when there is one, and otherwise transcribes it on
  the first press. Up to 25 MB, 60 an hour.
* **Shared reels play in the thread.** Beeper only sends a reel's still and
  its link, so the still gets a play button that swaps it for Instagram's
  embed player (`instagram.com/reel/<id>/embed`, `lib/instagram-embed.ts`),
  in the team's Instagram session so follower-only reels play too.
* **Posts open floating, signed in.** Click a link to an Instagram, Threads,
  TikTok, YouTube, Facebook or X post in a thread and it opens in a floating
  window over the page, on that page's login in the workspace (the account
  already open, else its first), so liking or commenting for an engagement
  group is one click. The next post of the same page loads into the same
  window; closing it closes its tab. Share parameters (`igsh`, `utm_*`,
  TikTok's `_r`, YouTube's `si`) are dropped first, so the visit is not tied
  to whoever shared it (`lib/post-links.ts`). Any other web link floats the
  same way, on a plain page of its own (`WEB_LINK_PLATFORM_ID`), named by
  its site; mailto and files go to the system. In a popped-out chats window
  a link opens in a window of its own. Either way it loads as a phone
  (Safari on an iPhone, `MOBILE_USER_AGENT`), so the site serves the page it
  made for that size.
* **On every outside page.** The sidebar (or bar) shows on every page from
  another site, not only ones Aden can read: asking for a review and the
  link's own actions always apply. It finds the page again while a new tab's
  view is still arriving (`usePageLocation` retries), so it no longer stays
  missing until you switch tabs.
* **Where it sits.** For the main window's page (a social tab or a rail
  pin) the sidebar lives in the window frame on the right, on the frame's
  glass, outside the page; folded, it is a thin strip there with the open
  button on top. The page card makes room for it (`ShellFrame`'s `right`).
  Its fold button is the web app's sidebar toggle; folding and opening glide
  the page's edge rather than snapping it. Rows sit at full strength on the
  frame's glass so they read beside a busy page.
  In full page (⌘S) it slides in over the page from the right edge, like
  the rail from the left. Split panes and floating windows keep it beside
  their page. As a bar it
  floats over the main pane.
* **Aden beside the page.** On any page Aden can read (DISCO, Samply,
  Session Studio, Songspace, untitled, SoundCloud, Dropbox, Drive, Google
  Docs and Sheets, Notion: `WORK_PLATFORMS`), any music link (private
  SoundCloud links too) and anyone's profile, an Aden sidebar runs down the
  page's left edge, in the main pane, split panes, floating windows and
  popped-out windows. Open, it is a labelled column that scrolls: the
  person the page is about (who they are to the team, their contact or
  "Add @handle to contacts", Collaborate on a track, Add to
  collaborators), like/pass and stars on music with its "…", the page's
  actions (the same ⌘K offers for the link: a track from it, the track its
  title names, a folder to import) and **Ask for a review** (see
  `link-reviews`). Open, the header holds like/pass and the rating, and the
  rows sit in two groups, "This track" (or "This page") and "Artist". The
  fold button turns it into an icon strip with the same things behind
  popovers (`aden:rail-collapsed`). The float button turns it into a bar
  over the page's foot instead, on the app's frosted glass
  (`floating-toolbar.tsx`, shared with the Inbox's selection bar): the
  person, the verdict, a plus for everything Aden can make of the page, and
  saving, reviews and the rest as icons, each with a tooltip; its sidebar
  button docks it back. A third layout, **Bar at the bottom**, fixes it
  across the page's foot, and a floating bar goes there on its own when the
  page is too narrow (picture in picture, a small floating window). The
  Layout menu (sidebar header, the bar, "Aden beside pages" in the page's "…" menu) picks among them,
  remembered on the computer (`aden:rail-layout`). The sidebar's edge drags wider or narrower
  (`ResizableSidebar`, `aden:rail-width`); the bar moves by its grip, stays
  inside the page, and a double-click on the grip puts it back
  (`aden:rail-bar-offset`). Hovering the star opens the five stars. In a pane under 640px wide the open sidebar
  floats over the page instead of squeezing it. It replaced the floating
  "Add to Aden contacts" pill (`ProfileContactSection`). The window's ⌘K
  offers the open page's actions first (`open-page-rows.tsx`). SoundCloud
  has no contact column, so a SoundCloud handle is kept as a profile link
  on the contact (`profileLink`) and matched back through those links.
  `aden://page?url=` opens a page this way from outside the app.
* **Menus close on a page click.** A menu or popover opened from the rail
  or the title bar closes when the page is clicked: a click inside a webview
  never reaches the window's document, so the main process relays it
  (`shell-page-pointer-down`, to the window hosting the page) and
  `closeOpenPopups` plays it back as an outside press.
* **⌘K on any page.** ⌘K pressed while a page has focus opens the app's
  palette (relayed as the `command-palette` browser shortcut); Aden's own
  pages keep their own ⌘K.
* **No sign-in walls.** SoundCloud's "Create an account or sign in" modal
  never shows on a page open in Aden, nor its cookie notice, the
  OneTrust cookie banner on any site, the "Now available" upsell
  banner or the Go mobile, legal links and language blocks:
  `main/page-annoyances.ts` hides them with CSS and a text match. Its Sign in button
  still works.
* **Hide anything on a page.** Right-click a page open in Aden (not Aden's
  own) for its menu: Back, Forward, Reload, Mute this page, Copy, ✦ Create
  on selected text (the chat bubble's rows: a track, a studio session, a
  todo, opened in quick create), Copy link, Copy page address, and **Hide
  this element**, which hides the block under the
  pointer on that site from then on; ⌘Z right after brings it back. &#x2A;*Show
  N hidden on \<site>** brings them all back, and "Hidden on this site" in the page's "…"
  menu lists each hidden element with its own Show. Saved as selectors per host in `hidden-elements.json`
  (`main/page-element-hider.ts`).
* **Mute a page.** While a tab plays sound the title bar has its speaker:
  click to mute or unmute. Mute this page in the right-click menu does the
  same.
* **Find on a page (⌘F).** The title bar's address field turns into find
  while it is open, with how many matches there are (`3/12`); Enter and
  Shift+Enter step through them, Escape leaves (`FindBar.tsx`).
* **Swipe back and forward.** A two-finger swipe goes back or forward on a
  page, like a Mac browser (`main/webview-swipe-nav.ts`: a wheel listener
  in each page, ignored where the page itself scrolls sideways).
* **A SoundCloud playlist, track by track.** On `soundcloud.com/…/sets/…`
  the sidebar lists the playlist's tracks, read from the page
  (`use-page-tracks.ts`), each with like, pass and stars kept in the team's
  demos, and "Add all N to demos". The bar has the same list behind a list
  button.
* **Keep a page on a track.** A song's page (Spotify, Apple Music, YouTube,
  SoundCloud, Bandcamp, Mixcloud, Tidal, Deezer, Beatport) offers &#x2A;*Add as
  reference track…**; a picture or a video (Pinterest pins, Instagram
  posts and reels, TikTok, Behance, Dribbble, Are.na, Unsplash, Vimeo,
  YouTube, any image file) offers &#x2A;*Save as inspiration…**. Either opens
  the team's tracks; picking one saves it as that track's reference
  (`track_references`, title and artist read from the page title) or on its
  moodboard (`track_media`, `is_inspiration`), with Open in the toast.
  ⌘K offers both while the page is open. Read in
  `@aden/navigation/smart-saves`, saved through
  `POST /tracks/:id/references` and `/tracks/:id/inspirations`.
* **Reply to a message:** right-click it, Reply (R). The reply box shows
  who and what you answer (Esc or the x cancels), and it goes out as a
  real reply on that network (Beeper `replyToMessageID`, Aden `replyTo`).
  Email answers the whole thread instead.
* **Send photos, videos and files:** paste (Cmd+V) or drop them on a
  Beeper chat. They wait above the reply box as thumbnails (x removes one);
  Enter sends them as the network's own photo, video or file, the draft as
  the first one's caption (`beeper_send_local_file`, read from disk as it
  uploads). A pasted screenshot is saved to a temp PNG first
  (`save_clipboard_image`). "..." hands them to "Send as a transfer" or
  "Start a track" instead. Aden chats and email have no native file send,
  so files there go straight to those options.
* **Edit your message:** right-click one of yours, Edit (E). Its text moves
  into the reply box under an "Editing" bar (Esc or the x cancels and gives
  back the draft you had); Enter saves. The bubble changes at once and shows
  "Edited" under it, as does any message edited elsewhere. A refused edit
  puts the old text back, with "Edit again" on the toast. Edit only shows
  where the network edits: Beeper reports it per chat (`capabilities.edit`,
  window `editMaxAge`), text messages only, saved with
  `PUT /v1/chats/{chatID}/messages/{messageID}`; past the window the item
  stays, disabled, "Too old to edit". Aden edits your own text messages with
  no window (`PATCH /chat/threads/:id/messages/:messageId`). Email can't.
* **Photos open large:** click one to zoom it over the window. Photos and
  videos keep their size before they load, so the thread never jumps.
* **Hover a link to preview it:** its title, image and site, read by the
  main process (`link_preview`, `@aden/shared/utils/og-metadata`) the first
  time you hover it.
* **Cards float over the thread.** The cards a chat's messages bring up (a
  track, a day to plan, asks) sit over the top of the thread on a fade of
  the page, so one appearing never resizes the thread. They are glass
  and lift in and out. A day like "tonight" or "tmr" counts from when its
  message was sent, and a day that has passed brings no card.
* **Opened links get a check.** A link you opened shows a check after it,
  for you only (local to this computer, `aden:opened-links`, the last 2000),
  so you can see which posts still wait on you. The same post shared twice
  counts once. Right-click the message, "Mark … as not opened", to clear it.
* **Aden chats in the feed:** your Aden conversations sit in the same list as
  Beeper's, with the Aden mark on their avatar, and open in the same thread
  view with a reply box. Aden says whether a chat is unread, not how many, so
  those show a dot. The **Aden** row in the sidebar, above your mailboxes,
  opens the Inbox with only your Aden chats and counts the unread ones; ⌘K
  "Aden chats" does the same.
* **Seen:** a row whose last message is yours shows "Seen" once it has
  been read, or "Seen by 3" in a group, where the unread badge sits on
  other rows. Beeper chats read it from the last message's read receipt
  (`seen`), Aden chats from the thread list's `lastMessage.seenBy`, counted
  from every member's receipt. Nothing shows while it is only sent or
  delivered, nor for networks without read receipts (email, Signal).
* **One person, one row:** chats with the same person on several networks
  fold into one row with each network's mark beside the name, in Inbox and
  on the Links start screen. They fold when they match the same Aden contact
  (Instagram handle, email or phone), share a phone number or email, or have
  the same full name on different apps (two words or more; two chats on one
  app never fold by name). Aden DMs fold in too. It's on by default: "Merge people across apps" in
  Inbox settings (and Links settings, and ⌘K) turns it off, and a folded
  row's "Show chats separately" splits one person again
  (`lib/person-fold.ts`). The setting, the people shown apart and chats tied
  to a contact by hand are kept on the account (`app_preferences.links_people`,
  per workspace for the ties), so every install shows the same people.
  Opening a folded person ties each of their chats to the contact, and a tied
  chat older than the loaded pages is fetched on its own, so a fold holds
  once one of its chats scrolls out of the newest page.
  The row behaves as one conversation: its message and unread state are the
  latest one, on whichever network it came, and opening it reads the person
  on every network. The thread has a tab per network to reply from, starting
  on where they last wrote. The network icon on the reply box is the same
  switch: hover or press it for the person's networks, and "Add a network"
  lists your other Beeper logins and the networks the contact has a handle on.
  Picking one joins their chat there to the person: the chat Beeper already
  has, one Beeper starts from the contact's handle or number, or, when neither
  exists, that network's page floating on your login (their profile when the
  handle is known, else a people search for their name) where you write to
  them; the first chat Beeper then shows with them on that network joins the
  person on its own (`ComposerNetworkSwitcher.tsx`).
  Right-click a chat and "Link to contact…" to fold in one that doesn't match
  on its own (a WhatsApp chat named by a number, say); "Unlink" undoes it.
  A folded row's menu opens any of its chats ("Open on WhatsApp").
* **Chats and Pages:** the Links sidebar has two halves. Chats on top: Inbox
  (every conversation) and your own groups. Pages below: the pages you use,
  with the rest behind "More pages". Make a group with the "+" beside Chats
  or "New group…" under Add to in a chat's right-click menu; file a chat
  there too (its group is checked; pick it again to take the chat out), or
  drag it from the feed onto a group in the sidebar (onto Inbox to
  take it out of its group, onto Hidden to hide it), or with "Add people" in
  the group's toolbar or on its empty state, a searchable list of your chats. A chat sits in one group at most, so Inbox always shows everything.
  Right-click a group to rename or delete it (its chats go back to Inbox
  only). Groups are in ⌘K too, and stay on this Mac.
* **Right-click a message** in a thread: Reply, React (the quick emoji, as
  a page) and Copy as icons, then its file, its links, its music as demos,
  and the sender's Aden actions (the same as a person's), all searchable
  like a chat's menu. In a group, the sender is
  named but has no handle, so the lookup matches on name only via contacts.
* **Hide a conversation** (Note to self, a code bot) from its right-click
  menu. Hidden ones collect under **Hidden** in the sidebar's Chats section;
  open it and right-click one to show it again.
* **Spam, block and delete** a chat from Beeper in its right-click or "…"
  menu. Beeper can't delete a chat or block anyone on their network, so:
  **Mark as spam** and **Block** (one to one only) mute the chat in Beeper
  and move it to **Spam & blocked** in the sidebar, whatever they send next;
  it stays out of Inbox, unread counts and follow-ups. Right-click it there
  for **Not spam** or **Unblock**. **Delete chat** asks first, then
  archives it in Beeper: it leaves Aden and Beeper until they message again,
  and stays on its own app. Each toast has Undo.
* **Spam, block and delete an email** from its right-click menu or the
  thread's "…" menu (a person's row acts on every email folded into it).
  **Move to spam** and **Delete email** take the row off at once with Undo;
  after five seconds the thread goes to the mailbox's own spam (Gmail's
  Spam, Outlook's Junk Email) or trash (Gmail's Trash, Outlook's Deleted
  Items). Inboxes connected before this existed are told to reconnect: it
  needs Gmail's `gmail.modify` or Graph's `Mail.ReadWrite`. &#x2A;*Block
  \{sender}** keeps that address's mail out of Aden in every workspace,
  what they sent and what they send next, without touching the mailbox; it
  lists under **Spam & blocked**, where **Unblock** brings it back.
* **Unread:** the reply icon on the sidebar's Inbox row, the feed filter's
  Unread option, or "Unread" in ⌘K narrows Inbox or a group to the chats waiting on you: unread, marked unread, a
  reminder that came due, or a one-to-one chat ending on their message.
  Hidden, Later, spam, blocked and low-priority chats stay out, and so do page
  notifications you already read. It reads the loaded chats only; press it
  again, clear the filter, or "Show all chats" once you're done, to see everything.
* **Search people and messages:** the box in the feed's toolbar filters every
  conversation, page notification and unread row by name, network and message
  (typos included). With Beeper connected it also asks Beeper, so a chat older
  than the 50 most recent still turns up. Every conversation is also in ⌘K:
  type a name and pick it to open that chat in the feed.
* **Unread first:** the top of the feed lists every open page with something
  waiting, with the same count as its sidebar badge, so unread from before the
  app opened is there too. Below it come the messages themselves.
* **Reply from the feed with Beeper:** connect Beeper Desktop from the bottom
  of the feed ("Connect Beeper", then approve Aden in Beeper). The feed then
  lists your real conversations on every network Beeper holds, and opening one
  shows the thread with a reply box: full width with a back arrow in the feed
  view, beside the feed in the split view. Replies go out from your own
  accounts. Networks Beeper covers stop showing their page notifications, so
  nothing appears twice. Beeper not running? "Start Beeper" launches it
  without its window (hidden on macOS). Once you have connected it, Links
  starts it that way on its own whenever it is closed; turn that off with
  "Start Beeper in the background" in the feed toolbar's Beeper menu or in
  Links settings. No browser? Paste a token from Beeper's Settings instead.
* **The desktop tour shows it:** the second step of the first-run tour plays
  a chat on sample rows (a sent track kept as a demo, a swipe that brings in
  Together, a group chat that starts a session, one linked to a release) with
  the same Beeper connect step under it. A two-finger swipe on the sample
  chat toggles Together, as it does in Links. Connecting there is optional.
  Settings → General → Onboarding "Replay" (or "Replay onboarding" in ⌘K)
  runs the whole tour again from its first step.
* **Email addresses in a message open a menu:** write an email, copy the
  address, or invite them to Aden by email. When the address belongs to a
  team or organisation member it says so, with their profile. When a
  contact's name fits the address (or the sender's name), "Save on \<name>"
  puts the address on that contact. Below that are the same person actions
  as a chat's menu: start a session, collaborate on a track, then a
  **Contact** submenu (open it, their team on Aden, link a team, copy the
  handle, and every group including Collaborators as one checked list).
* **A chat's "…" menu is the same menu:** the icon row, the person's rows,
  "Link this chat to…", Add to and Contact, then **Chat** (add a chat from
  another app, show a network's chat on its own, show what you share,
  Search). Same search box, same letters, so both read the same.
* **Music they send becomes a demo:** a SoundCloud, Dropbox, Drive, Box,
  OneDrive, WeTransfer, Inflyte, DISCO, untitled, hearthis.at, Audiomack or
  Suno link, or a direct audio file, gets a card under the message. It plays
  there in the platform's own player when the link allows it. The card
  always shows like (green), pass (red) and a 1-5 rating: the first one you
  set puts the link in the team's demos with the sender's name, once per
  link, with that verdict. Pressing the active thumb again takes it back to
  undecided, the same on the web demo cards, which lost their Pending
  button. The card's "…" holds the rest: Add to or Open in demos,
  Download… (you pick where; the toast shows the percentage), Add to a DJ
  playlist… (saved to \~/Music/Aden/From chats and added as a row, so a sent
  playlist carries it to rekordbox, Serato, Traktor and Virtual DJ), Upload
  to Aden as a new track or as a version of one, and Open on the host.
  Download, playlist and upload need a host that hands out the file by
  address (Dropbox, Drive, OneDrive, a direct audio link); SoundCloud,
  WeTransfer and promo players get demos and "Open on …" only. A host that
  answers with a web page instead of the file says to download it in the
  browser. "Open in demos" and every other Aden page opened from Links move
  the web app with its own router, without a reload.
* **Actions on a message:** hovering a message that asks for something
  ("do you want to collaborate?", "send over a playlist") shows a sparkle
  button with actions for that message alone. "Send a playlist of your tracks" makes a playlist of the
  team's 50 newest tracks and writes its share link into the draft; `#`
  lists the team's playlists and albums under its tracks, and `/playlist`
  makes one too. Planning suggestions stay at the top; there is no bottom
  suggestion bar.
* **Files people send:** a file, photo, video or voice note in a message
  has a "…" (and the message's right-click has Add to Aden and Save): audio
  as a new track or a version of one, a photo or video in a track's media,
  anything as a document of the team or of a track, or saved where you
  pick. The file comes from the chat first, with a toast for how it's
  going.
* **Click a file to open it:** a file row (PDF, doc, zip, anything) opens
  in the app your computer uses for it, no saving first. A sent song has an
  open button beside its player, and every file's "…" and right-click have
  Open. The row reads "Opening…" while it downloads; a second click opens
  the copy already there. A file that runs code (an app, a script, an
  installer) shows in its folder instead of opening.
* **Letters in the menus:** every chat menu shows ⌥ and a letter beside its
  rows; pressing them runs the row, whether or not you have typed. Plain
  letters always search, so typing "session" never trips a row. The letters
  are the first letter of their row. Conversations: P pin, U unread, R remind (opens the times; T there
  picks a time), L link to contact, H hide, which also work while the
  pointer is on the row with the menu closed. A person: S session, T
  collaborate on a track, I invite; inside Add to, K collaborators, A
  contacts. A message: R reply, E react, C copy, O open its file, F save it,
  D add its music as a demo. Inside a submenu page, ← or Backspace on the
  empty box goes back, and Escape goes back before it closes. A music card:
  A demos, D download, P DJ playlist, N new track, V version, O open. A
  file: N new track, V version, M media, D team documents, T track
  documents, O open, S save.
* **Inbox header:** one row, search first. The layout (list, or list and
  conversation), which networks show, and Beeper's accounts, autostart and
  disconnect sit behind the cog. A group, Later or Hidden names itself;
  Inbox needs no title. Avatars carry a small, quiet network mark. Opening
  a page, from the sidebar, a feed item or a page conversation, gives it the
  whole width; opening Inbox leaves the page.
* **New chat or group:** the sidebar's floating "New" (or "New chat or
  group" in ⌘K; New's menu also adds a page or a folder) opens the same Start new conversation panel in a dialog.
  It opens in the inbox once the chat exists.
* **Type it in ⌘K:** "ig gc with Senator and Palm Skies", "group chat with
  Jo, Sam & Kim on whatsapp", "dm Senator on insta", "telegram Jo". The row
  opens the same panel on that network with each person looked up in its
  Beeper contacts (or on Aden) and picked; a name nobody matches stays in
  the field with its results. Works for every network Beeper connects
  (Instagram, WhatsApp, Messenger, Telegram, Signal, iMessage, Discord,
  LinkedIn, X, Slack, Google Messages) and Aden. The phrases are read by
  `lib/chat-intent.ts` (`parseChatIntent`).
* **The split, your way:** in "List and conversation", drag the line
  between them to give either more room (the conversation keeps at least
  360px); double-click it for the default. The width is remembered. In the
  list view the search row lines up with the list's column.
* **"#" tabs:** All, Tracks, Playlists and Albums over the share list; ←
  and → switch between them.
* **Pages: yours, then Other:** the sidebar lists your pages (a saved team
  link, a page you added, a chat app you're connected to, anything with an
  open session) and the ones you pinned. Everything else waits in Other, a
  flyout with search where each page opens or pins to the sidebar, and a
  chat app also opens straight to its chats. A row's
  "…" has "Move to Other".
* **Two conversations at once:** in "List and conversation", drag a row to
  the left or right edge of the open conversation to open it beside it. The
  pane beside has a slim header: close it, or make it the main one (the two
  swap). With two open, a row dropped at an edge replaces the pane there.
  The pane closes with the list; it isn't remembered. The drop zones and
  the frosted outline (the same one a page dragged from the rail shows,
  `SplitDropPreview`) only appear while a row is dragged, so nothing moves
  before that (`ChatPaneDrop.tsx`, `lib/chat-drop.ts`).
* **A chat dropped on a chat:** drop a one-to-one row on another row, or on
  the middle of an open conversation, and what happens depends on who is on
  each side. A chat from another app joins that person's row at once:
  whether or not the fold matches them (contact, phone, email, full name),
  a group can't span apps, so "Glenn" on WhatsApp dropped on "Glenn
  Troncquo" on Instagram means the same person. Two people on
  the same app and account get "Start a group with …?", with an optional
  name; Beeper makes the group on the network (`beeper_chat_group_from`,
  from the other side of each chat), Aden makes a thread with both. A
  person dropped on an Aden group is added after "Add … to …?"
  (`aden_chat_add_members`, the thread says who added whom). A group, or a
  person folded from several chats, can't be dropped onto anything. A chat
  dropped on a group from another app is blocked with the reason. Beeper's API makes groups but adds no
  one to an existing one, so that drop is blocked with the reason and where
  to do it instead.
* **Same person, one row:** drag a chat from the list onto the name at the
  top of an open conversation to bundle them: the chat joins that person's
  contact (made from the open chat when there is none yet). "Add a chat"
  does the same from a search: it lists loaded chats and asks Beeper for
  older ones as you type (`useBeeperChatSearch`). Below them, "Search … on"
  Instagram, Facebook, X or LinkedIn opens that app's people search on your
  login there (`find-person-links`, `openOnLogin`), for when Beeper has no
  chat with them.
* **Not on Aden yet:** a mail icon beside the thread's name says so and
  holds the invite button; the line under the name keeps what they are to
  you (contact, collaborator, their team).
* **Collaborators from a chat:** "Add to collaborators…" in a person's menu
  opens the contact picker with your collaborators first, the same name
  next, and, as you type, Aden teams: picking a team saves them as a
  collaborator in that team.
* **Whole history, fast:** a thread loads its newest page and the page
  before it whenever you scroll up near the top, keeping your place. Opening
  or sending never loads older pages or moves the thread off the end; only the
  messages on screen render, so a long chat scrolls as fast as a short one.
  Beeper chats go back as far as Beeper has them; Aden chats as far as their
  history keeps (500 messages). The refresh every few seconds adds new
  messages without dropping the ones scrolled back to.
* **Search in a chat:** the magnifier in the thread header (or ⌘F) opens a
  search box. Beeper chats search their whole history through Beeper; Aden
  chats search their history here. Picking a result loads back to it,
  scrolls there and marks it for a moment.
* **Replies show at once:** a sent reply lands in the thread the moment you
  press Enter, faded with "Sending…" until the network takes it, and the reply
  box stays open for the next one. A reply that fails says "Not sent" with
  Retry and Remove. The thread swaps each one for the network's own copy when
  it loads, in the same row (`settleOutgoing` in `@aden/chat/smart/outbox`
  says which copy is whose), so nothing re-measures or nudges the thread.
* **Holds on to the newest message:** opening a chat lands on its last
  message, with room under it, and stays there while rows measure, pictures
  load, the cards above fill in and the reply box resizes. Only your own
  scrolling (wheel, touch, keys, the scrollbar) lets go; scrolling back to the
  end holds on again. Jumping to a search result or loading earlier messages
  lets go too.
* **Messages move like a chat:** a message landing at the end of the thread,
  yours or theirs, glides the rows up to make room and comes in from the reply
  box, growing from its corner. Only messages landing at the end move: opening
  a chat, loading earlier messages and scrolling never animate, and reduced
  motion turns it off. (`lib/use-append-motion.ts`: a transform on the rows'
  container, offset by what the scroll jumped, eased back over 240 ms; the
  virtualizer's positions never change.)
* **Read and typing, where the network says:** under your last message,
  "Sent" becomes "Delivered" or "Read" when the network reports it. Beeper
  carries a message's read receipt (`seen`) and delivery (`sendStatus`) for
  networks that have them (WhatsApp, Telegram, Instagram, Messenger); Aden
  chats read the thread's read receipts with every poll. A network that
  reports neither stays at "Sent". In an Aden chat, three dots under the last
  message show someone typing (named in a group), and your own typing is told
  to the thread while the draft changes (every 5s, under the API's 6s hold).
  Beeper's Desktop API carries no
  typing state in either direction (no endpoint to send it, and its event
  stream emits only `chat.*` and `message.*`), and email has none, so those
  chats show nothing for it rather than a guess.
  The same menu disconnects it.
* **Suggestions from what they ask:** above the reply box, one-click actions
  for what the messages on screen ask for. "Can you send the new version of
  Summer Nights?" offers "Send latest "Summer Nights"" (or "Share a version"
  when no track is named), "send me the stems" offers "Send files", "I'll send
  you the stems" offers "Send an upload link", a label or curator email
  like "I'm looking for new music" offers "Send music" (the track picker,
  writing a share link into the reply), "wanna collab?" offers
  "Collaborate on a track" and "Add to collaborators", "studio session
  friday?" offers "Start a session", and "the contract" offers "Request
  documents". A shared SoundCloud track, a Dropbox, Drive, WeTransfer, Box or
  OneDrive file, or any link to an audio or stems file offers "Collaborate on
  "…" in Aden": it starts a track named after the link (noting where it came
  from) and opens Collaborate with it picked. Each writes its link into the
  draft; the x hides them for those
  messages. Only the newest three messages from them that are on screen are
  read, one sentence at a time, so a long email's footer doesn't add a
  suggestion its sentences never ask for. To try it alone, send these to yourself in Beeper's Note to self:
  there, your own messages count.
* **One inbox per team:** the inbox follows the team switcher, like Links
  pages keep a browser session per team. Each team has its own groups, Hidden
  and Later lists, pins, unread marks and contact links. Aden chats show in
  their own team; direct chats (no team) show in every team. Which chats a
  team shows is one list, "Chats" in the inbox's settings: a row per Beeper
  account (two Instagram accounts are two rows) and one per network you only
  have as a page. Every account is on in every team until that team turns it
  off; turning an account on brings its network back too. Beeper is
  connected once per computer, so switching team never asks to pick or
  connect accounts again. The switcher only
  follows the embedded web app when it lands on a team URL
  (`/app/teams/{id}`); any other web page never moves it, so the inbox
  doesn't jump to a team (and lose its chats) when the web app reloads.
* **Connected chat apps first:** under the groups, Pages lists the chat apps
  you use first: ones with an open session in this team or a Beeper account
  on that network, and not turned off in the feed. The rest follow in their
  own order.
* **Groups have a colour and an icon:** set when creating one or with "Edit
  group" (right-click), from the same palette and icons as pages.
* **Manage chats like Beeper:** right-click a chat for Pin (it stays on
  top), Mark as unread, and Remind me: in an hour, two hours, this evening
  (before 18:00), tomorrow 09:00, this weekend (Monday to Thursday) or next
  Monday, or "Pick a time…". The chat leaves Inbox and waits under "Later"
  in the sidebar (and in ⌘K). On time it comes back on top, unread, with a
  notification; a reply from them brings it back early. "Remove reminder",
  first on the Remind me page while one is set, cancels it, and opening the
  chat clears it.
* **Who they are on Aden:** a one-to-one thread shows it under the name:
  contact, collaborator, their team, or "Not on Aden yet". "Connect team"
  picks the team a contact is in (public teams, by name); "Invite" writes your
  Aden invite link into the reply. A person's right-click menu has the same,
  plus "Add to contacts…" for someone who isn't one yet: one dialog to make a
  new contact or pick the one they already are (same name first), with "Add to
  collaborators" to file them in the team's "Collaborators" group. Picking
  ties the chat to that contact, and stores their handle on it. "New
  contact" opens a short form filled from the chat and the search (type an
  email and it lands in Email): name, email, phone, their team (an Aden team
  found by name connects them to it; anything else is kept as the company),
  Instagram, TikTok and website. Saving a collaborator shows a toast with
  "View collaborators", which opens the team's Collaborators group.
* **Share a track in any chat:** type `#` in a thread's reply box, pick a
  team track, then choose every version, the latest one or a single version.
  Aden makes a share link and puts it in the message, so it goes out on
  Instagram, WhatsApp or Aden alike. Versions show when they were uploaded,
  and a play button on each lets you hear it before sharing.
  An Aden link in the draft shows as a card above the reply box (cover,
  title, versions), with an x to take it out.
* **Commands:** `/` at the start of a word in the reply box lists four:
  Share a track, Send files, Request files…, and Request for a track or
  album…. Request files asks files (into your transfers) or documents, with
  the team's upload links that are still open listed under them to reuse.
  Request for a track or album picks one by typing, then asks what: a new
  version, stems, cover art, or photos and videos (cover art for an album),
  with that track's or album's open links under them. Typing after `/`
  reaches every step directly ("/stems", "/documents"). A new version or
  stems is asked for with a share link that takes uploads; artwork and media
  with an upload link tied to the track or album. Each writes its link into
  the draft, to read before sending.
* **Drop files on a chat:** a panel asks what to do with them: send them as
  a transfer link, or, for one audio file (mp3, wav, aiff, flac, m4a, ogg),
  start a track from it (its first version) and either share its link or
  open Collaborate with the person you're talking to, the new track picked.
* **Tag people with `@`:** lists your collaborators and contacts, your team's
  members and your organisations' members. Picking one writes their details:
  a contact's name, email, phone and Instagram; a member's name, email and
  Aden profile.
* **Collaborate finds them on Aden:** when a chat isn't tied to an Aden
  account, "Collaborate on a track" searches Aden users by the person's name
  and handle (`GET /user/lookup`: names, nickname, artist name, profile slug;
  never email) and lists matches with their picture and teams. Picking one
  adds them to the track as that user; otherwise the email invite stays.
* **Collaborators in ⌘K:** "collaborators" opens the team's Collaborators
  group, and each collaborator is a row that opens their contact.
* **Link previews:** an aden.space share link in a thread, sent by you or to
  you, shows as a card: cover, title, team and up to six versions. A version
  plays in the app's player bar (`playRemote`), with its waveform, queue and
  controls, and "Open track" shows when your team has it (the share page
  otherwise). File requests and transfers get a card with their button.
* **What it can see:** messages arrive as the page's own notifications, so a
  page has to be open in Links and signed in. Pages you are not looking at
  are told they are in the background, which is when chat sites notify.
  Messages stay on this computer.
* **Ads:** pages open in Links are filtered by the built-in ad blocker.
  **Block ads and trackers**, behind the **i** at the bottom of the sidebar,
  turns it off per machine and shows how much it has blocked. It used to be a
  switch pinned to the bottom of the sidebar, reporting a number nobody had
  asked for.
* **Cookie banners:** **Hide cookie banners**, in the same menu, removes
  cookie consent popups from pages in Links and unlocks the scrolling they
  block. It works with the ad blocker on or off. Both switches are also in
  the ⌘K palette ("cookie", "ad blocker").
* **Preview an account:** hover it in the sidebar for a live screenshot of the
  page behind it, with its title and domain.
* **Switch teams:** sessions are per team; switching the active team swaps the
  sidebar to that team's sessions.
* **Close an account:** hover it and click the x. Removing a whole page (the
  trash icon on your own pages) closes its accounts and drops their sessions.

## Email in the Inbox [#email-in-the-inbox]

The mailboxes you connected to Aden (your own, your team's, your
organisation's) sit in the Inbox beside your chats, one row per email
thread, and in the Links sidebar under your pages: click one to see only
its mail.

* **Connect another mailbox.** "New" › "Connect mailbox" in the Links
  sidebar (or "connect mailbox" in ⌘K) opens the team's integrations page
  floating over the Inbox, with Gmail and Outlook first
  (`connectMailboxPath`). Without a team it says to pick one first.

* **Read and reply in place.*&#x2A; An email opens in the same conversation
  view as a chat, the sender's name and address under its subject, with a
  reply line under it instead of the chat box. It stays one line until you
  click into it; then it opens, the body growing and its foot fading in
  over a beat, and offers **+ Participant*&#x2A;, **+ Cc*&#x2A;, **+ Bcc** and
  **Reply all**. Left empty, it folds back the same way. The recipients are the thread's
  own and stay out of the way until you open a line. Nothing sends on
  Enter: **Preview** shows the email exactly as it will go out, and Send
  lives there beside Edit. It goes as a reply on that thread, from that
  mailbox, so both sides keep one conversation. A newsletter's Reply-To is
  honoured, and any thread with a message can be answered.

* **Everything with this person, above.** Scroll up past a thread's first
  email and the earlier threads with the same address (from them or to
  them, in that mailbox) load above it, oldest at the top, five threads at
  a time, the way older messages load in a chat. Each thread starts with
  a small rule carrying its subject and day. "Earlier messages" at the top
  does the same by click.

* **Show all emails from them.** The thread's "…" menu, any email
  address's menu, and ⌘K while an email thread is open offer &#x2A;*Show all
  emails from \{name}**: the Inbox narrows to that address's threads, with
  a chip over the list to clear it.

* **Start an email.** "New email" in the feed's "+" menu and in ⌘K opens
  the same composer with From (when you read more than one mailbox), To,
  Cc, Bcc and Subject. Recipients suggest your contacts and whoever wrote
  to your mailboxes lately; paste several addresses at once. The sent
  thread opens in the Inbox right away.

* **The chat helpers work in email too.** `/` for requests, demos and
  sessions and `#` for a track drop links into the body as they do in a
  chat.

* **One row per person.** Mail from someone you also chat with on WhatsApp
  or Instagram joins their row, like any other app.

* **Only what matters.** Spam never shows. **Hide demos and promotions**
  (on by default) also keeps to Gmail's Primary tab or Outlook's Focused
  inbox and leaves out mail that reads as a demo submission: those land in
  your demo inbox.

* **One mailbox per address.** The same Gmail connected as yours and on a
  team shows once: the team's in its workspace, else yours.

* **Emails look like emails.** An email with its own layout shows it, images
  and links included, on white, scaled to fit, embedded pictures (a
  signature's logo) too. Hidden preview text and tracking pixels never
  show. A text email reads in the app's own type: the earlier conversation
  folds behind a small toggle, and long tracking links read as their label
  or site. Links open in your browser.

* **Their socials, one click away.** When an email links to the sender's
  Instagram, TikTok, X, Facebook, YouTube, SoundCloud, LinkedIn or Spotify
  artist page (a footer, a signature), small pills over it offer each one.
  A click puts it on their contact, made from the email when they have
  none, so their socials and their mail fold into one person. Profiles the
  contact already has don't show.

* **Faces and marks.** Senders show their picture: a teammate's Aden
  picture, else their Gravatar, else their company's icon. Each mailbox in
  the sidebar shows Gmail, Outlook, iCloud, Yahoo or Proton, or its own
  domain's icon.

* **Swipe right** on an open conversation to go back to the list.

* **Back where you were.** Leave for a page and come back, and the list
  still has the conversation you had open and its scroll position.

* **Turn it off** in the Inbox "…" menu, or in Settings, Chats: **Email in
  Inbox** and **Hide demos and promotions**. Both follow your account.