/* A thread on home: the Town Square or a group's chat. Its feed, then its
   message box. */

.thread {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* The head: a group's back arrow (phone only), the title, and a group's link to
   its members. */
.thread-head {
    display: flex;
    align-items: center;
    gap: var(--size-2);
    padding: var(--size-2) var(--size-3);
    border-bottom: var(--rule-1);
}

/* The title and the form row carry rules that span the card, so neither keeps
   normalize's measure on h2 and p. */
.thread-title {
    flex: 1;
    max-inline-size: none;
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--fs-2);
    font-weight: var(--fw-normal);
    color: var(--text-1);
}

.thread-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--tap-min);
    min-height: var(--tap-min);
    margin-left: calc(-1 * var(--size-2));
    color: var(--text-2);
}

.thread-settings {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--size-1);
}

.thread-settings .ui-icon {
    width: 1rem;
    height: 1rem;
}

/* A group's panel: its members and the admin's settings, in a drawer over the
   chat. It is a popover="auto", so the top layer holds it whatever the page
   behind is doing, and the stream's morph keeps it open. A phone gets the whole
   screen, entered like a page with a back arrow; a wide screen gets a column
   at the right edge with a close cross.
   Shut, it stays laid out off the right edge and hidden, rather than the
   popover's display: none, so it slides out as it slides in: only Chromium
   keeps a closing popover in the top layer (overlay), and elsewhere display
   would drop it at once. The z-index holds it over the page as it goes. */
.group-panel {
    inset: 0 0 0 auto;
    z-index: 50;
    width: 100vw;
    height: 100dvh;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: calc(var(--size-3) + env(safe-area-inset-top)) var(--size-3) calc(var(--size-3) + env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    gap: var(--size-4);
    overflow: hidden;
    background: var(--surface-2);
    color: var(--text-1);
    border: none;
    visibility: hidden;
    transform: translateX(100%);
}

.group-panel:popover-open {
    visibility: visible;
    transform: none;
}

.group-panel::backdrop {
    background: var(--color-backdrop);
}

.group-panel-top {
    display: flex;
    align-items: center;
    gap: var(--size-2);
}

.group-panel-close {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    background: transparent;
    color: var(--text-2);
    border: none;
    cursor: pointer;
}

@media (hover: hover) {
    .group-panel-close:hover {
        color: var(--text-1);
    }
}

.group-panel-close .ui-icon {
    width: 1.1rem;
    height: 1.1rem;
}

.group-panel-close-x {
    display: none;
}

/* The heading, or the admin's name field that edits it, takes the row. */
.group-panel-title,
.group-panel-name {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--fs-2);
}

/* The members scroll between the head and the foot, which stay put. */
.group-panel-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: var(--size-2);
    overflow-y: auto;
    overscroll-behavior: contain;
}

@media (min-width: 900px) {
    .group-panel {
        width: min(24rem, 100vw);
        border-left: var(--rule-strong);
    }

    .group-panel-close {
        order: 1;
    }

    .group-panel-close-x {
        display: inline-flex;
    }

    .group-panel-close-back {
        display: none;
    }
}

@media (prefers-reduced-motion: no-preference) {
    .group-panel {
        transition:
            transform 0.2s ease,
            visibility 0.2s ease,
            overlay 0.2s ease allow-discrete;
    }

    .group-panel::backdrop {
        background: transparent;
        transition:
            background 0.2s ease,
            overlay 0.2s ease allow-discrete,
            display 0.2s ease allow-discrete;
    }

    .group-panel:popover-open::backdrop {
        background: var(--color-backdrop);
    }

    @starting-style {
        .group-panel:popover-open::backdrop {
            background: transparent;
        }
    }
}

.group-members {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

/* Layout comes from .list-row .list-row--divided (base.css); the normalize's
   measure cap on li would stop the rows short of the panel's edge. */
.group-members .list-row {
    max-inline-size: none;
}

.group-member-name {
    flex: 1;
    min-width: 0;
    color: var(--text-1);
}

.member-avatar {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-token);
    background: var(--color-accent);
    color: var(--text-on-color);
    font-size: var(--font-size-0);
    letter-spacing: 0.02em;
}

.group-badge {
    font-size: var(--font-size-00);
    font-style: italic;
    color: var(--color-accent-text);
    border: 1px solid var(--color-accent-muted);
    padding: 2px var(--size-2);
    border-radius: var(--radius-2);
}

.group-badge--pending {
    color: var(--color-highlight-subtle-text);
    background: var(--color-highlight-subtle);
}

.group-panel-foot {
    border-top: var(--rule-1);
    padding-top: var(--size-3);
}

/* column-reverse + newest-first entries keeps the feed pinned to the bottom, so
   it opens on what is new with no scroll script. */
.thread-feed {
    display: flex;
    flex-direction: column-reverse;
    gap: var(--size-1);
    min-height: 8rem;
    max-height: 55dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--size-2) var(--size-3);
}

.thread-empty {
    margin: auto;
    text-align: center;
}

/* A thread has the room a game's dock lacks, so its messages read a step up
   on the fluid scale (chat.css). The feed is sunk into the card, on the
   unlit ground a game's chat sits on, as an input is: the boxes lift off it
   there, and the card's head and message box keep the panel every card has. */
.thread-feed {
    --chat-fs: var(--fs-0);
    background: var(--surface-1);
}

/* The cross on the viewer's own message. A pointer that hovers sees it only
   over that message; a touch screen keeps it, quiet, on every one of them.
   Its tap area spills past the head by the negative margin, so the head is no
   taller for it. */
.thread-msg-delete {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: calc(-1 * var(--size-1));
    padding: var(--size-1);
    background: transparent;
    border: none;
    color: var(--text-3);
    cursor: pointer;
}

.thread-msg-delete .ui-icon {
    width: 0.8rem;
    height: 0.8rem;
}

/* Shut, the cross is folded to no width rather than hidden, so the viewer's
   own times line up with everyone else's and a keyboard can still reach it. */
@media (hover: hover) {
    .thread-msg-delete {
        width: 0;
        margin: 0;
        padding: 0;
        overflow: hidden;
    }

    .chat-msg:hover .thread-msg-delete,
    .thread-msg-delete:focus-visible {
        width: auto;
        margin: calc(-1 * var(--size-1));
        padding: var(--size-1);
    }

    .thread-msg-delete:hover {
        color: var(--color-destructive);
    }
}

@media (pointer: coarse) {
    .thread-msg-delete {
        margin: calc(-1 * var(--size-2));
        padding: var(--size-2);
    }
}

/* A game card in the feed: a message's box (.chat-msg, chat.css), edged by the game's
   card status (home-card--lobby, --playing, --over, --closed in home.css), and
   its one action at Send's size. It is not a link: its one action is its own. */
.thread-card {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--size-2);
    border-left-width: 3px;
}

.thread-card-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

/* The title wraps rather than truncates: who set the board and which map are
   the card, so neither is ever cut off. The detail line still truncates. */
.thread-card-title {
    color: var(--text-1);
    font-size: var(--chat-fs);
    overflow-wrap: anywhere;
}

.thread-card-detail {
    font-size: var(--font-size-0);
    font-style: italic;
    color: var(--text-2);
}

/* Taking a seat and going back to one's seat are the same Join button, one
   size whichever it is. */
.thread-card-action {
    flex-shrink: 0;
    justify-content: center;
    min-width: 3.5rem;
    padding: var(--size-1) var(--size-3);
    font-size: var(--font-size-0);
    text-decoration: none;
}

/* The site admin's announcement: a message's box (.chat-msg, chat.css) edged in
   brass, apart from any game card's status, and a link as a whole, so it reads
   as one card, not as underlined text. */
.thread-announcement {
    display: flex;
    flex-direction: column;
    gap: var(--size-1);
    border-left: 3px solid var(--color-highlight);
    color: inherit;
    text-decoration: none;
}

@media (hover: hover) {
    .thread-announcement:hover {
        background-image: var(--hover-veil);
    }
}

.thread-announcement-title {
    color: var(--text-1);
    font-family: var(--font-display);
    font-size: var(--fs-1);
    line-height: 1.2;
    overflow-wrap: anywhere;
}

.thread-announcement-body {
    color: var(--text-1);
    font-size: var(--chat-fs);
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}

.thread-form {
    max-inline-size: none;
    display: flex;
    align-items: center;
    gap: var(--size-2);
    margin: 0;
    padding: var(--size-2);
    border-top: var(--rule-1);
}

.thread-signup {
    justify-content: center;
}

/* On a phone a conversation is the whole page, with a back arrow to the list
   of them, and runs edge to edge: no page gutter and no card frame, so the feed
   has every row the screen can spare. */
/* It fills the small viewport less the site header (53px) and the room kept
   for the bottom bar (76px), and a few pixels spare: Chrome on iOS takes 100svh
   as a little more than it shows. So the page is never taller than the screen
   and has nothing to scroll. The feed, or a group's open panel, takes what its
   head and message box leave. */
@media (max-width: 899px) {
    .content-wrapper:has(> .home--thread) {
        padding: 0;
    }

    .home--thread .thread {
        height: calc(100svh - 8.5rem - env(safe-area-inset-bottom));
        border: none;
        border-radius: 0;
        box-shadow: none;
    }
}

.home--thread .thread-feed,
.home--thread .group-panel {
    flex: 1;
    max-height: none;
}

/* The switcher: the open conversation's title, a wide screen's way to the
   others, with a dot while one of them holds something unseen. */
.thread-switch {
    display: none;
    flex: 1;
    min-width: 0;
    align-items: center;
    gap: var(--size-2);
    padding: 0;
    background: transparent;
    border: none;
    color: var(--text-1);
    font-family: var(--font-display);
    font-size: var(--fs-2);
    text-align: left;
    cursor: pointer;
}

.thread-switch .ui-icon {
    width: 1rem;
    height: 1rem;
    color: var(--text-3);
}

@media (hover: hover) {
    .thread-switch:hover .ui-icon {
        color: var(--link);
    }
}

.thread-switch-dot {
    flex-shrink: 0;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--radius-token);
    background: var(--color-accent);
}

[popovertarget="thread-switcher"] {
    anchor-name: --thread-switcher-trigger;
}

#thread-switcher {
    position-anchor: --thread-switcher-trigger;
    position-area: block-end span-inline-end;
    width: min(22rem, 40vw);
    max-height: 70dvh;
    overflow-y: auto;
    padding: var(--size-2);
}

/* On a wide screen the conversation is a panel the window's height less the
   site header (63px) and the page's gutters above and below it (32px each), so
   a short home has nothing to scroll; the title is the switcher between
   conversations. */
@media (min-width: 900px) {
    .content-wrapper:has(> .home--thread) {
        padding-bottom: var(--size-7);
    }

    .thread,
    .home--thread .thread {
        height: calc(100dvh - 8rem);
    }

    .thread-feed,
    .group-panel {
        flex: 1;
        max-height: none;
    }

    .thread-back,
    .thread-title {
        display: none;
    }

    .thread-switch {
        display: flex;
    }
}

/* On a phone the keyboard comes up over the fixed bottom nav, which would sit
   between it and the message box; while the box has focus the nav steps aside
   so the box rests right on the keyboard. A wide screen has no bottom nav. */
body:has(#thread .chat-input:focus) .bottom-nav {
    display: none;
}
