/* ---------------------------------------------------------------------------
   Peltify — the social surfaces: avatars, the public profile builder, the
   public profile as others see it, and Friends.

   SQUARED UP 2026-08-28 (Nick: "a lot of the UI is rounded boxes / pills …
   make everything feel cooler by making it more boxy"). Radii come from three
   tokens only: --r-box for every card, tag, badge and button, --r-art for
   cover art, --r-pill for the two things that stay round on purpose — the
   avatar and the friends search field.

   Owned by profile.js, friends.js and avatar.js. Nothing else writes here.
   Every colour is a token from tokens.css; every motion class comes from
   motion.css. Wide things scroll inside themselves, never the page.
   --------------------------------------------------------------------------- */

/* ================================================================ avatars == */

.av {
  display: inline-grid;
  place-items: center;
  flex: none;
  border-radius: 50%;
  overflow: hidden;
  background: var(--paper-deep);
  color: var(--white);
  font-weight: 800;
  letter-spacing: -0.02em;
  box-shadow: var(--lift), inset 0 0 0 1px var(--line-soft);
  user-select: none;
}
.av img,
.av-svg svg { display: block; width: 100%; height: 100%; object-fit: cover; }
.av-svg { display: block; width: 100%; height: 100%; line-height: 0; }
.av-initials { background: var(--spine); }
.av-xl { box-shadow: var(--raise-hi), inset 0 0 0 1px var(--line-soft); }

/* ====================================================== the profile builder = */

.pf { display: block; max-width: 980px; margin: 0 auto; }
.pf h1 { margin: 0 0 4px; font-size: clamp(26px, 3.4vw, 38px); letter-spacing: -0.03em; }

.pf-top {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 22px;
}
.pf-top-tools { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.pf-saved {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--r-box);
  border: 1px solid var(--line);
  background: var(--paper-deep);
  color: var(--ink-soft);
  font-size: 12.5px;
  font-weight: 700;
}
.pf-saved.ok { background: var(--ok-wash); color: var(--ok); }
.pf-saved.warn { background: var(--warn-wash); color: var(--warn); font-weight: 600; }

.pf-signin {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin-top: 20px;
  padding: 22px;
  border-radius: var(--r-box);
  background: var(--white);
  border: 1px solid var(--line-soft);
}
.pf-signin b { display: block; font-size: 17px; }
.pf-signin span { display: block; margin-top: 4px; color: var(--ink-soft); }

/* ---- the header card ---- */

.pf-header {
  display: flex;
  flex-wrap: wrap;
  gap: 26px;
  padding: 26px;
  margin-bottom: 26px;
  border-radius: var(--r-box);
  background: var(--white);
  border: 1px solid var(--line);
}
.pf-avatar { display: grid; justify-items: center; gap: 12px; }
.pf-avatar-btn { padding: 6px 16px; font-size: 13px; }
.pf-header-copy { flex: 1 1 320px; min-width: 0; display: grid; gap: 10px; align-content: start; }

.pf-name-input {
  width: 100%;
  padding: 6px 0;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--ink);
  font: 800 clamp(22px, 3vw, 30px) / 1.15 var(--font-sans);
  letter-spacing: -0.03em;
  transition: border-color var(--fast) var(--ease);
}
.pf-name-input:focus { outline: none; border-bottom-color: var(--violet); }

.pf-handle {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--ink-soft);
  font-weight: 700;
}
.pf-handle-set { display: grid; gap: 8px; }

.pf-bio {
  width: 100%;
  padding: 12px 14px;
  border-radius: var(--r-box);
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font: 400 15px/1.55 var(--font-sans);
  resize: vertical;
}
.pf-bio:focus { outline: 2px solid var(--violet); outline-offset: 1px; }

/* ---- one section card ---- */

.pf-sections { display: grid; gap: 18px; }

.pf-sec {
  border-radius: var(--r-box);
  background: var(--white);
  border: 1px solid var(--line);
  overflow: hidden;
  transition: opacity var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.pf-sec.is-hidden { opacity: 0.55; }
.pf-sec.is-dragging { box-shadow: var(--raise-hi); }

.pf-sec-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.pf-grip { display: inline-flex; color: var(--ink-faint); cursor: grab; }
.pf-sec-title {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: 800 16px var(--font-sans);
  letter-spacing: -0.01em;
  padding: 4px 0;
}
.pf-sec-title:focus { outline: none; border-bottom: 2px solid var(--violet); }
.pf-sec-tools { display: flex; align-items: center; gap: 2px; }
.pf-sec-tools .btn-clear { padding: 5px 7px; border-radius: var(--r-sm); color: var(--ink-faint); }
.pf-sec-tools .btn-clear:hover:not(:disabled) { background: var(--violet-wash); color: var(--violet); }
.pf-sec-tools .btn-clear:disabled { opacity: 0.3; }
.pf-sec-tools .btn-clear.is-on { color: var(--violet); }

.pf-sec-note {
  margin: 0;
  padding: 9px 16px;
  background: var(--warn-wash);
  color: var(--warn);
  font-size: 12.5px;
  font-weight: 600;
}
.pf-sec-body { padding: 16px; display: grid; gap: 14px; }

.pf-textarea {
  width: 100%;
  padding: 12px 14px;
  border-radius: var(--r-box);
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font: 400 15px/1.55 var(--font-sans);
  resize: vertical;
}

/* ---- the item grid inside a section ---- */

.pf-items {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 12px;
}
.pf-item {
  position: relative;
  border-radius: var(--r-box);
  border: 1px solid var(--line-soft);
  background: var(--paper);
  overflow: hidden;
}
.pf-item-open {
  display: grid;
  gap: 4px;
  width: 100%;
  padding: 8px;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.pf-item-art {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border-radius: var(--r-art);
  overflow: hidden;
  background: var(--paper-deep);
  color: var(--ink-faint);
}
.pf-item-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pf-item-genre {
  display: block;
  padding: 12px 10px;
  border-radius: var(--r-box);
  background: var(--violet-wash);
  color: var(--spine);
  font-weight: 800;
  font-size: 13.5px;
  text-align: center;
}
.pf-item-name {
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.25;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.pf-item-by { font-size: 11.5px; color: var(--ink-faint); }
.pf-item-x {
  position: absolute;
  top: 5px;
  right: 5px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: var(--r-box);
  background: rgba(36, 20, 46, 0.78);
  color: var(--white);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--fast) var(--ease);
}
.pf-item:hover .pf-item-x,
.pf-item-x:focus-visible { opacity: 1; }

.pf-sec-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.pf-add { margin-top: 22px; }
.pf-add-row { display: flex; flex-wrap: wrap; gap: 10px; }

.pf-preview { margin-top: 10px; }

/* ---- popups ---- */

.pf-pop { padding: 0; }
.pf-pop-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 24px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.pf-pop-head h3 { margin: 0; font-size: 20px; letter-spacing: -0.02em; }
.pf-pop-head p { margin: 6px 0 0; color: var(--ink-soft); font-size: 13.5px; max-width: 56ch; }
.pf-pop-body { padding: 20px 24px 24px; display: grid; gap: 16px; }
.pf-pop-actions { display: flex; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.pf-tabs { align-self: start; }

.pf-drop {
  display: grid;
  justify-items: center;
  gap: 10px;
  padding: 34px 24px;
  border-radius: var(--r-box);
  border: 1px dashed var(--line-strong);
  background: var(--paper);
  text-align: center;
  color: var(--ink-soft);
  transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.pf-drop.is-over { border-color: var(--violet); background: var(--violet-wash); }
.pf-drop b { color: var(--ink); font-size: 16px; }
.pf-drop span { max-width: 44ch; font-size: 13.5px; }

.pf-upload { display: grid; gap: 12px; justify-items: center; }
.pf-crop-wrap { position: relative; width: 300px; height: 300px; }
.pf-crop {
  display: block;
  width: 300px;
  height: 300px;
  border-radius: var(--r-md);
  background: var(--paper-deep);
  touch-action: none;
  cursor: grab;
}
.pf-crop-ring {
  position: absolute;
  inset: 0;
  border-radius: var(--r-md);
  pointer-events: none;
  box-shadow: inset 0 0 0 999px rgba(36, 20, 46, 0.42);
  -webkit-mask: radial-gradient(circle at 50% 50%, transparent 0 148px, #000 149px);
  mask: radial-gradient(circle at 50% 50%, transparent 0 148px, #000 149px);
}
.pf-crop-controls { display: flex; align-items: center; gap: 10px; color: var(--ink-faint); }
.pf-zoom { width: 220px; accent-color: var(--violet); }

.pf-stock { display: grid; gap: 14px; }
.pf-stock-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 12px; }
.pf-stock-cell {
  display: grid;
  place-items: center;
  padding: 6px;
  border: 2px solid transparent;
  border-radius: var(--r-box);
  background: transparent;
  cursor: pointer;
  transition: border-color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.pf-stock-cell:hover { transform: translateY(-2px); }
.pf-stock-cell.is-picked { border-color: var(--violet); background: var(--violet-wash); }

.pf-results {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 14px;
  max-height: 46vh;
  overflow-y: auto;
  padding: 2px;
}
.pf-res {
  position: relative;
  display: grid;
  gap: 4px;
  align-content: start;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-box);
  background: var(--white);
}
.pf-res.is-added { opacity: 0.6; }
.pf-res-art {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border-radius: var(--r-art);
  overflow: hidden;
  background: var(--paper-deep);
  color: var(--ink-faint);
}
.pf-res-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pf-res-name { font-size: 13px; font-weight: 800; line-height: 1.25; }
.pf-res-by { font-size: 12px; color: var(--ink-soft); }
.pf-res-kind { font-size: 11px; color: var(--ink-faint); text-transform: lowercase; }
.pf-plus {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--r-box);
  background: var(--violet);
  color: var(--white);
  cursor: pointer;
  transition: background var(--fast) var(--ease);
}
.pf-plus:hover:not(:disabled) { background: var(--spine); }
.pf-plus:disabled { background: var(--ok); cursor: default; }

/* ============================================== the public profile view ====
   EXPANSIVE, NOT BOXY (2026-08-27). Nick, on the first version: "Lets go more
   expansive" instead of a "pill box boxy feel". So: no card around the header,
   no chip around the public id, no "1 item(s)" counter beside a title. The page
   is a wide airy header and then full-width sections divided by hairlines —
   the shape a profile has when it trusts its own content.
   ------------------------------------------------------------------------- */

.pp { display: block; max-width: 1080px; margin: 0 auto; }

.pp-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 28px 32px;
  padding: 8px 0 34px;
}
.pp-ident { display: flex; align-items: center; gap: 24px; min-width: 0; flex: 1 1 320px; }
.pp-who { min-width: 0; }
.pp-name {
  margin: 0;
  font-size: clamp(28px, 4vw, 42px);
  line-height: 1.08;
  letter-spacing: -0.035em;
}
/* One line, grey: the editable username and the tail that never changes. */
.pp-tag {
  margin: 8px 0 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pp-tag-id { color: var(--ink-faint); font-weight: 500; }
.pp-bio { margin: 12px 0 0; max-width: 60ch; line-height: 1.55; color: var(--ink-soft); }
.pp-note { flex: 1 1 100%; margin: 0; font-size: 12.5px; color: var(--ink-faint); max-width: 70ch; }

/* ONE PRIMARY ACTION, and it sits alone. */
.pp-act { flex: 0 0 auto; }
.pp-act .btn-primary { padding: 12px 26px; font-size: 15px; }
.pp-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.pp-state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-faint);
}
.pp-state.is-ok { color: var(--ok); }

.pp-empty { margin: 0; padding: 34px 0; border-top: 1px solid var(--line-soft); color: var(--ink-soft); max-width: 62ch; }

.pp-sections { display: block; }
.pp-sec { padding: 34px 0; border-top: 1px solid var(--line-soft); }
.pp-sec-title {
  margin: 0 0 20px;
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.pp-text { margin: 0; max-width: 68ch; line-height: 1.65; color: var(--ink-soft); }

/* Artwork first, name under it. The grid is the section. */
.pp-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 24px 20px;
}
.pp-tile {
  display: grid;
  gap: 10px;
  align-content: start;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.pp-tile-art {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border-radius: var(--r-art);
  overflow: hidden;
  background: var(--paper-deep);
  color: var(--ink-faint);
  box-shadow: var(--lift);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.pp-tile:hover .pp-tile-art { transform: translateY(-4px); box-shadow: var(--raise); }
.pp-tile:focus-visible { outline: none; }
.pp-tile:focus-visible .pp-tile-art { outline: 2px solid var(--violet); outline-offset: 3px; }
.pp-tile-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pp-tile-name { font-size: 14px; font-weight: 700; line-height: 1.3; }
.pp-tile-by { font-size: 12.5px; color: var(--ink-faint); line-height: 1.3; }

/* Large soft chips. The description underneath is the genre table's own
   sentence, and a genre the table has no sentence for simply has none. */
.pp-chips { display: flex; flex-wrap: wrap; gap: 12px; }
.pp-chip {
  position: relative;
  display: block;
  max-width: 100%;
  padding: 14px 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-box);
  background: var(--violet-wash);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}
.pp-chip:hover { background: var(--violet-wash-strong); transform: translateY(-2px); }
.pp-chip:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.pp-chip-name { display: block; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.pp-chip-hint {
  display: block;
  max-width: 40ch;
  margin-top: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-soft);
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 0.3s var(--ease), max-height 0.3s var(--ease), margin-top 0.3s var(--ease);
}
.pp-chip:hover .pp-chip-hint,
.pp-chip:focus-visible .pp-chip-hint { opacity: 1; max-height: 6em; margin-top: 6px; }

/* ==================================================================== friends
   DISCORD'S SHAPE (2026-08-27). Nick: "Notice discord's conventions with left
   sidebar, online, all, pending, add friend."

   An inner left column, a tab row, one search field, section headers that
   carry their own count, and rows that are an avatar, a name, a grey handle
   and round action buttons on the right.

   THERE IS NO ONLINE COLUMN AND NO GREEN DOT, because Peltify has no presence
   system to draw one from. Everything else here is a real relationship the
   server returned.
   ------------------------------------------------------------------------- */

.fr { display: block; max-width: 1180px; margin: 0 auto; }
.fr h1 { margin: 0 0 6px; font-size: clamp(28px, 3.6vw, 40px); letter-spacing: -0.035em; }
.fr-back { margin-bottom: 22px; }
.fr-notice:empty { display: none; }

/* A refusal, in the words the server used. Never a colour on its own — the
   sentence is the message; the tint only makes it findable. */
.fr-warn {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 16px 0 0;
  padding: 12px 16px;
  border-radius: var(--r-box);
  border: 1px solid var(--warn);
  background: var(--warn-wash);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
}

/* ---- the two-column shell ---- */

.fr-shell {
  display: grid;
  grid-template-columns: 194px minmax(0, 1fr);
  gap: 34px;
  align-items: start;
}
.fr-main { min-width: 0; }

.fr-side {
  position: sticky;
  top: 8px;
  display: grid;
  gap: 2px;
  padding-right: 22px;
  border-right: 1px solid var(--line-soft);
}
.fr-nav {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--r-box);
  background: transparent;
  color: var(--ink-soft);
  font: 700 14.5px var(--font-sans);
  letter-spacing: -0.01em;
  text-align: left;
  cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.fr-nav:hover { background: var(--paper-deep); color: var(--ink); }
.fr-nav[aria-current] {
  background: var(--violet-wash);
  box-shadow: inset 3px 0 0 var(--violet);
  color: var(--spine);
}
.fr-nav-l { flex: 1 1 auto; min-width: 0; }

/* The waiting count. Absent — not zero — when nobody is waiting. */
.fr-badge {
  flex: none;
  min-width: 20px;
  padding: 2px 7px;
  border-radius: var(--r-box);
  background: var(--violet);
  color: var(--white);
  font: 800 11px var(--font-sans);
  text-align: center;
}

/* ---- the tab row ---- */

.fr-tabs {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line-soft);
}
.fr-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid transparent;
  border-radius: var(--r-box);
  background: transparent;
  color: var(--ink-soft);
  font: 700 14px var(--font-sans);
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.fr-tab:hover { background: var(--paper-deep); color: var(--ink); }
.fr-tab[aria-current] { background: var(--paper-deep); border-color: var(--line); color: var(--ink); }
.fr-tab-n {
  min-width: 18px;
  padding: 1px 6px;
  border-radius: var(--r-box);
  background: var(--violet);
  color: var(--white);
  font: 800 10.5px var(--font-sans);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* ONE FILLED BUTTON on the row, and it is the thing you came to do. */
.fr-tab.is-cta {
  margin-left: auto;
  background: var(--violet);
  border-color: var(--violet);
  color: var(--white);
  font-weight: 800;
}
.fr-tab.is-cta:hover { background: var(--spine); border-color: var(--spine); color: var(--white); }
.fr-tab.is-cta[aria-current] {
  background: var(--spine);
  border-color: var(--spine);
  color: var(--white);
}

/* ---- the search field ---- */

.fr-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
  padding: 11px 18px;
  border-radius: var(--r-box);
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--ink-faint);
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.fr-toolbar:focus-within { border-color: var(--violet); box-shadow: 0 0 0 4px var(--violet-wash); }
.fr-search {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: 400 15px var(--font-sans);
}
.fr-search:focus { outline: none; }
/* The spinner keeps its space so the bar does not twitch on every keystroke. */
.fr-spin { visibility: hidden; }
.fr-spin.is-on { visibility: visible; }

/* ---- a headed section of rows ---- */

.fr-body:empty { display: none; }
.fr-sec { margin-top: 26px; }
.fr-sec-h {
  margin: 0 0 4px;
  padding: 0 12px 10px;
  border-bottom: 1px solid var(--line-soft);
  font: 800 11.5px var(--font-sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

.fr-rows { display: block; }
.fr-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 11px 12px;
  border-radius: var(--r-box);
  transition: background var(--fast) var(--ease);
}
/* Hairlines BETWEEN rows, drawn by the row below and hidden the moment either
   neighbour is hovered — so the hover slab never has a line cutting it. */
.fr-row + .fr-row::before {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  top: -1px;
  height: 1px;
  background: var(--line-soft);
  transition: opacity var(--fast) var(--ease);
}
.fr-row:hover { background: var(--paper); }
.fr-row:hover::before,
.fr-row:hover + .fr-row::before { opacity: 0; }

.fr-open {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font: inherit;
  text-align: left;
}
.fr-open:focus-visible { outline: 2px solid var(--violet); outline-offset: 4px; border-radius: var(--r-box); }
.fr-who { display: grid; gap: 1px; min-width: 0; }
.fr-name {
  font-size: 15px;
  font-weight: 750;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fr-tag {
  font-size: 13px;
  color: var(--ink-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fr-tag-id { color: var(--ink-faint); opacity: 0.8; }

/* ---- the actions on the right ---- */

.fr-act { flex: 0 0 auto; display: flex; gap: 6px; align-items: center; }
.fr-ib {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--line);
  border-radius: var(--r-box);
  background: var(--white);
  color: var(--ink-soft);
  cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease),
              border-color var(--fast) var(--ease);
}
.fr-ib:hover:not([disabled]) { background: var(--paper-deep); border-color: var(--line-strong); color: var(--ink); }
.fr-ib.is-ok:hover:not([disabled]) { color: var(--ok); }
.fr-ib.is-danger:hover:not([disabled]) { color: var(--stop); }
.fr-ib.is-go:hover:not([disabled]) { color: var(--violet); }
.fr-ib[disabled] { opacity: 0.35; cursor: default; }
.fr-ib:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }

.fr-state { font-size: 13px; font-weight: 600; color: var(--ink-faint); }
.fr-gate-btn { padding: 7px 14px; font-size: 13px; }

.fr-empty { margin: 22px 12px 0; color: var(--ink-soft); font-size: 14px; max-width: 62ch; line-height: 1.55; }
.fr-gate { display: grid; justify-items: start; gap: 16px; padding-top: 4px; }
.fr-gate .fr-empty { margin: 18px 0 0; }

@media (max-width: 640px) {
  .pf-header { padding: 18px; gap: 18px; }
  .pf-crop-wrap, .pf-crop { width: 260px; height: 260px; }
  .pf-crop-ring {
    -webkit-mask: radial-gradient(circle at 50% 50%, transparent 0 128px, #000 129px);
    mask: radial-gradient(circle at 50% 50%, transparent 0 128px, #000 129px);
  }
  .pp-head { gap: 20px; padding-bottom: 26px; }
  .pp-ident { gap: 16px; }
  .pp-act { flex: 1 1 100%; }
  .pp-act .btn-primary { width: 100%; }
  .pp-tiles { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 18px 14px; }
  /* No hover on a touch screen, so the description is simply always there. */
  .pp-chip-hint { opacity: 1; max-height: 6em; margin-top: 6px; }
  .fr-row { flex-wrap: wrap; }
  .fr-act { flex: 1 1 100%; }
}

/* THE LEFT COLUMN IS THE FIRST THING TO GO on a narrow screen: the tab row
   already reaches every section it points at, so keeping both would be two
   copies of one control competing for the width. */
@media (max-width: 900px) {
  .fr-shell { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .fr-side { display: none; }
}

/* ---- buttons ----

   Same restatement as settings.css: `.btn` in app.css is still a pill, and
   app.css belongs to another lane, so these three surfaces square their own
   buttons and drop the hover lift. */

.pf .btn, .pf .btn-primary, .pf .btn-ghost, .pf .btn-quiet,
.pp .btn, .pp .btn-primary, .pp .btn-ghost, .pp .btn-quiet,
.fr .btn, .fr .btn-primary, .fr .btn-ghost, .fr .btn-quiet,
.pf-pop .btn, .pf-pop .btn-primary, .pf-pop .btn-ghost, .pf-pop .btn-quiet {
  border-radius: var(--r-box);
}
.pf .btn:hover:not(:disabled), .pf .btn-primary:hover:not(:disabled), .pf .btn-ghost:hover:not(:disabled),
.pp .btn:hover:not(:disabled), .pp .btn-primary:hover:not(:disabled), .pp .btn-ghost:hover:not(:disabled),
.fr .btn:hover:not(:disabled), .fr .btn-primary:hover:not(:disabled), .fr .btn-ghost:hover:not(:disabled) {
  transform: none;
  box-shadow: none;
}


/* ---------------------------------------------------------------------------
   THE TWO TASTE SECTIONS ON A PUBLIC PROFILE (2026-08-30, public-profile
   entries 1–2). The Dashboard's genre field and word map, drawn from what the
   owner's page carries. The Music | Film & books switch is a HIGHLIGHTER here:
   the other side greys, it never leaves the field.
   --------------------------------------------------------------------------- */
.pp-taste { display: grid; gap: 10px; }
.pp-seg { justify-self: start; }
.pp-taste .gr-block[data-dim="1"] { filter: grayscale(0.9); opacity: 0.42;
                                    transition: filter 220ms var(--ease), opacity 220ms var(--ease); }
.pp-taste .gr-block:disabled { cursor: default; }
@media (prefers-reduced-motion: reduce) {
  .pp-taste .gr-block[data-dim="1"] { transition: none; }
}

/* ===================================================== direct messages ==== */
/* [PELT-1..2], 2026-09-01. Owned by messages.js. Instagram's shape: threads,
   one conversation, a composer pinned at the bottom. Same tokens, same boxy
   language as the rest of Friends. */

.dm { display: block; min-height: 320px; }

.dm-threads { display: flex; flex-direction: column; gap: 6px; }
.dm-thread {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 10px 12px; text-align: left;
  border: 1px solid var(--line); border-radius: var(--r-box);
  background: var(--white); cursor: pointer;
  transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.dm-thread:hover { border-color: var(--line-strong); background: var(--paper); }
.dm-thread.is-unread { border-color: var(--violet); }
.dm-thread-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.dm-thread-name { font-size: 14px; letter-spacing: -0.01em; }
.dm-thread-last {
  font-size: 12.5px; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.dm-thread.is-unread .dm-thread-last { color: var(--ink); font-weight: 600; }
.dm-thread-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.dm-thread-when { font-size: 11px; color: var(--ink-faint); }
.dm-thread-n {
  min-width: 18px; height: 18px; padding: 0 5px; display: grid; place-items: center;
  border-radius: var(--r-pill); background: var(--violet); color: var(--white);
  font-size: 11px;
}

/* -- one conversation -- */
.dm-convo { display: flex; flex-direction: column; min-height: 380px; max-height: 72vh; }
.dm-convo-head {
  display: flex; align-items: center; gap: 12px; padding-bottom: 10px;
  border-bottom: 1px solid var(--line-soft); margin-bottom: 10px;
}
.dm-convo-who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.dm-convo-who b { font-size: 14px; }
.dm-convo-tag { font-size: 12px; color: var(--ink-faint); }
.dm-back { flex: none; }

/* NO VISIBLE SCROLLBAR on either column (Nick, 2026-09-07: "remove the
   obvious scroll bar on the very right … more seamless") — the boxes still
   scroll, the bar is simply not drawn. */
.dm-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 2px 2px 10px;
  scrollbar-width: none; -ms-overflow-style: none; }
.dm-scroll::-webkit-scrollbar, .dm-list::-webkit-scrollbar { display: none; width: 0; height: 0; }
.dm-msgs { display: flex; flex-direction: column; gap: 10px; }
.dm-msg { display: flex; flex-direction: column; max-width: min(78%, 460px); }
.dm-msg.is-me { align-self: flex-end; align-items: flex-end; }
.dm-msg.is-them { align-self: flex-start; align-items: flex-start; }
.dm-bubble {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--white); padding: 8px 12px; box-shadow: var(--shadow-sm);
}
.dm-msg.is-me .dm-bubble { background: var(--violet-wash); border-color: var(--violet-wash-strong); }
.dm-text { margin: 0; font-size: 13.5px; line-height: 1.45; white-space: pre-wrap; word-break: break-word; }
.dm-when { font-size: 10.5px; color: var(--ink-faint); margin-top: 3px; }

.dm-composer {
  display: flex; gap: 8px; align-items: flex-end;
  border-top: 1px solid var(--line-soft); padding-top: 10px;
  /* 19.3 — the @ picker and the emoji row are absolutely positioned against
     this row, so it is the containing block for both. */
  position: relative;
}
/* 19.3 — the @ picker's anchor: a zero-size box the panel hangs off, so the
   picker measures the composer's own rect when it decides which way to open. */
.dm-anchor { position: absolute; inset: 0; pointer-events: none; }
.dm-anchor .ch-mention { pointer-events: auto; }
/* 19.3 — the composer's emoji row: the same four the reaction row offers,
   over the composer rather than in it. */
.dm-emoji-compose { position: absolute; left: 0; bottom: calc(100% + 8px); z-index: 6; }
.dm-emoji-open { flex: none; height: 38px; min-width: 38px; font-size: 17px; line-height: 1; }
.dm-input {
  flex: 1; resize: none; min-height: 38px; max-height: 120px;
  border: 1px solid var(--line); border-radius: var(--r-box);
  background: var(--white); color: var(--ink);
  font: 13.5px/1.45 var(--font-sans); padding: 9px 12px;
}
.dm-input:focus-visible { outline: 2px solid var(--violet); outline-offset: 1px; }
.dm-send { flex: none; height: 38px; }

/* -- a pelted card inside a bubble -- */
.dm-card {
  border: 1px solid var(--line); border-radius: var(--r-box);
  background: var(--white); padding: 10px; margin-bottom: 6px; min-width: 240px;
}
.dm-card-hd { display: flex; gap: 10px; align-items: center; }
.dm-card-art {
  width: 56px; height: 56px; border-radius: var(--r-art);
  object-fit: cover; flex: none; background: var(--paper-deep);
}
.dm-card-art.is-blank { display: grid; place-items: center; color: var(--ink-faint); }
.dm-card-t { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.dm-card-name { font-size: 14px; letter-spacing: -0.01em; }
.dm-card-by { font-size: 12px; color: var(--ink-soft); }
.dm-card-yr { font-size: 11px; color: var(--ink-faint); }
.dm-card-desc { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-soft); line-height: 1.45; }
.dm-card-why { margin-top: 8px; border-top: 1px solid var(--line-soft); padding-top: 8px; }
.dm-card-why b { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--spine); }
.dm-card-why p { margin: 3px 0 0; font-size: 12.5px; line-height: 1.45; }

/* -- the three-column comparison ([PELT-2], QSplNl2QLj bar rows) -- */
.dm-cmp { margin-top: 10px; border-top: 1px solid var(--line-soft); padding-top: 8px; }
.dm-cmp-head, .dm-cmp-row {
  display: grid; grid-template-columns: minmax(84px, 1.2fr) 0.8fr 1fr 1fr;
  gap: 8px; align-items: center;
}
.dm-cmp-head { margin-bottom: 4px; }
.dm-cmp-head .dm-cmp-h:first-child { grid-column: 2; }
.dm-cmp-h { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-faint); }
.dm-cmp-row { padding: 3px 0; }
.dm-cmp-g { font-size: 12.5px; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.dm-cmp-state { font-style: normal; font-size: 10.5px; color: var(--ink-faint); }
.dm-cmp-cell { display: flex; align-items: center; gap: 6px; min-width: 0; }
.dm-cmp-cell.is-work { font-size: 11px; color: var(--ink-soft); }
.dm-cmp-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--violet); flex: none; }
.dm-cmp-track {
  flex: 1; height: 7px; border-radius: var(--r-pill);
  background: var(--paper-deep); overflow: hidden; min-width: 24px;
}
.dm-cmp-fill { display: block; height: 100%; border-radius: var(--r-pill); background: var(--violet); }
.dm-cmp-has b { font-size: 11.5px; }
.dm-cmp-new, .dm-cmp-unknown { font-size: 11px; color: var(--ink-faint); }
.dm-cmp-none, .dm-cmp-note { margin: 8px 0 0; font-size: 12px; color: var(--ink-faint); }

@media (max-width: 560px) {
  .dm-cmp-head, .dm-cmp-row { grid-template-columns: minmax(72px, 1fr) 0.7fr 1fr 1fr; gap: 5px; }
  .dm-msg { max-width: 92%; }
}

/* ======================================================== the Pelt popup == */
/* [PELT-2..3]. Rides the app's own sheet scrim. */

.pelt-sheet { max-width: 480px; width: min(480px, calc(100vw - 32px)); }
.pelt-body { display: flex; flex-direction: column; gap: 8px; max-height: 64vh; overflow-y: auto; }
.pelt-h {
  margin: 10px 0 2px; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink-faint);
}
.pelt-friend {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line); border-radius: var(--r-box);
  background: var(--white); padding: 8px 10px;
}
.pelt-friend-t { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.pelt-friend-t b { font-size: 13.5px; }
.pelt-friend-tag { font-size: 11.5px; color: var(--ink-faint); }
.pelt-state { font-size: 11.5px; color: var(--ink-faint); text-align: right; }
.pelt-state.is-ok { color: var(--ok); font-weight: 600; }
.pelt-state.is-warn { color: var(--warn); }
.pelt-send { flex: none; }
.pelt-linkpane { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.pelt-linkrow { display: flex; gap: 8px; width: 100%; }
.pelt-url {
  flex: 1; border: 1px solid var(--line); border-radius: var(--r-box);
  background: var(--paper); color: var(--ink); font: 12px var(--font-mono);
  padding: 8px 10px; min-width: 0;
}
.pelt-qr {
  border: 1px solid var(--line); border-radius: var(--r-box);
  background: #fff; align-self: center;
  image-rendering: pixelated; width: 172px; height: 172px;
}
.pelt-note { margin: 0; font-size: 12px; color: var(--ink-faint); }

/* Settings › Shared cards */
.stg-cardact { display: flex; gap: 6px; align-items: center; flex: none; }

/* ---- [PELT-8] one submenu: Messages · Friends · Profile; inner tabs inside Friends ---- */
.fr-nav svg { flex: none; color: currentColor; opacity: .85; }
.fr-tabs[hidden] { display: none; }
.fr-ib.is-go { color: var(--violet); }
.fr-ib.is-go:hover { background: var(--violet-wash); }

/* ---- [PELT-14] the received pelt card: real columns, a quote, a small sender line ---- */
.dm-card-why { margin: 10px 0 0; padding: 8px 12px; border-left: 3px solid var(--violet); border-top: 0;
               background: var(--violet-wash); border-radius: 0 var(--r-box) var(--r-box) 0; }
.dm-card-why b { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--spine); }
.dm-card-why p { margin: 4px 0 0; font-size: 13px; line-height: 1.5; font-style: italic; }
.dm-card-inf { display: block; margin-top: 6px; font-size: 10.5px; color: var(--ink-faint); font-style: normal; }
.dm-cmp-head, .dm-cmp-row { grid-template-columns: minmax(96px, 1.3fr) repeat(3, minmax(0, 1fr)); }
.dm-cmp-head .dm-cmp-h { text-align: left; }
.dm-cmp-row { border-top: 1px solid var(--line-soft); padding: 5px 0; }
.dm-cmp-row:first-of-type { border-top: 0; }

/* ---------------------------------------------------------------------------
   2026-09-06 — Messages as two panes on a desktop (src/ui/messages.js).
   The list on the left is a column of rows inside one card; the open
   conversation on the right is the same card's other half. A phone keeps
   the one-pane flow above.
   --------------------------------------------------------------------------- */
.dm-split {
  display: grid; grid-template-columns: minmax(260px, 340px) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  min-height: min(72vh, 720px);
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  background: var(--white); box-shadow: var(--shadow-sm);
}
.dm-list { min-width: 0; min-height: 0; border-right: 1px solid var(--line); overflow-y: auto; padding: 8px;
  scrollbar-width: none; -ms-overflow-style: none; }
.dm-split .dm-threads { gap: 2px; }
.dm-split .dm-thread { border: 0; border-radius: 8px; background: transparent; padding: 10px 10px; }
.dm-split .dm-thread:hover { background: var(--paper); }
.dm-split .dm-thread.is-open { background: var(--violet-wash); }
.dm-split .dm-thread.is-unread { box-shadow: inset 3px 0 0 var(--violet); }
.dm-open { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.dm-split .dm-convo { flex: 1 1 auto; min-height: 0; max-height: none; padding: 14px 16px; }
.dm-split .dm-back { display: none; }
.dm-split .dm-convo-head { padding: 0 0 12px; }
.dm-split .fr-empty, .dm-split .live-empty { padding: 24px 16px; }
.dm-none {
  flex: 1 1 auto; display: grid; place-content: center; justify-items: center; gap: 8px;
  padding: 40px 24px; text-align: center; color: var(--ink-soft);
}
.dm-none-ic { display: grid; place-items: center; width: 72px; height: 72px; border-radius: 50%;
              border: 2px solid var(--ink); color: var(--ink); margin-bottom: 6px; }
.dm-none b { font-size: 20px; font-weight: 800; color: var(--ink); }
.dm-none p { margin: 0; max-width: 34ch; font-size: 13.5px; line-height: 1.5; }
.dm-none .ig-btn { margin-top: 8px; }
@media (max-width: 900px) { .dm-split { grid-template-columns: minmax(0, 1fr); } .dm-open { display: none; } }

/* ---------------------------------------------------------------------------
   2026-09-07 — the Messages page fills the viewport height, never taller
   (messages RAW.md entries 3–4: "it goes too vertical for big chats …
   always starts from the top"; the answer: "Fill the viewport height",
   a phone "Fill the screen"). The box is as tall as the window leaves it
   inside the app frame; the thread list and the conversation scroll INSIDE
   their panes, the composer stays at the bottom, and the page itself does
   not scroll. messages.js measures the frame and writes `--dm-h` on `.dm`;
   the fallbacks below are the frame as measured in ig.css / app.css /
   this file on 2026-09-07, for the frames before the first measurement:

     desktop (≥ 901px, no top bar on Messages — `.topbar.is-empty`):
       .surface padding-top clamp(20px, 3vw, 34px)  → up to 34px
       .fr-toolbar margin-top 18px + 11px×2 padding + 2px border + ~20px
         line                                      → ~64px
       breath above the window's edge              → 20px
       ⇒ 100dvh − 118px
     phone (≤ 900px):
       .topbar-phone 52px (sticky) + .surface padding-top 12px
       + the toolbar ~64px                          → 128px
       the fixed tab bar: 4px + 48px + 4px + safe-area → 56px + inset
       breath                                       → 8px
       ⇒ 100dvh − 192px − env(safe-area-inset-bottom)
   --------------------------------------------------------------------------- */
.fr[data-only="messages"] .dm {
  --dm-fallback: calc(100dvh - 118px);
}
.fr[data-only="messages"] .dm-split {
  height: var(--dm-h, var(--dm-fallback)); min-height: 320px; max-height: var(--dm-h, var(--dm-fallback));
}
/* the one-pane phone flow: the open conversation is the box */
.fr[data-only="messages"] .dm > .dm-convo {
  height: var(--dm-h, var(--dm-fallback)); min-height: 320px; max-height: var(--dm-h, var(--dm-fallback));
  box-sizing: border-box;
}
/* the page under the box stops where the box does — any padding below a
   box that already ends at the window's edge is exactly how far the page
   then scrolls (dashboard.css settled the same for the suggestions chat) */
.surface:has(> .surface-wide[data-view="messages"]) { padding-bottom: 0; }
@media (max-width: 900px) {
  .fr[data-only="messages"] .dm { --dm-fallback: calc(100dvh - 192px - env(safe-area-inset-bottom)); }
  /* A phone fills the screen with the open conversation (entry 4): the
     search bar above it steps aside while a conversation is open, and the
     Back button brings it back with the list. */
  .fr[data-only="messages"] .fr-main:has(> .fr-body > .dm > .dm-convo) .fr-toolbar { display: none; }
}

/* ===========================================================================
   2026-09-07 — MESSAGES AS A FULL PAGE (Nick, chrome_W8KHmikA78 against
   Instagram): "I dont like the rounded cartoonish feel … bold, elements are
   bold and not super rounded. I dont want it to be a hovering thing. Full
   page, bold elements." So: no floating card, no shadow, no 12px radius.
   The split is the page — a thread column with a bold "Messages" head and a
   hairline on its right, the conversation beside it with a 75px head, grey
   bubbles for them and solid violet for you, a flat composer at the bottom.
   =========================================================================== */
.fr[data-only="messages"] { max-width: none; }
.fr[data-only="messages"] .fr-shell { display: block; }
.fr[data-only="messages"] .fr-toolbar { display: none; }
.fr[data-only="messages"] .dm { --dm-fallback: calc(100dvh - 54px); }

.dm-split {
  grid-template-columns: minmax(300px, 400px) minmax(0, 1fr);
  border: 1px solid var(--line); border-radius: 0; box-shadow: none;
  background: var(--white);
}
.dm-list { padding: 0; border-right: 1px solid var(--line); }
.dm-list-h {
  display: flex; align-items: center; height: 75px; padding: 0 24px;
  border-bottom: 1px solid var(--line);
}
.dm-list-h b { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; }
.dm-split .dm-threads { gap: 0; padding: 8px 0; }
.dm-split .dm-thread { border-radius: 0; padding: 8px 24px; min-height: 72px; gap: 14px; }
.dm-split .dm-thread:hover { background: var(--paper); }
.dm-split .dm-thread.is-open { background: var(--paper-deep); box-shadow: none; }
.dm-split .dm-thread.is-unread { box-shadow: none; }
.dm-thread-name { font-size: 14px; font-weight: 400; }
.dm-thread.is-unread .dm-thread-name { font-weight: 700; }
.dm-thread-last { font-size: 12.5px; color: var(--ink-faint); }
.dm-thread-when { font-size: 12px; }
.dm-thread-n { width: 8px; min-width: 8px; height: 8px; padding: 0; font-size: 0; }
.dm-split .fr-empty, .dm-split .live-empty { padding: 24px; }

.dm-split .dm-convo { padding: 0; }
.dm-split .dm-convo-head {
  height: 75px; padding: 0 16px; margin: 0; align-items: center;
  border-bottom: 1px solid var(--line);
}
.dm-convo-who b { font-size: 16px; font-weight: 600; }
.dm-convo-tag { font-size: 12px; }

.dm-scroll { padding: 16px 16px 8px; }
.dm-msgs { gap: 8px; }
.dm-msg { max-width: min(70%, 520px); }
.dm-bubble { border: 0; border-radius: 18px; padding: 8px 14px; box-shadow: none; background: var(--paper-deep); }
.dm-msg.is-them .dm-bubble { background: #efefef; border-radius: 18px 18px 18px 6px; }
.dm-msg.is-me .dm-bubble { background: var(--violet); border: 0; border-radius: 18px 18px 6px 18px; }
.dm-msg.is-me .dm-text { color: #fff; }
/* 19.3 — a mention inside YOUR OWN bubble. `.ig-mention` is `--spine` (violet
   on paper), which on a violet bubble is violet on violet; the bubble's own
   white is the readable colour, and the underline on hover still marks it as
   the control it is. */
.dm-msg.is-me .dm-text .ig-mention { color: #fff; }
.dm-msg.is-me .dm-text .ig-mention:hover { background: rgba(255, 255, 255, 0.22); }
/* 22.3 (Open from 21: "purple mention in the purple bubble") — the word inside
   the mention carried its own purple, which out-ranked the white above. */
.dm-msg.is-me .dm-text .ig-mention .ig-mention-word { color: #fff; }
.dm-msg.is-me .dm-text .ig-handle { color: #fff; }
.dm-msg.is-me .dm-card { background: var(--white); color: var(--ink); }
/* 19.3 — A CARD THAT TRAVELS ALONE WEARS NO BUBBLE (`messages/SPEC.md` entry
   8). The card is already a bordered, rounded, pressable panel; the bubble
   around it was a second frame and the padding Nick pointed at. */
.dm-bubble.is-bare { padding: 0; background: none; border-radius: 0; }
.dm-msg.is-me .dm-bubble.is-bare, .dm-msg.is-them .dm-bubble.is-bare { background: none; border-radius: 0; }
.dm-text { font-size: 15px; line-height: 1.4; }
.dm-when { font-size: 11px; margin-top: 4px; }

.dm-composer { border-top: 0; padding: 12px 16px 16px; gap: 10px; }
.dm-input {
  min-height: 44px; padding: 12px 16px; border-radius: 8px;
  border: 1px solid var(--line-strong); font-size: 15px; background: var(--white);
}
.dm-send { height: 44px; min-width: 44px; border-radius: 8px; }

.dm-none-ic { width: 96px; height: 96px; border-width: 2px; }
.dm-none b { font-size: 20px; font-weight: 700; }
.dm-none p { font-size: 14px; color: var(--ink-faint); }
@media (max-width: 900px) {
  .dm-split { border-left: 0; border-right: 0; }
  .fr[data-only="messages"] .dm { --dm-fallback: calc(100dvh - 128px - env(safe-area-inset-bottom)); }
}

/* 2026-09-07, second correction — "I said FULL width. Its still contained in
   its own box." The Messages page has no surface padding at all: the thread
   column starts at the rail's edge, the conversation runs to the window's. */
.surface:has(> .surface-wide[data-view="messages"]) { padding: 0; }
.surface-wide[data-view="messages"] { width: 100%; }
.fr[data-only="messages"] .dm { --dm-fallback: 100dvh; }
.fr[data-only="messages"] .dm-split { border: 0; border-left: 1px solid var(--line); }
.dm-split { grid-template-columns: minmax(300px, 380px) minmax(0, 1fr); }
@media (max-width: 900px) {
  .fr[data-only="messages"] .dm-split { border-left: 0; }
}

/* A NEW INBOX GROWS FROM THE BOTTOM (Nick, 2026-09-07, chrome_nrPMkCY8Ci):
   the first message sits above the composer, the next stacks on top of it —
   Instagram's shape — instead of one bubble stranded at the top. */
.dm-scroll { display: flex; flex-direction: column; }
.dm-msgs { margin-top: auto; }
.dm-scroll > .fr-empty, .dm-scroll > .live-empty { margin-top: auto; }

/* AN UNREAD CONVERSATION IS OBVIOUS (Nick, 2026-09-07: "I dont see it
   highlighted unopened"): bold name, bold dark preview, a violet count disc. */
.dm-split .dm-thread.is-unread { background: var(--violet-wash); }
.dm-split .dm-thread.is-unread:hover { background: var(--violet-wash-strong); }
.dm-thread.is-unread .dm-thread-name, .dm-thread.is-unread .dm-thread-last { font-weight: 700; color: var(--ink); }
.dm-thread-n { width: auto; min-width: 20px; height: 20px; padding: 0 6px; font-size: 11.5px; font-weight: 700; border-radius: 10px; }

/* ===========================================================================
   THE PELT (HANDOFF-12 lane 12.7, pelt-card/SPEC.md). The card is the
   metadata popup plus the people block (.pc); the send sheet is .ps; the
   inbox strip .pl; the feed teaser .pt. Nothing here draws a chip — that is
   cards.js relatedChips, in its pair mode.
   =========================================================================== */
/* The block keeps its own ink whatever the popup's theme — inside the dark metadata popup "wants this too" was white on white (audit 2026-09-08). */
.plt { margin-top: 14px; padding: 14px; border-top: 1px solid var(--line); border-radius: var(--r-box); background: var(--white); color: var(--ink); display: flex; flex-direction: column; gap: 10px; position: relative; min-width: 0; max-width: 100%; }
/* The phone's scroll row must not size its column: a nowrap row inside the popup's grid pushed the body column to 846px on a 390px phone (audit 2026-09-08). */
.plt .sc-chips.is-pair, .plt .sc-pair { max-width: 100%; }
.plt-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 5px; }
.plt-head { margin: 0; font-weight: 700; font-size: 14.5px; }
.plt-who { border: 0; background: none; padding: 0; font: inherit; font-weight: 800; color: var(--spine); cursor: pointer; }
.plt-who:hover { text-decoration: underline; }
.plt-via { font-size: 12.5px; color: var(--ink-soft); }
.plt-via-b { border: 0; background: none; padding: 0; font: inherit; color: var(--ink-soft); cursor: pointer; text-decoration: underline dotted; }
.plt-chain { display: none; margin: 6px 0 0 14px; padding: 0; font-size: 12.5px; color: var(--ink-soft); }
.plt-chain.is-open { display: block; }
.plt-note { margin: 0; font-family: var(--font-serif); color: var(--ink); }
.plt-line { margin: 0; font-weight: 700; font-size: 14px; }
.plt-empty { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 12px; border-radius: var(--r-box); background: var(--paper); font-size: 13px; }
.plt-empty p { margin: 0; color: var(--ink-soft); }
.plt-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding-top: 4px; }
.plt-act { display: inline-flex; align-items: center; gap: 4px; padding: 7px 11px; border-radius: 999px; border: 1px solid var(--line); background: var(--white); font: inherit; font-size: 12.5px; font-weight: 600; color: var(--ink); cursor: pointer; }
.plt-act.is-on { background: var(--violet); border-color: var(--violet); color: #fff; }
.plt-act:disabled { opacity: .5; cursor: default; }
/* 15.9 — SIX CONTROLS, TWO ROWS OF THREE (pelt-card entries 9-10). Nick:
   "its cluttered for pelt receivers, it isnt 2 rows 3 columns for big
   screens." Row one is what you do with the pelt, row two the verdicts; the
   mark and the reactions span both columns beneath. Below 640 the grid falls
   back to the wrapping row `mobile.css` already sets. */
.plt-actions.plt-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px; align-items: stretch;
}
.plt-actions.plt-grid .plt-act { justify-content: center; width: 100%; }
.plt-actions.plt-grid .plt-mark,
.plt-actions.plt-grid .plt-react { grid-column: 1 / -1; }
.plt-mark {
  display: flex; align-items: baseline; gap: 5px; margin: 6px 0 0;
  font-size: 12.5px; line-height: 1.45; color: var(--ink-soft);
}
.plt-mark b { color: var(--ink); }
.plt-mark svg { flex: 0 0 auto; align-self: center; }
.plt-react { display: inline-flex; gap: 2px; margin-left: auto; }
.plt-actions.plt-grid .plt-react { margin-left: 0; justify-content: flex-start; }
.plt-emoji { border: 0; background: none; font-size: 16px; cursor: pointer; padding: 4px 6px; border-radius: 999px; display: inline-flex; align-items: center; gap: 3px; }
.plt-emoji.is-sent, .plt-emoji.is-on { background: var(--paper); box-shadow: inset 0 0 0 1px var(--violet); }
.plt-emoji-n { font-size: 11px; font-weight: 700; color: var(--ink-soft); }

/* 15.9 — the component as it lands on the feed: the same block, no controls,
   set off from the words above it the way the artwork is. */
.pc-pelt { padding: 0 16px 12px; }
.pc-pelt .plt { border-top: 1px solid var(--line-soft); padding-top: 10px; }
.plt-status, .plt-signin { margin: 0; font-size: 13px; color: var(--ink-soft); }
.plt-signin a { color: var(--spine); font-weight: 700; }
.plt-pop { position: relative; padding: 10px 32px 10px 12px; border-radius: var(--r-box); background: var(--paper); border: 1px solid var(--line); font-size: 12.5px; }
.plt-pop p { margin: 2px 0; }
.plt-pop-h { display: block; margin-bottom: 4px; }
.plt-pop-x { position: absolute; top: 6px; right: 6px; border: 0; background: none; cursor: pointer; }
.sc-tag.is-pair.is-hidden { opacity: .35; text-decoration: line-through; }

/* --- the send sheet (Q17): centred dialog; a bottom sheet on a phone --- */
.ps-sheet { width: min(560px, 100%); max-height: min(88vh, 760px); display: flex; flex-direction: column; padding: 22px 22px 0; }
.ps-body { display: flex; flex-direction: column; gap: 12px; overflow-y: auto; flex: 1 1 auto; min-height: 0; padding-bottom: 12px; }
.ps-h { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.ps-people-wrap { display: flex; flex-direction: column; gap: 8px; }
.ps-people { display: flex; gap: 10px; overflow-x: auto; padding: 2px 0 6px; scrollbar-width: none; }
.ps-people::-webkit-scrollbar { display: none; }
.ps-person { flex: none; display: flex; flex-direction: column; align-items: center; gap: 4px; width: 64px; border: 0; background: none; padding: 4px; border-radius: var(--r-box); font: inherit; cursor: pointer; }
.ps-person small { font-size: 11px; color: var(--ink-soft); max-width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ps-person.is-on { background: color-mix(in srgb, var(--violet) 12%, var(--white)); outline: 2px solid var(--violet); }
.ps-link-i { width: 44px; height: 44px; border-radius: 50%; border: 1px dashed var(--line); display: grid; place-items: center; color: var(--ink-soft); }
.ps-search { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-box); font: inherit; font-size: 13px; }
.ps-preview { border: 1px solid var(--line); border-radius: var(--r-xl); padding: 14px; background: var(--paper); }
.ps-card { display: flex; flex-direction: column; gap: 10px; }
.ps-card-hd { display: flex; gap: 12px; align-items: center; }
.ps-art { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; flex: none; background: var(--white); }
.ps-art.is-blank { display: grid; place-items: center; color: var(--ink-faint); }
.ps-title { display: block; font-size: 15px; }
.ps-by, .ps-yr { font-size: 12.5px; color: var(--ink-soft); margin-right: 6px; }
.ps-hint { margin: 0; font-size: 11.5px; color: var(--ink-faint); }
.ps-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ps-chips .sc-chips { display: contents; }
.ps-note { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-box); font: inherit; font-size: 13.5px; resize: vertical; }
.ps-foot { position: sticky; bottom: 0; display: flex; align-items: center; gap: 10px; padding: 12px 0 18px; background: var(--white); border-top: 1px solid var(--line); }
.ps-result { margin: 0; flex: 1; font-size: 12.5px; color: var(--ink-soft); }
.ps-result.is-ok { color: var(--ok); font-weight: 600; }
.ps-result.is-warn { color: var(--warn); }
.ps-send { flex: none; }
.ps-save { text-decoration: none; }
@media (max-width: 640px) {
  .sheet-scrim.is-pelt { place-items: end center; padding: 0; }
  .ps-sheet.is-bottom, .sheet-scrim.is-pelt .ps-sheet { width: 100%; max-height: 92vh; border-radius: var(--r-xl) var(--r-xl) 0 0; padding: 16px 16px 0; animation: rise var(--med) var(--ease) both; }
  .ps-foot { padding-bottom: max(14px, env(safe-area-inset-bottom)); }
}

/* --- the inbox strip in Messages --- */
.pl-strip { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px 10px; border-bottom: 1px solid var(--line); }
.pl-h { display: flex; align-items: center; gap: 8px; font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); }
.pl-n { min-width: 18px; padding: 0 6px; border-radius: 999px; background: var(--danger, #c8462f); color: #fff; font-size: 11px; font-weight: 700; text-align: center; }
.pl-row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 6px 4px; border: 0; background: none; border-radius: var(--r-box); text-align: left; font: inherit; cursor: pointer; }
.pl-row:hover { background: var(--paper); }
.pl-row.is-unread .pl-t b { font-weight: 800; }
.pl-row.is-unread::after { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--violet); margin-left: auto; flex: none; }
.pl-art { width: 36px; height: 36px; border-radius: 6px; object-fit: cover; flex: none; background: var(--paper); }
.pl-art.is-blank { display: grid; place-items: center; color: var(--ink-faint); }
.pl-t { display: flex; flex-direction: column; min-width: 0; }
.pl-t b { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-t small { font-size: 11.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-req, .pl-sub { margin: 6px 0 0; font-size: 11.5px; color: var(--ink-faint); }

/* --- the feed teaser: the have-you-heard card's shape, not a post --- */
.pt-card { margin: 0 0 14px; }
.pt-hero { height: 160px; display: grid; place-items: center; overflow: hidden; border-radius: var(--r-box) var(--r-box) 0 0; background: var(--paper); }
.pt-hero .cd-art { max-height: 160px; }
.pt-open { flex: 1; }

/* Unsend on the sender's copy (Q26; HANDOFF-12 audit 2026-09-08): the quiet status keeps the left, the control sits at the right. */
.plt-actions .plt-status { flex: 1 1 auto; min-width: 0; }
.plt-unsend { color: var(--ink-soft); }
.plt-unsend:hover { color: var(--danger, #c8462f); border-color: var(--danger, #c8462f); }

/* --- replies in Messages (HANDOFF-12 lane 12.9, messages/SPEC.md entry 5) ---
   Instagram's shape: the hover row appears beside the bubble on hover or
   focus, the reply label and faint quote sit above the reply bubble, and the
   composer grows a "Replying to" strip while a reply is being written. */
.dm-row { display: flex; align-items: center; gap: 4px; }
.dm-msg.is-me .dm-row { flex-direction: row-reverse; }
.dm-hover { display: flex; gap: 2px; opacity: 0; transition: opacity .12s; }
.dm-msg:hover .dm-hover, .dm-msg:focus-within .dm-hover { opacity: 1; }
.dm-act {
  width: 26px; height: 26px; border: 0; border-radius: 50%; padding: 0;
  display: inline-grid; place-items: center; background: transparent;
  color: var(--ink-soft); cursor: pointer;
}
.dm-act:hover { background: var(--paper-deep); color: var(--ink); }
.dm-reply-label { font-size: 11px; color: var(--ink-faint); display: inline-flex; gap: 4px; align-items: center; margin-bottom: 2px; }
.dm-quote {
  border: 0; border-left: 3px solid var(--line); background: var(--paper-deep);
  color: var(--ink-soft); border-radius: 12px; padding: 6px 10px; margin-bottom: -6px;
  max-width: 100%; text-align: left; cursor: pointer; opacity: .8; font: inherit;
}
.dm-quote[disabled] { cursor: default; }
.dm-quote-text, .dm-quote-gone { margin: 0; font-size: 12.5px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.dm-quote-gone { font-style: italic; }
.dm-quote-card, .dm-strip-card { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; }
.dm-quote-art { width: 28px; height: 28px; border-radius: 6px; object-fit: cover; }
.dm-msg.is-flash .dm-bubble { outline: 2px solid var(--violet); outline-offset: 2px; }
.dm-reply-strip {
  display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--line-soft);
  padding: 8px 4px 0; margin-top: 6px;
}
.dm-strip-body { flex: 1; min-width: 0; border-left: 3px solid var(--violet); padding-left: 8px; display: grid; gap: 2px; }
.dm-strip-who { font-size: 11.5px; color: var(--ink-soft); font-weight: 600; }
.dm-strip-text { font-size: 12.5px; color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dm-strip-x { border: 0; background: transparent; color: var(--ink-soft); cursor: pointer; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; }
.dm-strip-x:hover { background: var(--paper-deep); }
@media (hover: none) { .dm-hover { opacity: 1; } }

/* --- reactions on a message (15.11, messages/SPEC.md entry 7) ---
   The picker rises where the smile was pressed; what is already on the message
   hangs under its bubble, on the bubble's own side, the way Instagram's does.
   A reaction of yours is outlined — the one thing a tap takes back. */
.dm-emoji-pick {
  display: inline-flex; gap: 2px; margin-top: 4px; padding: 3px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .10); align-self: flex-start;
}
.dm-msg.is-me .dm-emoji-pick, .dm-msg.is-me .dm-reacts { align-self: flex-end; }
.dm-emoji-b {
  border: 0; background: transparent; cursor: pointer; font-size: 17px; line-height: 1;
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
}
.dm-emoji-b:hover { background: var(--paper-deep); }
.dm-emoji-b.is-on { background: var(--violet-wash, var(--paper-deep)); }
.dm-reacts { display: flex; gap: 4px; margin-top: -4px; align-self: flex-start; }
.dm-react {
  display: inline-flex; align-items: center; gap: 3px; font: inherit; font-size: 12px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 999px;
  padding: 1px 7px; cursor: pointer; color: var(--ink-soft);
}
.dm-react.is-mine { border-color: var(--violet); color: var(--ink); }
.dm-react-e { font-size: 13px; line-height: 1.5; }

/* --- a pelt as a message in the thread (HANDOFF-12 lane 12.10) --- */
.dm-card-pelt { cursor: pointer; text-align: left; font: inherit; color: inherit; width: 100%; }
.dm-card-pelt:hover { border-color: var(--violet); }
/* 13.9 (pelt-card answer 24): the bubble stays LIT while `/messages/pelt/<id>`
   is the address, so it is obvious which message the open card came from. */
.dm-card-pelt.is-open { border-color: var(--violet); box-shadow: 0 0 0 2px color-mix(in srgb, var(--violet) 22%, transparent); }
.dm-card-lead { display: block; font-size: 11px; color: var(--ink-faint); }

/* --- Requests, above the conversations (13.16, pelt-card Q24) -------------- */
.pl-reqs { border-bottom: 1px solid var(--line); }
.pl-reqs-b { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 14px;
  border: 0; background: none; font: inherit; text-align: left; color: var(--ink); cursor: pointer; }
.pl-reqs-b:hover { background: var(--paper); }
.pl-reqs-i { display: grid; place-items: center; width: 34px; height: 34px; flex: none;
  border-radius: 50%; background: var(--paper-deep); color: var(--spine); }
.pl-reqs-t { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.pl-reqs-t b { font-size: 14px; }
.pl-reqs-t small { font-size: 12px; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-reqs-n { font-size: 11.5px; font-weight: 700; color: var(--spine); }
.pl-reqs-list { display: flex; flex-direction: column; }
.pl-req-row { display: flex; align-items: center; gap: 10px; padding: 8px 14px 8px 20px; }
.pl-req-row .pl-t { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.pl-req-row .pl-t small { font-size: 11.5px; color: var(--ink-soft); }
.pl-req-yes { padding: 5px 12px; border: 0; border-radius: 8px; background: var(--spine);
  color: #fff; font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; }
.pl-req-yes[disabled] { opacity: .6; cursor: default; }

/* 17.7 — the ⋯ opens a menu (15.11's report: it was unwired). Delete is on it
   only for your own message; the server refuses anybody else's. */
.dm-menu { position: absolute; z-index: 5; margin-top: 26px; min-width: 132px;
  display: flex; flex-direction: column; padding: 4px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--white);
  box-shadow: var(--raise); }
.dm-menu-b { padding: 7px 10px; border: 0; border-radius: 7px; background: none;
  font: inherit; font-size: 13px; color: var(--ink); text-align: left; cursor: pointer; }
.dm-menu-b:hover { background: var(--paper-deep); }
.dm-menu-b.is-danger { color: var(--coral-dark, #b4453a); }
.dm-menu-note { margin: 4px 0 0; font-size: 12px; color: var(--coral-dark, #b4453a); }
.dm-hover { position: relative; }

/* ===========================================================================
   20.6 (`messages/SPEC.md` entry 9) — THE EMOJI SUITE IN THE DM COMPOSER.
   Nick: "a real genuine suite". A search, the groups, and a scrolling grid;
   the four reaction emoji keep their own tiny row (`.dm-emoji-pick` without
   `.dm-emoji-compose`) above a bubble.
   =========================================================================== */
.dm-emoji-pick.dm-emoji-compose {
  position: absolute; bottom: calc(100% + 8px); left: 8px; z-index: 20;
  display: grid; gap: 8px; width: min(340px, calc(100vw - 24px));
  padding: 10px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--white); box-shadow: var(--shadow);
}
.dm-emoji-q {
  min-height: 34px; padding: 0 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--white); color: var(--ink); font: inherit; font-size: 13px;
}
.dm-emoji-tabs { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; }
.dm-emoji-tabs::-webkit-scrollbar { display: none; }
.dm-emoji-tab {
  flex: none; min-height: 28px; padding: 0 10px; border: 0; border-radius: 999px;
  background: transparent; color: var(--ink-soft);
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.dm-emoji-tab:hover { background: var(--paper); color: var(--ink); }
.dm-emoji-tab.is-on { background: var(--ink); color: var(--white); }
.dm-emoji-compose .dm-emoji-grid {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
  max-height: 216px; overflow-y: auto; scrollbar-width: thin;
}
.dm-emoji-compose .dm-emoji-b {
  display: grid; place-items: center; width: 100%; aspect-ratio: 1;
  border: 0; border-radius: 8px; background: none; font-size: 19px; line-height: 1; cursor: pointer;
}
.dm-emoji-compose .dm-emoji-b:hover { background: var(--paper); }
.dm-emoji-none { grid-column: 1 / -1; margin: 0; padding: 12px 4px; font-size: 12.5px; color: var(--ink-faint); }
.dm-composer { position: relative; }

/* 21.5 (messages/SPEC.md 10) — the emoji panel leaves the way it came: a short
   fade and a small drop, then it is gone (EMOJI_FADE_MS in messages.js). */
.dm-emoji-pick.dm-emoji-compose.is-closing { animation: dm-emoji-out 160ms cubic-bezier(.4,0,.6,1) forwards; pointer-events: none; }
@keyframes dm-emoji-out { to { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .dm-emoji-pick.dm-emoji-compose.is-closing { animation-duration: 1ms; } }
/* A shared post travelling alone is the card and nothing around it — the same
   contained, single clickable entity a pelt is. */
.dm-bubble.is-bare > .dm-card-post { margin: 0; }

/* 21.6 (shell/SPEC.md 3) — the conversation header has room for its avatar,
   and the person in it is one quiet link to their page. */
.dm-convo-head { padding-top: 10px; padding-bottom: 10px; min-height: 58px; box-sizing: border-box; }
.dm-convo-who {
  display: inline-flex; align-items: center; gap: 10px; min-width: 0;
  margin: 0; padding: 4px 10px 4px 4px; border: 0; border-radius: 999px;
  background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.dm-convo-who:hover { background: var(--paper); }
.dm-convo-who:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }

/* 26.3 — "Seen 10:42" under your last message, Instagram style: small, quiet,
   right-aligned under the bubble, no per-message ticks. */
.dm-seen { align-self: flex-end; margin: 2px 6px 0 auto; text-align: right;
           font-size: 11.5px; font-weight: 500; color: var(--ink-faint); }
