Summary

Two surfaces the user described as flat: the conversation, and the five search tabs that all opened on the same thing.

Register is product — design serves the product. Palette from the existing brand: coral #FF5E57 primary, violet #8A2BE2 secondary, mint and warm sun for state.

Chat

Three things separate a chat that looks designed from a list of rectangles. This one had none of them.

Day boundaries

A thread spanning three nights read as one uninterrupted run, so “see you at 11” could have been said last Tuesday.

Drawn as a ruled line that stops for the label, not a floating centred pill: it is a boundary, so it looks like one. A pill floats; a rule divides.

Note

isNewDay compares calendar days, not elapsed hours. 23:50 and 00:10 are twenty minutes apart and still two different nights — a distinction a nightlife app has to get right.

Labels degrade by distance: today, yesterday, weekday within the week, then a date. Within the week the weekday places a plan; a date makes you count.

Run continuity

Every bubble carried identical corners, so four messages in a row looked like four unrelated blocks stacked with a gap.

Only the message that opens a run keeps the notched corner; the rest round off to 7px. A burst then reads as one stream.

A day boundary always breaks a run: two messages either side of midnight are not one thought, however close the clock says they are.

Warning

The list is reverse: true, so index - 1 is newer and index + 1 is older. Getting that backwards rounds the wrong corners and the run reads upside down.

Speakers

Group chats carried “who said this” entirely in an avatar the eye has to decode. Names now appear in a colour hashed from the user id — stable across devices and reloads, because a colour that changes is not a signal — drawn from six hues, none of them the coral reserved for the current user’s own bubble.

Shown only where it disambiguates: never in a one-to-one, where there are two people and one of them is you; never mid-run.

Search Discovery

Five tabs shared one answer. All, Events and Crews rendered the same 2×2 grid of the same four categories, differing only in a row of chips. People and Venues got an explainer — an icon, a title and a sentence telling you what you could search for, instead of showing you anything you could act on.

Each tab asks a different question, so shape now carries meaning.

TabQuestionShape
Crewswho is going out and has roomseat count leading at 26px, countdown turning coral under three hours, sorted closest-to-expiry
Venueswheretwo columns of short rows — a venue is a name and a city
Peoplewhoa wrap of faces

Note

A countdown in a list of venues would be noise. On a crew it is the point.

Crews sort by closest to expiry because a crew for tonight matters more than one for Saturday, and being about to happen is the whole point of a crew.

Venues get short rows rather than full-width cards: giving a name and a city a whole card wastes the screen it sits on.

People are a wrap, not a list, because people are recognised rather than read, and a vertical list asks you to read fifteen names.

All three read real rows and fall back to the inline empty state rather than to invented content.

Files Changed

  • lib/shared/widgets/chat_day_separator.dart — new: separator and SpeakerPalette
  • lib/shared/widgets/message_bubble.dart — run-aware corners, sender name
  • lib/features/messaging/screens/chat_screen.dart — boundary insertion, run detection
  • lib/features/search/widgets/search_discovery_sections.dart — new: three per-tab sections
  • lib/features/search/screens/search_screen.dart — routes tabs to them; _buildExplainerState removed, nothing called it any more

Open Items

  • The All and Events tabs still share the category bento. Events is the right home for it; All should probably be temporal (tonight / this weekend) rather than categorical.
  • People suggestions are unranked — the first fifteen profiles. Friends of friends, or people going to the same events, would be the real answer.
  • The composer, the app bar and the chat list rows were not touched.

feature-crew-chat-lifecycle — the crew chat this styles localization — keys added