html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

html {
  position: relative;
  min-height: 100%;
}

body {
  margin-bottom: 60px;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}

/* ===== MamoCrown ===== */

.mamo-brand {
  font-weight: 800;
  letter-spacing: 0.06em;
  background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Links that should read as text, not as links — usernames, counts, icons.
   Uses Bootstrap's theme variable so they stay readable in dark mode. */
.mamo-icon-link {
  color: var(--bs-body-color);
  text-decoration: none;
}

.mamo-icon-link:hover {
  color: var(--bs-body-color);
  opacity: 0.75;
}

.mamo-tag {
  color: #0d6efd;
  text-decoration: none;
}

[data-bs-theme="dark"] .mamo-tag {
  color: #6ea8fe;
}

.mamo-tag:hover {
  text-decoration: underline;
}

/* Avatars */
.mamo-avatar-lg,
.mamo-avatar-md {
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bs-secondary-bg);
}

.mamo-avatar-lg { width: 96px; height: 96px; }
.mamo-avatar-md { width: 64px; height: 64px; }

.mamo-avatar-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
}

/* Profile post grid (3 columns, like the classic photo grid) */
.mamo-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}

.mamo-grid-item {
  position: relative;
  aspect-ratio: 1 / 1;
  display: block;
  overflow: hidden;
  background: var(--bs-secondary-bg);
}

/* Video posts without a captured poster frame */
.mamo-grid-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.75rem;
  opacity: 0.5;
}

.mamo-grid-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mamo-video-badge {
  position: absolute;
  top: 6px;
  right: 8px;
  color: white;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.6);
  font-size: 0.9rem;
}

/* Feed */
.mamo-avatar-sm {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bs-secondary-bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
  text-decoration: none;
}

/* No box drawn around the photo. The photo is the content; a border around it is a
   second rectangle competing with the first. Posts are told apart by the rule
   between them instead. */
.mamo-post {
  margin-bottom: 1.25rem;
}

.mamo-post + .mamo-post {
  border-top: 1px solid var(--bs-border-color);
  padding-top: 1.25rem;
}

.mamo-post-media {
  border-radius: 8px;
  overflow: hidden;
  /* Makes 1cqw equal 1% of the media's own width, which is what the height cap
     below is expressed against. */
  container-type: inline-size;
}

.mamo-post-img {
  display: block;
  width: 100%;
  /* Fallback: browsers without container query units, and any use of this class
     outside a media container. */
  max-height: 860px;
  object-fit: cover;
  background: var(--bs-secondary-bg);
}

/* Portrait photos are clamped to 4:5, the ratio people already frame for. It almost
   never cuts a face, and unlike the fixed 600px this replaces, the crop is identical
   at every window width instead of changing with the column. Landscape photos are
   under the cap already and keep their own shape.

   Deliberately scoped to the container: `cqw` with no container ancestor resolves
   against the viewport, which would mean no cap at all — and it would still beat the
   pixel fallback above, so the safety net would never fire. */
.mamo-post-media .mamo-post-img {
  max-height: 125cqw;
}

/* The caption is the post's own words, and used to render identically to the comments
   under it — so the first line of a conversation read as part of the post. */
.mamo-post-caption { white-space: pre-line; }

.mamo-post-comments {
  margin-top: .5rem;
  display: grid;
  gap: 3px;
}

.mamo-post-comment {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: .9rem;
  min-width: 0;
}

.mamo-post-comment-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mamo-post-comment-replies { flex: none; font-size: .8rem; color: var(--bs-secondary-color); }

/* Where the post was taken, beside the name — it's a property of the post rather
   than part of what anyone wrote in the caption. */
/* --------------------------------------------------------------------------
   Breaking long unbroken runs of user-typed text.

   Anything a person types can arrive as one unbroken run — a pasted URL, a mash
   of keys — and with no permission to break mid-word the glyphs paint straight
   out of their column. Inside a flex row that also widens the page, so a single
   bad caption hands the whole feed a horizontal scrollbar on a phone. Each of
   the selectors below was measured doing exactly that at 390px.

   "anywhere" rather than "break-word": only "anywhere" counts the break when
   min-content width is worked out, which is what stops the column being pushed
   wide in the first place. "break-word" would wrap the visible text and leave
   the layout pressure behind it.

   The property inherits, so naming the container covers the text inside it.
   -------------------------------------------------------------------------- */
.mamo-post-caption,
.mamo-comment-text,
.mamo-post-comment-text,
.mamo-banner,
.mamo-ident-name,
.mamo-chat-body,
.mamo-tray-name,
.mamo-reel-caption {
  overflow-wrap: anywhere;
}

.mamo-post-place {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: var(--bs-secondary-color);
  text-decoration: none;
  font-size: .8rem;
  min-width: 0;
  /* The header row wraps, so a chip too wide for the line is simply put on a line
     of its own — still at its full width, still overflowing. min-width: 0 lets it
     shrink; this is what stops it asking for more room than exists. */
  max-width: 100%;
}

.mamo-post-place svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* The ellipsis only bites once the span is allowed to be narrower than its text.
   As a flex item it defaults to min-width: auto, so a long place name pushed the
   chip — and with it the whole post header — wider than the page. */
.mamo-post-place span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.mamo-post-place:hover { color: var(--bs-body-color); }

/* The post menu. */
.mamo-post-menu {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bs-body-color);
  cursor: pointer;
  flex: none;
}

.mamo-post-menu:hover { background: rgba(128, 128, 128, .14); }

.mamo-post-menu svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
  stroke: none;
}

/* One choice, so it reads as one control rather than two buttons that happen to
   sit together. */
.mamo-seg {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--bs-secondary-bg);
}

.mamo-seg button {
  border: 0;
  border-radius: 999px;
  padding: 5px 14px;
  font-size: 13px;
  background: transparent;
  color: var(--bs-secondary-color);
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}

.mamo-seg button.on {
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}

/* New-post preview thumbnails */
.mamo-preview-thumb {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--bs-border-color);
}

/* Likes and saves. The buttons themselves are styled by `.mamo-act` since the icons
   became SVG — what was here before sized emoji characters, which no longer exist.
   The classes stay because the toggle scripts select on them. */
.mamo-dbl-like {
  user-select: none;
}

/* Notifications */
.mamo-notif-unread {
  background: rgba(13, 110, 253, 0.08);
}

/* ===== Messages ===== */

.min-width-0 { min-width: 0; }

.mamo-unread-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--bs-primary);
  flex-shrink: 0;
}

.mamo-thread {
  height: 60vh;
  overflow-y: auto;
  padding: 1rem 0.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.mamo-msg-row {
  display: flex;
}

.mamo-msg-row.mine { justify-content: flex-end; }
.mamo-msg-row.theirs { justify-content: flex-start; }

.mamo-msg {
  max-width: 75%;
  padding: 0.5rem 0.75rem;
  border-radius: 18px;
  background: var(--bs-secondary-bg);
  word-wrap: break-word;
}

.mamo-msg-row.mine .mamo-msg {
  background: var(--bs-primary);
  color: #fff;
}

.mamo-msg-text {
  white-space: pre-wrap;
}

.mamo-msg-time {
  display: block;
  font-size: 0.7rem;
  opacity: 0.7;
  margin-top: 0.15rem;
}

/* A story reply carries a thumbnail of what was replied to */
.mamo-msg-story {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  opacity: 0.85;
  margin-bottom: 0.35rem;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid rgba(128, 128, 128, 0.3);
}

.mamo-msg-story img {
  width: 28px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
}

.mamo-story-reply {
  display: flex;
  gap: 0.5rem;
  width: min(520px, 90%);
}

/* Group chats, reactions, replies, shares */
.mamo-msg-wrap {
  display: flex;
  flex-direction: column;
  max-width: 78%;
  position: relative;
}

.mamo-msg-row.mine .mamo-msg-wrap { align-items: flex-end; }

.mamo-msg-wrap .mamo-msg { max-width: 100%; }

.mamo-msg-author {
  font-size: 0.7rem;
  opacity: 0.7;
  padding-left: 0.5rem;
}

.mamo-msg-quote {
  font-size: 0.75rem;
  opacity: 0.85;
  border-left: 3px solid currentColor;
  padding: 0.15rem 0 0.15rem 0.5rem;
  margin-bottom: 0.35rem;
}

.mamo-msg-quote strong { display: block; }

.mamo-msg-photo {
  max-width: 240px;
  border-radius: 10px;
  display: block;
  margin-bottom: 0.25rem;
}

/* A safety number is read aloud to another person, so it is set to be read aloud: a
   monospace face that distinguishes 0 from O and 1 from l, spaced out, and wrapping in
   whole groups rather than splitting one across two lines. */
.mamo-safety-number {
  font-family: ui-monospace, "Cascadia Mono", "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 1.05rem;
  letter-spacing: 0.12em;
  line-height: 1.9;
  word-spacing: 0.5em;
  margin-bottom: 0.75rem;
  overflow-wrap: normal;
}

/* An encrypted photo before its bytes have been fetched and opened. The width is held
   here so the thread does not lurch when the picture arrives; the img that replaces this
   note carries its own dimensions and takes over. */
.mamo-msg-encphoto {
  min-width: 160px;
  max-width: 240px;
  margin-bottom: 0.25rem;
}

.mamo-msg-encphoto img {
  max-width: 240px;
  height: auto;
}

.mamo-msg-encphoto-note {
  display: block;
  padding: 1.25rem 0.75rem;
  border-radius: 10px;
  background: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
  font-size: 0.8rem;
  text-align: center;
}

.mamo-msg-post {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem;
  margin-bottom: 0.35rem;
  border-radius: 8px;
  background: rgba(128, 128, 128, 0.18);
  color: inherit;
  text-decoration: none;
  font-size: 0.8rem;
  max-width: 240px;
}

.mamo-msg-post img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 6px;
  flex-shrink: 0;
}

.mamo-msg-post div { min-width: 0; }

.mamo-msg-tools {
  display: flex;
  gap: 0.15rem;
  opacity: 0;
  transition: opacity 0.15s;
}

.mamo-msg-row:hover .mamo-msg-tools,
.mamo-msg-tools:focus-within { opacity: 1; }

.mamo-msg-tool {
  border: 0;
  background: none;
  font-size: 0.8rem;
  line-height: 1;
  padding: 0.1rem 0.2rem;
  cursor: pointer;
  color: var(--bs-secondary-color);
}

.mamo-reactions {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.mamo-reaction {
  font-size: 0.7rem;
  padding: 0.05rem 0.35rem;
  border-radius: 10px;
  background: var(--bs-secondary-bg);
  border: 1px solid transparent;
}

.mamo-reaction.mine { border-color: var(--bs-primary); }

.mamo-react-menu {
  position: absolute;
  z-index: 1050;
  display: flex;
  gap: 0.2rem;
  padding: 0.3rem 0.45rem;
  border-radius: 20px;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2);
}

.mamo-react-menu button {
  border: 0;
  background: none;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}

.mamo-reply-banner {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  padding: 0.4rem 0.6rem;
  border-radius: 8px;
  background: var(--bs-secondary-bg);
  margin-bottom: 0.35rem;
}

.mamo-reply-banner span {
  flex-grow: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mamo-share-thumb {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 6px;
}

/* ===== Notes, presence, verified, insights ===== */

/* The notes list that used to sit above the inbox is gone — notes ride with the
   story tray now (`.mamo-tray-note`). Only the editor for your own note remains. */
.mamo-note-editor summary {
  cursor: pointer;
}

.mamo-verified {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05em;
  height: 1.05em;
  border-radius: 50%;
  background: #0d6efd;
  color: #fff;
  vertical-align: middle;
}

/* The tick used to be the ✔ character, which each platform drew at its own weight and
   sat off-centre in the disc. Drawn, it centres and scales with the name beside it. */
.mamo-verified svg {
  width: 62%;
  height: 62%;
  fill: none;
  stroke: currentColor;
  stroke-width: 3.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Insights */
.mamo-stat {
  background: var(--bs-secondary-bg);
  border-radius: 8px;
  padding: 0.6rem;
  text-align: center;
}

.mamo-stat-value {
  display: block;
  font-size: 1.25rem;
  font-weight: 600;
}

.mamo-stat-label {
  display: block;
  font-size: 0.7rem;
  color: var(--bs-secondary-color);
}

.mamo-chart-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.3rem;
}

.mamo-chart-label {
  flex: 0 0 68px;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

.mamo-chart-track {
  flex-grow: 1;
  height: 14px;
  border-radius: 7px;
  background: var(--bs-secondary-bg);
  overflow: hidden;
}

.mamo-chart-fill {
  display: block;
  height: 100%;
  background: var(--bs-primary);
  border-radius: 7px;
}

.mamo-chart-value {
  flex: 0 0 28px;
  text-align: right;
  font-size: 0.75rem;
}

.mamo-top-thumb {
  width: 44px;
  height: 44px;
  border-radius: 6px;
  background: var(--bs-secondary-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}

.mamo-top-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* No thumbnail: the kind of post stands in for the picture. The tile is already a
   centring flex box, so the icon only needs a size. */
.mamo-top-thumb svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  color: var(--bs-secondary-color);
}

/* Pinned / scheduled markers on a grid tile */
.mamo-grid-tag {
  position: absolute;
  top: 6px;
  left: 6px;
  font-size: 0.8rem;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.6);
}

.mamo-slide-move {
  display: inline-flex;
  align-items: center;
  gap: 0.1rem;
  padding: 0 0.25rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 6px;
}

/* Voice messages */
.mamo-msg-voice {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.25rem;
  font-size: 0.7rem;
}

.mamo-msg-voice audio {
  height: 32px;
  max-width: 200px;
}

/* "Add yours" sticker on a story */
.mamo-story-prompt {
  position: absolute;
  bottom: 28%;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  background: rgba(255, 255, 255, 0.92);
  color: #212529;
  border-radius: 14px;
  padding: 0.45rem 0.9rem;
  text-decoration: none;
  font-size: 0.85rem;
  max-width: 80%;
  text-align: center;
}

.mamo-story-prompt-label {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.65;
}

/* ===== Create sheet ===== */

/* Anchored to the bottom like a phone sheet, but capped so it stays sane on a desktop */
.mamo-sheet-dialog {
  align-items: flex-end;
  min-height: 100%;
  margin: 0 auto;
  max-width: 460px;
}

.mamo-sheet {
  border-radius: 16px 16px 0 0;
  border: 0;
  padding-bottom: 0.25rem;
}

.mamo-sheet-grab {
  width: 42px;
  height: 4px;
  border-radius: 2px;
  background: var(--bs-secondary-color);
  opacity: 0.4;
  margin: 0.6rem auto 0;
}

.mamo-sheet-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.25rem;
  border-top: 1px solid var(--bs-border-color);
  text-decoration: none;
  color: var(--bs-body-color);
  font-size: 1.05rem;
}

.mamo-sheet-row:hover:not(.disabled) {
  background: var(--bs-secondary-bg);
}

.mamo-sheet-row.disabled {
  color: var(--bs-secondary-color);
  cursor: default;
}

.mamo-sheet-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  font-size: 1.1rem;
}

.mamo-sheet-icon svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The Reel row's play mark reads better solid — an outlined triangle at this size looks
   like a bug rather than a button. */
.mamo-sheet-icon svg path[fill="currentColor"] { stroke: none; }

/* ===== Profile header ===== */

.mamo-avatar-stack {
  position: relative;
  flex-shrink: 0;
  padding-top: 1.5rem;
  /* Sits above the neighbours tucked either side of it. Needed on the stack rather than
     the picture, because the two are not siblings — the picture is nested in here and the
     neighbours are outside, so this is the box that has to win. Without it the right-hand
     one would lie on top, being later in the document. */
  z-index: 1;
}

/* The owner's note, as a speech bubble over their own avatar */
.mamo-avatar-note {
  position: absolute;
  top: 0;
  left: -6px;
  max-width: 110px;
  background: var(--bs-secondary-bg);
  border-radius: 12px;
  padding: 0.25rem 0.5rem;
  font-size: 0.65rem;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mamo-avatar-note::after {
  content: "";
  position: absolute;
  bottom: -4px;
  left: 14px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--bs-secondary-bg);
}

.mamo-avatar-add {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--bs-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  font-size: 1rem;
  line-height: 1;
  border: 2px solid var(--bs-body-bg);
}

/* Two columns: the bio on the left, and name / stats / picture stacked down the right.
   Right-aligning the identity alone left a wide empty band beside it on a desktop
   screen — the bio is what belongs in that space. */
.mamo-profile-head {
  display: flex;
  align-items: flex-start;
  gap: 2rem;
}

.mamo-profile-bio {
  flex: 1;
  /* Without this a long unbroken word in a bio would widen the column and push the
     identity off the edge, since flex items refuse to shrink below their content. */
  min-width: 0;

  /* min-width: 0 governs the box, not the text inside it. A bio with one long unbroken
     run — a pasted link, a keyboard mash — still painted straight past the column's
     edge and ran under the identity, because nothing had given the browser permission
     to break mid-word. "anywhere" rather than "break-word" so the break is also counted
     when the column's minimum width is worked out, which is what keeps the header from
     being pushed wider than its share in the first place. */
  overflow-wrap: anywhere;

  /* Sits on the identity's centre line rather than at the top. The identity column is
     tall — picture, counter, name, stats — so a one-line bio left at flex-start hung in
     the top corner with a deep empty band under it. Centring is self-cancelling once the
     bio outgrows the identity: at that point the bio is the taller item, so it sets the
     header's height and simply flows from the top like any block. */
  align-self: center;
}

/* A grid of three columns — one per stat — so the picture can line up with the middle
   one. A plain column stack could only centre it against the whole block, and "Posts"
   and "Reverse" are different widths, so that would not land under Accept. */
.mamo-profile-ident {
  /* Was flex: none, which also meant flex-shrink: 0 — so a display name with one long
     unbroken run sized this block to that word and pushed the header past the page.
     0 1 auto keeps the block at its natural width whenever there is room (the bio
     flexes and absorbs the slack, so this never shrinks in normal use) and lets it
     give way only when there genuinely isn't any. */
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: end;
  column-gap: 1.75rem;
  row-gap: 0.5rem;
}

/* The name sits above all three. */
.mamo-ident-name { grid-column: 1 / -1; justify-self: end; }

/* The wrapper's box is dropped so its three cells become items of the grid above —
   that is what puts each stat in its own column. */
.mamo-profile-head .mamo-stats { display: contents; }

/* Second row, middle column: directly under Accept.
   width: 0 is doing real work — an auto grid track sizes to its widest item, so without a
   definite width this row (picture plus two dots, ~134px) would stretch the Accept column
   to match and blow a hole in the stats spacing. At zero width it contributes nothing to
   the track, and centring its own children makes them overhang evenly either side, which
   leaves the picture centred on the stat. */
.mamo-avatar-row {
  /* Mirrors .mamo-avatar-stack's padding-top, which reserves room for the note bubble.
     That padding makes the stack taller than the picture inside it, so centring the row
     centres the stack and leaves the dots sitting above the picture's own centre line. */
  --stack-note-space: 1.5rem;

  grid-column: 2;
  justify-self: center;
  width: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  /* No gap: the neighbours tuck under the picture instead of sitting apart from it, and
     the overlap is set on them individually. */
  gap: 0;
  /* It leads the block now, so its breathing room goes underneath it. */
  margin-bottom: 0.5rem;
}

/* Smaller here than the 96px .mamo-avatar-lg gets elsewhere — that class is shared with
   the call screen and the edit page, so the size is set on this row rather than on it. */
.mamo-avatar-row .mamo-avatar-lg {
  width: 84px;
  height: 84px;
}

/* A round window onto a strip of pictures. The circle is cut here, on the window, so the
   pictures inside can stay square and sit flush against each other — rounding them
   individually would show a sliver of the next one's edge mid-swipe.
   touch-action: pan-y hands horizontal movement to the script while leaving the page
   free to scroll vertically under the finger. */
.mamo-avatar-deck {
  position: relative;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  overflow: hidden;
  touch-action: pan-y;
  background: var(--bs-secondary-bg);
  /* A ring in the page's own colour, so the tucked-in neighbours are cut cleanly away
     from it rather than touching, and a soft shadow to lift it in front of them. This is
     what makes the three read as one stack with a subject, instead of three circles of
     different sizes. The colour is a token, so it holds in both themes. */
  box-shadow:
    0 0 0 3px var(--bs-body-bg),
    0 2px 10px rgba(0, 0, 0, .13);
}

.mamo-avatar-track {
  display: flex;
  height: 100%;
  /* Sized to the pictures it holds. Without this it takes the window's width and the
     strip only appears to line up because the overflow happens to be visible — a real
     width means the layout is what it looks like. */
  width: max-content;
  will-change: transform;
}

/* Only while settling. During a drag the strip must track the finger exactly, and a
   transition would make it lag behind by its own duration. */
.mamo-avatar-track.settling {
  transition: transform .34s cubic-bezier(.22, .61, .36, 1);
}

.mamo-avatar-deck .mamo-avatar-lg {
  flex: none;
  width: 84px;
  height: 84px;
  border-radius: 0;
  user-select: none;
  -webkit-user-drag: none;
}


@media (prefers-reduced-motion: reduce) {
  .mamo-avatar-track.settling,
  button.mamo-avatar-dot { transition: none; }
}

/* ---- managing the set, on the edit screen ------------------------------- */

.mamo-photo-set {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: 1.25rem;
}

.mamo-photo-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  position: relative;
}

.mamo-photo-slot.is-default .mamo-avatar-lg {
  outline: 2px solid var(--bs-primary);
  outline-offset: 3px;
}

.mamo-photo-tag {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--bs-primary);
}

.mamo-photo-slot-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  font-size: 0.78rem;
}

/* Matches the pictures beside it, so the row reads as a set of slots with one empty. */
.mamo-photo-add {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  border: 2px dashed var(--bs-border-color);
  color: var(--bs-secondary-color);
  font-size: 1.75rem;
  cursor: pointer;
}

.mamo-photo-add:hover {
  border-color: var(--bs-primary);
  color: var(--bs-primary);
}

/* How far through the set. Deliberately quiet — it answers a question rather than asking
   for attention, so it takes the same muted grey as the stat labels beside it. */
.mamo-avatar-count {
  grid-column: 2;
  justify-self: center;
  width: 0;
  display: block;
  margin-top: -0.25rem;
  margin-bottom: 0.4rem;
  font-size: 0.7rem;
  line-height: 1;
  white-space: nowrap;
  color: var(--bs-secondary-color);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* Sized against the picture rather than picked in isolation: at 12px they read as a pair
   of marks flanking it, where 7px read as specks. */
.mamo-avatar-dot {
  flex: none;
  width: 12px;
  height: 12px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--bs-secondary-color);
  opacity: .55;
  /* Down by half the reserved note space, so the dots share the picture's centre line
     instead of the taller stack's. */
  transform: translateY(calc(var(--stack-note-space) / 2));
}

/* Only a control when there is more than one picture to reach. Nothing is ever disabled:
   the strip wraps, so both always lead somewhere. */
button.mamo-avatar-dot {
  cursor: pointer;
  transition: opacity .15s ease, transform .15s ease;
}

button.mamo-avatar-dot:focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: 3px;
}

/* Each side is the picture it leads to, not a mark standing in for one. Big enough to
   recognise a face, and no bigger — past about half the main picture they stop reading as
   its neighbours and start competing with it.
   The box is 44px while the picture inside is 38: that is the smallest comfortable touch
   target, and the padding buys it without the circle growing. The matching negative margin
   keeps the gap either side looking the same as before. */
.mamo-avatar-peek {
  width: 44px;
  height: 44px;
  padding: 3px;
  background: none;
  opacity: .7;
  overflow: visible;
}

/* Each neighbour slides 8px under the main picture — measured from the visible circle,
   not the button, hence the extra 3px of padding in the number. What shows is a crescent
   of the picture either side, which reads as a stack you are flipping through. */
.mamo-avatar-peek[data-photo-step="-1"] { margin: -3px -11px -3px -3px; }
.mamo-avatar-peek[data-photo-step="1"]  { margin: -3px -3px -3px -11px; }

.mamo-avatar-peek img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  background: var(--bs-secondary-bg);
  user-select: none;
  -webkit-user-drag: none;
}

.mamo-avatar-peek:hover {
  opacity: 1;
  transform: scale(1.08) translateY(calc(var(--stack-note-space) / 2));
}

/* The header no longer stacks at any width. It used to fall into a column below 768px,
   then below 576px, and both thresholds were still being crossed on a wide monitor —
   browser zoom shrinks the CSS viewport, so a 1000px window at 200% reports about
   470px and takes the phone layout. The bio kept dropping under the name on what
   looked, to the person using it, like a perfectly wide screen.
   So the bio stays on the left and vertically centred everywhere. What gives instead
   is its width: the identity column is a fixed ~190px, so on a genuinely small phone
   the bio is left with a narrow measure and wraps hard. min-width: 0 on the bio is
   what keeps that from overflowing the header. */
.mamo-profile-head { flex-wrap: nowrap; }

.mamo-stats {
  display: flex;
  gap: 1.75rem;
  margin-top: 0.5rem;
  /* Packed to the right, under the name. */
  justify-content: flex-end;
}

.mamo-stat-cell {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--bs-body-color);
  /* Number centred over its label — which is also what the picture below centres on. */
  align-items: center;
}

.mamo-stat-cell strong {
  font-size: 1.15rem;
  line-height: 1.1;
}

.mamo-stat-cell span {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}

/* Banner chips */
.mamo-banners {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.75rem 0;
}

.mamo-banner {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 20px;
  padding: 0.25rem 0.75rem;
  font-size: 0.8rem;
  text-decoration: none;
  color: var(--bs-body-color);
}

.mamo-banner-icon {
  font-size: 0.75rem;
  opacity: 0.8;
}

.mamo-banner-add {
  border-style: dashed;
  color: var(--bs-secondary-color);
}

.mamo-profile-actions {
  display: flex;
  gap: 0.5rem;
  margin: 0.75rem 0 1rem;
}

/* Grid / Reels tabs */
.mamo-tabs {
  display: flex;
  border-top: 1px solid var(--bs-border-color);
}

.mamo-tab {
  flex: 1;
  text-align: center;
  padding: 0.6rem 0;
  text-decoration: none;
  color: var(--bs-secondary-color);
  border-top: 2px solid transparent;
  margin-top: -1px;
  font-size: 1.1rem;
}

.mamo-tab.active {
  color: var(--bs-body-color);
  border-top-color: var(--bs-body-color);
}

.mamo-tab-count {
  font-size: 0.75rem;
  vertical-align: middle;
}

/* ===== Edit profile (row layout) ===== */

.mamo-edit-rows {
  border-top: 1px solid var(--bs-border-color);
}

.mamo-edit-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 0.25rem;
  border-bottom: 1px solid var(--bs-border-color);
  text-decoration: none;
  color: var(--bs-body-color);
}

.mamo-edit-label {
  flex: 0 0 32%;
  margin: 0;
  color: var(--bs-body-color);
}

/* Borderless inputs so a row reads as a line of text until it's focused */
.mamo-edit-input {
  flex-grow: 1;
  border: 0;
  background: transparent;
  color: var(--bs-body-color);
  padding: 0.15rem 0.25rem;
  border-radius: 4px;
  min-width: 0;
}

.mamo-edit-input:focus {
  outline: 0;
  background: var(--bs-secondary-bg);
}

.mamo-edit-input::placeholder {
  color: var(--bs-secondary-color);
}

.mamo-edit-value {
  margin-left: auto;
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
}

.mamo-edit-chevron {
  color: var(--bs-secondary-color);
  font-size: 1.2rem;
  line-height: 1;
}

.mamo-edit-nav:hover {
  background: var(--bs-secondary-bg);
}

/* The blue action rows at the bottom of the screen */
.mamo-edit-action {
  color: #0d6efd;
  cursor: pointer;
}

[data-bs-theme="dark"] .mamo-edit-action {
  color: #6ea8fe;
}

.mamo-profile-link {
  font-size: 0.85rem;
  color: #0d6efd;
  text-decoration: none;
}

[data-bs-theme="dark"] .mamo-profile-link {
  color: #6ea8fe;
}

.mamo-grid-pin {
  position: absolute;
  bottom: 4px;
  right: 4px;
}

/* ===== Photo filters ===== */

.mamo-filters {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  padding-bottom: 0.25rem;
}

.mamo-filter {
  flex: 0 0 auto;
  border: 2px solid transparent;
  background: none;
  padding: 0.15rem;
  border-radius: 8px;
  cursor: pointer;
  color: var(--bs-body-color);
}

.mamo-filter.active {
  border-color: var(--bs-primary);
}

/* A gradient stands in for a photo, so each swatch shows what the filter does. */
.mamo-filter-swatch {
  display: block;
  width: 48px;
  height: 48px;
  border-radius: 6px;
  background: linear-gradient(135deg, #f6b26b, #6fa8dc 55%, #93c47d);
}

.mamo-filter-name {
  display: block;
  font-size: 0.65rem;
  text-transform: capitalize;
  margin-top: 0.15rem;
}

/* ===== Two-factor ===== */

.mamo-2fa-steps {
  padding-left: 1.1rem;
}

.mamo-2fa-steps li {
  margin-bottom: 0.85rem;
}

.mamo-2fa-key {
  font-family: var(--bs-font-monospace);
  font-size: 1.05rem;
  letter-spacing: 0.08em;
  background: var(--bs-secondary-bg);
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  margin: 0.4rem 0 0.25rem;
  user-select: all;
  word-break: break-all;
}

.mamo-2fa-codes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 0.4rem;
}

.mamo-2fa-codes code {
  background: var(--bs-secondary-bg);
  padding: 0.35rem 0.5rem;
  border-radius: 4px;
  text-align: center;
  user-select: all;
}

/* ===== Reels ===== */

/* One reel fills the viewport slot and snaps into place; the container scrolls, the page doesn't. */
.mamo-reels {
  width: min(420px, 100vw);
  /* The player stays phone-shaped because a reel is vertical video — widening it
     would only letterbox. But it lives in the same 720 column as every other page,
     so it has to sit in the middle of it rather than hug the left edge. */
  margin-inline: auto;
  height: calc(100vh - 190px);
  min-height: 380px;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  border-radius: 12px;
  background: #000;
  scrollbar-width: none;
}

.mamo-reels::-webkit-scrollbar { display: none; }

.mamo-reel {
  position: relative;
  height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  overflow: hidden;
}

.mamo-reel-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

.mamo-reel-muted {
  position: absolute;
  top: 12px;
  right: 12px;
  font-size: 0.7rem;
  color: #fff;
  background: rgba(0, 0, 0, 0.5);
  padding: 0.15rem 0.5rem;
  border-radius: 12px;
  pointer-events: none;
}

.mamo-reel.sound-on .mamo-reel-muted { display: none; }

.mamo-reel-overlay {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  padding: 1rem;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.75));
  color: #fff;
}

.mamo-reel-meta {
  flex-grow: 1;
  min-width: 0;
}

.mamo-reel-caption {
  margin: 0.4rem 0 0.15rem;
  font-size: 0.85rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.mamo-reel-caption .mamo-tag { color: #9ec5fe; }

.mamo-reel-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  flex-shrink: 0;
}

.mamo-reel-actions .mamo-like-btn,
.mamo-reel-actions .mamo-save-btn,
.mamo-reel-action {
  color: #fff;
  text-decoration: none;
  font-size: 1.4rem;
  line-height: 1.1;
}

.mamo-reel-actions .mamo-like-btn.liked { color: #ff4d6d; }

.mamo-reel-count {
  font-size: 0.7rem;
  margin-bottom: 0.4rem;
}

.mamo-reel-sentinel {
  height: 100%;
  scroll-snap-align: start;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #adb5bd;
  font-size: 0.85rem;
}

/* ===== Stories ===== */

/* The row of circles above the feed, and highlights on a profile */
.mamo-tray {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  padding: 0.25rem 0 0.5rem;
  /* No visible scrollbar: it sat under the avatars and sliced the last one in half.
     The tray still scrolls by drag and wheel. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.mamo-tray::-webkit-scrollbar { display: none; }

/* Feed only. The same tray markup carries profile highlights, which sit inside their
   own section and would be wrong to underline. */
.mamo-tray-feed {
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--bs-border-color);
}

/* When nobody you follow has a story, the row is one circle and 600-odd pixels of
   nothing, which reads as broken rather than empty. This says what the row is for,
   and gets out of the way the moment somebody posts. */
.mamo-tray-hint {
  flex: 1 1 auto;
  min-width: 0;
  align-self: center;
  margin: 0;
  font-size: .84rem;
  line-height: 1.4;
  color: var(--bs-secondary-color);
  max-width: 44ch;
}

.mamo-tray-item {
  flex: 0 0 auto;
  width: 72px;
  text-align: center;
  text-decoration: none;
  color: var(--bs-body-color);
  /* Anchors the note bubble that sits above the ring. */
  position: relative;
}

.mamo-tray-ring {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bs-secondary-bg);
  margin: 0 auto 0.25rem;
  padding: 3px;
  box-sizing: border-box;
}

.mamo-tray-ring img,
.mamo-tray-initial {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  background: var(--bs-body-bg);
}

/* An unseen story gets the gradient ring; a seen one goes flat grey. */
.mamo-tray-ring.unseen {
  background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888);
}

.mamo-tray-ring.seen {
  background: var(--bs-border-color);
}

/* Close-friends stories get the green ring, the convention people already know. */
.mamo-tray-ring.close.unseen {
  background: linear-gradient(45deg, #37b24d, #2f9e44);
}

/* A comment held back for approval */
.mamo-comment-hidden {
  opacity: 0.72;
  border-left: 3px solid var(--bs-warning);
  padding-left: 0.5rem;
}

.mamo-tray-add {
  border: 2px dashed var(--bs-border-color);
  background: transparent;
  font-size: 1.5rem;
  color: var(--bs-secondary-color);
}

.mamo-tray-name {
  display: block;
  font-size: 0.75rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Full-screen viewer */
.mamo-story-body {
  margin: 0;
  background: #000;
  overflow: hidden;
}

.mamo-story-stage {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  user-select: none;
}

.mamo-story-bars {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  gap: 3px;
  padding: 8px;
  z-index: 3;
}

.mamo-story-bar {
  flex: 1;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.3);
  overflow: hidden;
}

.mamo-story-bar span {
  display: block;
  height: 100%;
  width: 0;
  background: #fff;
}

.mamo-story-head {
  position: absolute;
  top: 18px;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  z-index: 3;
  color: #fff;
}

.mamo-story-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  display: none;
  align-items: center;
  justify-content: center;
}

.mamo-story-slide.active {
  display: flex;
}

.mamo-story-slide img,
.mamo-story-slide video {
  max-width: 100%;
  max-height: 100vh;
  object-fit: contain;
}

.mamo-story-text {
  position: absolute;
  bottom: 15%;
  left: 5%;
  right: 5%;
  text-align: center;
  color: #fff;
  font-size: 1.25rem;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
  padding: 0.5rem;
}

.mamo-story-nav {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 25%;
  border: 0;
  background: transparent;
  color: rgba(255, 255, 255, 0.6);
  font-size: 2.5rem;
  cursor: pointer;
  z-index: 2;
}

.mamo-story-nav.prev { left: 0; }
.mamo-story-nav.next { right: 0; }

.mamo-story-foot {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem;
  z-index: 3;
}

.mamo-story-owner-bar {
  display: flex;
  gap: 0.5rem;
}

/* Create page preview */
/* A story is one portrait frame, so its preview is shown at the shape it will actually
   have rather than as a small square tile.

   Named apart from the viewer's .mamo-story-stage on purpose. Both used to be called
   .mamo-story-stage, and because this block sits later in the file at equal specificity
   it won everywhere — including in the full-screen player, whose `position: fixed;
   inset: 0` never applied. That left the player laid out in normal flow as a small
   rounded box, with its bars, header and nav anchored to that box instead of the
   viewport. Two unrelated components, so they get two names. */
.mamo-story-preview-box {
  position: relative;
  display: grid;
  place-items: center;
  padding: 12px;
  border-radius: 14px;
  background: var(--bs-secondary-bg);
}

.mamo-story-preview {
  max-height: 420px;
  max-width: 100%;
  border-radius: 10px;
  display: block;
}

.mamo-story-clear { top: 20px; right: 20px; }

/* Green is already what a close-friends story ring uses, so the switch and its heart
   carry the same signal rather than inventing a second one. */
.mamo-close-friends { border-bottom: 0; margin-top: 8px; }

.mamo-close-friends .mamo-switch-text b {
  display: flex;
  align-items: center;
  gap: 7px;
}

.mamo-close-friends svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
  stroke: none;
  color: #2f9e44;
}

.mamo-switch.green:checked,
.mamo-switch.green.on { background: #2f9e44; }

/* Highlight picker */
.mamo-story-picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 6px;
}

.mamo-story-pick {
  position: relative;
  aspect-ratio: 9 / 16;
  cursor: pointer;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bs-secondary-bg);
}

.mamo-story-pick img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mamo-story-pick input {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 2;
  width: 18px;
  height: 18px;
}

.mamo-story-pick:has(input:checked) {
  outline: 3px solid var(--bs-primary);
  outline-offset: -3px;
}

/* ==========================================================================
   App chrome: top bar + floating nav pill
   Bundled rather than linked from Google so the wordmark needs no third-party
   request and renders identically offline. Grand Hotel, SIL Open Font Licence.
   ========================================================================== */

@font-face {
  font-family: 'Grand Hotel';
  src: url('../fonts/grand-hotel.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  /* Latin subset only — the wordmark is four ASCII letters. */
  font-display: swap;
}

/* ONE column width for every page — feed, profile, search, reels, messages.
   Three different widths made the app change shape as you moved through it.
   720 rather than the profile's old 935: post media is capped at 600px tall with
   object-fit cover, so a wider column doesn't enlarge a photo, it crops more off
   a tall one — and a search box or chat thread at 935 is simply too long to read. */
.mamo-shell {
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding-left: 12px;
  padding-right: 12px;
}

.mamo-topbar {
  position: sticky;
  top: 0;
  z-index: 1030;
  background: var(--bs-body-bg);
  border-bottom: 1px solid var(--bs-border-color);
}

/* The wordmark sits at the left edge and everything else is pushed to the right, so
   the bar needs nothing balancing it — which is why the empty spacer spans that used
   to hold a grid column are gone from the markup. Back to a flex row: with only two
   children and no centred element, a three-column grid was machinery for a job that
   no longer exists. */
.mamo-topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 54px;
}

.mamo-topbar-end {
  display: flex;
  align-items: center;
  gap: 4px;
}

.mamo-wordmark {
  font-family: 'Grand Hotel', cursive;
  font-size: 30px;
  line-height: 1;
  color: var(--bs-body-color);
  text-decoration: none;
  /* Optical, not geometric. Centring the ink box reads as too high: the capital M's
     flourish inflates the top while "MamoCrown" has no descenders, so the letterforms'
     visual mass sits above centre. Nudged down to sit level with the icons.
     A relative offset, not padding — padding grows the box, and align-items:center
     then re-centres it, so the text moves only half as far as the number implies. */
  position: relative;
  top: 6px;
}

.mamo-wordmark:hover { color: var(--bs-body-color); }

.mamo-chrome-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--bs-body-color);
  text-decoration: none;
}

.mamo-chrome-btn:hover { color: var(--bs-body-color); opacity: .65; }

.mamo-chrome-badge {
  position: absolute;
  top: -2px;
  right: -4px;
  min-width: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #ff3b30;
  color: #fff;
  font-size: 10px;
  line-height: 16px;
  text-align: center;
  font-weight: 600;
}

/* Clears the fixed pill so the last post and the footer are never trapped under it. */
.mamo-main { padding-bottom: 24px; }

/* The footer is gone. Clearing the fixed pill was its other job, and that now belongs to
   main at every width — see the rule below, which used to live inside the phone-only
   media query. */
main[role="main"] { padding-bottom: 88px; }


.mamo-navpill {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 14px;
  z-index: 1040;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px 10px;
  border-radius: 999px;
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .18);
}

.mamo-navpill-item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-width: 48px;
  height: 40px;
  padding: 0 12px;
  border-radius: 999px;
  color: var(--bs-secondary-color);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .2s ease, color .2s ease;
}

.mamo-navpill-item:hover { color: var(--bs-body-color); }

/* Only the selected tab is named. Five labels at once need a bar wider than a small phone
   has, and a paper plane or a magnifier on its own is a guess until you have tapped it. */
.mamo-navpill-item.active {
  color: var(--bs-body-color);
  background: var(--bs-body-bg);
}

/* The label drives the width rather than the item having two fixed sizes: max-width is
   animatable where width:auto is not, and letting the text size the pill means a longer
   word than "Explore" cannot clip. */
.mamo-navpill-label {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  font-size: .82rem;
  font-weight: 600;
  transition: max-width .28s ease, opacity .2s ease, margin-left .28s ease;
}

.mamo-navpill-item.active .mamo-navpill-label {
  max-width: 7rem;
  opacity: 1;
  margin-left: 7px;
}

.mamo-navpill-dot {
  position: absolute;
  top: 5px;
  /* Pinned to the icon, not the item: the item grows when it is the selected one, and a
     dot measured from the right edge would drift out over the label. */
  left: 27px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff3b30;
  border: 2px solid var(--bs-secondary-bg);
}

.mamo-navpill-item.active .mamo-navpill-dot { border-color: var(--bs-body-bg); }

@media (prefers-reduced-motion: reduce) {
  .mamo-navpill-item,
  .mamo-navpill-label { transition: none; }
}

/* --------------------------------------------------------------------------
   The aperture: the pill's alternative. One button, and the five destinations
   fan around your thumb when you press it. Which one is showing is set by
   Ui:Nav in appsettings.

   The nav element is only the size of the button; everything else is placed
   from its centre, so there is no bar and the whole bottom of the screen is
   content again.
   -------------------------------------------------------------------------- */

.mamo-ap {
  position: fixed;
  left: 50%;
  bottom: 14px;
  margin-left: -28px;
  width: 56px;
  height: 56px;
  z-index: 1040;
}

.mamo-ap-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .18);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
  z-index: 1;
}

.mamo-ap[data-ap-open] .mamo-ap-scrim { opacity: 1; pointer-events: auto; }

.mamo-ap-btn {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  /* The mark is drawn in ink, not knocked out of a brand fill, so it follows the
     theme like every other glyph in the chrome. */
  color: var(--bs-body-color);
  cursor: pointer;
  /* The gesture is a drag off this button; without this the browser claims the
     movement for scrolling and the fan never tracks the thumb. */
  touch-action: none;
  z-index: 3;
}

.mamo-ap-btn:hover,
.mamo-ap-btn:active { border-color: var(--bs-secondary-color); }

/* Sits outside the circle rather than on it, so it reads in both themes whatever
   the button's own fill is. */
.mamo-ap-btn:focus-visible {
  outline: 2px solid var(--bs-body-color);
  outline-offset: 3px;
}

/* The logo mark on the button's face.
   Grand Hotel's m is an x-height glyph — its ink is 43% of the font size, so it
   needs a size far larger than an icon would to read at the same weight, and its
   ink sits 0.071em below the middle of the line box. Flex centring aligns the box,
   not the ink, so without the nudge the mark sits visibly low in the circle. */
/* The logo mark on the button's face: the favicon's m as an alpha mask, filled with
   currentColor so it takes the theme's ink the way a glyph would.
   30px tall keeps the same proportion the letter has inside the icon — 55% of the
   tile — and 22px is that height at the mark's own 0.736 aspect. px rather than rem
   because the button is a fixed 56px on both sides of the 768px root-size change.
   No vertical nudge: the mask is the ink box itself, evenly padded, so centring the
   element centres the letter. */
.mamo-ap-mark {
  width: 22px;
  height: 30px;
  background-color: currentColor;
  -webkit-mask: url('../brand/mark.png') center / contain no-repeat;
  mask: url('../brand/mark.png') center / contain no-repeat;
}

/* The rim: one tick per destination, the current one filled. This is the whole
   reason a single button can replace a bar — it says, without being opened,
   that there are five places and which one you are standing in. Outside the
   button so a tick is never its own target. */
.mamo-ap-rim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
}

.mamo-ap-tick {
  position: absolute;
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: var(--bs-secondary-color);
  opacity: .5;
}

.mamo-ap-tick[data-ap-on="1"] {
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  background: var(--bs-body-color);
  opacity: 1;
}

/* Where the collapsed bar's unread badge went. No ring: red needed one to survive
   against the icon's blue, but on the button's own grey it separates on its own,
   at roughly 3:1 in light and 3.2:1 in dark. */
.mamo-ap-tick[data-ap-alert="1"] { background: #ff3b30; opacity: 1; }

/* Four ticks, one per destination — Chats left for the top bar. Spread 150° to 30°
   at a 21px radius from the button's centre. */
.mamo-ap-tick:nth-child(1) { left: 9.8px;  top: 17.5px; }
.mamo-ap-tick:nth-child(2) { left: 20.8px; top: 8.3px; }
.mamo-ap-tick:nth-child(3) { left: 35.2px; top: 8.3px; }
.mamo-ap-tick:nth-child(4) { left: 46.2px; top: 17.5px; }

.mamo-ap-menu {
  position: absolute;
  inset: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  z-index: 2;
}

.mamo-ap-menu li {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) translate(var(--x), var(--y));
  transition: transform .26s cubic-bezier(.22, .61, .36, 1);
}

/* Five petals now — four destinations and Create — symmetric about the button so
   neither hand is the favoured one. The radius stays 105px and the arc narrows to
   149.4°–30.6°, which holds the same 54px between neighbours that the labels need
   to stay clear of each other. Losing a petal pulls the ends up and in rather than
   spreading the remaining five wider. */
.mamo-ap-menu li:nth-child(1) { --x: -90.4px; --y: -53.4px; }
.mamo-ap-menu li:nth-child(2) { --x: -52px;   --y: -91.2px; }
.mamo-ap-menu li:nth-child(3) { --x: 0;       --y: -105px; }
.mamo-ap-menu li:nth-child(4) { --x: 52px;    --y: -91.2px; }
.mamo-ap-menu li:nth-child(5) { --x: 90.4px;  --y: -53.4px; }

.mamo-ap-petal {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
  text-decoration: none;
  transition: color .15s ease, border-color .15s ease, transform .15s ease;
}

.mamo-ap-petal[aria-current="page"] {
  color: var(--bs-body-color);
  border-color: var(--bs-body-color);
}

/* Set while a drag is hovering this one, so releasing is a confirmation rather
   than a guess. Also applied on hover and keyboard focus. */
.mamo-ap-petal:hover,
.mamo-ap-petal:focus-visible,
.mamo-ap-petal[data-ap-hot] {
  color: var(--bs-body-color);
  border-color: var(--bs-body-color);
  transform: scale(1.12);
}

/* Filled, so the one thing here that does something rather than goes somewhere
   does not read as a sixth destination. */
.mamo-ap-make {
  background: var(--bs-body-color);
  border-color: var(--bs-body-color);
  color: var(--bs-body-bg);
}

/* The shared hover rule below sets the icon to the body colour, which on this
   filled circle would paint it out entirely. */
.mamo-ap-make:hover,
.mamo-ap-make:focus-visible,
.mamo-ap-make[data-ap-hot] {
  color: var(--bs-body-bg);
  border-color: var(--bs-body-color);
}

.mamo-ap-name {
  position: absolute;
  top: 44px;
  left: 50%;
  transform: translateX(-50%);
  font-size: .69rem;
  white-space: nowrap;
  color: var(--bs-secondary-color);
}

.mamo-ap-coach {
  position: absolute;
  left: 50%;
  bottom: 68px;
  transform: translateX(-50%);
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--bs-body-color);
  color: var(--bs-body-bg);
  font-size: .69rem;
  white-space: nowrap;
  /* Never in the way of the button it is pointing at. */
  pointer-events: none;
  z-index: 5;
}

/* Once the fan is out, the hint has been taken. */
.mamo-ap[data-ap-open] .mamo-ap-coach { display: none; }

.mamo-ap-dot {
  position: absolute;
  top: 1px;
  right: 1px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff3b30;
  border: 2px solid var(--bs-body-bg);
}

/* Everything above draws the menu open. The collapse is applied only once the
   script has claimed the nav, so with no JavaScript the five links stay on
   screen and the navigation still works. */
.mamo-ap[data-ap-ready] .mamo-ap-menu li {
  transform: translate(-50%, -50%) scale(.4);
  opacity: 0;
  pointer-events: none;
  transition: transform .26s cubic-bezier(.22, .61, .36, 1), opacity .16s ease;
}

.mamo-ap[data-ap-ready][data-ap-open] .mamo-ap-menu li {
  transform: translate(-50%, -50%) translate(var(--x), var(--y));
  opacity: 1;
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .mamo-ap-menu li,
  .mamo-ap-petal,
  .mamo-ap-scrim { transition: none; }

  /* No travel — the petals are simply there or not. */
  .mamo-ap[data-ap-ready] .mamo-ap-menu li {
    transform: translate(-50%, -50%) translate(var(--x), var(--y));
  }
}

/* ==========================================================================
   Desktop (>=1024px): the top bar and floating pill give way to a labelled
   sidebar. A pill floating over a wide monitor reads as a stretched phone;
   below this width the pill is the right answer and comes back.
   ========================================================================== */

.mamo-sidebar { display: none; }

.mamo-side-item {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 11px 10px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--bs-body-color);
  text-decoration: none;
  font-size: 15px;
  text-align: left;
}

.mamo-side-item svg { width: 24px; height: 24px; flex: none; }
.mamo-side-item:hover { background: var(--bs-secondary-bg); color: var(--bs-body-color); }
.mamo-side-item.active { font-weight: 700; }

.mamo-side-count {
  margin-left: auto;
  min-width: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #ff3b30;
  color: #fff;
  font-size: 11px;
  line-height: 18px;
  text-align: center;
  font-weight: 600;
}

@media (min-width: 1024px) {
  /* The sidebar takes over from all three of these on a wide screen — but the sidebar
     only renders when someone is signed in. Hiding the top bar unconditionally left a
     signed-out desktop visitor with no wordmark and no Log in button anywhere on the
     page: the only route to the front door was a profile's Reverse button, which is not
     a login control and does not read as one. So the bar is hidden only where something
     replaces it. The nav pill and aperture stay unconditional, since neither has any
     meaning to a visitor who is not signed in. */
  .has-sidebar .mamo-topbar,
  .mamo-navpill,
  .mamo-ap { display: none; }

  .mamo-sidebar {
    display: flex;
    flex-direction: column;
    gap: 4px;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 245px;
    padding: 18px 12px 20px;
    background: var(--bs-body-bg);
    border-right: 1px solid var(--bs-border-color);
    overflow-y: auto;
    z-index: 1030;
  }

  .mamo-sidebar-brand { padding: 6px 10px 22px; align-self: flex-start; }
  .mamo-side-spacer { flex: 1; min-height: 20px; }

  /* The feed and rail are centred together in whatever room is left. This applies on
     every page — it is the centring mechanism, not the sidebar allowance. */
  .mamo-page {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    gap: 28px;
    padding: 8px 16px 0;
  }

  /* Only the allowance is conditional. The sidebar is fixed, so content is pushed
     clear of its width — but it is rendered only for someone signed in, and applying
     the offset regardless pushed the auth screens right by 245px of nothing.
     Scoping the whole rule above would be worse than the bug: it would take the flex
     centring away with it and drop the login card against the left edge. */
  .has-sidebar .mamo-page { margin-left: 245px; }

  /* The shell's `margin: 0 auto` centres it on mobile, but as a flex item those
     auto margins eat the free space and beat justify-content, shunting the whole
     group off-centre. Hand the centring back to the container. */
  .mamo-page > .mamo-shell { margin-left: 0; margin-right: 0; }

  /* Both columns must be able to give. Pinned at exactly 470 and 300 they can
     neither absorb spare width nor yield when there isn't enough, so a window that
     doesn't happen to suit that number becomes a dead strip beside the feed. Letting
     the column grow into the slack keeps the page filled at any width. */
  .mamo-page > .mamo-shell {
    flex: 1 1 auto;
    max-width: 720px;
    min-width: 0;
  }

  .mamo-main { padding-bottom: 32px; }

  .has-sidebar .footer { margin-left: 245px; }
  .footer { padding-bottom: 24px; }
}

/* ==========================================================================
   Shell fit-ups
   ========================================================================== */

/* Every view predates the shell and centres itself with `.row > .col-md-8 col-lg-6`,
   written back when the page was a full-width Bootstrap container. Inside a 470px
   shell those fractions resolve against 470 instead, halving the feed to ~210px.
   The shell is the width constraint now, so the inner columns give theirs up.
   Multi-column rows stack as a result, which is the right call at this width. */
.mamo-shell .row > [class*="col-"] {
  flex: 0 0 100%;
  max-width: 100%;
  width: 100%;
}


/* ==========================================================================
   Filling the screen
   Nothing used to stretch, so a short page left its content clinging to the top
   with the footer floating in the middle of the viewport. Classic sticky footer:
   the body is a column, the page area takes the slack.
   ========================================================================== */

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Replaced by the layout below; the old value left a permanent gap. */
  margin-bottom: 0;
}

.mamo-page { flex: 1 0 auto; }


/* An empty page should look deliberately empty, not broken. Centred in the space
   it has rather than pinned to the top of it. */
.mamo-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 44vh;
  color: var(--bs-secondary-color);
}

.mamo-empty > :last-child { margin-bottom: 0; }

/* ==========================================================================
   Post action icons — inline SVG, matching the nav
   ========================================================================== */

.mamo-act {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--bs-body-color);
  text-decoration: none;
  cursor: pointer;
}

.mamo-act svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
}

.mamo-act:hover { color: var(--bs-body-color); opacity: .6; }

/* Base for every emoji used as an icon. The family list is explicit because a bare
   sans-serif will happily draw a monochrome outline glyph instead of the colour one.
   Sized to the text it sits beside and nudged onto its baseline — unlike .mamo-inline
   (which styles SVGs) there is no recolouring here, because an emoji carries its own
   colour and ignores currentColor entirely. */
.mamo-emoji {
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  font-style: normal;
  font-size: 1.05em;
  vertical-align: -0.1em;
}

/* Like, comment and share are emoji — a butterfly, a honeybee and a dove. Sized to sit on
   the same line as the save icon beside them. Wins over the base above on specificity. */
.mamo-act .mamo-emoji {
  display: block;
  font-size: 22px;
  line-height: 24px;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  transition: opacity .18s ease, transform .18s ease, filter .18s ease;
}

/* An emoji is a colour glyph, so the liked state cannot be a fill the way the old heart's
   was — currentColor does not reach it. Colour itself carries the toggle instead: no colour
   at all until you like, then the glyph's own. Opacity alone was not enough, because a
   half-faded butterfly is still a pink butterfly and still reads as "on".
   Comment and share are not toggles, so they never fade. */
.mamo-like-btn .mamo-emoji { filter: grayscale(1); opacity: .55; transform: scale(.94); }
.mamo-like-btn.liked .mamo-emoji { filter: none; opacity: 1; transform: scale(1.08); }

/* Save is still a line icon, so it still fills. */
.mamo-like-btn.liked { color: #e0245e; }
.mamo-save-btn.saved svg { fill: currentColor; }

/* On a reel these sit over video, where a flat emoji can vanish into a pale frame.
   filter does not accumulate across rules — the last matching one replaces the others — so
   the like button has to restate the shadow next to its greyscale. Leave it to the rule
   below and the drop-shadow wins on source order, dropping the greyscale on reels only. */
.mamo-reel-actions .mamo-emoji { filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .55)); }
.mamo-reel-actions .mamo-like-btn .mamo-emoji {
  filter: grayscale(1) drop-shadow(0 1px 3px rgba(0, 0, 0, .55));
}
.mamo-reel-actions .mamo-like-btn.liked .mamo-emoji {
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .55));
}

@media (prefers-reduced-motion: reduce) {
  .mamo-act .mamo-emoji { transition: none; }
}

/* ==========================================================================
   Narrow desktop (1024–1263px): the sidebar collapses to icons.
   Below 1264px a 245px sidebar plus a 470px feed leaves the page looking mostly
   empty, so the labels go and the 172px comes back to the content.
   ========================================================================== */

.mamo-side-mark { display: none; }

@media (min-width: 1024px) {
  .mamo-sidebar-brand {
    display: flex;
    align-items: center;
    padding: 6px 10px 22px;
    text-decoration: none;
  }
}

@media (min-width: 1024px) and (max-width: 1263px) {
  .mamo-sidebar { width: 73px; padding-left: 8px; padding-right: 8px; align-items: center; }
  .mamo-side-label { display: none; }
  .mamo-side-mark { display: inline; font-size: 34px; }
  .mamo-sidebar-brand { justify-content: center; padding: 6px 0 22px; }
  .mamo-side-item { justify-content: center; padding: 12px 0; }
  /* Same reasoning as the wider breakpoint: only offset for a sidebar that exists. */
  .has-sidebar .mamo-page,
  .has-sidebar .footer { margin-left: 73px; }

  /* No room for a label, so the count shrinks to a dot on the icon's shoulder. */
  .mamo-side-count {
    position: absolute;
    top: 6px;
    right: 12px;
    min-width: 8px;
    height: 8px;
    padding: 0;
    font-size: 0;
    line-height: 0;
  }

  .mamo-side-item { position: relative; }
  .dropdown .mamo-side-item.w-100 { width: 100% !important; }
}

/* ==========================================================================
   Notes on the story tray
   A note sits above its author's ring rather than in its own panel — the note and
   the story are the same "what's this person up to right now" glance.
   ========================================================================== */

.mamo-tray-note {
  display: block;
  max-width: 84px;
  margin: 0 auto 4px;
  padding: 4px 8px;
  border-radius: 12px 12px 12px 3px;
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  color: var(--bs-body-color);
  font-size: 10px;
  line-height: 1.25;
  text-align: center;
  /* Two lines then ellipsis: notes are capped at 60 characters, and a tray circle
     is not the place to read one in full. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* No story to play, so no gradient — a plain outline says "note only". */
.mamo-tray-ring.note-only {
  background: transparent;
  border: 2px solid var(--bs-border-color);
}


/* ==========================================================================
   Chat list, filter pills, message requests, day separators
   ========================================================================== */

.mamo-chat-filters { display: flex; gap: 8px; flex-wrap: wrap; }

.mamo-chat-pill {
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
  text-decoration: none;
  font-size: 13px;
  white-space: nowrap;
}

.mamo-chat-pill:hover { color: var(--bs-body-color); }
.mamo-chat-pill.on { background: var(--bs-primary); border-color: var(--bs-primary); color: #fff; }
.mamo-chat-pill.requests { border-color: var(--bs-primary); color: var(--bs-primary); }

.mamo-chat-archived {
  display: flex;
  align-items: center;
  padding: 12px 4px;
  border-bottom: 1px solid var(--bs-border-color);
  color: var(--bs-body-color);
  text-decoration: none;
  font-size: 14px;
}

.mamo-chat-row { display: flex; align-items: stretch; border-bottom: 1px solid var(--bs-border-color); }

.mamo-chat-open {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
  padding: 11px 4px;
  color: var(--bs-body-color);
  text-decoration: none;
}

.mamo-chat-open:hover { background: var(--bs-secondary-bg); color: var(--bs-body-color); }

.mamo-chat-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.mamo-chat-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mamo-chat-preview {
  font-size: 13px;
  color: var(--bs-secondary-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mamo-chat-row.unread .mamo-chat-preview { color: var(--bs-body-color); font-weight: 600; }
.mamo-chat-tick { margin-right: 3px; }

.mamo-chat-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  flex-shrink: 0;
}

.mamo-chat-time { font-size: 12px; color: var(--bs-secondary-color); white-space: nowrap; }

/* Only reachable on hover or focus, so archiving is never an accidental tap. */
.mamo-chat-archive { display: flex; align-items: center; opacity: 0; transition: opacity .15s; }
.mamo-chat-row:hover .mamo-chat-archive,
.mamo-chat-archive:focus-within { opacity: 1; }

.mamo-request {
  padding: 14px 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.mamo-request-text {
  margin: 10px 0 6px;
  padding: 9px 12px;
  border-radius: 12px;
  background: var(--bs-secondary-bg);
  font-size: 14px;
  word-wrap: break-word;
}

/* Day separator in a thread */
.mamo-day-sep {
  display: flex;
  justify-content: center;
  margin: 14px 0 8px;
}

.mamo-day-sep span {
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
  font-size: 11px;
  font-weight: 600;
}

/* ==========================================================================
   Calls
   Media never reaches the server; this is only what the two browsers show
   each other while they talk directly.
   ========================================================================== */

.mamo-call-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  margin-top: 10px;
  border-radius: 10px;
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
}

/* The call floats over the page instead of sitting in the flow. A call happens
   *while* you're in a conversation — pushing the conversation off screen to make
   room for it gets the priority backwards, and a ringing call has nothing to show
   that's worth a whole screen anyway. */
.mamo-call {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 1070;
  width: min(330px, calc(100vw - 24px));
  padding: 14px;
  border-radius: 18px;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  box-shadow: 0 16px 44px rgba(0, 0, 0, .3);
}

@media (max-width: 575px) {
  /* On a phone it spans the width and clears the nav pill. */
  .mamo-call { right: 12px; left: 12px; bottom: 84px; width: auto; }
}

.mamo-call-head { text-align: center; margin-bottom: 12px; }
.mamo-call-who { display: block; font-weight: 600; }

.mamo-call-status {
  display: block;
  font-size: 13px;
  color: var(--bs-secondary-color);
  /* Reserves the line so the panel doesn't jump when the timer replaces
     "Calling…" — a control that moves under the cursor is a control you misclick. */
  min-height: 1.2em;
  font-variant-numeric: tabular-nums;
}

.mamo-call-notice {
  font-size: 12.5px;
  line-height: 1.4;
  padding: 8px 10px;
  margin-bottom: 12px;
  border-radius: 10px;
  background: rgba(224, 36, 94, .1);
  border: 1px solid rgba(224, 36, 94, .35);
  color: var(--bs-body-color);
}

/* Stands in for video on a voice call, and while a video call is still ringing. */
.mamo-call-face { display: flex; justify-content: center; padding: 6px 0 14px; }

.mamo-call-stage {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bs-secondary-bg);
  aspect-ratio: 3 / 4;
  margin-bottom: 12px;
}

/* Hidden until their track lands, so the panel never shows a black hole where a
   person is supposed to be. */
.mamo-call-stage video#callRemote {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: none;
  background: #000;
}

.mamo-call-stage.connected video#callRemote { display: block; }

/* Your own camera, mirrored — people expect to see themselves the way a mirror
   does, not the way the lens does. Fills the stage while you're the only one on
   it, then shrinks into the corner when they arrive. */
.mamo-call-stage video#callLocal {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
  border-radius: 12px;
  background: #111;
  /* Named properties, not `all`: a <video> has plenty of properties that have no
     business animating, and transitioning them made this box's own geometry
     unreadable while it was being debugged. */
  transition: width .25s ease, height .25s ease, right .25s ease, bottom .25s ease, border-radius .25s ease;
}

/* Driven by a class on the stage rather than a sibling combinator off the remote
   video: it doesn't care about DOM order, and it reads as the state it is.
   Sized in fixed pixels rather than a percentage — the stage is a known size, and
   a percentage has to resolve against a positioned ancestor, which is one more
   thing to get wrong for no benefit. */
.mamo-call-stage.connected video#callLocal {
  top: auto;
  left: auto;
  right: 10px;
  bottom: 10px;
  width: 96px;
  height: 128px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, .3);
}

.mamo-call-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.mamo-call-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 0;
  background: var(--bs-secondary-bg);
  color: var(--bs-body-color);
  cursor: pointer;
}

.mamo-call-btn svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mamo-call-btn:hover { filter: brightness(1.15); }

.mamo-call-btn:focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .mamo-call-stage video#callLocal { transition: none; }
}

/* Off is a state worth seeing at a glance — muted by accident is a long call. */
.mamo-call-btn.off { background: #e0245e; color: #fff; }

.mamo-call-btn .off-state { display: none; }
.mamo-call-btn.off .on-state { display: none; }
.mamo-call-btn.off .off-state { display: inline-flex; }
.mamo-call-btn span { display: inline-flex; }

.mamo-call-btn.end { background: #e0245e; color: #fff; }
.mamo-call-btn.end svg { stroke-width: 2; }

/* ---- the composer ------------------------------------------------------
   One pill holding the tools and the field, with the send button outside it.
   The row reads as a single object rather than four separate controls, and it
   picks up the radius of the chat search directly above it. */

/* The rule separates the thread from the whole composer dock, so the mode chip
   sits below it — it belongs to the composer, not to the conversation. */
.mamo-composer-modes { border-top: 1px solid var(--bs-border-color); padding-top: 12px; }

.mamo-composer svg,
.mamo-vanish-chip svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
}

.mamo-composer-modes { display: flex; justify-content: flex-end; margin-bottom: 10px; }

.mamo-vanish-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 13px 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--bs-border-color);
  background: transparent;
  color: var(--bs-secondary-color);
  font-size: 13px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.mamo-vanish-chip svg { width: 17px; height: 17px; }
.mamo-vanish-chip:hover { border-color: var(--bs-secondary-color); }

/* On is a state you should be able to see without reading the label. */
.mamo-vanish-chip.on {
  background: rgba(224, 36, 94, .12);
  border-color: rgba(224, 36, 94, .5);
  color: #e0245e;
}

.mamo-composer-row { display: flex; align-items: flex-end; gap: 9px; }

.mamo-composer-pill {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 6px 4px 8px;
  border-radius: 22px;
  border: 1px solid transparent;
  background: var(--bs-secondary-bg);
  transition: border-color .15s ease, background .2s ease;
}

.mamo-composer-pill:focus-within { border-color: rgba(56, 151, 240, .55); }

.mamo-composer-tool {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bs-secondary-color);
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}

.mamo-composer-tool:hover { background: rgba(128, 128, 128, .16); color: var(--bs-body-color); }

.mamo-composer-input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--bs-body-color);
  font: inherit;
  font-size: 15px;
  line-height: 1.4;
  padding: 8px 6px;
  /* Grows with what you type, up to a few lines, then scrolls. A one-line box
     for a message you can write 1000 characters into hides most of it. */
  resize: none;
  max-height: 120px;
}

.mamo-composer-input::placeholder { color: var(--bs-secondary-color); }

/* The only coloured thing in the row, and only once there is something to send. */
.mamo-composer-send {
  flex: none;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 50%;
  background: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
  cursor: pointer;
  transition: background .18s ease, color .18s ease, transform .12s ease;
}

.mamo-composer-send svg { width: 20px; height: 20px; transform: translateX(-1px); }
.mamo-composer-send:disabled { cursor: not-allowed; }
.mamo-composer-send.ready { background: #3897f0; color: #fff; }
.mamo-composer-send.ready:hover { filter: brightness(1.07); }
.mamo-composer-send.ready:active { transform: scale(.94); }

/* Recording takes over the pill rather than adding a caption somewhere else. */
.mamo-composer-rec { display: none; align-items: center; gap: 10px; flex: 1; min-width: 0; padding: 8px 4px; }
.mamo-composer-pill.rec { background: rgba(224, 36, 94, .1); border-color: rgba(224, 36, 94, .45); }
.mamo-composer-pill.rec .mamo-composer-rec { display: flex; }
.mamo-composer-pill.rec .mamo-composer-input,
.mamo-composer-pill.rec .mamo-composer-tool.cam { display: none; }
.mamo-composer-tool.mic.armed { background: #e0245e; color: #fff; }

.mamo-composer-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #e0245e;
  animation: mamo-rec-pulse 1.1s ease-in-out infinite;
}

@keyframes mamo-rec-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

.mamo-composer-time { font-size: 14px; font-weight: 600; color: #e0245e; font-variant-numeric: tabular-nums; }

.mamo-composer-hint {
  font-size: 12.5px;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* There is no Esc key on a phone, and at this width the whole hint truncates to
   nonsense trying to mention one. */
@media (max-width: 575px) {
  .mamo-composer-key { display: none; }
}

/* The photo you picked, as the photo you picked. */
.mamo-composer-attach {
  display: flex;
  align-items: center;
  gap: 10px;
  width: max-content;
  max-width: 100%;
  padding: 7px 8px 7px 7px;
  margin-bottom: 10px;
  border-radius: 12px;
  background: var(--bs-secondary-bg);
}

.mamo-composer-attach img { width: 40px; height: 40px; border-radius: 8px; object-fit: cover; flex: none; }
.mamo-composer-attach span { font-size: 13px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mamo-composer-x {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.mamo-composer-x:hover { background: rgba(128, 128, 128, .18); }
.mamo-composer-x svg { width: 15px; height: 15px; }

.mamo-composer-error { font-size: 13px; color: #e0245e; margin: 8px 0 0; }

@media (prefers-reduced-motion: reduce) {
  .mamo-composer-dot { animation: none; }
}

/* ---- menu and heading icons --------------------------------------------
   For the chrome that still had emoji in it: the sidebar's More menu, the footer, the
   profile menu, and page titles. An emoji arrives with its own colour and its own idea
   of the baseline; these take the text's colour and sit on it. */

.mamo-menu-item {
  display: flex;
  align-items: center;
  gap: 9px;
}

.mamo-menu-item svg {
  flex: none;
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The dismiss button is positioned absolutely by Bootstrap, so the flex row must not
   try to lay it out as a third column. */
.alert.mamo-menu-item { align-items: flex-start; }
.alert.mamo-menu-item svg { margin-top: 2px; }

.mamo-title { display: flex; align-items: center; gap: 9px; }

.mamo-title svg {
  flex: none;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A highlight with no cover yet: the star stands in for the picture, so it fills the
   ring rather than sitting in it like a letter. */
.mamo-tray-glyph { display: grid; place-items: center; }

.mamo-tray-glyph svg {
  width: 26px;
  height: 26px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  color: var(--bs-secondary-color);
}

.mamo-video-badge svg { width: 14px; height: 14px; fill: currentColor; stroke: none; display: block; }

/* Profile tabs: the icon carries the meaning, the count sits beside it. */
.mamo-tab { display: inline-flex; align-items: center; gap: 6px; }

.mamo-tab svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mamo-tab svg path[fill="currentColor"] { stroke: none; }

/* ---- back links ---------------------------------------------------------
   Two shapes, because the pages use two. `.mamo-back` is the worded link that sits at
   the foot of a page ("Settings", "Back to feed"); `.mamo-back-btn` is the bare arrow in
   a header bar, which needs a tap target rather than a text baseline. */

.mamo-back {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--bs-secondary-color);
  text-decoration: none;
  font-size: 0.925rem;
}

.mamo-back:hover { color: var(--bs-body-color); }

.mamo-back-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: none;
  margin-left: -6px;   /* the arrow's own padding, pulled back to the page edge */
  border-radius: 50%;
  color: var(--bs-body-color);
  text-decoration: none;
}

.mamo-back-btn:hover { background: var(--bs-secondary-bg); color: var(--bs-body-color); }

/* The archived-chats row is a full-width list row, not a link in a paragraph, so the
   arrow needs the gap the row didn't have when the character supplied its own space. */
.mamo-chat-archived { gap: 10px; }

.mamo-back svg, .mamo-back-btn svg, .mamo-chat-archived svg {
  flex: none;
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A heart in a heading, in the green the close-friends ring already uses. */
.mamo-title-cf svg { fill: currentColor; stroke: none; color: #2f9e44; }

/* ---- buttons that lead with an icon -------------------------------------
   "＋ New group", "✓ Close friend". A button is inline by default, so the icon and its
   label were sitting on the text baseline at whatever size the font chose. */

.mamo-pill-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.mamo-pill-btn svg {
  flex: none;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- the page header ----------------------------------------------------
   One row carrying the way back and the page's name. Replaced three separate habits: an
   arrow link at the foot of the page, a plain underlined link at the foot, and an arrow at
   the top — so "back" was in a different place depending on which screen you were on. */

.mamo-page-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0 10px;
}

.mamo-page-title {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  min-width: 0;
  font-size: 1.25rem;
  font-weight: 600;
}

.mamo-page-title svg {
  flex: none;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mamo-page-title svg path[fill="currentColor"] { stroke: none; }

/* ---- icons inside a run of text -----------------------------------------
   A location beside a caption, "with" before a tagged name, the voice-note length. The
   emoji these replace each set their own size and sat off the baseline; this matches the
   text around it and nudges up by the small amount an icon needs to look centred. */

.mamo-inline svg {
  width: 1.05em;
  height: 1.05em;
  vertical-align: -0.175em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mamo-inline svg path[fill="currentColor"] { stroke: none; }

/* ---- icon-only buttons --------------------------------------------------
   Remove a tag, remove a link, hide a post. The button keeps whatever colour it was
   given (danger, muted), the icon just takes it. */

.mamo-btn-glyph svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
}

.mamo-btn-glyph svg path[fill="currentColor"] { stroke: none; }

/* ---- grid marks ---------------------------------------------------------
   Sit on top of a thumbnail, so they carry the same shadow the emoji did. */

.mamo-grid-fallback svg {
  width: 30px;
  height: 30px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.mamo-grid-tag svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.65));
}

.mamo-avatar-placeholder svg {
  width: 55%;
  height: 55%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- empty states -------------------------------------------------------
   An illustration, not a control — so it is drawn large and thin, and in the muted
   colour, which is what the 3rem emoji was reaching for. */

.mamo-empty-glyph {
  display: block;
  margin-bottom: 0.85rem;
}

.mamo-empty-glyph svg {
  width: 60px;
  height: 60px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.35;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Already a translucent token — muting it again made the illustration nearly vanish. */
  color: var(--bs-secondary-color);
}

/* A finished action — the ✅ these replace was the only green on the page. */
.mamo-empty-ok svg { color: #2f9e44; opacity: 1; }

/* ---- the last few marks, sized where they sit --------------------------- */

.mamo-banner-icon svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
}

.mamo-banner-icon svg path[fill="currentColor"] { stroke: none; }

.mamo-profile-link { display: inline-flex; align-items: center; gap: 5px; }

.mamo-profile-link svg {
  flex: none;
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mamo-msg-tool svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
}

.mamo-chat-archive svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
}

.mamo-call-toast-icon svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- the front door -----------------------------------------------------
   The login screen. It carries no chrome, so it is the one page that has the whole
   viewport to arrange itself in. */

.login-shell {
  display: grid;
  place-items: center;
  /* What is left of the viewport once the layout's padding has taken its share —
     measured, not guessed, so the front door does not hand you a scrollbar. On a short
     screen the card is taller than this and the page scrolls, which is the right outcome:
     clipping a login form would be worse.

     Was 205px when a footer sat below this. 72px is what remains outside this element
     once that strip is gone — read off the rendered page, not derived by subtracting the
     footer's height from the old figure, which left a 16px scrollbar. */
  min-height: calc(100dvh - 72px);
  padding: 24px 0 40px;
}

.login-col {
  width: 100%;
  max-width: 380px;
}

.login-card {
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  padding: 44px 32px 30px;
}

/* Live text in the bundled face rather than a picture of it: sharp at any size, and it
   takes the body colour so it inverts itself in dark mode instead of staying black on a
   dark card. */
.login-mark {
  font-family: 'Grand Hotel', cursive;
  font-size: 54px;
  line-height: 1.15;
  text-align: center;
  color: var(--bs-body-color);
  margin: 0 0 2px;
}

.login-sub {
  text-align: center;
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
  margin: 0 0 30px;
}

/* Remember me and Forgot password share a row. As two stacked rows they were mostly
   empty space, and that space was most of what made the form feel long. */
.login-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 2px 0 22px;
  font-size: 0.875rem;
}

.login-meta .form-check { margin: 0; }
.login-meta a { text-decoration: none; }

/* A rule under the field it applies to, so it is read before it is broken rather than
   discovered as a validation message afterwards. */
.login-hint {
  margin: 2px 0 20px;
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}

/* A one-time code is read as a block of digits, not as words. */
.login-code { letter-spacing: 0.35em; text-indent: 0.35em; }

/* Signing in and signing up are different errands, so they do not share a card. */
.login-alt {
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  padding: 18px;
  text-align: center;
  margin-top: 14px;
  font-size: 0.925rem;
}

.login-alt a { font-weight: 600; text-decoration: none; }

/* ---- settings rows ------------------------------------------------------
   Grouped, and every row carries the value it's set to. The list used to be fourteen
   equal rows in no order, which meant finding anything required reading all of them. */

.mamo-set-group { margin-bottom: 1.75rem; }

.mamo-set-head {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
  margin: 0 0 .45rem .15rem;
}

.mamo-set-rows {
  border: 1px solid var(--bs-border-color);
  border-radius: 12px;
  overflow: hidden;
}

.mamo-set-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 14px;
  border: 0;
  border-bottom: 1px solid var(--bs-border-color);
  border-radius: 0;
  background: transparent;
  color: var(--bs-body-color);
  text-align: left;
  text-decoration: none;
  font-size: .95rem;
}

.mamo-set-rows > *:last-child .mamo-set-row,
.mamo-set-row:last-child { border-bottom: 0; }

a.mamo-set-row:hover,
button.mamo-set-row:hover,
label.mamo-set-row:hover { background: var(--bs-secondary-bg); color: var(--bs-body-color); }

label.mamo-set-row { cursor: pointer; margin: 0; }

.mamo-set-icon { flex: none; display: grid; place-items: center; width: 20px; height: 20px; color: var(--bs-secondary-color); }
.mamo-set-icon.green { color: #2f9e44; }

.mamo-set-icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mamo-set-label { flex: 1; min-width: 0; }
.mamo-set-label small { display: block; font-size: .78rem; color: var(--bs-secondary-color); }

/* The value is the point of the redesign: the list answers questions instead of posing
   them. Muted, right-aligned, never competing with the label. */
.mamo-set-value {
  flex: none;
  font-size: .82rem;
  color: var(--bs-secondary-color);
  max-width: 45%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* One colour, for one thing: a security setting that's off. Not a banner, not a nag. */
.mamo-set-value.warn { color: #b8860b; font-weight: 600; }

.mamo-set-count {
  flex: none;
  min-width: 22px;
  padding: 1px 8px;
  border-radius: 999px;
  background: #3897f0;
  color: #fff;
  font-size: .72rem;
  font-weight: 650;
  text-align: center;
}

.mamo-set-chev { flex: none; display: grid; place-items: center; color: var(--bs-secondary-color); opacity: .55; }
.mamo-set-chev svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }

.mamo-set-choice { cursor: pointer; }

/* Out of the list, behind its own border, with the consequence beside it rather than
   discovered on the next screen. Distance is the safeguard. */
.mamo-set-danger {
  margin-top: 2rem;
  padding: 14px 16px;
  border: 1px solid rgba(224, 36, 94, .45);
  border-radius: 12px;
  background: rgba(224, 36, 94, .06);
}

.mamo-set-danger a { color: #e0245e; font-weight: 600; text-decoration: none; }
.mamo-set-danger a:hover { text-decoration: underline; }
.mamo-set-danger p { margin: .35rem 0 0; font-size: .8rem; color: var(--bs-secondary-color); }

/* The segmented control doubles as a tab strip on the limited-people screen. */
.mamo-seg a {
  border: 0;
  border-radius: 999px;
  padding: 5px 14px;
  font-size: 13px;
  background: transparent;
  color: var(--bs-secondary-color);
  text-decoration: none;
}

.mamo-seg a.on {
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}

/* ---- the New post composer ---------------------------------------------
   The picker is the screen. Everything below it is deliberately quieter. */

.mamo-compose-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 1.5rem 0 1.25rem;
}

.mamo-seg button svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mamo-seg button { display: inline-flex; align-items: center; gap: 6px; }

/* The drop zone. A whole area is a target; the native button was a 90px sliver. */
.mamo-drop {
  display: grid;
  place-items: center;
  text-align: center;
  padding: 40px 20px;
  border: 2px dashed var(--bs-border-color);
  border-radius: 14px;
  background: var(--bs-secondary-bg);
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}

.mamo-drop:hover,
.mamo-drop:focus-visible,
.mamo-drop.over { border-color: #3897f0; }

.mamo-drop svg {
  width: 34px;
  height: 34px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--bs-secondary-color);
  margin-bottom: 10px;
}

.mamo-drop b { display: block; font-size: 15px; font-weight: 620; }
.mamo-drop span { display: block; font-size: 13px; color: var(--bs-secondary-color); margin-top: 4px; }

/* Chosen photos, as the photos. */
.mamo-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 10px;
}

.mamo-tile {
  position: relative;
  aspect-ratio: 1;
  border-radius: 10px;
  overflow: hidden;
  background: var(--bs-secondary-bg);
}

.mamo-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Removing one photo from a batch of twelve shouldn't mean choosing all twelve again. */
.mamo-tile-x {
  position: absolute;
  top: 5px;
  right: 5px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  cursor: pointer;
}

.mamo-tile-x svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.mamo-tile-x:hover { background: rgba(0, 0, 0, .75); }

.mamo-tile-n {
  position: absolute;
  left: 6px;
  bottom: 5px;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .5);
  color: #fff;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.mamo-tile-add {
  display: grid;
  place-items: center;
  border: 2px dashed var(--bs-border-color);
  background: transparent;
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.mamo-tile-add svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.mamo-tile-add:hover { border-color: #3897f0; color: var(--bs-body-color); }

.mamo-video-preview { width: 100%; border-radius: 12px; margin-top: 12px; }

/* Fields */
.mamo-field { margin-top: 22px; }

.mamo-field-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}

.mamo-field label { font-size: 13.5px; font-weight: 620; margin: 0; }

.mamo-count { font-size: 12px; color: var(--bs-secondary-color); font-variant-numeric: tabular-nums; }
.mamo-count.warn { color: #e0245e; }

.mamo-input {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--bs-border-color);
  border-radius: 12px;
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  font: inherit;
  font-size: 14.5px;
  outline: none;
  transition: border-color .15s ease;
}

.mamo-input:focus { border-color: rgba(56, 151, 240, .6); }
.mamo-textarea { resize: vertical; min-height: 92px; }
.mamo-hint { font-size: 12.5px; color: var(--bs-secondary-color); margin: 5px 0 0; }

.mamo-input-icon { position: relative; }

.mamo-input-icon svg {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--bs-secondary-color);
  pointer-events: none;
}

.mamo-input-icon .mamo-input { padding-left: 38px; }

/* Advanced: what's rarely wanted, gathered rather than scattered. */
.mamo-advanced { margin-top: 24px; border-top: 1px solid var(--bs-border-color); padding-top: 16px; }

.mamo-advanced-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--bs-body-color);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.mamo-advanced-toggle svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .18s ease;
}

.mamo-advanced.open .mamo-advanced-toggle svg { transform: rotate(90deg); }
.mamo-advanced-body { display: none; margin-top: 14px; }
.mamo-advanced.open .mamo-advanced-body { display: block; }

.mamo-switch-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.mamo-switch-row:last-of-type { border-bottom: 0; }
.mamo-switch-text { flex: 1; min-width: 0; }
.mamo-switch-text b { display: block; font-size: 14px; font-weight: 600; }
.mamo-switch-text span { display: block; font-size: 12.5px; color: var(--bs-secondary-color); }

/* A real checkbox, drawn as a switch — so it submits, validates and reaches the keyboard
   without any of that having to be rebuilt. */
.mamo-switch {
  flex: none;
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 42px;
  height: 24px;
  margin: 0;
  border: 0;
  border-radius: 999px;
  background: var(--bs-border-color);
  cursor: pointer;
  transition: background .18s ease;
}

.mamo-switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  transition: transform .18s ease;
}

.mamo-switch:checked { background: #3897f0; }
.mamo-switch:checked::after { transform: translateX(18px); }

/* The Settings rows draw the switch as a <button> rather than a checkbox, so toggling is a
   real form post and keeps working with scripting off. A button can never match :checked,
   so it needs an on-state of its own — without this the markup was setting `.on` while the
   stylesheet listened for something a button cannot be, and the switch sat grey however the
   setting was actually saved. */
.mamo-switch.on { background: #3897f0; }
.mamo-switch.on::after { transform: translateX(18px); }

.mamo-share {
  width: 100%;
  margin-top: 22px;
  padding: 13px;
  border: 0;
  border-radius: 999px;
  background: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
  font: inherit;
  font-size: 15px;
  font-weight: 640;
  cursor: not-allowed;
  transition: background .18s ease, color .18s ease;
}

.mamo-share.ready { background: #3897f0; color: #fff; cursor: pointer; }
.mamo-share.ready:hover { filter: brightness(1.07); }

@media (prefers-reduced-motion: reduce) {
  .mamo-advanced-toggle svg, .mamo-switch, .mamo-switch::after { transition: none; }
}

/* ---- the comment popup -------------------------------------------------
   Opens over whatever you're looking at, so reading comments never costs you your
   place in the feed. A bottom sheet on a phone, a centred dialog above that. */

.mamo-sheet-root {
  position: fixed;
  inset: 0;
  z-index: 1090;
}

.mamo-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .45);
  opacity: 0;
  transition: opacity .2s ease;
}

.mamo-sheet-root.open .mamo-sheet-backdrop { opacity: 1; }

/* While it's up, the page behind must not scroll under your finger. */
body.mamo-sheet-open { overflow: hidden; }

/* NOT `.mamo-sheet` — that name already belongs to the Create bottom sheet's
   `.modal-content` further up this file, and redefining it here silently restyled that
   dialog instead. The rest of the `mamo-sheet-*` names below are this component's alone;
   the Create sheet owns `-dialog`, `-grab`, `-row` and `-icon`.

   Phone: rises from the bottom, stopping short of the top so the post stays in view. */
.mamo-comments-panel {
  position: absolute;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  transition: transform .24s cubic-bezier(.32, .72, 0, 1), opacity .2s ease;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 86vh;
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -12px 40px rgba(0, 0, 0, .3);
  transform: translateY(100%);
}

.mamo-sheet-root.open .mamo-comments-panel { transform: translateY(0); }

.mamo-sheet-grip {
  width: 38px;
  height: 4px;
  border-radius: 999px;
  background: var(--bs-border-color);
  margin: 8px auto 0;
  flex: none;
}

@media (min-width: 576px) {
  /* Desktop: a centred dialog. A sheet stuck to the bottom of a tall window puts the
     comments a long way from the post they belong to. */
  .mamo-comments-panel {
    left: 50%;
    top: 50%;
    right: auto;
    bottom: auto;
    width: min(520px, calc(100vw - 40px));
    max-height: 78vh;
    border-radius: 16px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
    transform: translate(-50%, -46%) scale(.97);
    opacity: 0;
  }

  .mamo-sheet-root.open .mamo-comments-panel { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  .mamo-sheet-grip { display: none; }
}

.mamo-sheet-head {
  display: flex;
  align-items: center;
  padding: 12px 14px;
  border-bottom: 1px solid var(--bs-border-color);
  flex: none;
}

.mamo-sheet-title { flex: 1; margin: 0; text-align: center; font-size: 15px; font-weight: 640; }
.mamo-sheet-spacer { width: 30px; flex: none; }

.mamo-sheet-close {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bs-body-color);
  cursor: pointer;
}

.mamo-sheet-close:hover { background: rgba(128, 128, 128, .16); }
.mamo-sheet-close svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; }

/* The body holds the scrolling list and the pinned composer. */
.mamo-sheet-body { display: flex; flex-direction: column; min-height: 0; flex: 1; }

.mamo-sheet-list {
  flex: 1;
  min-height: 120px;
  overflow-y: auto;
  padding: 14px;
  display: grid;
  gap: 14px;
  align-content: start;
}

.mamo-sheet-empty { color: var(--bs-secondary-color); font-size: 14px; text-align: center; padding: 28px 12px; margin: 0; }

.mamo-comment { display: flex; gap: 10px; align-items: flex-start; }
.mamo-comment-avatar { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; flex: none; }
.mamo-comment-body { flex: 1; min-width: 0; font-size: 14px; }
.mamo-comment-text { white-space: pre-line; }
.mamo-comment-when { color: var(--bs-secondary-color); font-size: 12.5px; margin-top: 2px; }

.mamo-comment-flag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--bs-warning);
  color: #3d2f00;
  font-size: 11px;
  font-weight: 600;
}

/* A comment held for approval. Same amber the inline list used, so the state reads the
   same wherever it's shown. */
.mamo-comment.held .mamo-comment-body {
  background: rgba(255, 193, 7, .12);
  border-left: 3px solid var(--bs-warning);
  border-radius: 6px;
  padding: 6px 8px;
}

/* ---- threads ----
   One level deep, collapsed until asked for. The indent and the connecting line come from
   the wrapper, so a reply's own markup is identical to a top-level comment's. */

.mamo-replies-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: 42px;
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--bs-secondary-color);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

/* The little rule before the label reads as "there's more attached here". */
.mamo-replies-toggle::before {
  content: "";
  width: 22px;
  height: 1px;
  background: var(--bs-border-color);
}

.mamo-replies-toggle:hover { color: var(--bs-body-color); }
.mamo-replies-toggle .mamo-replies-close { display: none; }
.mamo-replies-toggle.open .mamo-replies-open { display: none; }
.mamo-replies-toggle.open .mamo-replies-close { display: inline; }

.mamo-replies { margin-left: 42px; }

.mamo-replies .mamo-comment {
  position: relative;
  padding-left: 20px;
  font-size: 13.5px;
}

/* The spine, and the elbow into each reply. The last one stops the line short so a thread
   ends rather than trailing off. */
.mamo-replies .mamo-comment::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--bs-border-color);
}

.mamo-replies .mamo-comment:last-child::before { bottom: auto; height: 20px; }

.mamo-replies .mamo-comment::after {
  content: "";
  position: absolute;
  left: 0;
  top: 20px;
  width: 13px;
  height: 1px;
  background: var(--bs-border-color);
}

.mamo-replies .mamo-comment-avatar { width: 26px; height: 26px; }

/* Who you're answering, and a way out of it. */
.mamo-replying {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 4px 8px;
  font-size: 12.5px;
  color: var(--bs-secondary-color);
}

.mamo-replying b { color: var(--bs-body-color); }

.mamo-replying button {
  margin-left: auto;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: var(--bs-secondary-color);
  cursor: pointer;
  padding: 2px;
}

.mamo-replying button svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.mamo-replying button:hover { color: var(--bs-body-color); }

/* Row actions. Reply is for everyone; the rest belong to the author or the writer and
   stay out of the way until wanted. */
.mamo-comment-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.mamo-comment-act {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--bs-secondary-color);
  text-decoration: none;
  cursor: pointer;
}

.mamo-comment-act:hover { color: var(--bs-body-color); }
.mamo-comment-act.danger:hover { color: #e0245e; }
.mamo-comment-act.strong { color: var(--bs-success); }

.mamo-comment-act.owner { opacity: 0; transition: opacity .15s ease; }
.mamo-comment:hover .mamo-comment-act.owner,
.mamo-comment-act.owner:focus-visible { opacity: 1; }
@media (hover: none) { .mamo-comment-act.owner { opacity: 1; } }

.mamo-comment-action { margin: 0; display: inline; }

.mamo-comment-approve {
  border: 1px solid var(--bs-success);
  background: transparent;
  color: var(--bs-success);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  cursor: pointer;
}

.mamo-comment-approve:hover { background: var(--bs-success); color: #fff; }

.mamo-comment-delete {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bs-secondary-color);
  cursor: pointer;
  /* Shown on hover on a pointer device; always there on touch, where there is no hover. */
  opacity: 0;
  transition: opacity .15s ease;
}

.mamo-comment:hover .mamo-comment-delete,
.mamo-comment-delete:focus-visible { opacity: 1; }

@media (hover: none) {
  .mamo-comment-delete { opacity: 1; }
}

.mamo-comment-delete:hover { background: rgba(128, 128, 128, .18); color: var(--bs-body-color); }
.mamo-comment-delete svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; }

/* Same pill and state-aware button as the chat composer — the two places you write in
   MamoCrown should not behave differently. */
.mamo-sheet-foot { flex: none; border-top: 1px solid var(--bs-border-color); padding: 10px 12px; }
.mamo-sheet-form { display: flex; align-items: center; gap: 8px; margin: 0; }

.mamo-sheet-pill {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  background: var(--bs-secondary-bg);
  border: 1px solid transparent;
  border-radius: 22px;
  padding: 4px 14px;
}

.mamo-sheet-pill:focus-within { border-color: rgba(56, 151, 240, .55); }

.mamo-sheet-pill input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--bs-body-color);
  font: inherit;
  font-size: 14px;
  padding: 8px 0;
}

.mamo-sheet-pill input::placeholder { color: var(--bs-secondary-color); }

.mamo-sheet-send {
  flex: none;
  border: 0;
  border-radius: 999px;
  padding: 8px 18px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  background: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
  cursor: not-allowed;
  transition: background .18s ease, color .18s ease;
}

.mamo-sheet-send.ready { background: #3897f0; color: #fff; cursor: pointer; }
.mamo-sheet-send.ready:hover { filter: brightness(1.07); }

.mamo-sheet-signin { display: block; text-align: center; font-size: 14px; padding: 6px 0; }
.mamo-sheet-closed { text-align: center; font-size: 14px; color: var(--bs-secondary-color); margin: 0; padding: 6px 0; }

.mamo-comment-report {
  align-self: center;
  font-size: 12px;
  color: var(--bs-secondary-color);
  text-decoration: none;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .15s ease;
}

.mamo-comment:hover .mamo-comment-report,
.mamo-comment-report:focus-visible { opacity: 1; }
@media (hover: none) { .mamo-comment-report { opacity: 1; } }
.mamo-comment-report:hover { color: #e0245e; }

/* The report form quotes what's being reported back at you. */
.mamo-report-quote {
  margin: 0 0 18px;
  padding: 10px 14px;
  border-left: 3px solid var(--bs-border-color);
  background: var(--bs-secondary-bg);
  border-radius: 0 8px 8px 0;
  font-size: 14px;
}

/* ---- held comments queue ---- */
.mamo-pending-list { display: grid; gap: 14px; }

.mamo-pending {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px;
  border: 1px solid var(--bs-border-color);
  border-left: 3px solid var(--bs-warning);
  border-radius: 10px;
  background: var(--bs-secondary-bg);
}

.mamo-pending-post { flex: none; }
.mamo-pending-post img,
.mamo-pending-noimg {
  display: block;
  width: 48px;
  height: 48px;
  border-radius: 8px;
  object-fit: cover;
  background: var(--bs-body-bg);
}

.mamo-pending-body { flex: 1; min-width: 0; font-size: 14px; }
.mamo-pending-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; flex: none; }
.mamo-pending-actions form { margin: 0; }

@media (max-width: 575px) {
  .mamo-pending { flex-wrap: wrap; }
  .mamo-pending-actions { flex-direction: row; width: 100%; justify-content: flex-end; gap: 12px; }
}

/* With scripting on, the popup is the comment surface — the page's own list is only
   there so a visitor without JavaScript still has one. Both are decided by a class set
   on <html> before paint, so neither flashes into view and gets snatched back. */
.js .mamo-comments-fallback { display: none; }
.js-only { display: none; }
.js .js-only { display: block; }

@media (prefers-reduced-motion: reduce) {
  .mamo-comments-panel, .mamo-sheet-backdrop { transition: none; }
}

/* A call in the timeline: an event, not something anyone said, so it reads as a
   card rather than a speech bubble. */
.mamo-call-log {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  max-width: 78%;
}

.mamo-call-log-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--bs-body-bg);
  flex: none;
}

.mamo-call-log-icon svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Pink is reserved for a call that never connected. A call you cancelled yourself,
   or one somebody declined, is a decision rather than something you missed — and if
   every card is pink, none of them are. */
.mamo-call-log.missed {
  background: rgba(224, 36, 94, .09);
  border-color: rgba(224, 36, 94, .4);
}

.mamo-call-log.missed .mamo-call-log-icon,
.mamo-call-log.missed .mamo-call-log-detail { color: #e0245e; }

.mamo-call-log-detail { color: var(--bs-secondary-color); }
.mamo-call-log-time { font-size: .7rem; opacity: .7; margin-left: 6px; }

/* The app-wide incoming-call prompt. Fixed above everything, because a ringing
   phone that scrolls out of view is not a ringing phone. */
.mamo-call-toast {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1080;
  display: flex;
  align-items: center;
  gap: 12px;
  width: min(420px, calc(100vw - 24px));
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .28);
}

.mamo-call-toast-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--bs-secondary-bg);
  flex: none;
}

/* Chat rows, refined. Glyphs are inline SVG so they take the row's colour and sit
   on the baseline; emoji bring their own palette and fight everything near them. */

.mamo-chat-search {
  border-radius: 999px;
  padding-left: 16px;
  background: var(--bs-secondary-bg);
  border-color: transparent;
}

.mamo-chat-search:focus { background: var(--bs-body-bg); }

/* Squared off so a group reads as a group before you've read the name. */
.mamo-avatar-group { border-radius: 16px; }

.mamo-chat-kind svg,
.mamo-chat-tick svg,
.mamo-avatar-group svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -2px;
}

.mamo-chat-kind svg { width: 15px; height: 15px; }
.mamo-chat-kind { margin-right: 4px; opacity: .8; }

.mamo-avatar-group svg { width: 28px; height: 28px; stroke-width: 1.6; }

.mamo-chat-tick { display: inline-block; margin-right: 4px; color: var(--bs-secondary-color); }
.mamo-chat-tick svg { width: 15px; height: 12px; stroke-width: 2.4; }
.mamo-chat-tick.read svg { width: 19px; }

/* Read is the only state that gets colour — it's the one that tells you something
   you didn't already know. */
.mamo-chat-tick.read { color: #3897f0; }

/* "Waiting": read, and left unanswered. Unread tells you what you haven't opened;
   this tells you who you've left hanging, which is the question you actually had. */
.mamo-chat-pill.waiting { border-color: #f0a13a; color: #f0a13a; }
.mamo-chat-pill.waiting.on { background: #f0a13a; border-color: #f0a13a; color: #1a1a1a; }

/* Nothing to report. Still there so the feature can be found, but it takes the
   plain treatment — a colour with no number behind it is a false alarm. */
.mamo-chat-pill.quiet,
.mamo-chat-pill.quiet.waiting,
.mamo-chat-pill.quiet.requests {
  border-color: var(--bs-border-color);
  color: var(--bs-secondary-color);
}

.mamo-chat-pill.quiet:hover { color: var(--bs-body-color); }

.mamo-chat-row.waiting .mamo-chat-name::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 7px;
  border-radius: 50%;
  background: #f0a13a;
  vertical-align: middle;
}

/* ==========================================================================
   Search suggestions
   ========================================================================== */

.mamo-suggest-wrap { position: relative; }

.mamo-suggest {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 1060;
  max-height: 60vh;
  overflow-y: auto;
  padding: 6px;
  border-radius: 14px;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .22);
}

.mamo-suggest-head {
  padding: 8px 10px 4px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--bs-secondary-color);
}

.mamo-suggest-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 10px;
  color: var(--bs-body-color);
  text-decoration: none;
}

/* Hover and keyboard share one state, so arrowing through feels like pointing. */
.mamo-suggest-row:hover,
.mamo-suggest-row.on {
  background: var(--bs-secondary-bg);
  color: var(--bs-body-color);
}

.mamo-suggest-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.mamo-suggest-text strong { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mamo-suggest-sub {
  font-size: 12px;
  color: var(--bs-secondary-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mamo-suggest-badge {
  flex: none;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
}

/* ── Obverse ───────────────────────────────────────────────────────────────
   The locked profile, drawn as the coin the word Reverse already implies. Two
   states, both server-rendered from the view model — no script, and no flip
   animation on load, because a coin that spins itself every time you land on a
   stranger's page would be a toy rather than a statement of where you stand.

   .is-edge turns it side-on: asked, not answered. */
.mamo-obverse {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 46px 16px 56px;
  text-align: center;
}

.mamo-coin-scene {
  width: 190px;
  height: 190px;
  perspective: 900px;
}

.mamo-coin {
  width: 100%;
  height: 100%;
  transition: transform 900ms cubic-bezier(.3, .8, .25, 1);
}

/* Side-on. Not 90deg exactly — a true right angle renders as a hairline and reads
   as a rendering fault; 78deg still says "edge" and keeps the coin a coin. */
.mamo-obverse.is-edge .mamo-coin { transform: rotateY(78deg); }

.mamo-coin-face { width: 100%; height: 100%; display: block; }

/* Struck metal. These are literals rather than theme tokens on purpose: a coin is
   the same colour in a dark room, and the panel around it carries the theme. */
.mamo-coin-face { filter: drop-shadow(0 6px 14px rgb(0 0 0 / 0.16)); }
.mamo-coin-rim     { stroke: #7A5B24; stroke-width: 1.5; opacity: 0.55; }
.mamo-coin-rim-dot { stroke: #7A5B24; stroke-width: 0.8; opacity: 0.38; stroke-dasharray: 2 4; }
.mamo-coin-relief  { fill: #7A5B24; opacity: 0.3; }

.mamo-coin-legend {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  fill: #7A5B24;
}

.mamo-obverse-state {
  margin: 4px 0 0;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
}

.mamo-obverse-copy {
  margin: 0;
  max-width: 32ch;
  font-size: 15px;
  color: var(--bs-body-color);
}

/* The coin's ground, painted on the element that ROTATES — not on .mamo-coin-scene,
   which holds the perspective and must stay still. Put it on the scene and the gold
   disc stays a full circle while only the engraving turns, which reads as a rendering
   fault rather than as a coin on its edge. */
.mamo-coin {
  border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, #E8D08C 0%, #B08842 46%, #7A5B24 100%);
}

@media (prefers-reduced-motion: reduce) {
  .mamo-coin { transition: none; }
}
