/* ---------------------------------------------------------------------------
   Group conversation — the chat log and its message bubbles, the composer and its overflow menu, the
   merged-timeline activity event rows, and the two surfaces hosting the shared GroupConvo: the clubhouse
   rail's panel and the in-match PanelModal overlay. Backed by GroupConvo.razor, GroupConvoOverlay.razor,
   GroupMatchView.razor. The clubhouse layout positioning the rail is css/group.css.
   See docs/design/group.md.
   --------------------------------------------------------------------------- */

.group-chat { display: flex; flex-direction: column; gap: 0.45rem; }
.group-chat__log {
    display: flex;
    flex-direction: column;
    gap: 0.12rem;   /* tight base: consecutive lines in a run stack close; run starts add their own top margin */
    max-height: 13rem;
    overflow-y: auto;
    padding: 0.6rem;
    border-radius: 0.8rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
}
/* A run start (a new speaker, an event, or a line after a lull) breathes from what precedes it; the first item
   in the log needs no leading gap. */
.group-chat__log > :first-child { margin-top: 0; }
/* The log scrolls, so it is a tab stop (tabindex="0" in GroupConvo.razor) and shows where the cursor is. */
.group-chat__log:focus-visible { outline: var(--focus-ring); outline-offset: calc(-1 * var(--focus-ring-offset)); }
/* The empty log is the shared EmptyState, compacted for a panel-sized box and centred in the log's height.
   Compounded with the primitive's class so the trimmed padding and type win whatever the sheet order. */
.app-empty.group-chat__empty { margin: auto; padding: 1.1rem 1rem; gap: 0.25rem; }
.group-chat__empty .app-empty__art { font-size: 1.5rem; }
.group-chat__empty .app-empty__title { font-size: 0.95rem; }

/* A chat line as a message row: others' lines sit left with the speaker's name leading the bubble, the
   viewer's own sit right in an accent bubble with no name — the familiar messaging layout. The name reads as a
   bold, per-sender coloured header inside the bubble (WhatsApp-style), and the text + time wrap as a row
   beneath it; the per-sender hue is a stable hash of the sender's id set on the name element. */
.group-msg { display: flex; flex-direction: column; align-items: flex-start; max-width: 85%; margin-right: auto; }
.group-msg--mine { align-items: flex-end; margin-right: 0; margin-left: auto; }
/* Space a run start from the line above it; continuation lines keep the tight log gap so a run stacks. */
.group-msg--run-start { margin-top: 0.4rem; }
/* Bubble + its hover actions ride one row so the ⋯ sits beside the message, never on a line of its own. */
.group-msg__line { display: flex; align-items: center; gap: 0.25rem; max-width: 100%; min-width: 0; }
.group-msg__bubble {
    display: inline-flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.1rem;
    padding: 0.35rem 0.55rem;
    border-radius: 0.9rem;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
}
.group-msg--mine .group-msg__bubble {
    background: var(--accent-blue);
    border-color: transparent;
}
/* A continuation bubble tightens its leading top corner toward the bubble above, so a run reads as one stack. */
.group-msg--run-cont .group-msg__bubble { border-top-left-radius: 0.35rem; }
.group-msg--mine.group-msg--run-cont .group-msg__bubble { border-top-left-radius: 0.9rem; border-top-right-radius: 0.35rem; }
/* …and only the run's last bubble grows the tail, so a stack ends in one point the way it carries one
   timestamp. Mid-run bubbles stay fully rounded on the trailing edge. */
.group-msg--run-end .group-msg__bubble { border-bottom-left-radius: 0.25rem; }
.group-msg--mine.group-msg--run-end .group-msg__bubble { border-bottom-left-radius: 0.9rem; border-bottom-right-radius: 0.25rem; }
/* The sender's name carries their own hashed hue, and it is read on two opposite canvases: the clubhouse
   rail's navy card and the in-match overlay's white one. A fixed lightness can only serve one of them, so the
   hue is pulled toward --text-primary — declared per canvas — the same way the app's -ink accents are: the one
   declaration lightens the name against navy and darkens it against white, clearing 4.5:1 at every hue on
   both. See docs/design/theming.md. */
.group-msg__sender {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    color: color-mix(in srgb, hsl(var(--sender-hue, 210) 55% 50%) 45%, var(--text-primary));
}
.group-msg__content { display: flex; align-items: baseline; gap: 0.4rem; flex-wrap: wrap; }
.group-msg__text { font-size: 0.86rem; line-height: 1.3; color: var(--text-primary); word-break: break-word; }
.group-msg--mine .group-msg__text { color: var(--text-on-accent); }
.group-msg__time { flex: none; margin-left: auto; font-size: 0.7rem; color: var(--text-secondary); white-space: nowrap; }
.group-msg--mine .group-msg__time { color: color-mix(in srgb, var(--text-on-accent) 78%, transparent); }
.group-msg__removed { font-size: 0.78rem; line-height: 1.3; font-style: italic; color: var(--text-muted); }
.group-msg--mine .group-msg__removed { color: color-mix(in srgb, var(--text-on-accent) 70%, transparent); }
.group-msg__report { display: inline-flex; gap: 0.3rem; align-items: center; flex-wrap: wrap; }
.group-msg__report-input { width: 12rem; }

/* The per-message overflow: a ⋯ button opening a small menu. Unlike the friends list (whose rows sit in an
   overflow: visible container), the chat log scrolls (overflow-y: auto) and clips absolutely-positioned
   children, so the menu is Blazor-controlled and opens toward the available vertical space — down by default,
   up when the message sits near the bottom of the scroll viewport (the newest line, the common Remove/Report
   target, pins there). A transparent backdrop captures an outside click to close it. The menu anchors left so
   it opens rightward from the ⋯ into the space beside a left-aligned message rather than off the panel's edge. */
.group-msg__overflow { position: relative; flex: 0 0 auto; }
.group-msg__overflow-btn {
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 0.15rem 0.4rem;
    border-radius: 0.5rem;
    color: var(--text-muted);
    font: inherit;
    font-size: 1rem;
    line-height: 1;
    opacity: 0;   /* hidden at rest; revealed on hover/focus of the row, or while its menu is open (see below) */
    transition: opacity 0.12s ease, background-color 0.15s ease, color 0.15s ease;
}
.group-msg__overflow-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
/* Reveal the actions only when the row is engaged — a resting log stays bubbles alone. Keyboard focus and an
   open menu both count as engaged, so the control never becomes unreachable. */
.group-msg:hover .group-msg__overflow-btn,
.group-msg:focus-within .group-msg__overflow-btn,
.group-msg__overflow-btn[aria-expanded="true"] { opacity: 1; }
/* Coarse-pointer devices have no hover and the bubble isn't focusable, so the reveal-on-hover would leave the
   actions undiscoverable there — keep them visible on touch. */
@media (hover: none) {
    .group-msg__overflow-btn { opacity: 1; }
}
/* A full-surface transparent layer that captures a click outside the open menu to close it. position: fixed is
   viewport-scoped in the docked rail; under the overlay's transformed panel it is scoped to the panel, which is
   the right surface there. It sits below the menu so the menu's items stay clickable. */
.group-msg__overflow-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-chrome) - 1); }
/* Placement only — the surface, the column and the row recipe are .app-menu / .app-menu__item (chrome.css). */
.group-msg__overflow-menu { left: 0; }
.group-msg__overflow-menu--down { top: 100%; margin-top: 0.2rem; }
.group-msg__overflow-menu--up { bottom: 100%; margin-bottom: 0.2rem; }

.group-chat__composer { display: flex; gap: 0.4rem; align-items: stretch; }
.group-chat__input { flex: 1 1 auto; min-width: 0; }
.group-chat__send {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border-radius: 9999px;
    border: none;
    background: var(--accent-blue);
    color: var(--text-on-accent);
    cursor: pointer;
    transition: filter 0.15s ease, opacity 0.15s ease;
}
.group-chat__send:hover:not(:disabled) { filter: brightness(1.05); }
.group-chat__send:disabled { opacity: 0.45; cursor: default; }


/* The merged-timeline activity event rows rendered inline among the chat bubbles: a full-width track so
   the timestamp floats to the column's right edge, holding a compact pill (icon + actor + text) that reads as
   a quiet system event rather than a message. */
.group-convo__event {
    align-self: stretch;
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin-top: 0.4rem;   /* an event breaks a run: give it the same breathing room a run start gets */
}
.group-convo__event-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
    padding: 0.2rem 0.6rem;
    border-radius: 9999px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    font-size: 0.76rem;
    color: var(--text-secondary);
}
.group-convo__event-icon { flex: 0 0 auto; }
.group-convo__actor-pill { flex: 0 0 auto; padding: 0.05rem 0.4rem; border-radius: 9999px; background: color-mix(in srgb, var(--accent-blue) 14%, transparent); font-weight: 600; }
.group-convo__event-text { min-width: 0; word-break: break-word; }
.group-convo__event-time { margin-left: auto; flex: 0 0 auto; color: var(--text-muted); font-size: 0.7rem; white-space: nowrap; }



/* ── Group conversation overlay (GroupConvoOverlay.razor) ──
   A PanelModal summoned over a live group table, hosting the shared GroupConvo unchanged. It sits on the
   OverRoom tier so it clears the room (z-55) while staying below the input-grabbing top layer (z-100) — the
   same tier the rules reading panel uses. The card is narrower and height-bounded compared with the
   primitive's default, and its header carries a rule under it. */
.app-modal__panel.group-convo-overlay__panel {
    max-width: 30rem;
    max-height: min(80dvh, 720px);
}
.group-convo-overlay__panel .app-modal__panel-head {
    padding: 0.85rem 1rem 0.6rem;
    border-bottom: 1px solid var(--border-color);
}
/* A long group name ellipsizes rather than pushing the close button off the row. */
.group-convo-overlay__title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.group-convo-overlay__body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 0.75rem; }
/* The hosted conversation fills the panel so its timeline scrolls internally while the composer + voice
   controls stay pinned — the same flex rule the docked rail applies. */
.group-convo-overlay__body .group-convo { flex: 1 1 auto; min-height: 0; }
.group-convo-overlay__body .group-convo .group-chat__log { flex: 1 1 auto; max-height: none; }
.group-convo-overlay__loading { margin: auto; padding: 2rem 1rem; font-size: 0.9rem; color: var(--text-muted); text-align: center; }

/* The in-match group view fills the overlay panel: a persistent visitor CTA banner, the tab bar, then the
   role-branched body. The body scrolls internally so the Chat composer, the tables shelf, and the roster stay
   reachable while the panel keeps its bounded height. */
.group-match-view { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; gap: 0.5rem; }
.group-match-view__cta { display: flex; flex-direction: column; gap: 0.4rem; }
.group-match-view__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.group-match-view__body .group-convo { flex: 1 1 auto; min-height: 0; }
