/* Community chat (/chat).
   Light, to match the site: white panels on the #e9e9e9 page, the .ddg-box
   border stack, #eba133 for anything interactive. Fills the viewport, with
   the rules panel taking the width a single column of chat would waste. */

.cchat {
    --cc-accent: #eba133;
    --cc-accent-dark: #c9821a;
    --cc-panel: #fff;
    --cc-rule: #e5e6e9;
    --cc-soft: #f2f2f4;
    --cc-ink: #3f3f45;
    --cc-dim: #8b8b90;
    --cc-faint: #b0b0b6;
    --cc-tint: #fdf8f0;

    display: flex;
    flex-direction: column;

    /* Clear of the site header. The panels sat flush against the dark nav bar
       otherwise, which reads as the page having no top edge. The height
       subtracts this margin along with the header so the room still ends at
       the bottom of the viewport. */
    margin-top: 12px;

    /* Out of the Bootstrap .container the page wraps everything in, so the
       room uses the width it actually needs — a chat in a 1140px column is
       mostly empty margin.

       Negative margins rather than a transform: .cchat-pop is position:fixed
       and measured against the viewport, and a transformed ancestor would
       make "fixed" resolve against this element instead, quietly breaking
       every popup's placement. */
    margin-left: calc(50% - 50vw + 22px);
    margin-right: calc(50% - 50vw + 22px);

    /*
     * Sized to what is actually left below the header rather than to a guessed
     * constant. The old 150px was the site header plus margins as they happened
     * to be on one screen; it was wrong the moment a sub-menu appeared or a
     * notice bar showed up, leaving either a gap under the room or a page that
     * scrolled behind it.
     *
     * community-chat.js measures the gap and sets --cc-top. This is what the
     * room falls back to before that runs, and if it never does. dvh rather
     * than vh so a phone's collapsing address bar does not cut the composer
     * off the bottom.
     */
    height: calc(100dvh - var(--cc-top, 150px));
    min-height: 420px;
    color: var(--cc-ink);
}

/* The wrapper's padding is meant for pages that scroll; the room ends at the
   bottom of the viewport instead, so it would only ever add a scrollbar. */
body.cchat-page .pageWrap,
body.cchat-page .pageContent { padding-bottom: 0; margin-bottom: 0; }

/*
 * The page itself does not scroll here; the stream inside it does.
 *
 * Without this, anything that nudged the document — an anchor jump, a focused
 * element being scrolled into view, a stray pixel of overflow — slid the whole
 * room up past the site header and left the composer floating mid-page with
 * dead space beneath it. The room is sized to the viewport, so there is
 * nothing below it worth reaching anyway.
 */
body.cchat-page { overflow: hidden; }

/* ── Header bar (inside the panel) ────────────────────────── */

.cchat-bar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: 0 0 auto;
    padding: 9px 16px;
    border-bottom: 1px solid var(--cc-rule);
    background: linear-gradient(180deg, #fffdfa 0%, #fff 100%);
}
.cchat-bar-text {
    display: flex;
    /* center, not baseline: this row sits beside a 30px icon box, and aligning
       a 17px title's baseline against the middle of a square leaves the name
       sitting a few pixels low — which is exactly how it looked. */
    align-items: center;
    gap: 10px;
    flex: 1 1 auto;
    min-width: 0;
}

/* text-align is set explicitly because the theme centres headings further up
   the tree, which left the title floating over the middle of the page. */
.cchat-title {
    margin: 0;
    color: #2f2f34;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.25;
    text-align: left;
    white-space: nowrap;
}
.cchat-sub {
    margin: 0;
    color: var(--cc-dim);
    font-size: 12.5px;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* A hairline between the name and the strapline, so they read as one line
   rather than two things that happen to be next to each other. */
.cchat-sub:before {
    content: '';
    display: inline-block;
    width: 1px;
    height: 11px;
    margin-right: 10px;
    vertical-align: -1px;
    background: #dcdce0;
}

.cchat-status {
    display: flex;
    align-items: center;
    gap: 7px;
    flex: 0 0 auto;
    color: var(--cc-faint);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}
.cchat-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: #c9c9ce;
    transition: background 0.25s, box-shadow 0.25s;
}
/*
 * Out of the bar entirely while it is working.
 *
 * "LIVE" in the corner of a live chat tells nobody anything — the messages
 * arriving are the indicator. What is worth a line in the bar is the moment it
 * STOPS working, so the badge only speaks up while connecting or offline.
 *
 * display, not visibility: keeping its place reserved a slot of nothing at the
 * end of the bar, which read as a hole. It appearing shifts the row slightly,
 * but that happens only when the connection actually drops — which is a moment
 * worth drawing the eye to anyway.
 */
.cchat-status.is-live { display: none; }
.cchat-status.is-live .cchat-dot {
    background: #4caf7d;
    box-shadow: 0 0 0 3px rgba(76, 175, 125, 0.16);
}
.cchat-status.is-offline .cchat-dot { background: #d9705c; }
.cchat-status.is-offline { color: #c26450; }

/*
 * How many people have the room open. Sits with the connection light because
 * both answer "is anything happening here" — deliberately a bare number, since
 * naming who is reading is nobody else's business.
 */
/*
 * Presence in the "recently active" list. Grey by default and green while the
 * person has the room open — the list is a record of who spoke lately, and
 * this says which of them is actually here to read a reply.
 */
.cchat-person-photo {
    position: relative;
    display: inline-flex;
    flex: 0 0 auto;
}
.cchat-person-dot {
    position: absolute;
    right: -1px;
    bottom: -1px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #c9c9ce;
    box-shadow: 0 0 0 2px #fff;
}
.cchat-person.is-here .cchat-person-dot {
    background: #4caf7d;
}

.cchat-watching {
    display: flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
    color: var(--cc-faint);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 1.2px;
    font-variant-numeric: tabular-nums;
}
.cchat-watching-eye {
    font-size: 11px;
    line-height: 1;
    /* The emoji carries its own colour; muted to sit with the label. */
    filter: grayscale(1);
    opacity: 0.75;
}

.cchat-rules-toggle {
    flex: 0 0 auto;
    padding: 5px 13px;
    border: 1px solid var(--cc-rule);
    border-radius: 20px;
    background: #fff;
    color: var(--cc-ink);
    font-size: 12px;
    font-weight: 600;
}
.cchat-rules-toggle[aria-expanded="true"] {
    border-color: var(--cc-accent);
    color: var(--cc-accent-dark);
}

/* ── Header: mark, online count, faces ────────────────────── */

.cchat-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: var(--cc-tint);
    color: var(--cc-accent);
    font-size: 15px;
    overflow: hidden;
}
/* A group's own picture, in the place the generic mark otherwise holds — so
   the bar does not change shape depending on whether one has been set. */
.cchat-mark img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.cchat-online {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    color: var(--cc-dim);
    font-size: 12.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.cchat-online-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #4caf7d;
    box-shadow: 0 0 0 3px rgba(76, 175, 125, 0.16);
}

/* Overlapped faces, the way a room shows who is in it. */
.cchat-faces {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
}
.cchat-face {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid #fff;
    background: var(--cc-soft);
}
.cchat-face + .cchat-face,
.cchat-face-more { margin-left: -9px; }
.cchat-face-more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 5px;
    min-width: 26px;
    background: var(--cc-soft);
    color: var(--cc-dim);
    font-size: 10.5px;
    font-weight: 700;
}
.cchat-faces:empty { display: none; }

/* ── The pinned welcome ───────────────────────────────────── */

.cchat-pinned {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    flex: 0 0 auto;
    padding: 11px 16px;
    border-bottom: 1px solid var(--cc-rule);
    background: var(--cc-tint);
    color: var(--cc-ink);
}
.cchat-pinned[hidden] { display: none !important; }
.cchat-pinned > .fa {
    flex: 0 0 auto;
    margin-top: 2px;
    color: var(--cc-accent);
    font-size: 13px;
}
.cchat-pinned p {
    flex: 1 1 auto;
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
}
.cchat-pinned strong { color: var(--cc-accent-dark); }
.cchat-pinned-x {
    flex: 0 0 auto;
    padding: 0 2px;
    border: 0;
    background: none;
    color: var(--cc-faint);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}
.cchat-pinned-x:hover { color: var(--cc-ink); }

/* An owner alone in a group they made: the pinned strip again, carrying the
   way out of that state instead of a dismiss. The button is the one thing
   here worth pressing, so it is the accent rather than another line of text. */
.cchat-alone-invite {
    flex: 0 0 auto;
    align-self: center;
    padding: 5px 10px;
    border: 1px solid var(--cc-accent);
    border-radius: 6px;
    background: var(--cc-accent);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}
.cchat-alone-invite:hover { background: var(--cc-accent-dark); border-color: var(--cc-accent-dark); }

/* ── Layout ───────────────────────────────────────────────── */

.cchat-main {
    display: flex;
    align-items: stretch;
    gap: 14px;
    flex: 1 1 auto;
    min-height: 0;
}

.cchat-col {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    /* The drop overlay is absolutely positioned against this, and the
       overflow below clips it to the panel. */
    position: relative;
    background: var(--cc-panel);
    border: 1px solid;
    border-color: var(--cc-rule) #dfe0e4 #d0d1d5;
    border-radius: 8px;
    overflow: hidden;
}

/*
 * Three columns: who is around on the left, the room in the middle, and
 * whoever was last clicked on the right.
 *
 * The right column is out of the layout until somebody is clicked, so the
 * room keeps the full width whenever nobody is being looked at — a permanently
 * reserved empty panel is a permanent tax on the thing people came for.
 */
/*
 * Column widths taken from the reference: roughly 19% / 53% / 27%. The right
 * column now matches the rooms rail opposite it, so the conversation sits
 * between two equal sides. It used to be much the wider of the two because it
 * holds pictures and a three-up grid at this width was smaller than the dreams
 * deserved — the grid is two-up now, which buys the same thumbnail back.
 *
 * The people list that used to be the left side of that pair is a dropdown off
 * the bar; see .cchat-people-drop.
 */
.cchat-side,
.cchat-who {
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* Matched to .cchat-rooms on the other side, so the conversation sits
       centred between two columns of the same width rather than wedged
       off-centre. The two are one rule because they take turns in the same
       slot — the profile panel replaces the board when a person is clicked —
       and a different width for each made the conversation jump sideways at
       the moment somebody's face was being looked at. */
    flex: 0 0 288px;
    width: 288px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: #d6d6da transparent;
}
.cchat-who[hidden] { display: none !important; }

.cchat-side::-webkit-scrollbar,
.cchat-who::-webkit-scrollbar,
.cchat-people-drop::-webkit-scrollbar { width: 8px; }
.cchat-side::-webkit-scrollbar-thumb,
.cchat-who::-webkit-scrollbar-thumb,
.cchat-people-drop::-webkit-scrollbar-thumb { background: #d6d6da; border-radius: 4px; }

.cchat-side[hidden] { display: none !important; }

/* ── The room's own panel ─────────────────────────────────── */

.cchat-about-text {
    margin: 0 0 10px;
    color: var(--cc-dim);
    font-size: 12.5px;
    line-height: 1.5;
}
.cchat-about-link {
    padding: 0;
    border: 0;
    background: none;
    color: var(--cc-accent-dark);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
}
.cchat-about-link:hover { text-decoration: underline; }

/* Pictures shared in the room lately, as a grid of squares — a thumbnail is
   enough to recognise your own work and jump back to what was said about it.

   Two across, not three: the column that holds these is 288px now, matching
   the rooms rail opposite it, and three at that width is an 85px square —
   which is the size this grid was widened away from once already. */
.cchat-shared-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px;
}
.cchat-shared-item {
    display: block;
    position: relative;
    aspect-ratio: 1;
    overflow: hidden;
    border-radius: 6px;
    background: var(--cc-soft);
}
.cchat-shared-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.18s;
}
.cchat-shared-item:hover img { transform: scale(1.06); }

/* Video and album need saying: a still frame of either looks like a picture,
   and the panel is small enough that the difference is otherwise invisible. */
.cchat-shared-mark {
    position: absolute;
    right: 5px;
    bottom: 5px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 9px;
}

/* "See all (40)" in a panel heading. The look is the feedback strip's link,
   but this one opens a dialog rather than going anywhere, so it is a button
   and needs the browser's button chrome taken off it. */
button.cchat-panel-link {
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

/* ── Everything shared here, behind "See all" ─────────────── */

/* Below the lightbox's 1060 on purpose: a thumbnail in this grid opens the
   room's one lightbox, and it has to land on top of the dialog it was opened
   from rather than behind it. */
.cchat-sm {
    position: fixed;
    inset: 0;
    z-index: 1050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.cchat-sm[hidden] { display: none !important; }
.cchat-sm-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(24, 24, 27, 0.55);
}
.cchat-sm-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 720px;
    max-height: 100%;
    background: var(--cc-panel, #fff);
    border-radius: 12px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
    overflow: hidden;
    animation: cchatSmIn 0.18s ease-out;
}
@keyframes cchatSmIn {
    from { opacity: 0; transform: translateY(8px) scale(0.98); }
    to   { opacity: 1; transform: none; }
}
.cchat-sm-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--cc-rule);
}
.cchat-sm-title {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--cc-ink);
}
.cchat-sm-x {
    border: 0;
    background: transparent;
    color: var(--cc-faint);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}
.cchat-sm-x:hover { color: var(--cc-ink); }

.cchat-sm-body {
    padding: 14px 16px 16px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* Wider than the rail's two columns: this one has the whole dialog to fill,
   and squares that size are what makes a long grid scannable. */
.cchat-sm-grid {
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 8px;
}
.cchat-sm-note {
    margin: 12px 0 0;
    color: var(--cc-dim);
    font-size: 12.5px;
    text-align: center;
}
.cchat-sm-more {
    display: block;
    width: 100%;
    margin-top: 12px;
    padding: 8px 10px;
    border: 1px solid var(--cc-rule);
    border-radius: 8px;
    background: var(--cc-panel);
    color: var(--cc-dim);
    font-size: 12.5px;
    cursor: pointer;
}
.cchat-sm-more:hover { border-color: var(--cc-accent); color: var(--cc-accent-dark); }
.cchat-sm-more[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
    .cchat-sm-panel { animation: none; }
}

/* On a phone the dialog is the screen: a centred card with a margin wastes
   the width the grid is there to use. */
@media (max-width: 767px) {
    .cchat-sm { padding: 0; }
    .cchat-sm-panel { max-width: none; height: 100%; border-radius: 0; }
    .cchat-sm-grid { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); }
}

/* ── The profile panel ────────────────────────────────────── */

.cchat-who {
    gap: 0;
    background: var(--cc-panel);
    border: 1px solid;
    border-color: var(--cc-rule) #dfe0e4 #d0d1d5;
    border-radius: 8px;
    overflow: hidden;
}

.cchat-who-bar {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    padding: 11px 14px;
    border-bottom: 1px solid var(--cc-rule);
    background: linear-gradient(180deg, #fffdfa 0%, #fff 100%);
}
.cchat-who-label {
    flex: 1 1 auto;
    color: var(--cc-faint);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}
.cchat-who-x {
    flex: 0 0 auto;
    padding: 0 3px;
    border: 0;
    background: none;
    color: var(--cc-faint);
    font-size: 19px;
    line-height: 1;
    cursor: pointer;
}
.cchat-who-x:hover { color: var(--cc-ink); }

.cchat-who-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 22px 18px 20px;
    text-align: center;
}
.cchat-who-photo {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--cc-soft);
}
.cchat-who-name {
    margin: 12px 0 2px;
    color: var(--cc-ink);
    font-size: 17px;
    font-weight: 700;
}
.cchat-who-state {
    margin: 0;
    color: var(--cc-faint);
    font-size: 12px;
}
.cchat-who-state.is-here { color: #4b9c74; }

.cchat-who-acts {
    display: flex;
    gap: 8px;
    margin-top: 18px;
    width: 100%;
}
.cchat-who-act {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    flex: 1 1 0;
    padding: 11px 6px;
    border-radius: 8px;
    background: var(--cc-soft);
    color: var(--cc-ink);
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
.cchat-who-act:hover {
    background: var(--cc-tint);
    color: var(--cc-accent-dark);
    text-decoration: none;
}
.cchat-who-act[hidden] { display: none !important; }
.cchat-who-act .fa { font-size: 15px; }

.cchat-who-dreams {
    padding: 0 18px 18px;
}
.cchat-who-dreams[hidden] { display: none !important; }
.cchat-who-dreams-title {
    margin: 0 0 9px;
    color: var(--cc-faint);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}

/* The row whose panel is open. */
.cchat-person.is-open { background: var(--cc-tint); }
.cchat-person-open { cursor: pointer; }

/* ── Stream ───────────────────────────────────────────────── */

.cchat-stream {
    flex: 1 1 auto;
    min-height: 0;
    /* Room under the newest message, so it does not sit on the composer's
       border — the way every messaging app leaves a breath above the box. */
    padding: 6px 0 24px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: #d6d6da transparent;
}
.cchat-stream::-webkit-scrollbar { width: 9px; }
.cchat-stream::-webkit-scrollbar-thumb { background: #d6d6da; border-radius: 5px; }
.cchat-stream::-webkit-scrollbar-thumb:hover { background: #c0c0c6; }

/* Same trap as .cchat-pop: `display` here beats the UA stylesheet's
   `[hidden] { display: none }`, so without this the "nothing here yet" panel
   stays on screen above the messages it is supposed to make way for. */
.cchat-empty[hidden] { display: none !important; }

.cchat-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 70px 20px;
    color: var(--cc-dim);
    font-size: 13.5px;
    text-align: center;
}
.cchat-empty-mark { font-size: 30px; opacity: 0.45; margin-bottom: 4px; }
.cchat-empty strong { color: var(--cc-ink); font-size: 15px; font-weight: 600; }

.cchat-msg {
    display: flex;
    gap: 8px;
    padding: 1px 14px;
    animation: cchat-arrive 0.26s ease-out both;
}
.cchat-msg:hover { background: #fcfcfd; }

/* Your own messages used to get a rail down the left edge of the row and a
   tint behind it. Both are gone: the bubble is on the right now and says so
   by itself, and a rail on the far side from the message it belongs to points
   at nothing. The row keeps its mirrored padding so the bubble sits the same
   distance from its own edge. */


@keyframes cchat-arrive {
    from { opacity: 0; transform: translateY(5px); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .cchat-msg { animation: none; } }

/* Consecutive messages from one person read as one block: the avatar and
   name appear only when the speaker changes. */
/* Tight within a run, a clear gap when the speaker changes — the spacing is
   what tells the two apart now that the bubbles have no outline. */
.cchat-msg + .cchat-msg:not(.is-continuation) { margin-top: 7px; }
.cchat-msg.is-continuation { padding-top: 1px; padding-bottom: 1px; }
.cchat-msg.is-continuation .cchat-avatar { visibility: hidden; height: 0; }
.cchat-msg.is-continuation .cchat-meta { display: none; }

.cchat-avatar {
    flex: 0 0 30px;
    /* A broken image draws its alt text, which spilled out of the round frame
       and over the bubble beside it. Clipped, so the worst case is an empty
       circle while the fallback swaps in. */
    overflow: hidden;
    border-radius: 50%;
    line-height: 0;
}
.cchat-avatar img {
    object-fit: cover;
    width: 30px; height: 30px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--cc-soft);
}


.cchat-name {
    color: var(--cc-accent-dark);
    font-size: 13.5px;
    font-weight: 600;
    text-decoration: none;
}
.cchat-name:hover, .cchat-name:focus { color: var(--cc-accent); text-decoration: underline; }
.cchat-time { color: var(--cc-faint); font-size: 11px; font-variant-numeric: tabular-nums; }

.cchat-text {
    color: var(--cc-ink);
    font-size: 14px;
    line-height: 1.45;
}

/* Only the words. pre-wrap on the bubble made every newline between its child
   tags a rendered blank line, which is what turned each message into a
   half-screen of nothing. */
.cchat-said {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.cchat-text a {
    color: var(--cc-accent-dark);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.cchat-text a:hover { color: var(--cc-accent); }

/* The quote line and the name are links too, but they are chrome rather than
   something in the message, so they opt out of the link treatment above. */
.cchat-text .cchat-quote,
.cchat-text .cchat-name {
    text-decoration: none;
    border-bottom: 0;
}

.cchat-inline-image {
    display: block;
    max-width: 300px;
    margin: 6px 0 2px;
    border: 1px solid var(--cc-rule);
    border-radius: 8px;
    overflow: hidden;
    text-decoration: none !important;
    background: #fafafb;
}
.cchat-inline-image img { display: block; width: 100%; height: auto; }
.cchat-inline-image:hover { border-color: var(--cc-accent); }

/* ── Unfurled dream card ──────────────────────────────────── */

.cchat-dream {
    display: flex;
    gap: 12px;
    max-width: 400px;
    margin: 7px 0 3px;
    padding: 8px;
    border: 1px solid var(--cc-rule);
    border-left: 3px solid var(--cc-accent);
    border-radius: 8px;
    background: var(--cc-tint);
    text-decoration: none !important;
    transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}
.cchat-dream:hover {
    border-color: #e6d0aa;
    border-left-color: var(--cc-accent);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.07);
    transform: translateY(-1px);
}

.cchat-dream-thumb {
    position: relative;
    flex: 0 0 92px;
    width: 92px;
    height: 92px;
    border-radius: 6px;
    overflow: hidden;
    background: #ece9e4;
}
.cchat-dream-thumb img,
.cchat-dream-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }

.cchat-dream-play {
    position: absolute;
    top: 50%; left: 50%;
    width: 32px; height: 32px;
    margin: -16px 0 0 -16px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
}
.cchat-dream-play:after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    margin: -6px 0 0 -3px;
    border-style: solid;
    border-width: 6px 0 6px 10px;
    border-color: transparent transparent transparent #fff;
}

.cchat-dream-stack {
    position: absolute;
    right: 5px; bottom: 5px;
    width: 18px; height: 18px;
    border: 2px solid #fff;
    border-radius: 3px;
    background: rgba(0, 0, 0, 0.35);
    box-shadow: -4px -4px 0 -2px rgba(255, 255, 255, 0.75);
}

.cchat-dream-info {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-width: 0;
    padding-right: 4px;
}
.cchat-dream-kind {
    color: var(--cc-accent-dark);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 1.1px;
    text-transform: uppercase;
}
.cchat-dream-title {
    color: #2f2f34;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.cchat-dream-author { color: var(--cc-dim); font-size: 12px; }

.cchat-msg.is-pending { opacity: 0.5; }
.cchat-msg.is-pending .cchat-text:after {
    content: ' · sending…';
    color: var(--cc-dim);
    font-size: 12px;
}

.cchat-msg.is-removed { animation: cchat-leave 0.3s ease-in forwards; }
@keyframes cchat-leave {
    to { opacity: 0; transform: translateX(-12px); }
}

/* ── Composer ─────────────────────────────────────────────── */

.cchat-composer {
    flex: 0 0 auto;
    padding: 9px 12px 11px;
    border-top: 1px solid var(--cc-rule);
    background: #fbfbfc;
}

/* One field holds the textarea and its controls, so focus lights the whole
   thing up instead of drawing a box inside a box. */
.cchat-field {
    border: 1px solid #d8d8dd;
    border-radius: 10px;
    background: #fff;
    transition: border-color 0.15s, box-shadow 0.15s;
}
/* The mention picker anchors to this. */
.cchat-field { position: relative; }

.cchat-field:focus-within {
    border-color: var(--cc-accent);
    box-shadow: 0 0 0 3px rgba(235, 161, 51, 0.14);
}

.cchat-input {
    display: block;
    width: 100%;
    /* It grows by itself to about five lines (community-chat.js); taller only
       by dragging the field's top edge (feedback #207), never past half the
       window. */
    max-height: 50vh;
    padding: 11px 14px 4px;
    border: 0;
    background: transparent;
    color: var(--cc-ink);
    font-size: 14.5px;
    line-height: 1.55;
    resize: none;

    /* The writing box never shows a scrollbar. It grows with the text, and
       past its max height it still scrolls — the bar itself is just hidden,
       because a track inside a one-line input looks broken. */
    overflow-y: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.cchat-input::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* The writing box's top edge, which drags it taller (feedback #207): a short
   bar on the border, where a grip is looked for on a box docked at the bottom. */
.cchat-input-grip {
    position: absolute;
    top: -8px;
    left: 50%;
    z-index: 2;
    width: 56px;
    height: 16px;
    margin-left: -28px;
    cursor: ns-resize;
    touch-action: none;
}
.cchat-input-grip::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 12px;
    right: 12px;
    height: 4px;
    border-radius: 2px;
    background: #d6d6da;
    transition: background 0.15s;
}
.cchat-input-grip:hover::before,
.cchat-field.is-resizing .cchat-input-grip::before { background: var(--cc-accent); }
.cchat-field.is-resizing { user-select: none; }

/* Dragged taller, it is a box you read back through: the bar is worth seeing. */
.cchat-input.is-sized,
.cchat-edit-input.is-sized { scrollbar-width: thin; scrollbar-color: #d6d6da transparent; }
.cchat-input.is-sized::-webkit-scrollbar,
.cchat-edit-input.is-sized::-webkit-scrollbar { display: block; width: 8px; }
.cchat-input.is-sized::-webkit-scrollbar-thumb,
.cchat-edit-input.is-sized::-webkit-scrollbar-thumb { background: #d6d6da; border-radius: 4px; }
.cchat-input:focus { outline: none; }
.cchat-input::placeholder { color: #b4b4ba; }

.cchat-field-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 2px 8px 6px 10px;
}
/* The composer's tools: image, emoji, and the fix-and-translate wand. One rule
   for all three — they were three near-identical blocks that had already
   drifted apart in size and hover behaviour. */
.cchat-field-tools { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }

.cchat-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--cc-faint);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.cchat-tool:hover:not(:disabled) { background: var(--cc-soft); color: var(--cc-accent-dark); }
.cchat-tool:disabled { opacity: 0.4; cursor: default; }
.cchat-tool.is-assist:hover:not(:disabled) { background: var(--cc-tint); color: var(--cc-accent); }
.cchat-tool.is-working { color: var(--cc-accent); }
.cchat-tool.is-working .fa { animation: cchat-spin 0.9s linear infinite; }

/* The real file input can never be seen: a class rule that sets `display`
   beats the UA stylesheet's [hidden], the same trap the popups hit. */
#cchat-image { display: none !important; }

.cchat-field-hint {
    color: var(--cc-faint);
    font-size: 11.5px;
    line-height: 1.4;
    min-width: 0;
}
.cchat-field-hint strong { color: var(--cc-dim); font-weight: 600; }

.cchat-field-right { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.cchat-count { color: var(--cc-faint); font-size: 11px; font-variant-numeric: tabular-nums; }
.cchat-count.is-low { color: #d9705c; }

.cchat-send {
    padding: 7px 20px;
    border: 0;
    border-radius: 7px;
    background: var(--cc-accent);
    color: #fff;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, opacity 0.15s;
}
.cchat-send:hover:not(:disabled) { background: #d99327; }
.cchat-send:disabled { opacity: 0.5; cursor: default; }

.cchat-error {
    flex: 0 0 auto;
    margin: 0;
    padding: 10px 20px;
    border-top: 1px solid #f0d5cf;
    background: #fdf1ef;
    color: #b4503a;
    font-size: 13.5px;
}

/* ── Locked / muted states ────────────────────────────────── */

.cchat-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex: 0 0 auto;
    padding: 16px 20px;
    border-top: 1px solid var(--cc-rule);
    background: #fbfbfc;
    color: var(--cc-dim);
    font-size: 13.5px;
}
.cchat-notice strong { display: block; color: #2f2f34; font-size: 14.5px; margin-bottom: 2px; }
.cchat-notice.is-muted { background: #fdf1ef; border-top-color: #f0d5cf; color: #b4503a; }
.cchat-notice.is-muted strong { color: #93412f; }

.cchat-cta {
    flex: 0 0 auto;
    padding: 9px 20px;
    border-radius: 8px;
    background: var(--cc-accent);
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.cchat-cta:hover, .cchat-cta:focus { background: #d99327; color: #fff; text-decoration: none; }

/* ── Side panel: recently active ──────────────────────────── */

.cchat-panel {
    padding: 11px 13px;
    background: var(--cc-panel);
    border: 1px solid;
    border-color: var(--cc-rule) #dfe0e4 #d0d1d5;
    border-radius: 8px;
}
.cchat-panel-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin: 0 0 7px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--cc-soft);
    color: #2f2f34;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 1.3px;
    text-transform: uppercase;
    text-align: left;
}
.cchat-people-count {
    padding: 1px 7px;
    border-radius: 10px;
    background: var(--cc-soft);
    color: var(--cc-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0;
}

.cchat-people { margin: 0; padding: 0; list-style: none; }
.cchat-person a {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 5px 6px;
    border-radius: 6px;
    color: var(--cc-ink);
    font-size: 13px;
    text-decoration: none;
}
.cchat-person a:hover { background: #faf6ef; color: var(--cc-accent-dark); text-decoration: none; }
.cchat-person img {
    width: 26px; height: 26px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--cc-soft);
}
.cchat-person-name {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
/* Newly active names slide in at the top rather than blinking into place. */
.cchat-person.is-new { animation: cchat-arrive 0.3s ease-out both; }
.cchat-people-empty { padding: 6px; color: var(--cc-dim); font-size: 12.5px; }

/* ── Reactions ────────────────────────────────────────────── */

.cchat-reactions {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 3px;
}
.cchat-reactions:empty { display: none; }

.cchat-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px 3px 8px;
    border: 1px solid var(--cc-rule);
    border-radius: 14px;
    background: #fff;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.03);
    font-size: 12.5px;
    line-height: 19px;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s;
}
.cchat-chip:hover:not(:disabled) { border-color: #d8c49c; background: var(--cc-tint); }
.cchat-chip:disabled { cursor: default; }
.cchat-chip.is-mine {
    border-color: var(--cc-accent);
    background: var(--cc-tint);
}
.cchat-chip-emoji { font-size: 14px; line-height: 1; }

/* The standing add button. Quieter than a tally — it is an invitation, not a
   count, and should not read as a reaction nobody has made yet. */
.cchat-chip-add {
    padding: 3px 9px;
    color: var(--cc-faint);
    font-size: 13px;
}
.cchat-chip-add:hover { color: var(--cc-accent-dark); }
.cchat-chip-count { color: var(--cc-dim); font-variant-numeric: tabular-nums; }
.cchat-chip.is-mine .cchat-chip-count { color: var(--cc-accent-dark); font-weight: 600; }

/* The hover toolbar: react, then edit, then delete, left to right.
   It shares a line with the text rather than floating over the message. A
   floating pill sat on top of the words — these rows are barely taller than
   the buttons, so there is no "under the message" to put it in. Its width is
   reserved while hidden, so revealing it moves nothing. */
/* .cchat-line and .cchat-body are defined once, with the two-sided layout. */
.cchat-line > .cchat-text { min-width: 0; flex: 0 1 auto; }

.cchat-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
    /* visibility, not display: the space stays reserved either way. */
    visibility: hidden;
}
.cchat-msg:hover .cchat-actions,
.cchat-actions:focus-within,
.cchat-actions.is-open { visibility: visible; }

/* Font Awesome throughout, like the rest of the site. One font means one set
   of metrics, so the three sit at the same size and on the same baseline
   without per-icon nudging — the previous mix of text glyphs and a colour
   emoji could be made neither to match in weight nor to line up. */
.cchat-act {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 30px, which is a comfortable target rather than a decoration — at 24 the
       glyph was small enough to be hard to tell apart at a glance, and the hit
       area was under what a finger expects. */
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--cc-faint);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.cchat-act .fa {
    /* Cancels Font Awesome's own inline-block line-height so the glyph
       centres on the button rather than sitting a pixel high. */
    line-height: 1;
    vertical-align: middle;
}
.cchat-act:hover { background: var(--cc-soft); color: var(--cc-ink); }
.cchat-act.is-delete:hover { background: #fdf1ef; color: #b4503a; }

.cchat-react-btn:hover { background: var(--cc-tint); color: var(--cc-accent-dark); }
.cchat-react-btn.is-active { background: var(--cc-tint); color: var(--cc-accent-dark); }

/* The "(edited)" marker after a changed message. */
.cchat-edited {
    margin-left: 6px;
    color: var(--cc-faint);
    font-size: 11px;
}

/* Inline edit box, replacing the text while it is open. It is a flex item of
   .cchat-line now, so it has to claim the whole width or it shrinks to its
   content; the hover toolbar steps aside while it is open. */
.cchat-edit-form { flex: 1 1 100%; min-width: 0; margin: 2px 0 4px; }
.cchat-msg.is-editing .cchat-actions { display: none; }
.cchat-edit-input {
    width: 100%;
    max-height: 50vh;
    padding: 7px 10px;
    border: 1px solid var(--cc-accent);
    border-radius: 8px;
    background: #fff;
    color: var(--cc-ink);
    font-size: 14.5px;
    line-height: 1.55;
    resize: vertical;
    overflow-y: auto;
    scrollbar-width: none;
}
.cchat-edit-input::-webkit-scrollbar { width: 0; display: none; }
.cchat-edit-input:focus { outline: none; box-shadow: 0 0 0 3px rgba(235, 161, 51, 0.14); }
.cchat-edit-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 5px;
    color: var(--cc-faint);
    font-size: 11.5px;
}
.cchat-edit-save {
    padding: 4px 12px;
    border: 0;
    border-radius: 6px;
    background: var(--cc-accent);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.cchat-edit-save:hover { background: #d99327; }
.cchat-edit-save:disabled { opacity: .5; cursor: default; }
.cchat-edit-cancel {
    padding: 4px 8px;
    border: 0;
    background: none;
    color: var(--cc-dim);
    font-size: 12px;
    cursor: pointer;
}
.cchat-edit-cancel:hover { color: var(--cc-ink); }

/* The composer's "fix it" button. */
@keyframes cchat-pulse { 50% { opacity: 0.25; } }

/* A tall message should not put the button halfway down its side; keep it on
   the first line, where the name and time are. */
.cchat-msg { align-items: flex-start; }
.cchat-msg:hover .cchat-react-btn,
.cchat-react-btn:focus,
.cchat-react-btn.is-active { opacity: 1; }
.cchat-react-btn.is-active {
    border-color: var(--cc-accent);
    color: var(--cc-accent-dark);
}
.cchat-react-btn:hover { color: var(--cc-accent-dark); border-color: var(--cc-accent); }

/* ── Popups (reaction palette, emoji picker) ──────────────── */

.cchat-pop {
    /* Fixed, not absolute. The palette is anchored to a rect measured from the
       viewport, and the stream it points into is its own scroll container
       inside a full-height layout — with `absolute` the numbers only line up
       if nothing in the ancestor chain happens to be positioned, which is not
       a thing worth depending on. */
    position: fixed;
    z-index: 1040;
    padding: 8px;
    border: 1px solid var(--cc-rule);
    border-radius: 10px;
    background: #fff;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.14);
}
/* The `hidden` attribute is only `display: none` from the UA stylesheet, so
   any class here that sets `display` beats it and the popup shows itself on
   load. This has to win. */
.cchat-pop[hidden] { display: none !important; }

/* Wraps rather than running off the side: the palette grows whenever a
   reaction is added, and it can never shrink again — removing one would
   strand every reaction already made with it. Capped so it breaks to a
   second row instead of overflowing a phone. */
.cchat-pop--reactions {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    max-width: 232px;
}
/*
 * overflow-x is stated, not left to default.
 *
 * With one axis `auto` and the other `visible`, CSS promotes the visible one
 * to `auto` as well — so this scrolled sideways too, and showed a bar for it,
 * the moment the grid inside was a pixel over. Nothing here is ever meant to
 * be reached by scrolling sideways.
 *
 * scrollbar-gutter keeps the emoji from reflowing by a few pixels when the
 * vertical bar appears on hover in the browsers that overlay it.
 */
.cchat-pop--emoji {
    width: 268px;
    max-height: 260px;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
}

.cchat-pop-group + .cchat-pop-group { margin-top: 8px; }
.cchat-pop-label {
    margin-bottom: 3px;
    color: var(--cc-faint);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1.1px;
    text-transform: uppercase;
}
/*
 * minmax(0, 1fr), not 1fr.
 *
 * `1fr` is `minmax(auto, 1fr)`, so a track will not shrink below its content's
 * min-content width — and an emoji glyph plus its padding is wider than an
 * eighth of this box in some fonts. The tracks refused to fit, the grid ran
 * over the edge, and the popup grew a horizontal scrollbar. With a zero
 * minimum the columns share what there is.
 */
.cchat-pop-grid {
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    gap: 1px;
}

.cchat-pop-emoji {
    /* Lets the track above actually be narrower than the glyph's own idea of
       how much room it needs. */
    min-width: 0;
    padding: 4px 2px;
    border: 0;
    border-radius: 6px;
    background: none;
    font-size: 18px;
    line-height: 1.3;
    cursor: pointer;
    transition: background 0.1s, transform 0.1s;
}
.cchat-pop-emoji:hover { background: var(--cc-tint); transform: scale(1.15); }


/* ── Rules modal ──────────────────────────────────────────── */

/* `width: 100%` here meant the viewport width, which Bootstrap's own 10px
   dialog margin then pushed past both edges on a phone. Letting the block size
   itself inside its margins is what keeps it on screen at any width. */
.cchat-modal-dialog {
    width: auto;
    max-width: 780px;
    margin: 24px auto;
}

.cchat-modal-content {
    position: relative;
    display: flex;
    flex-direction: column;
    /* The rules are long. Without a ceiling the dialog grows past the viewport
       and the page scrolls instead of the dialog, which puts the end of the
       list — and the close button — somewhere you cannot reach. */
    max-height: calc(100vh - 48px);
    border: 0;
    border-radius: 10px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
}
.cchat-modal-close {
    position: absolute;
    top: 8px; right: 12px;
    z-index: 3;
    padding: 0;
    border: 0;
    background: none;
    color: #b0b0b6;
    font-size: 26px;
    line-height: 1;
}
.cchat-modal-close:hover { color: var(--cc-accent-dark); }

/* The body is what scrolls, so the close button stays put at the top. */
.cchat-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 24px 26px;
}
.cchat-modal-title {
    margin: 0 0 6px;
    color: #2f2f34;
    font-size: 19px;
    font-weight: 700;
    text-align: left;
}
.cchat-modal-lede {
    margin: 0 0 18px;
    color: var(--cc-dim);
    font-size: 13px;
    line-height: 1.6;
}
.cchat-modal-lede a { color: var(--cc-accent-dark); text-decoration: underline; }

.cchat-modal-cols { display: flex; gap: 26px; align-items: flex-start; }
.cchat-modal-section { flex: 1 1 0; min-width: 0; }
.cchat-modal-section h4 {
    margin: 0 0 8px;
    color: #2f2f34;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    text-align: left;
}
.cchat-modal-section p { margin: 0; color: var(--cc-dim); font-size: 12.5px; line-height: 1.6; }
.cchat-modal-section p strong { color: var(--cc-ink); font-weight: 600; }
.cchat-modal-section a { color: var(--cc-accent-dark); text-decoration: underline; }

.cchat-modal-foot {
    display: flex;
    gap: 26px;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--cc-soft);
}

.cchat-rules { margin: 0; padding: 0; list-style: none; }
.cchat-rules li {
    display: flex;
    gap: 8px;
    padding: 6px 0;
    color: var(--cc-dim);
    font-size: 12.5px;
    line-height: 1.5;
}
.cchat-rules li + li { border-top: 1px solid var(--cc-soft); }
.cchat-rules strong { color: var(--cc-ink); font-weight: 600; }
.cchat-rules em { font-style: normal; color: var(--cc-accent-dark); }

.cchat-rule-mark {
    flex: 0 0 16px;
    width: 16px; height: 16px;
    margin-top: 1px;
    border-radius: 50%;
    font-size: 9px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
}
.cchat-rule-mark.is-yes { background: #e4f3ea; color: #3f8b62; }
.cchat-rule-mark.is-no  { background: #fbe6e1; color: #b4503a; }

/* ── Narrow screens ───────────────────────────────────────── */

@media (max-width: 1280px) {
    /* One side column, not two. The room is what people came for. */
    .cchat-side,
    .cchat-who  { flex-basis: 240px; width: 240px; }
}

@media (max-width: 991px) {
    /* No room for either column; the room takes the whole width. The profile
       panel is left reachable, because the only way to open it is a
       deliberate tap and it should not silently do nothing. */
    .cchat-side { display: none; }

    .cchat-who {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        z-index: 1050;
        width: min(320px, 88vw);
        flex-basis: auto;
        border-radius: 0;
        box-shadow: -8px 0 28px rgba(0, 0, 0, 0.16);
    }
}

@media (max-width: 767px) {
    /* Two columns of rules do not fit a phone; they stack. */
    .cchat-modal-cols, .cchat-modal-foot { flex-direction: column; gap: 18px; }

    .cchat-modal-dialog { margin: 10px; }
    .cchat-modal-content { max-height: calc(100vh - 20px); }
    .cchat-modal-body { padding: 20px 16px; }
    .cchat-modal-title { font-size: 17px; padding-right: 28px; }

    .cchat-pop--emoji { width: min(240px, calc(100vw - 32px)); }
    /* Seven across at this width rather than eight squeezed: the glyphs stay
       the size of something you can hit with a thumb. */
    .cchat-pop-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
    .cchat-pop--reactions { flex-wrap: wrap; max-width: calc(100vw - 32px); }
}

@media (max-width: 767px) {
    .cchat {
        margin-top: 8px;
        /* Right to the edges on a phone: 22px a side is most of the screen. */
        margin-left: calc(50% - 50vw + 6px);
        margin-right: calc(50% - 50vw + 6px);
        /* No height override here. There used to be a calc(100vh - 120px),
           which fought the measured --cc-top and, because 100vh on a phone
           includes the space the address bar occupies, made the room taller
           than the screen — the composer ended up below the fold on a page
           that cannot scroll. */
    }

    /* A bubble may use the width it has; the measure cap exists to stop long
       lines on a wide screen, and there are none here. */
    .cchat-text { max-width: 100%; }

    /*
     * The header ran out of room and its parts sat on top of each other. The
     * count and the faces go: on a phone the title, a way into the rules and
     * the connection light are what the bar is for.
     */
    .cchat-bar { padding: 9px 12px; gap: 9px; }
    .cchat-sub, .cchat-faces, .cchat-online, .cchat-badge { display: none; }
    /* Keep the connection light: on a phone it is the only thing in the bar
       that can tell you why nothing is arriving. */
    .cchat-status { font-size: 9px; letter-spacing: 0.8px; }
    .cchat-title { font-size: 15px; }
    .cchat-bar-text { min-width: 0; }
    .cchat-title, .cchat-sub {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .cchat-rules-toggle { padding: 4px 10px; font-size: 11.5px; }
    .cchat-status { font-size: 9px; letter-spacing: 0.8px; }

    /* Symmetric again: this dated from before the two sides, and left every
       message shoved right. */
    .cchat-msg { padding-left: 10px; padding-right: 10px; }
    .cchat-avatar { flex-basis: 26px; }
    .cchat-avatar img { width: 26px; height: 26px; }

    .cchat-pinned { padding: 9px 12px; font-size: 12.5px; }
    .cchat-composer { padding: 8px 10px 10px; }
    .cchat-field-hint { display: none; }
    .cchat-field-bar { padding: 2px 6px 5px 6px; }
    .cchat-dream { max-width: 100%; }
    .cchat-notice { flex-direction: column; align-items: stretch; text-align: center; }

    /* The overlays need the whole screen at this size. */
    .cchat-context { padding: 12px; }
    .cchat-context-card { max-height: 80vh; }
}

/* ── Bubbles ──────────────────────────────────────────────── */

/*
 * Laid out the way a chat client lays out: what other people said on the left,
 * what you said on the right, each in a bubble with the name inside it and the
 * time at its foot.
 *
 * Sides rather than one column, because with the room full width a single
 * left-hand column left most of the screen empty and gave no quick answer to
 * "which of these are mine".
 */
.cchat-msg.is-mine { flex-direction: row-reverse; }

/*
 * The conversation fills its column rather than sitting in a centred block
 * inside it.
 *
 * Capping the rows and centring them left a gutter down both sides, so the
 * bubbles floated in the middle with the panel's edges nowhere near them —
 * which is what made the room read as wide and empty however much was said.
 * The column itself is now the right width, so the rows can simply use it.
 */
.cchat-msg { width: 100%; }

/* The column holding the bubble. align-items decides which edge it hangs
   from; without this the bubble stretches the whole row and the sides stop
   meaning anything. */
.cchat-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    flex: 1 1 auto;
    min-width: 0;
}
.cchat-msg.is-mine .cchat-body { align-items: flex-end; }

/* The bubble and its hover toolbar. The toolbar sits outside the bubble, on
   the side the bubble hangs from, so it never covers the words. */
.cchat-line {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    max-width: 100%;
}
.cchat-msg.is-mine .cchat-line { flex-direction: row-reverse; }

/* Name and time above the bubble, on both sides. */
/*
 * The name line has a fixed height because the avatar is offset by exactly
 * this much to sit level with the bubble rather than with the name. The two
 * numbers below have to stay in step: 18 + 4 = 22.
 */
.cchat-meta {
    display: flex;
    align-items: baseline;
    gap: 6px;
    height: 18px;
    /* Stated, so the 13px name and the 11.5px time both sit inside the fixed
       height rather than relying on whatever the default line box works out
       to — a descender clipped by a pixel is the kind of thing that only
       shows up on someone else's font stack. */
    line-height: 18px;
    margin: 0 0 4px 3px;
}
.cchat-msg.is-mine .cchat-meta { flex-direction: row-reverse; margin: 0 3px 4px 0; }
.cchat-msg.is-continuation .cchat-meta { display: none; }

/*
 * The avatar lines up with the top of the bubble, not the top of the row.
 *
 * The row starts with the name line, so a top-aligned avatar sat beside the
 * name — raised above the bubble it belongs to, and reading as detached from
 * it. Pushed down by the height of that line it sits level with the first
 * line of what was said, which is where every chat app puts it.
 *
 * Only where there is a name line to clear: a continuation has none, and its
 * avatar is hidden anyway.
 */
.cchat-msg:not(.is-continuation) .cchat-avatar { margin-top: 22px; }

.cchat-name {
    color: var(--cc-ink);
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
}
.cchat-name:hover { color: var(--cc-accent-dark); text-decoration: none; }

.cchat-time {
    color: var(--cc-faint);
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ── The bubble ───────────────────────────────────────────── */

.cchat-text {
    display: inline-block;
    max-width: min(62ch, 100%);
    padding: 6px 12px;
    /* No border and a full pill. The border was separating one message from
       the next, which the fill and the spacing now do on their own — and an
       outline around every line makes a long room look like a form. */
    border: 0;
    border-radius: 18px;
    background: #f0f0f2;
    word-break: break-word;
}

/*
 * Your own, in a soft amber fill with the ink left dark.
 *
 * A solid #9c6209 with white text was readable but heavy — a screen of your
 * own messages became a wall of dark blocks. The tint reads as clearly yours
 * against the grey without shouting, and keeps the same ink as everything
 * else so a long message is no harder to read on one side than the other.
 */
.cchat-msg.is-mine .cchat-text {
    background: #fdf1dc;
    color: var(--cc-ink);
}

/* A run from one person is one stack: the corner facing the previous bubble
   squares off so they read as a group rather than separate cards. */
.cchat-msg.is-continuation .cchat-text { border-top-left-radius: 6px; }
.cchat-msg.is-mine.is-continuation .cchat-text {
    border-top-left-radius: 18px;
    border-top-right-radius: 6px;
}

/* An image brings its own frame, so a picture-only message gets the bubble
   out of the way. The image sits inside .cchat-said, which is why this reaches
   through it rather than looking for a direct child. */
.cchat-text:has(.cchat-said > .cchat-inline-image:only-child) {
    padding: 3px;
    background: transparent;
}
.cchat-inline-image { max-width: min(340px, 100%); }

/* ── The quoted message above a reply ─────────────────────── */

.cchat-quote {
    display: flex;
    gap: 7px;
    align-items: flex-start;
    margin: -1px 0 6px;
    padding: 5px 9px;
    border-left: 3px solid var(--cc-accent);
    border-radius: 3px;
    background: rgba(0, 0, 0, 0.028);
    color: var(--cc-dim);
    font-size: 12.5px;
    line-height: 1.35;
    text-decoration: none;
    cursor: pointer;
}
.cchat-quote:hover { background: rgba(0, 0, 0, 0.05); text-decoration: none; }
.cchat-quote-name {
    flex: 0 0 auto;
    color: var(--cc-accent-dark);
    font-weight: 700;
}
.cchat-quote-text {
    flex: 1 1 auto;
    min-width: 0;
    /* Two lines rather than one. A single clipped line often stopped before
       the part being answered, which made the reply read as an answer to
       nothing. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.cchat-quote-text.is-gone { font-style: italic; opacity: 0.7; }

/* The quote sits on the amber fill rather than the grey one, so it needs a
   little more contrast to stay separate from the bubble around it. */
.cchat-msg.is-mine .cchat-quote {
    background: rgba(0, 0, 0, 0.05);
}
.cchat-msg.is-mine .cchat-quote:hover { background: rgba(0, 0, 0, 0.08); }

/* Where a quote link lands, so the reader can see what they jumped to. */
.cchat-msg.is-flash {
    animation: cchat-flash 1.2s ease-out;
}
@keyframes cchat-flash {
    0%, 30% { background: rgba(235, 161, 51, 0.16); }
    100%    { background: transparent; }
}

/* ── Replying, in the composer ────────────────────────────── */

.cchat-replying {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0 0 7px;
    padding: 6px 10px;
    border-left: 3px solid var(--cc-accent);
    border-radius: 3px;
    background: var(--cc-tint);
    color: var(--cc-dim);
    font-size: 12.5px;
}
.cchat-replying[hidden] { display: none !important; }
.cchat-replying-to {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cchat-replying-to strong { color: var(--cc-accent-dark); }
.cchat-replying-x {
    flex: 0 0 auto;
    padding: 0 2px;
    border: 0;
    background: none;
    color: var(--cc-faint);
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
}
.cchat-replying-x:hover { color: var(--cc-ink); }

/* ── Lightbox loading ─────────────────────────────────────── */

/*
 * The full image arrives after the box opens, so the box does not wait for it
 * empty. The thumbnail — already decoded, since it is what was clicked — sits
 * behind it blurred at the right shape, and the real picture fades over the
 * top. Nothing resizes on arrival.
 */
.cchat-lightbox-frame {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: min(92vw, 1200px);
    max-height: 78vh;
    border-radius: 10px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.04);
}

.cchat-lightbox-blur {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: blur(18px);
    transform: scale(1.12);      /* hides the blur's soft edges */
    opacity: 0.75;
    transition: opacity 0.35s ease-out;
}
.cchat-lightbox-frame.is-ready .cchat-lightbox-blur { opacity: 0; }

.cchat-lightbox-full {
    position: relative;
    display: block;
    max-width: min(92vw, 1200px);
    max-height: 78vh;
    width: auto;
    height: auto;
    border-radius: 10px;
    opacity: 0;
    transition: opacity 0.35s ease-out;
}
.cchat-lightbox-frame.is-ready .cchat-lightbox-full { opacity: 1; }

/* While the frame is standing in for the picture it needs a size of its own;
   once the real one is in, it sets the size and this must not fight it. */
.cchat-lightbox-frame.is-loading { width: min(92vw, 1200px); }
.cchat-lightbox-frame.is-loading .cchat-lightbox-full { position: absolute; inset: 0; }

.cchat-lightbox-spin {
    position: absolute;
    width: 30px;
    height: 30px;
    border: 2px solid rgba(255, 255, 255, 0.28);
    border-top-color: #fff;
    border-radius: 50%;
    animation: cchat-spin 0.75s linear infinite;
    transition: opacity 0.2s;
}
.cchat-lightbox-frame.is-ready .cchat-lightbox-spin,
.cchat-lightbox-frame.is-failed .cchat-lightbox-spin { opacity: 0; }

/* A dream whose file has gone should not leave a spinner turning forever. */
.cchat-lightbox-frame.is-failed::after {
    content: 'That image could not be loaded.';
    position: absolute;
    color: rgba(255, 255, 255, 0.8);
    font-size: 13px;
}

@media (prefers-reduced-motion: reduce) {
    .cchat-lightbox-blur,
    .cchat-lightbox-full { transition: none; }
    .cchat-lightbox-spin { animation: none; }
}

/* ── Dropping a picture on the room ───────────────────────── */

.cchat-drop[hidden] { display: none !important; }

.cchat-drop {
    position: absolute;
    inset: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 253, 250, 0.88);
    backdrop-filter: blur(1px);
    /* The overlay must not eat the very drag it is announcing: pointer events
       go to the room underneath, which is what carries the handlers. */
    pointer-events: none;
    animation: cchat-fade 0.12s ease-out;
}

.cchat-drop-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 26px 40px;
    border: 2px dashed var(--cc-accent);
    border-radius: 14px;
    background: #fff;
    color: var(--cc-ink);
    box-shadow: 0 12px 34px rgba(0, 0, 0, 0.12);
}
.cchat-drop-card .fa { color: var(--cc-accent); font-size: 26px; }
.cchat-drop-card strong { font-size: 15px; }
.cchat-drop-card span { color: var(--cc-faint); font-size: 12.5px; }

/* ── Attached pictures ────────────────────────────────────── */

/*
 * Thumbnails above the box, the way every messaging app does it. The URL only
 * joins the message when it is sent — watching a long storage URL appear in
 * the middle of your sentence is not what attaching a picture should feel
 * like, and it is what this replaced.
 */
.cchat-attached {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    margin: 0 0 8px;
}
.cchat-attached[hidden] { display: none !important; }

.cchat-attach {
    position: relative;
    width: 58px;
    height: 58px;
    border-radius: 9px;
    overflow: hidden;
    background: var(--cc-soft);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
.cchat-attach img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.cchat-attach-x {
    position: absolute;
    top: 3px;
    right: 3px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.12s;
}
.cchat-attach-x:hover { background: rgba(0, 0, 0, 0.85); }

/* ── Mentions ─────────────────────────────────────────────── */

.cchat-mention-tag {
    padding: 1px 4px;
    margin: 0 -1px;
    border-radius: 4px;
    background: rgba(235, 161, 51, 0.16);
    color: var(--cc-accent-dark);
    font-weight: 600;
}
/* On the amber bubble the tint would disappear into the fill. */
.cchat-msg.is-mine .cchat-mention-tag {
    background: rgba(0, 0, 0, 0.07);
    color: #8a5a0c;
}

/* The picker. Above the field rather than below it: the composer sits at the
   bottom of the room, so a list under it would open off the screen. */
.cchat-mentions {
    position: absolute;
    left: 10px;
    right: 10px;
    bottom: calc(100% + 6px);
    z-index: 30;
    max-height: 232px;
    overflow-y: auto;
    padding: 5px;
    border: 1px solid var(--cc-rule);
    border-radius: 10px;
    background: #fff;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.14);
}
.cchat-mentions[hidden] { display: none !important; }

.cchat-mention {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 6px 8px;
    border: 0;
    border-radius: 7px;
    background: none;
    color: var(--cc-ink);
    font-size: 13.5px;
    text-align: left;
    cursor: pointer;
}
.cchat-mention img { border-radius: 50%; object-fit: cover; background: var(--cc-soft); }
.cchat-mention:hover,
.cchat-mention.is-on { background: var(--cc-tint); color: var(--cc-accent-dark); }

/* ── Posting an image ─────────────────────────────────────── */

/* The real file input can never be seen: a class rule that sets `display`
   beats the UA stylesheet's [hidden], the same trap the popups hit. */
#cchat-image { display: none !important; }

@keyframes cchat-spin { to { transform: rotate(360deg); } }

/* ── Press and hold, on a touch screen ────────────────────── */

/*
 * The toolbar is a hover affordance and a phone has no hover, so the buttons
 * were present but unreachable. A long press opens them, which is the gesture
 * every messaging app already teaches.
 */
.cchat-msg.is-menu .cchat-actions {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
.cchat-msg.is-menu .cchat-text {
    box-shadow: 0 0 0 2px rgba(235, 161, 51, 0.35);
}

/* ── Reviewing a report before filing it ──────────────────── */

.cchat-report[hidden] { display: none !important; }

.cchat-report {
    position: fixed;
    inset: 0;
    z-index: 1070;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(20, 18, 15, 0.5);
    backdrop-filter: blur(2px);
    animation: cchat-fade 0.16s ease-out;
}

.cchat-report-card {
    width: min(560px, 100%);
    max-height: min(84vh, 720px);
    display: flex;
    flex-direction: column;
    border-radius: 14px;
    background: #fff;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
    overflow: hidden;
    animation: cchat-rise 0.18s ease-out;
}

.cchat-report-bar {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    padding: 12px 16px;
    border-bottom: 1px solid var(--cc-rule);
    background: var(--cc-tint);
}
.cchat-report-label {
    flex: 1 1 auto;
    color: var(--cc-accent-dark);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}
.cchat-report-x {
    flex: 0 0 auto;
    padding: 0 3px;
    border: 0;
    background: none;
    color: var(--cc-faint);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
.cchat-report-x:hover { color: var(--cc-ink); }

.cchat-report-body {
    flex: 1 1 auto;
    padding: 16px;
    overflow-y: auto;
}
.cchat-report-note {
    margin: 0 0 12px;
    color: var(--cc-dim);
    font-size: 12.5px;
    line-height: 1.5;
}

.cchat-report-kind { display: flex; gap: 8px; margin-bottom: 12px; }
.cchat-report-kind label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border: 1px solid var(--cc-rule);
    border-radius: 20px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    margin: 0;
}
.cchat-report-kind input { margin: 0; }

.cchat-report-field { display: block; margin-bottom: 12px; }
.cchat-report-field > span {
    display: block;
    margin-bottom: 4px;
    color: var(--cc-faint);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 1.1px;
    text-transform: uppercase;
}
.cchat-report-field input,
.cchat-report-field textarea {
    width: 100%;
    padding: 9px 11px;
    border: 1px solid var(--cc-rule);
    border-radius: 8px;
    color: var(--cc-ink);
    font-family: inherit;
    font-size: 14px;
    line-height: 1.5;
    resize: vertical;
}
.cchat-report-field input:focus,
.cchat-report-field textarea:focus { border-color: var(--cc-accent); outline: none; }

.cchat-report-error {
    padding: 8px 11px;
    border-radius: 8px;
    background: #fdf1ef;
    color: #b4503a;
    font-size: 13px;
}
.cchat-report-error[hidden] { display: none !important; }

.cchat-report-foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    flex: 0 0 auto;
    padding: 12px 16px;
    border-top: 1px solid var(--cc-rule);
}
.cchat-report-cancel,
.cchat-report-send {
    padding: 8px 18px;
    border-radius: 20px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}
.cchat-report-cancel {
    border: 1px solid var(--cc-rule);
    background: #fff;
    color: var(--cc-ink);
}
.cchat-report-cancel:hover { border-color: var(--cc-accent); color: var(--cc-accent-dark); }
.cchat-report-send {
    border: 0;
    background: var(--cc-accent);
    color: #fff;
}
.cchat-report-send:hover:not(:disabled) { background: var(--cc-accent-dark); }
.cchat-report-send:disabled { opacity: 0.6; cursor: default; }

@media (max-width: 767px) {
    .cchat-report { padding: 10px; }
    .cchat-report-card { max-height: 92vh; }
}

/* ── The quoted message, in full ──────────────────────────── */

.cchat-context[hidden] { display: none !important; }

.cchat-context {
    position: fixed;
    inset: 0;
    z-index: 1060;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(20, 18, 15, 0.5);
    backdrop-filter: blur(2px);
    animation: cchat-fade 0.16s ease-out;
}
@keyframes cchat-fade { from { opacity: 0; } to { opacity: 1; } }

.cchat-context-card {
    width: min(560px, 100%);
    max-height: min(70vh, 640px);
    display: flex;
    flex-direction: column;
    border-radius: 14px;
    background: #fff;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
    overflow: hidden;
    animation: cchat-rise 0.18s ease-out;
}
@keyframes cchat-rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

.cchat-context-bar {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    padding: 11px 14px;
    border-bottom: 1px solid var(--cc-rule);
    background: var(--cc-tint);
}
.cchat-context-label {
    flex: 1 1 auto;
    color: var(--cc-accent-dark);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}
.cchat-context-x {
    flex: 0 0 auto;
    padding: 0 3px;
    border: 0;
    background: none;
    color: var(--cc-faint);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
.cchat-context-x:hover { color: var(--cc-ink); }

.cchat-context-body {
    flex: 1 1 auto;
    padding: 14px 8px;
    overflow-y: auto;
}
/* The copy is a real message row; it just has no room to hover in. */
.cchat-context-body .cchat-msg { animation: none; }
.cchat-context-body .cchat-msg:hover { background: none; }
.cchat-context-gone {
    margin: 0;
    padding: 10px 8px;
    color: var(--cc-dim);
    font-size: 13.5px;
    font-style: italic;
    text-align: center;
}

/* Same voice while the original is on its way. */
.cchat-context-loading {
    margin: 0;
    padding: 10px 8px;
    color: var(--cc-dim);
    font-size: 13.5px;
    font-style: italic;
    text-align: center;
}

/* ── The top of the loaded history ─────────────────────────
   Sits above the first message and says what is happening up there: a page on
   its way, or the room's own beginning. Quiet by design — it is furniture at
   the edge of the conversation, not part of it. */

.cchat-older {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 8px 6px;
    color: var(--cc-dim);
    font-size: 12.5px;
}
.cchat-older[hidden] { display: none; }
.cchat-older-text { letter-spacing: 0.2px; }

/* A ring that turns while a page is being fetched, in the site's own colour
   rather than a spinner glyph that would sit on a different baseline. */
.cchat-older.is-loading .cchat-older-text::before {
    content: '';
    display: inline-block;
    width: 11px;
    height: 11px;
    margin-right: 7px;
    vertical-align: -1px;
    border: 2px solid rgba(235, 161, 51, .3);
    border-top-color: #eba133;
    border-radius: 50%;
    animation: cchat-older-spin .7s linear infinite;
}

@keyframes cchat-older-spin { to { transform: rotate(360deg); } }

.cchat-context-foot {
    flex: 0 0 auto;
    padding: 10px 14px;
    border-top: 1px solid var(--cc-rule);
    text-align: right;
}
.cchat-context-jump {
    padding: 6px 14px;
    border: 1px solid var(--cc-rule);
    border-radius: 20px;
    background: #fff;
    color: var(--cc-ink);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
}
.cchat-context-jump:hover { border-color: var(--cc-accent); color: var(--cc-accent-dark); }
.cchat-context-jump[hidden] { display: none !important; }

/* ── Lightbox ─────────────────────────────────────────────── */

/* A shared dream opens here rather than in a new tab: leaving a live room to
   watch a six-second clip is a bad trade. */
.cchat-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1060;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 40px 24px 24px;
    background: rgba(20, 17, 13, 0.88);
    animation: cchat-fade 0.18s ease-out both;
}
.cchat-lightbox[hidden] { display: none; }
@keyframes cchat-fade { from { opacity: 0; } to { opacity: 1; } }

.cchat-lightbox-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: min(1100px, 92vw);
    max-height: 78vh;
    animation: cchat-zoom 0.22s cubic-bezier(0.16, 0.9, 0.3, 1) both;
}
@keyframes cchat-zoom {
    from { opacity: 0; transform: scale(0.965); }
    to   { opacity: 1; transform: none; }
}
.cchat-lightbox-stage video,
.cchat-lightbox-stage img {
    display: block;
    max-width: min(1100px, 92vw);
    max-height: 78vh;
    width: auto;
    height: auto;
    border-radius: 8px;
    background: #000;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}

.cchat-lightbox-bar {
    display: flex;
    align-items: center;
    gap: 16px;
    max-width: 92vw;
    color: #e6ddd2;
    font-size: 13.5px;
}
.cchat-lightbox-sub {
    display: block;
    margin-top: 2px;
    opacity: 0.7;
    font-weight: 400;
    font-size: 12px;
}
.cchat-lightbox-title {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.cchat-lightbox-open {
    flex: 0 0 auto;
    color: var(--cc-accent, #eba133);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.cchat-lightbox-open:hover { color: #f7b04a; text-decoration: underline; }

.cchat-lightbox-close {
    position: absolute;
    top: 14px;
    right: 20px;
    padding: 0;
    border: 0;
    background: none;
    color: #b9ada0;
    font-size: 34px;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s;
}
.cchat-lightbox-close:hover { color: #fff; }

@media (prefers-reduced-motion: reduce) {
    .cchat-lightbox, .cchat-lightbox-stage { animation: none; }
}

/* ── Feedback strip and the "file this?" offer ────────────── */

.cchat-panel--feedback { margin-bottom: 12px; }
.cchat-panel-link {
    color: var(--cc-accent-dark);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-decoration: none;
    text-transform: uppercase;
}
.cchat-panel-link:hover { color: var(--cc-accent); text-decoration: underline; }

.cchat-feedback { margin: 0; padding: 0; list-style: none; }
.cchat-fb-item a {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 6px;
    border-radius: 6px;
    color: var(--cc-ink);
    font-size: 12.5px;
    text-decoration: none;
}
.cchat-fb-item a:hover { background: #faf6ef; text-decoration: none; }

.cchat-fb-score {
    flex: 0 0 auto;
    min-width: 20px;
    padding: 1px 5px;
    border-radius: 9px;
    background: var(--cc-soft);
    color: var(--cc-dim);
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
}
.cchat-fb-score.is-positive { background: #e4f3ea; color: #3f8b62; }

.cchat-fb-text { min-width: 0; }
.cchat-fb-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.4;
}
.cchat-fb-type {
    display: inline-block;
    margin-top: 2px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.7px;
    text-transform: uppercase;
}
.cchat-fb-type.is-bug { color: #b4503a; }
.cchat-fb-type.is-feature { color: #4169e1; }

.cchat-feedback-empty { padding: 6px; color: var(--cc-dim); font-size: 12.5px; line-height: 1.5; }
.cchat-feedback-empty a { color: var(--cc-accent-dark); }

/* The offer under your own message. Only its author ever sees it. */
.cchat-offer {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 7px 0 3px;
    padding: 7px 10px;
    border: 1px dashed var(--cc-accent);
    border-radius: 8px;
    background: var(--cc-tint);
    font-size: 12.5px;
    animation: cchat-arrive 0.28s ease-out both;
}
.cchat-offer-text { color: var(--cc-ink); }
.cchat-offer-yes {
    padding: 4px 11px;
    border: 0;
    border-radius: 6px;
    background: var(--cc-accent);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.cchat-offer-yes:hover:not(:disabled) { background: #d99327; }
.cchat-offer-yes:disabled { opacity: 0.6; cursor: default; }
.cchat-offer-no {
    padding: 4px 8px;
    border: 0;
    background: none;
    color: var(--cc-dim);
    font-size: 12px;
    cursor: pointer;
}
.cchat-offer-no:hover { color: var(--cc-ink); }
.cchat-offer-link { color: var(--cc-accent-dark); font-weight: 600; text-decoration: underline; }

/* ── The stamp on a message ────────────────────────────────
   Anything older than today now carries its day as well as its clock, which
   is what makes a week of scroll-back readable — see timeLabel(). It also
   makes the meta line about forty pixels wider, so on a narrow screen the
   name is the part that gives way rather than the date being pushed out of
   the row. */

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

.cchat-name {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.cchat-time { flex: 0 0 auto; }


/* ── Group chats ──────────────────────────────────────────────
   The rooms rail, the members list inside a group, and the one
   dialog that makes and runs a group. Everything borrows the
   palette above; nothing here introduces a colour of its own.
   ───────────────────────────────────────────────────────────── */

.cchat-rooms {
    display: flex;
    flex-direction: column;
    /* Wide enough for a group's name to be read rather than guessed at.
       176px ellipsised anything past about twelve characters, which is most
       names people actually give a group — and the conversation beside it is
       the widest thing on the page, so it is the one that can spare the room. */
    flex: 0 0 288px;
    width: 288px;
    min-height: 0;
    background: var(--cc-panel);
    border: 1px solid var(--cc-rule);
    border-radius: 10px;
    padding: 10px 8px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: #d6d6da transparent;
}
.cchat-rooms::-webkit-scrollbar { width: 8px; }
.cchat-rooms::-webkit-scrollbar-thumb { background: #d6d6da; border-radius: 4px; }

.cchat-rooms-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 6px 8px;
}
.cchat-rooms-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--cc-faint);
}
.cchat-rooms-new {
    border: 1px solid var(--cc-rule);
    background: transparent;
    color: var(--cc-dim);
    border-radius: 6px;
    width: 24px;
    height: 24px;
    line-height: 1;
    cursor: pointer;
    transition: border-color .15s, color .15s, background .15s;
}
.cchat-rooms-new:hover {
    border-color: var(--cc-accent);
    color: var(--cc-accent-dark);
    background: var(--cc-tint);
}

.cchat-rooms-list { display: flex; flex-direction: column; gap: 2px; }

.cchat-room {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 8px;
    border-radius: 7px;
    color: var(--cc-ink);
    font-size: 13px;
    text-decoration: none;
    transition: background .15s, color .15s;
}
.cchat-room:hover { background: var(--cc-soft); color: var(--cc-ink); text-decoration: none; }

/* The room you are reading. A filled tint rather than a bar, so the
   rail reads as a set of places and not a list with one thing ticked. */
.cchat-room.is-current {
    background: var(--cc-tint);
    color: var(--cc-accent-dark);
    font-weight: 600;
}
.cchat-room-icon { flex: 0 0 auto; width: 15px; text-align: center; color: var(--cc-faint); font-size: 12px; }
.cchat-room.is-current .cchat-room-icon { color: var(--cc-accent); }

.cchat-room-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cchat-room-dot {
    flex: 0 0 auto;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--cc-accent);
    box-shadow: 0 0 0 2px rgba(235, 161, 51, .25);
}

/*
 * Invitations, under the rooms.
 *
 * Deliberately not styled as a room: it is not a place you have. Until it is
 * accepted there is nothing behind it to open — no history, no socket, not
 * even a member list — so it reads as a question with two answers rather than
 * a row you might click into.
 */
/* Above the rooms, not below them: an invitation is the one thing in this
   rail that is waiting on you, and under a list of groups it was missed. */
.cchat-invites {
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--cc-rule);
}
.cchat-invites .cchat-rooms-label { display: block; padding: 0 6px 8px; }

/* The number, so a glance says how many answers are owed. */
.cchat-invites-count {
    display: inline-block;
    min-width: 16px;
    margin-left: 4px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--cc-accent);
    color: #fff;
    font-size: 10.5px;
    line-height: 16px;
    text-align: center;
    letter-spacing: 0;
}

.cchat-invite {
    padding: 9px 10px;
    margin-bottom: 6px;
    border: 1px solid var(--cc-rule);
    border-left: 3px solid var(--cc-accent);
    border-radius: 7px;
    background: var(--cc-tint);
}
.cchat-invite.is-busy { opacity: .5; pointer-events: none; }

.cchat-invite-name {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--cc-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cchat-invite-from {
    display: block;
    margin-top: 1px;
    font-size: 11.5px;
    color: var(--cc-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cchat-invite-actions {
    display: flex;
    gap: 6px;
    margin-top: 8px;
}
.cchat-invite-yes,
.cchat-invite-no {
    flex: 1 1 auto;
    padding: 5px 8px;
    border-radius: 6px;
    font-size: 12px;
    cursor: pointer;
    border: 1px solid transparent;
}
.cchat-invite-yes {
    background: var(--cc-accent);
    border-color: var(--cc-accent);
    color: #fff;
    font-weight: 600;
}
.cchat-invite-yes:hover { background: var(--cc-accent-dark); border-color: var(--cc-accent-dark); }

/* Declining is not a lesser action and is not dressed as one — it is the
   right answer as often as Join is, and it has to be easy to give. */
.cchat-invite-no {
    background: #fff;
    border-color: var(--cc-rule);
    color: var(--cc-dim);
}
.cchat-invite-no:hover { border-color: #e0b6b2; color: #b4433b; }

/* Asked, not answered — in the dialog's member list. */
.cchat-gm-member.is-pending { opacity: .75; }
.cchat-gm-pending-wrap { margin-top: 14px; }
.cchat-gm-pending-wrap[hidden] { display: none !important; }

.cchat-rooms-hint {
    margin: 10px 6px 2px;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--cc-faint);
}

/*
 * A group's membership, in the bar.
 *
 * The public room keeps a column of "recently active" because it has hundreds
 * of people in it and who is talking is real information. A group has the few
 * you picked — a column listing five names next to a conversation between
 * those five is furniture — so the faces move up here and the whole strip is
 * the button that opens the members list.
 */
.cchat-faces-btn {
    gap: 0;
    padding: 3px 8px 3px 4px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}
.cchat-faces-btn:hover {
    border-color: var(--cc-rule);
    background: var(--cc-soft);
}
.cchat-faces-btn .cchat-face + .cchat-face { margin-left: -9px; }

/* Present in the room now, the same distinction the people rail draws. */
.cchat-face.is-here { border-color: #58c26b; }

/*
 * "Recently active", hung off the faces.
 *
 * .cchat-col clips its children, which is what keeps this inside the panel
 * rather than spilling over the page — it opens downward into the stream, so
 * the clip never reaches it.
 */
.cchat-people-pop { position: relative; display: inline-flex; flex: 0 0 auto; }

.cchat-faces-btn.is-open {
    border-color: var(--cc-rule);
    background: var(--cc-soft);
}
.cchat-faces-btn.is-open .cchat-faces-gear { transform: rotate(180deg); }
.cchat-faces-gear { transition: transform .15s, color .15s; }

.cchat-people-drop {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    z-index: 1050;
    width: 260px;
    max-height: 60vh;
    overflow-y: auto;
    border: 1px solid var(--cc-rule);
    border-radius: 10px;
    background: var(--cc-panel, #fff);
    box-shadow: 0 12px 30px rgba(0, 0, 0, .14);
    animation: cchatPeopleIn .14s ease-out;
}
.cchat-people-drop[hidden] { display: none !important; }
@keyframes cchatPeopleIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

/* The panel inside it was a rail card; in a dropdown it is the dropdown. */
.cchat-people-drop .cchat-panel {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    margin: 0;
}

@media (prefers-reduced-motion: reduce) {
    .cchat-people-drop { animation: none; }
}

.cchat-faces-count {
    margin-left: 8px;
    color: var(--cc-dim);
    font-size: 12.5px;
    font-weight: 600;
}
.cchat-faces-gear {
    margin-left: 7px;
    color: var(--cc-faint);
    font-size: 12px;
}
.cchat-faces-btn:hover .cchat-faces-gear { color: var(--cc-accent-dark); }

/*
 * "Private", beside the group's name.
 *
 * It was a loose grey line of text in a baseline-aligned flex row, so it drifted
 * away from the title it belongs to and wrapped onto two lines in whatever space
 * was left — which is how "Private group" ended up stacked in the middle of the
 * bar. A pill hugs the name, cannot wrap, and says the same thing in one word
 * plus a lock, which is the part that carries the meaning.
 */
.cchat-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
    align-self: center;
    padding: 2px 9px 2px 7px;
    border-radius: 999px;
    background: var(--cc-soft);
    color: var(--cc-dim);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
}
.cchat-badge i { font-size: 10px; opacity: .8; }

/* Nothing after the name should be dragged across the bar by the spare room. */
.cchat-bar-text > :last-child { margin-right: auto; }

/* The connection light sits with the room's name now, so its coming and going
   cannot shove the faces and the rules button sideways. */
.cchat-bar-text .cchat-status { align-self: center; }

/* ── The group dialog ─────────────────────────────────────── */

.cchat-gm[hidden] { display: none !important; }
.cchat-gm {
    /*
     * Its own copy of the palette.
     *
     * The dialog is rendered after </div> of .cchat, deliberately: a fixed
     * overlay inside the room would be at the mercy of that layout's scroll
     * containers. But the palette is declared ON .cchat, so out here every
     * var(--cc-…) resolved to nothing — the panel's background fell away
     * entirely and the chat showed straight through it, and "Create group"
     * lost its orange. Declared here so the dialog carries its own colours
     * wherever it is mounted.
     */
    --cc-accent: #eba133;
    --cc-accent-dark: #c9821a;
    --cc-panel: #fff;
    --cc-rule: #e5e6e9;
    --cc-soft: #f2f2f4;
    --cc-ink: #3f3f45;
    --cc-dim: #8b8b90;
    --cc-faint: #b0b0b6;
    --cc-tint: #fdf8f0;

    position: fixed;
    inset: 0;
    /* Above every other overlay the room has; the report card tops out at 1070. */
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.cchat-gm-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(24, 24, 27, .55);
}
body.cchat-gm-lock { overflow: hidden; }

.cchat-gm-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    /* Wide enough for a name, a username and how you know somebody on one
       line, because that is what tells two people of the same name apart. */
    max-width: 560px;
    max-height: 100%;
    /* #fff behind the token: a dialog that reads as transparent is worse than
       one with the wrong white, and this is what it fell back to. */
    background: #fff;
    background: var(--cc-panel, #fff);
    border-radius: 12px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .3);
    overflow: hidden;
    animation: cchatGmIn .18s ease-out;
}
@keyframes cchatGmIn {
    from { opacity: 0; transform: translateY(8px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.cchat-gm-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--cc-rule);
}
.cchat-gm-title {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--cc-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cchat-gm-x {
    border: 0;
    background: transparent;
    color: var(--cc-faint);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}
.cchat-gm-x:hover { color: var(--cc-ink); }

.cchat-gm-body {
    padding: 14px 16px;
    overflow-y: auto;
}
.cchat-gm-label {
    display: block;
    margin: 0 0 5px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--cc-faint);
}
.cchat-gm-label + .cchat-gm-label,
.cchat-gm-picked + .cchat-gm-search-wrap { margin-top: 0; }

/* ── The group's picture ──────────────────────────────────── */

/*
 * The picture sits beside the name, under a label that spans both — so the
 * dialog keeps one left edge all the way down. It was its own column before,
 * which indented the name field past every other field in the panel.
 *
 * The well matches the input's height exactly, so the two read as one row
 * rather than as a square that happens to be nearby.
 */
.cchat-gm-identity {
    display: flex;
    align-items: stretch;
    gap: 10px;
    margin-bottom: 14px;
}

/*
 * Bootstrap sets `input[type="file"] { display: block }`, which beats the
 * `hidden` attribute's UA `display: none` — so the native "Choose File" button
 * appeared in the middle of the dialog and shoved the name field aside. The
 * same trap is handled the same way by #cchat-image a few hundred lines up,
 * and in the support and feedback modules.
 */
.cchat-gm-identity input[type="file"] { display: none !important; }

.cchat-gm-photo-wrap { position: relative; flex: 0 0 auto; }

.cchat-gm-photo {
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px dashed var(--cc-rule);
    border-radius: 9px;
    background: var(--cc-soft);
    color: var(--cc-faint);
    font-size: 14px;
    cursor: pointer;
    overflow: hidden;
    transition: border-color .15s, color .15s, background .15s;
}
.cchat-gm-photo:hover:not(:disabled) {
    border-color: var(--cc-accent);
    color: var(--cc-accent-dark);
    background: var(--cc-tint);
}
/* Once there is a picture it is the content, so the dashed "empty" edge goes. */
.cchat-gm-photo.has-photo { border-style: solid; border-color: var(--cc-rule); }
.cchat-gm-photo.is-readonly { cursor: default; opacity: .85; }
.cchat-gm-photo.is-busy { cursor: default; }

.cchat-gm-photo-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.cchat-gm-photo-img[hidden] { display: none !important; }

.cchat-gm-photo-empty,
.cchat-gm-photo-busy {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.cchat-gm-photo-empty[hidden],
.cchat-gm-photo-busy[hidden] { display: none !important; }
.cchat-gm-photo-busy { background: rgba(255, 255, 255, .75); color: var(--cc-accent); }

/* On the picture, not under it: a row that appears when a photo is set would
   move everything below it each time. */
.cchat-gm-photo-clear {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 1px solid var(--cc-rule);
    border-radius: 50%;
    background: #fff;
    color: var(--cc-dim);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}
.cchat-gm-photo-clear:hover { border-color: #e0b6b2; color: #b4433b; }
.cchat-gm-photo-clear[hidden] { display: none !important; }

.cchat-gm-identity .cchat-gm-name { flex: 1 1 auto; min-width: 0; margin-bottom: 0; }

/* What the shelf says before anything has been shared in a group. */
.cchat-side-empty p {
    margin: 0;
    color: var(--cc-faint);
    font-size: 12.5px;
    line-height: 1.55;
}

/* The picture, wherever a group is named. */
.cchat-room-icon img {
    width: 18px;
    height: 18px;
    border-radius: 5px;
    object-fit: cover;
    display: block;
}
.cchat-invite {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "photo name" "photo from" "actions actions";
    column-gap: 9px;
}
.cchat-invite-photo {
    grid-area: photo;
    align-self: center;
    border-radius: 8px;
    object-fit: cover;
}
.cchat-invite-name { grid-area: name; }
.cchat-invite-from { grid-area: from; }
.cchat-invite-actions { grid-area: actions; }

.cchat-gm-name,
.cchat-gm-search {
    width: 100%;
    /* Its own, like the palette above: the dialog is mounted outside .cchat
       and cannot assume anything the room's stylesheet sets. Without it the
       padding is added to the width and the panel scrolls sideways. */
    box-sizing: border-box;
    padding: 9px 11px;
    border: 1px solid var(--cc-rule);
    border-radius: 8px;
    background: #fff;
    color: var(--cc-ink);
    font-size: 14px;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.cchat-gm-name:focus,
.cchat-gm-search:focus {
    border-color: var(--cc-accent);
    box-shadow: 0 0 0 3px rgba(235, 161, 51, .16);
}
.cchat-gm-name:disabled { background: var(--cc-soft); color: var(--cc-dim); }
.cchat-gm-name { margin-bottom: 14px; }

.cchat-gm-picked {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 8px;
}
.cchat-gm-picked:empty { display: none; }

.cchat-gm-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 4px 3px 3px;
    border: 1px solid var(--cc-rule);
    border-radius: 999px;
    background: var(--cc-soft);
    font-size: 12.5px;
    color: var(--cc-ink);
}
.cchat-gm-chip img { border-radius: 50%; }
.cchat-gm-chip-x {
    border: 0;
    background: transparent;
    color: var(--cc-faint);
    font-size: 16px;
    line-height: 1;
    padding: 0 3px;
    cursor: pointer;
}
.cchat-gm-chip-x:hover { color: var(--cc-ink); }

.cchat-gm-search-wrap { position: relative; }
.cchat-gm-search-icon {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 12px;
    color: var(--cc-faint);
    pointer-events: none;
}
.cchat-gm-search-wrap .cchat-gm-search { padding-left: 30px; }

/* What the list below is: the people you talk to, or what a search found. */
.cchat-gm-results-label {
    margin: 12px 0 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--cc-faint);
}
.cchat-gm-results-label[hidden] { display: none !important; }

/*
 * In the dialog rather than floating over it.
 *
 * As an absolutely positioned dropdown it was clipped by the panel's own
 * scroll — the last row cut in half — and put a second scrollbar beside the
 * first. It also covered the name field, which stopped mattering when the
 * list only appeared after typing and started mattering the moment it began
 * opening by itself with the people you talk to.
 */
.cchat-gm-results {
    max-height: 300px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--cc-rule);
    border-radius: 8px;
    scrollbar-width: thin;
    scrollbar-color: #d6d6da transparent;
}
.cchat-gm-results::-webkit-scrollbar { width: 8px; }
.cchat-gm-results::-webkit-scrollbar-thumb { background: #d6d6da; border-radius: 4px; }

/* Nothing found is an answer, and a better one than the list vanishing. */
.cchat-gm-results-empty {
    padding: 14px 12px;
    font-size: 13px;
    color: var(--cc-dim);
    text-align: center;
}
.cchat-gm-results[hidden] { display: none !important; }

/* A name is not enough to tell two people apart on a site this size, so each
   row carries the username under it and how you know them. */
.cchat-gm-result-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}
.cchat-gm-result-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cchat-gm-result-meta {
    font-size: 11.5px;
    color: var(--cc-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cchat-gm-result {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border: 0;
    border-bottom: 1px solid var(--cc-rule);
    background: transparent;
    text-align: left;
    font-size: 13.5px;
    color: var(--cc-ink);
    cursor: pointer;
    transition: background .12s;
}
.cchat-gm-result:last-child { border-bottom: 0; }
.cchat-gm-result:hover,
.cchat-gm-result:focus-visible { background: var(--cc-tint); outline: none; }
.cchat-gm-result img { border-radius: 50%; flex: 0 0 auto; width: 32px; height: 32px; object-fit: cover; }

.cchat-gm-note {
    margin: 12px 0 0;
    font-size: 11.5px;
    line-height: 1.55;
    color: var(--cc-faint);
}
.cchat-gm-note[hidden] { display: none !important; }

.cchat-gm-members-wrap { margin-top: 16px; }
.cchat-gm-members-wrap[hidden] { display: none !important; }

.cchat-gm-members {
    margin: 0;
    padding: 0;
    list-style: none;
    max-height: 220px;
    overflow-y: auto;
}
.cchat-gm-member {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 2px;
    border-bottom: 1px solid var(--cc-soft);
    font-size: 13.5px;
    color: var(--cc-ink);
}
.cchat-gm-member:last-child { border-bottom: 0; }
.cchat-gm-member img { border-radius: 50%; flex: 0 0 auto; }
.cchat-gm-member.is-loading { color: var(--cc-faint); }
.cchat-gm-member-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cchat-gm-member-tag {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--cc-soft);
    color: var(--cc-faint);
    font-size: 10px;
    letter-spacing: .04em;
    text-transform: uppercase;
}
.cchat-gm-member-x {
    border: 0;
    background: transparent;
    color: var(--cc-faint);
    font-size: 12px;
    cursor: pointer;
    padding: 2px 4px;
    border-radius: 5px;
}
.cchat-gm-member-x:hover { background: var(--cc-soft); color: #b4433b; }
.cchat-gm-member-x:disabled { opacity: .5; cursor: default; }

.cchat-gm-error {
    margin: 12px 0 0;
    padding: 8px 10px;
    border-radius: 7px;
    background: #fdf1f0;
    color: #b4433b;
    font-size: 12.5px;
}
.cchat-gm-error[hidden] { display: none !important; }

.cchat-gm-foot {
    padding: 12px 16px;
    border-top: 1px solid var(--cc-rule);
    background: var(--cc-soft);
}
.cchat-gm-actions {
    display: flex;
    align-items: center;
    /* flex-end, with the destructive button pushed left by its own margin.
       space-between put the pair on the LEFT whenever Delete was hidden — as
       it is for a new group — because one child has nothing to be spaced
       against. */
    justify-content: flex-end;
    gap: 10px;
}
.cchat-gm-leave { margin-right: auto; }
.cchat-gm-actions[hidden] { display: none !important; }
.cchat-gm-foot-right { display: inline-flex; align-items: center; gap: 8px; }

/*
 * "Are you sure", in the panel.
 *
 * Takes the footer's place rather than stacking a second box on top, so the
 * group's name and the people in it stay on screen while the question is being
 * answered — which is the context somebody needs to answer it.
 */
.cchat-gm-confirm {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    margin: -12px -16px;
    padding: 12px 16px;
    border-radius: 0 0 12px 12px;
    background: #fdf1f0;
    animation: cchatConfirmIn .16s ease-out;
}
.cchat-gm-confirm[hidden] { display: none !important; }
@keyframes cchatConfirmIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .cchat-gm-confirm { animation: none; }
}

.cchat-gm-confirm-text {
    flex: 1 1 220px;
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
    color: #8f342d;
}
.cchat-gm-confirm-buttons {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

/* The destructive one is the one that looks destructive; "Keep it" is the
   plain button, and the one that takes focus. */
.cchat-gm-danger {
    border: 0;
    background: #b4433b;
    color: #fff;
    padding: 9px 16px;
    border-radius: 7px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s;
}
.cchat-gm-danger:hover { background: #99352e; }

.cchat-invite.is-stale { opacity: .6; }
.cchat-invite-note {
    margin: 8px 0 0;
    font-size: 11.5px;
    line-height: 1.45;
    color: #b4433b;
}

.cchat-gm-cancel,
.cchat-gm-leave {
    border: 1px solid var(--cc-rule);
    background: #fff;
    color: var(--cc-dim);
    padding: 8px 14px;
    border-radius: 7px;
    font-size: 13px;
    cursor: pointer;
}
.cchat-gm-cancel:hover { color: var(--cc-ink); }
.cchat-gm-leave[hidden] { display: none !important; }
.cchat-gm-leave:hover { border-color: #e0b6b2; color: #b4433b; }
.cchat-gm-leave.is-danger { color: #b4433b; }

.cchat-gm-save {
    border: 0;
    background: var(--cc-accent);
    color: #fff;
    padding: 9px 18px;
    border-radius: 7px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s;
}
.cchat-gm-save:hover { background: var(--cc-accent-dark); }
.cchat-gm-save:disabled { opacity: .6; cursor: default; }
.cchat-gm-save[hidden] { display: none !important; }

@media (max-width: 1280px) {
    .cchat-rooms { flex-basis: 240px; width: 240px; }
}

/* Narrow: the people rail and the side panel go, as they already did — they
   are reference. The rooms are navigation, so instead of going they lie down
   into a strip above the conversation. A group you cannot reach from a phone
   is a group you do not have. */
@media (max-width: 991px) {
    /*
     * A column, not a wrapping row. flex-wrap made .cchat-main a multi-line
     * flex container, and a flex line is as tall as its content, not as tall
     * as the container: the conversation grew to the height of every message
     * in it, the stream had nothing left to scroll, and the page is locked so
     * it could not scroll either. On every phone and tablet the room froze,
     * with the composer below the screen (feedback #58). Stacked, the rooms
     * strip takes the height it needs and the conversation gets what is left.
     */
    .cchat-main { flex-direction: column; }

    /* A column item's min-height defaults to its content — the same trap, one
       level down. Zero lets it shrink to the space and scroll inside. */
    .cchat-main > .cchat-col { min-height: 0; }

    .cchat-rooms {
        flex: 0 0 auto;
        width: 100%;
        flex-direction: row;
        align-items: center;
        gap: 6px;
        padding: 6px 8px;
        overflow-x: auto;
        overflow-y: hidden;
    }
    .cchat-rooms-head { padding: 0 4px 0 0; }
    .cchat-rooms-label { display: none; }
    .cchat-rooms-list { flex-direction: row; gap: 6px; }
    .cchat-room { white-space: nowrap; padding: 6px 10px; }
    .cchat-room-name { max-width: 120px; }
    .cchat-rooms-hint { display: none; }
}
