/* No Cover Charge · Social styles. Owned by WS3 Social (profiles, messages, gear, badges); Foundation owns ncc.css.
   Linked from both hosts (GuitarSuperSystem/wwwroot/index.html, GuitarSuperSystem.Web/Components/App.razor)
   after ncc/ncc.css with the shared build stamp, so it ships with every deploy and can use the tokens.
   Plain CSS (Tailwind does not compile this file): scope every rule under the feature's root class,
   use var(--n-*) tokens instead of raw colours, and keep motion to the ncc.css kit. */

/* ---- Profiles: /profile (MyProfile), /profile/{name} (UserProfile), /badges --------------------- */
.pf-page { --pf-avatar: 96px; padding-bottom: var(--n-6); }
@media (min-width: 768px) { .pf-page { --pf-avatar: 112px; } }

/* ProfileHero: avatar in a 2px red ring beside the level and meta; bio, stats and actions below. The
   ring sits off a 2px gap of page ink so it reads on any photo. */
.pf-hero { display: grid; gap: var(--n-4); margin: 0 0 var(--n-section); min-width: 0; }
.pf-hero__top { display: flex; align-items: center; gap: var(--n-5); min-width: 0; }
.pf-hero__avatar.n-avatar {
  width: var(--pf-avatar); height: var(--pf-avatar); margin: 4px; font-size: calc(var(--pf-avatar) * .42);
  box-shadow: 0 0 0 2px var(--n-bg), 0 0 0 4px var(--n-red);
}
.pf-hero__id { display: grid; gap: var(--n-2); justify-items: start; min-width: 0; }
.pf-hero__level { cursor: default; }
.pf-hero__meta { display: flex; flex-wrap: wrap; gap: 4px 14px; color: var(--n-text-2); font-size: var(--n-fs-small); line-height: 1.4; }
.pf-hero__meta > span { display: inline-flex; align-items: center; gap: 5px; min-width: 0; overflow-wrap: anywhere; }
.pf-hero__meta .n-icon { color: var(--n-text-3); }
.pf-hero__bio { margin: 0; max-width: 62ch; color: var(--n-text); font-size: var(--n-fs-body); line-height: 1.55; white-space: pre-line; overflow-wrap: anywhere; }
.pf-hero__bio .n-skel-lines { width: 100%; }
.pf-hero__addbio {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; color: var(--n-pink);
  font: 600 14px/1.3 var(--n-font-body); text-decoration: none;
}
.pf-hero__actions { display: flex; flex-wrap: wrap; gap: var(--n-2); }
/* Phones: one action fills the row; two that don't fit side by side stack, each full width. */
.pf-hero__actions > .n-btn { flex: 1 1 auto; }
@media (min-width: 768px) { .pf-hero__actions > .n-btn { flex: 0 0 auto; } }

/* Stats row: value over label, hairline dividers, on one card. */
.pf-stats {
  display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); max-width: 560px; margin: 0;
  border-radius: var(--n-r-md); background: var(--n-card); border: 1px solid var(--n-line);
}
.pf-stat { display: flex; flex-direction: column-reverse; align-items: center; justify-content: center; gap: 4px; min-width: 0; padding: 12px 6px; text-align: center; }
.pf-stat + .pf-stat { border-left: 1px solid var(--n-line); }
.pf-stat__label {
  font: 700 var(--n-fs-kicker)/1.2 var(--n-font-display); letter-spacing: var(--n-ls-kicker); text-transform: uppercase;
  color: var(--n-text-2); white-space: nowrap;
}
.pf-stat__value { display: grid; place-items: center; min-height: 22px; margin: 0; font: 800 20px/1.1 var(--n-font-display); color: var(--n-text); }
/* On the card, step the shimmer up a surface (ncc.css does this for .n-card). */
.pf-stats .n-skel { background-image: linear-gradient(90deg, var(--n-card-2) 25%, var(--n-card-3) 50%, var(--n-card-2) 75%); }

/* ProfileSection: a heading that holds the toggle; the body folds on its grid row. It clips only while
   moving or shut, so an open card's desktop menu popover can hang past the edge. */
.pf-sec { margin: 0 0 var(--n-section); min-width: 0; }
.pf-sec__head { display: flex; align-items: center; gap: var(--n-2); min-height: 44px; margin: 0 0 var(--n-3); }
.pf-sec__h { flex: 1 1 auto; min-width: 0; margin: 0; }
.pf-sec__toggle {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0; border: 0; background: none;
  color: var(--n-text); text-align: left; cursor: pointer;
}
.pf-sec__title { font: 700 17px/1.3 var(--n-font-display); }
.pf-sec__count { font: 600 14px/1 var(--n-font-body); color: var(--n-text-3); font-variant-numeric: tabular-nums; }
.pf-sec__chev { margin-left: -2px; color: var(--n-text-3); transition: rotate calc(320ms / var(--n-tempo)) var(--n-glide); }
.pf-sec:not(.is-open) .pf-sec__chev { rotate: -90deg; }
.pf-sec__trail { flex: none; display: flex; align-items: center; }
.pf-sec__body {
  display: grid; grid-template-rows: 1fr;
  transition: grid-template-rows calc(320ms / var(--n-tempo)) var(--n-glide), opacity calc(320ms / var(--n-tempo)) var(--n-glide);
}
.pf-sec:not(.is-open) .pf-sec__body { grid-template-rows: 0fr; opacity: 0; }
.pf-sec__inner { min-height: 0; min-width: 0; }
.pf-sec:not(.is-open) .pf-sec__inner, .pf-sec.is-moving .pf-sec__inner { overflow: hidden; }
.pf-sec__more { display: flex; justify-content: center; margin-top: var(--n-4); }
.pf-sec__alert { margin-top: var(--n-3); }
/* An empty or failed section is a quiet dashed well, not a hole in the page. */
.pf-sec .n-empty { border: 1px dashed var(--n-line-2); border-radius: var(--n-r-md); }

/* Grids (gear, listings, skeletons) and the posts column */
.pf-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--n-3); }
@media (min-width: 768px) { .pf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--n-4); } }
.pf-posts { display: flex; flex-direction: column; gap: var(--n-4); max-width: 680px; }

/* Gear board card (UserGearSection) */
.pf-gear { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.pf-gear__img.n-img { border-radius: 0; }
.pf-gear__private { position: absolute; top: 8px; left: 8px; }
.pf-gear__body { display: grid; gap: 2px; min-width: 0; padding: 10px 12px 12px; }
.pf-gear__title {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
  font: 600 14px/1.3 var(--n-font-body); color: var(--n-text);
}
.pf-gear__meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--n-fs-meta); color: var(--n-text-3); }
.pf-gear__actions { display: flex; justify-content: space-between; margin: 8px -6px -6px; padding-top: 4px; border-top: 1px solid var(--n-line); }
@media (hover: hover) { .pf-gear__actions .pf-gear__del:hover:not(:disabled) { color: var(--n-danger); } }

/* MyProfile: streak card (the feature card) beside lessons and practice days */
.pf-practice { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--n-3); margin: 0 0 var(--n-section); }
.pf-streak { grid-column: 1 / -1; display: grid; gap: var(--n-2); }
@media (min-width: 768px) {
  .pf-practice { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); }
  .pf-streak { grid-column: auto; }
}
.pf-streak__count { display: flex; align-items: baseline; gap: 8px; }
.pf-streak__num { font: 800 48px/1 var(--n-font-display); color: var(--n-text-hi); }
.pf-streak__unit { font: 700 var(--n-fs-h3)/1 var(--n-font-display); color: var(--n-pink); }
.pf-streak__bar { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin-top: 4px; }
.pf-streak__seg { height: 6px; border-radius: var(--n-r-pill); background: var(--n-card-3); }
.pf-streak__seg.is-on { background: var(--n-red); }
.pf-streak__best { margin: 0; }
.pf-tile { display: grid; align-content: start; gap: 6px; }
.pf-tile__num { font: 800 32px/1 var(--n-font-display); color: var(--n-text); }
.pf-alert { margin: 0 0 var(--n-section); }
.pf-preview { margin: 0 0 var(--n-5); }
.pf-trophies { margin: 0 0 var(--n-section); }

/* Badges: two columns on phones, three from 390px (the trophy case and /badges) */
.pf-badge-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--n-3); }
@media (min-width: 390px) { .pf-badge-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 768px) { .pf-badge-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .pf-badge-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.pf-badge-group { margin: 0 0 var(--n-6); }
.pf-badge-group__title { display: flex; align-items: baseline; gap: 8px; margin: 0 0 var(--n-3); }
.pf-badge-group__count { color: var(--n-text-3); font-weight: 600; letter-spacing: .04em; text-transform: none; }
.pf-badge-group__skel { margin-bottom: var(--n-3); }

/* BadgeTile: earned = pink on a red wash with a solid red hairline; not yet = one quiet dashed style. */
.pf-badge {
  display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; padding: 16px 10px 14px;
  border-radius: var(--n-r-md); border: 1px dashed var(--n-line-2); background: var(--n-card);
  color: var(--n-text); font: inherit; text-align: center; cursor: pointer;
}
.pf-badge.is-earned {
  border-style: solid; border-color: var(--n-red-line);
  background: radial-gradient(120% 90% at 50% 0%, var(--n-red-wash) 0%, transparent 65%), var(--n-card);
}
@media (hover: hover) { .pf-badge:hover { border-color: var(--n-line-3); } }
.pf-badge__disc {
  position: relative; display: grid; place-items: center; flex: none; width: 56px; height: 56px; margin-bottom: 4px;
  border-radius: 50%; background: var(--n-card-2); color: var(--n-text-3);
}
.is-earned > .pf-badge__disc { background: var(--n-red-wash); color: var(--n-pink); box-shadow: inset 0 0 0 2px var(--n-pink); }
.pf-badge__lock {
  position: absolute; right: -2px; bottom: -2px; display: grid; place-items: center; width: 20px; height: 20px;
  border-radius: 50%; background: var(--n-card-3); color: var(--n-text-2); box-shadow: 0 0 0 2px var(--n-card);
}
.pf-badge__name { font: 700 13px/1.25 var(--n-font-display); color: var(--n-text-2); overflow-wrap: anywhere; }
.pf-badge.is-earned .pf-badge__name { color: var(--n-text); }
.pf-badge__sub {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  font-size: var(--n-fs-meta); line-height: 1.35; color: var(--n-text-3);
}
.pf-badge.is-earned .pf-badge__sub { color: var(--n-pink); font-weight: 600; }

/* BadgeSheet ("how to earn it"). The sheet moves to <body>, so nothing here hangs off a page class. */
.pf-badgesheet { display: grid; justify-items: center; gap: var(--n-3); padding-bottom: var(--n-2); text-align: center; }
.pf-badgesheet__badge .pf-badge__disc { width: 88px; height: 88px; margin: 0; }
.pf-badgesheet__badge .pf-badge__lock { width: 26px; height: 26px; }
.pf-badgesheet__rule { display: grid; justify-items: center; gap: 4px; }
.pf-badgesheet__rule p { max-width: 32ch; margin: 0; }
.pf-badgesheet .n-btn { margin-top: var(--n-2); }

/* ProfileSkeleton */
.pf-skel__avatar.n-skel { flex: none; margin: 4px; border-radius: 50%; }
.pf-skel__chip.n-skel { border-radius: var(--n-r-pill); }
.pf-skel__stat { gap: 8px; }
.pf-skel__sec { display: grid; gap: var(--n-3); margin: 0 0 var(--n-section); }

/* ---- Messages: /messages (inbox), /messages/{id} (thread), /settings/blocked ------------------- */
/* Inbox rows: one tile per member on the card surface. Unread: the name in bold and bright, a red dot
   on the avatar and the count pill at the end of the preview line. */
.dm-alert { margin: 0 0 var(--n-3); }
.dm-list { display: grid; gap: var(--n-2); margin: 0; padding: 0; list-style: none; }
.dm-row {
  display: flex; align-items: center; gap: 14px; min-height: 72px; padding: 12px 14px;
  border-radius: var(--n-r-md); background: var(--n-card); border: 1px solid var(--n-line);
  color: var(--n-text); text-decoration: none;
}
@media (hover: hover) { a.dm-row:hover { border-color: var(--n-line-2); } }
.dm-row__main { display: grid; gap: 4px; flex: 1 1 auto; min-width: 0; }
.dm-row__top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-width: 0; }
.dm-row__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 15px/1.3 var(--n-font-body); color: var(--n-text); }
.dm-row__time { flex: none; font-size: var(--n-fs-meta); color: var(--n-text-3); font-variant-numeric: tabular-nums; }
.dm-row__bottom { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dm-row__preview { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; line-height: 1.35; color: var(--n-text-2); }
.dm-row__you { color: var(--n-text-3); }
.dm-row.is-unread .dm-row__name { font-weight: 800; color: var(--n-text-hi); }
.dm-row.is-unread .dm-row__preview { color: var(--n-text); }
.dm-row.is-unread .dm-row__time { color: var(--n-pink); }
.dm-row--skel .dm-row__main { gap: 10px; }

/* Find a member (UserAutocomplete, the new-message sheet): the field, then rows right under it. */
.dm-find { display: grid; gap: var(--n-3); }
.dm-find__field { position: relative; }
.dm-find__icon { position: absolute; top: 50%; left: 12px; translate: 0 -50%; color: var(--n-text-3); pointer-events: none; }
.dm-find__input.n-input { padding-left: 42px; padding-right: 46px; }
.dm-find__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.dm-find__end { position: absolute; top: 50%; right: 4px; translate: 0 -50%; display: grid; place-items: center; min-width: 36px; }
.dm-find__head { margin: var(--n-1) 4px 0; }
.dm-find__list { display: grid; gap: 2px; margin: 0 -8px; padding: 0; list-style: none; }
.dm-find__row {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 8px; border: 0; border-radius: 12px;
  background: none; color: var(--n-text); text-align: left; cursor: pointer; transition: background-color var(--n-dur-fast) ease;
}
.dm-find__row:active, .dm-find__row.is-hl { background: var(--n-card-2); }
@media (hover: hover) { .dm-find__row:hover { background: var(--n-card-2); } }
.dm-find__name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 15px/1.3 var(--n-font-body); }
.dm-find__chev { color: var(--n-text-4); }
.dm-find__none { margin: 0; padding: var(--n-3) 4px; }

/* Thread: a column exactly as tall as the screen under the top bar (no tab pill here), so the list
   scrolls on its own and the composer stays at the bottom. social.js sets --dm-h to what's left above
   the keyboard while it's up. */
.dm-thread {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  height: var(--dm-h, calc(100dvh - var(--n-safe-t) - var(--n-topbar-h)));
}
/* The header is one row (back, name, avatar, ⋯) so the messages get the height: the back label and
   the kicker are left out (the button's name still says "Back to Inbox"). About 52px. */
.dm-thread.n-page { padding-top: 0; }
.dm-thread > .n-ph {
  flex: none; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 4px; margin: 0;
  padding: var(--n-1) var(--n-gutter) var(--n-2) calc(var(--n-gutter) - 10px); border-bottom: 1px solid var(--n-line);
}
.dm-thread > .n-ph .n-ph__back { margin: 0; }
.dm-thread > .n-ph .n-back__label,
.dm-thread > .n-ph .n-ph__titles > .n-kicker { display: none; }
.dm-thread > .n-ph .n-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--n-fs-h2); }
.dm-thread > .n-ph .n-ph__trail { gap: 2px; }
.dm-thread > .n-empty { flex: 1 1 auto; align-content: center; }
.dm-thread__scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; overflow-anchor: none; }
.dm-thread__list {
  display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; min-height: 100%;
  padding: var(--n-4) var(--n-gutter) var(--n-3);
}
.dm-skel { gap: 10px; }
.dm-skel__b.n-skel { border-radius: 18px; }
.dm-skel__b.is-mine { align-self: flex-end; }
.dm-earlier { display: flex; justify-content: center; padding: 0 0 var(--n-3); }
.dm-earlier__alert { margin: 0 0 var(--n-3); }
.dm-start { margin: 0 0 var(--n-3); text-align: center; }
.dm-hello { margin-top: auto; }
.dm-day { display: flex; align-items: center; gap: 12px; margin: var(--n-4) 0 var(--n-2); }
.dm-day::before, .dm-day::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--n-line); }
.dm-day .n-kicker { color: var(--n-text-3); }

/* "About this listing" (from gear's Message seller) */
.dm-listing { display: flex; align-items: center; gap: 12px; width: 100%; max-width: 420px; margin: 0 auto var(--n-4); }
.dm-listing__img.n-img { flex: none; width: 56px; border-radius: var(--n-r-sm); }
.dm-listing__txt { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; }
.dm-listing__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 14px/1.3 var(--n-font-body); color: var(--n-text); }
.dm-listing__chev { color: var(--n-text-4); }

/* Bubbles (MessageBubble). A run from one sender stacks tight; the corners on the sender's side tuck
   in between bubbles of a run, so a single message is fully round. */
.dm-msg { display: flex; flex-direction: column; max-width: min(80%, 560px); }
.dm-msg.is-mine { align-self: flex-end; align-items: flex-end; }
.dm-msg.is-theirs { align-self: flex-start; align-items: flex-start; }
.dm-msg.is-first { margin-top: var(--n-2); }
.dm-msg__row { display: flex; align-items: center; gap: 4px; max-width: 100%; }
.dm-msg.is-mine .dm-msg__row { flex-direction: row-reverse; }
.dm-msg__stack { display: flex; flex-direction: column; align-items: inherit; gap: 2px; min-width: 0; }
.dm-msg.is-mine .dm-msg__stack { align-items: flex-end; }
.dm-bubble {
  padding: 8px 13px; border-radius: 18px; font: 400 15px/1.4 var(--n-font-body);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.dm-msg.is-theirs .dm-bubble { background: var(--n-card-2); color: var(--n-text); }
.dm-msg.is-mine .dm-bubble { background: var(--n-red); color: var(--n-on-red); }
.dm-msg.is-mine:not(.is-first) :where(.dm-bubble, .dm-photo) { border-top-right-radius: 6px; }
.dm-msg.is-mine:not(.is-last) :where(.dm-bubble, .dm-photo) { border-bottom-right-radius: 6px; }
.dm-msg.is-theirs:not(.is-first) :where(.dm-bubble, .dm-photo) { border-top-left-radius: 6px; }
.dm-msg.is-theirs:not(.is-last) :where(.dm-bubble, .dm-photo) { border-bottom-left-radius: 6px; }
.dm-msg .dm-bubble.dm-bubble--stub {
  display: inline-flex; align-items: center; gap: 6px; background: none; border: 1px dashed var(--n-line-2);
  color: var(--n-text-3); font-size: 14px; font-style: italic;
}
.dm-photo { display: block; overflow: hidden; line-height: 0; border-radius: 18px; background: var(--n-card-2); }
.dm-photo img { display: block; max-width: min(240px, 100%); max-height: 320px; object-fit: cover; }
/* In the app a long press opens the bubble's menu (with Copy), not WebKit's callout or link preview. */
html.is-native .dm-msg__stack { -webkit-touch-callout: none; }
.dm-msg.is-sending .dm-msg__stack { opacity: .6; }
.dm-msg.is-failed .dm-msg__stack { opacity: .75; }
.dm-msg__meta { margin-top: 4px; padding: 0 4px; }
.dm-msg__retry {
  display: inline-flex; align-items: center; gap: 4px; min-height: 32px; margin-top: 2px; padding: 0 4px; border: 0;
  background: none; color: var(--n-danger); font: 600 12px/1.2 var(--n-font-body); cursor: pointer;
}
/* Pointers that hover get a ⋯ beside the bubble; touch has the long press. */
.dm-msg__more { opacity: 0; transition: opacity var(--n-dur-fast) ease; }
@media (hover: hover) { .dm-msg:hover .dm-msg__more, .dm-msg__more:focus-visible, .dm-msg__more[aria-expanded="true"] { opacity: 1; } }
@media (hover: none) { .dm-msg__more { display: none; } }

/* Composer: photo, field (1 to 5 lines), send. Safe-area padding until the keyboard covers it. */
.dm-composer {
  position: relative; flex: none; display: grid; gap: var(--n-2);
  padding: var(--n-2) var(--n-gutter) calc(var(--n-2) + var(--n-safe-b));
  border-top: 1px solid var(--n-line); background: var(--n-bg);
}
html.kb-open .dm-composer { padding-bottom: var(--n-2); }
.dm-composer__alert { margin: 0; }
.dm-composer__row { display: flex; align-items: flex-end; gap: 6px; }
.dm-composer__attach { flex: none; overflow: hidden; color: var(--n-pink); cursor: pointer; }
.dm-composer__attach.is-off { opacity: .45; cursor: default; }
.dm-composer__file { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: inherit; }
.dm-composer__input.n-input {
  flex: 1 1 auto; min-width: 0; min-height: 44px; max-height: calc(1.4em * 5 + 22px); padding: 11px 16px;
  border-radius: 22px; line-height: 1.4; resize: none; overflow-y: hidden;
}
.dm-send {
  flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%;
  background: var(--n-red); color: var(--n-on-red); cursor: pointer;
  transition: scale var(--n-dur-fast) ease, background-color var(--n-dur) ease, color var(--n-dur) ease;
}
.dm-send:active:not(:disabled) { scale: .92; background: var(--n-red-press); }
@media (hover: hover) { .dm-send:hover:not(:disabled) { background: var(--n-red-press); } }
.dm-send:disabled { background: var(--n-card-3); color: var(--n-text-3); cursor: default; }
.dm-composer__hint { margin: 0; text-align: right; }
@media (hover: none), (pointer: coarse) { .dm-composer__hint { display: none; } }
html.is-native .dm-composer__hint { display: none; }
.dm-composer__photo {
  position: relative; justify-self: start; display: grid; place-items: center; width: 72px; height: 72px; margin-top: 6px;
  border-radius: var(--n-r-sm); background: var(--n-card-2);
}
.dm-composer__photo img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.dm-composer__unphoto { position: absolute; top: -10px; right: -10px; }

/* "New message" while reading history: floats above the composer, centred. */
.dm-newpill {
  position: absolute; bottom: calc(100% + 10px); left: 0; right: 0; z-index: var(--n-z-raised); width: max-content; margin: 0 auto;
  display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 14px; border: 1px solid var(--n-line-2);
  border-radius: var(--n-r-pill); background: var(--n-card-2); color: var(--n-text); box-shadow: var(--n-shadow-float);
  font: 600 13px/1 var(--n-font-body); cursor: pointer;
}

/* Settings › Blocked members */
.dm-blocked__row { gap: 12px; }
.dm-blocked__who { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; color: var(--n-text); text-decoration: none; }
.dm-blocked__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 15px/1.3 var(--n-font-body); }

/* ---- Gear: /gear, /gear/{id}, /gear/new, /gear/{id}/edit, /gear/mine ---------------------------- */
/* Header actions, then search + Filters, then the sort / active-filter rail. */
.gr-actions { display: flex; flex-wrap: wrap; gap: var(--n-2); margin: calc(var(--n-2) * -1) 0 var(--n-5); }
.gr-actions > .n-btn { flex: 1 1 auto; }
@media (min-width: 640px) { .gr-actions > .n-btn { flex: 0 0 auto; } }
.gr-toolbar { display: flex; align-items: center; gap: var(--n-2); margin: 0 0 var(--n-3); }
.gr-search { position: relative; flex: 1 1 auto; min-width: 0; margin: 0; }
.gr-search__icon { position: absolute; top: 50%; left: 12px; translate: 0 -50%; color: var(--n-text-3); pointer-events: none; }
.gr-search__input.n-input { padding-left: 42px; padding-right: 44px; }
.gr-search__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.gr-search__clear { position: absolute; top: 50%; right: 4px; translate: 0 -50%; }
.gr-toolbar > .n-btn { flex: none; }
.gr-filters__count { margin-left: 2px; }
.gr-rail { margin-bottom: var(--n-4); }
.gr-count { margin: 0 0 var(--n-3); }
.gr-alert { margin: 0 0 var(--n-3); }
.gr-alert--more { margin: var(--n-4) 0 0; }
.gr-more { display: flex; justify-content: center; margin-top: var(--n-5); }

/* Grid: two cards on phones, three from 768px, four on a desktop (the page is the wide one). */
.gr-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--n-3); }
@media (min-width: 768px) { .gr-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--n-4); } }
@media (min-width: 1024px) { .gr-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* GearCard: photo, then the title on its own line (two at most), price + condition, brand · year. */
.gr-card.n-card { display: flex; flex-direction: column; min-width: 0; overflow: hidden; color: var(--n-text); text-decoration: none; }
@media (hover: hover) { .gr-card.n-card:hover { border-color: var(--n-line-2); } }
.gr-card.is-featured { border-color: var(--n-red-line); }
/* Sold and taken down read as past: muted photo (a filter, so the NImg fade-in still runs). */
.gr-card.is-dim .gr-card__img img { filter: grayscale(.7) brightness(.65); }
.gr-card__img.n-img { border-radius: 0; }
.gr-card__flags { position: absolute; inset: 8px 8px auto; display: flex; justify-content: space-between; gap: 6px; pointer-events: none; }
.gr-flag.n-badge { background: var(--n-glass); color: var(--n-text-hi); -webkit-backdrop-filter: var(--n-glass-fx); backdrop-filter: var(--n-glass-fx); }
.gr-flag--featured.n-badge { background: var(--n-red); color: var(--n-on-red); }
.gr-flag--end { margin-left: auto; }
.gr-card__body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; min-width: 0; padding: 10px 12px 12px; }
.gr-card__title {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
  font: 600 14px/1.3 var(--n-font-body); color: var(--n-text);
}
.gr-card__row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; min-width: 0; }
.gr-card__price { font: 800 16px/1.2 var(--n-font-display); color: var(--n-text-hi); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gr-card__cond { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--n-fs-meta); color: var(--n-text-2); }
.gr-card__meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--n-fs-meta); color: var(--n-text-3); }
.gr-card__review { display: flex; min-width: 0; margin-top: 2px; }
.gr-card__review > .n-badge { max-width: 100%; overflow: hidden; }
.gr-card--skel .gr-card__body { gap: 8px; }

/* Chip groups (filters sheet, form options). Sheets move to <body>: nothing here hangs off a page class. */
.gr-chips { display: flex; flex-wrap: wrap; gap: var(--n-2); }
.gr-group { display: grid; gap: var(--n-3); margin: 0 0 var(--n-5); }
.gr-group > .n-kicker { margin: 0; }
.gr-group__hint { margin-left: 6px; color: var(--n-text-3); font-weight: 600; letter-spacing: .04em; text-transform: none; }
.gr-group--page { gap: 0; margin-bottom: var(--n-section); }
.gr-group__note { margin: calc(var(--n-2) * -1) 0 var(--n-3); }
.gr-filters__foot { display: flex; gap: var(--n-2); }
.gr-filters__foot > .n-btn--ghost { flex: none; }
.gr-safety { display: grid; gap: var(--n-4); }
.gr-safety__list { display: grid; gap: var(--n-3); margin: 0; padding-left: 20px; font-size: var(--n-fs-body); line-height: 1.5; color: var(--n-text); }
.gr-safety__list strong { color: var(--n-text-hi); }
.gr-safety > p { margin: 0; }

/* Detail: gallery and details side by side from 768px (the gallery stays in view on a desktop). */
.gr-detail__back { margin: 0 0 var(--n-3) -10px; }
.gr-detail__head .n-title { overflow-wrap: anywhere; }
.gr-detail__flags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--n-2); }
.gr-detail__review { margin: calc(var(--n-2) * -1) 0 var(--n-5); }
.gr-detail__grid { display: grid; gap: var(--n-5); align-items: start; }
@media (min-width: 768px) {
  .gr-detail__grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--n-8); }
  .gr-gallery { position: sticky; top: calc(var(--n-safe-t) + var(--n-topbar-h) + var(--n-4)); }
}
.gr-detail__info { display: grid; gap: var(--n-4); min-width: 0; }
.gr-gallery { display: grid; gap: var(--n-2); min-width: 0; }
.gr-gallery__main { position: relative; display: block; width: 100%; padding: 0; border: 0; border-radius: var(--n-r-md); background: none; cursor: zoom-in; }
.gr-gallery__img.n-img { border-radius: var(--n-r-md); background: var(--n-sunken); }
.gr-gallery__img.n-img > img { object-fit: contain; }
.gr-gallery__count.n-badge { position: absolute; right: 10px; bottom: 10px; background: var(--n-glass); color: var(--n-text-hi); }
.gr-gallery__thumbs.n-rail { gap: 6px; }
.gr-thumb { flex: none; width: 64px; padding: 0; border: 2px solid transparent; border-radius: calc(var(--n-r-sm) + 2px); background: none; cursor: pointer; }
.gr-thumb .n-img { border-radius: var(--n-r-sm); }
.gr-thumb.is-on { border-color: var(--n-red); }
.gr-detail__price { margin: 0; font: 800 32px/1.1 var(--n-font-display); letter-spacing: var(--n-ls-title); color: var(--n-text-hi); font-variant-numeric: tabular-nums; }
.gr-facts.n-card { display: grid; margin: 0; padding: 4px 16px; }
.gr-facts > div { display: flex; justify-content: space-between; gap: var(--n-4); padding: 10px 0; }
.gr-facts > div + div { border-top: 1px solid var(--n-line); }
.gr-facts dt { flex: none; color: var(--n-text-2); font-size: var(--n-fs-small); }
.gr-facts dd { margin: 0; min-width: 0; text-align: right; overflow-wrap: anywhere; font: 600 var(--n-fs-small)/1.4 var(--n-font-body); color: var(--n-text); }
.gr-lesson.n-card { display: flex; align-items: center; gap: 12px; color: var(--n-pink); }
.gr-lesson__txt { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; }
.gr-lesson__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 14px/1.3 var(--n-font-body); color: var(--n-text); }
.gr-lesson__chev, .gr-seller__chev { color: var(--n-text-4); }
.gr-detail__audio { width: 100%; }
.gr-detail__about { display: grid; gap: var(--n-2); }
.gr-detail__about > .n-kicker { margin: 0; }
.gr-detail__about > p { margin: 0; }
.gr-detail__desc { white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--n-fs-body); line-height: 1.55; color: var(--n-text); }
.gr-seller.n-card { display: flex; align-items: center; gap: 12px; }
.gr-seller__txt { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; }
.gr-seller__name { display: flex; align-items: center; gap: 6px; min-width: 0; font: 700 15px/1.3 var(--n-font-body); color: var(--n-text); }
.gr-owner { display: flex; flex-wrap: wrap; gap: var(--n-2); }
.gr-owner > .n-btn { flex: 1 1 auto; }
@media (min-width: 640px) { .gr-owner > .n-btn { flex: 0 0 auto; } }
.gr-buy { display: none; gap: var(--n-2); }
.gr-buy__safe {
  justify-self: center; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin-top: calc(var(--n-2) * -1);
  padding: 0 8px; border: 0; background: none; color: var(--n-pink); font: 600 13px/1 var(--n-font-body); cursor: pointer;
}

/* Phones and tablets (the tab pill is up): price + Message seller in a bar just above the pill. */
.gr-buybar {
  position: fixed; z-index: calc(var(--n-z-tabbar) - 1); left: 14px; right: 14px; bottom: calc(84px + var(--n-safe-b));
  max-width: 520px; margin-inline: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--n-3);
  padding: 8px 8px 8px 16px; border-radius: var(--n-r-lg); border: 1px solid var(--n-line-2);
  background: var(--n-glass); -webkit-backdrop-filter: var(--n-glass-fx); backdrop-filter: var(--n-glass-fx);
  box-shadow: var(--n-shadow-float); animation: n-rise var(--n-dur) var(--n-out) both;
}
.gr-buybar__price { display: grid; gap: 2px; min-width: 0; }
.gr-buybar__amt { font: 800 18px/1.1 var(--n-font-display); color: var(--n-text-hi); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gr-buybar > .n-btn { flex: none; }
.gr-detail.has-bar { padding-bottom: 80px; }
html.kb-open .gr-buybar { display: none; }
@media (min-width: 1024px) {
  .gr-buybar { display: none; }
  .gr-buy { display: grid; }
  .gr-detail.has-bar { padding-bottom: 0; }
}

/* Forms: /gear/new, /gear/{id}/edit, and the gear-board sheet. One column on phones, pairs from 640px. */
.gr-edit__skel { display: grid; gap: var(--n-4); }
.gr-edit__form { display: grid; gap: var(--n-5); margin: 0; }
.gr-form { display: grid; gap: var(--n-4); }
.gr-form__pair { display: grid; gap: var(--n-4); }
/* start: an error under one field must not stretch its neighbour's rows apart. */
@media (min-width: 640px) { .gr-form__pair { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
.gr-form__opt { margin-left: 4px; color: var(--n-text-3); font-weight: 400; }
.gr-form__desc.n-input { min-height: 140px; }
.gr-form__money { position: relative; display: block; }
.gr-form__cur { position: absolute; top: 50%; left: 12px; translate: 0 -50%; color: var(--n-text-2); font-weight: 600; pointer-events: none; }
.gr-form__money > .n-input { padding-left: 26px; }
.gr-form .n-input[aria-invalid="true"] { border-color: var(--n-red); }
.gr-edit__actions { display: flex; justify-content: flex-end; gap: var(--n-2); padding-top: var(--n-4); border-top: 1px solid var(--n-line); }
.gr-edit__actions > .n-btn--primary { flex: 1 1 auto; }
@media (min-width: 640px) { .gr-edit__actions > .n-btn--primary { flex: 0 0 auto; } }
.gr-edit__actions--sheet { padding-top: 0; border-top: 0; }
.gr-edit__note { margin: calc(var(--n-2) * -1) 0 0; }

/* GearPhotoPicker: tiles with a local preview, a progress line while uploading, the cover marked. */
.gr-photos-field { position: relative; }
.gr-photos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--n-2); }
@media (min-width: 480px) { .gr-photos { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.gr-photo {
  position: relative; aspect-ratio: 1; min-width: 0; overflow: hidden; border-radius: var(--n-r-sm);
  border: 1px solid var(--n-line); background: var(--n-card-2);
}
.gr-photo > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; }
.gr-photo__veil {
  position: absolute; inset: 0; display: grid; place-items: center; align-content: center; gap: 6px; padding: 6px; border: 0;
  background: var(--n-glass); color: var(--n-text); font: 600 12px/1.2 var(--n-font-body); text-align: center;
}
.gr-photo__retry { color: var(--n-danger); cursor: pointer; }
.gr-photo__bar { position: absolute; left: 0; bottom: 0; height: 3px; width: var(--p, 0%); background: var(--n-red); transition: width var(--n-dur) ease; }
.gr-photo__cover.n-badge { position: absolute; left: 6px; bottom: 6px; background: var(--n-glass); color: var(--n-text-hi); }
.gr-photo__remove.n-icon-btn { position: absolute; top: 2px; right: 2px; background: var(--n-glass); color: var(--n-text-hi); }
.gr-photo--add {
  display: grid; place-items: center; align-content: center; gap: 4px; padding: 6px; border-style: dashed; border-color: var(--n-line-3);
  background: var(--n-sunken); color: var(--n-pink); text-align: center; cursor: pointer;
}
.gr-photo__add { font: 600 13px/1.2 var(--n-font-body); color: var(--n-text); }
.gr-photos__file { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); border: 0; opacity: 0; }
