/*
 * ============================================================
 * style_participants.css — Participant Card & Notification Styles
 * ============================================================
 *
 * STATUS: ENTIRELY NEW FILE — did not exist before Phase 2.
 *
 * CONTENTS (four sections):
 *   1. .video-slot            — wrapper div replacing bare <video> elements
 *                               in the thumbnail strip
 *   2. .participant-card      — thumbnail card shown when camera is off
 *      .card-speaking-ring    — animated green border on speech detection
 *      .card-avatar           — gradient circle with initial letter
 *      .card-name             — nickname label
 *      .card-timer            — HH:MM:SS live counter (monospace)
 *      .peer-mute-btn         — local-mute icon button (remote peers only)
 *   3. .main-participant-card — full-size card in the main viewing area,
 *                               replaces #main-video when camera is off
 *      .main-card-ring        — larger speaking ring for the main card
 *      .main-card-avatar      — larger avatar (90 px vs 40 px)
 *      .main-card-name        — larger nickname label
 *      .main-card-timer       — larger timer
 *      .main-card-controls    — mute button row
 *   4. .notification-container — fixed top-right toast stack
 *      .notification-toast     — individual slide-in/out toast
 *
 * DESIGN LANGUAGE (matches existing app aesthetic):
 *   Background  : near-black with 85–92 % opacity
 *   Border      : 1 px solid rgba(0, 255, 255, 0.22) — subtle cyan
 *   Accent      : #00ffff / rgba(0,255,255) for timers and active states
 *   Speaking    : rgba(0, 255, 120, 0.78) green glow for audio ring
 *   Avatar      : linear-gradient(135deg, #00b4d8, #0077b6) — app blues
 *   Glass effect: backdrop-filter: blur(8–12px) — glassmorphism
 *
 * CSS VARIABLE DEPENDENCY:
 *   --layout-margin  : defined in style_common.css (loaded first)
 *   --corner-radius  : defined in style_common.css (loaded first)
 *   Fallbacks (8px, 5px) are provided for safety in case variables
 *   are not yet defined when this file is parsed.
 *
 * CRITICAL LAYOUT NOTE — .video-slot replaces .video-stream in the strip:
 *   BEFORE Phase 2: <video.video-stream> was sized by rules in
 *     style_desktop.css (width: 20%) and style_mobile.css (width: 50%).
 *   AFTER Phase 2:  <div.video-slot> carries those exact same percentage
 *     dimensions.  The nested <video.video-stream> is then overridden to
 *     width:100%; height:100% via the .video-slot .video-stream rule,
 *     so the visual result is identical for users who have their cameras on.
 *
 * HOW TO REVERT:
 *   1. Delete this file entirely.
 *   2. In index.hbs, remove:
 *        <link rel="stylesheet" href="css/style_participants.css">
 *   Removing the CSS file alone will not break layout for users with cameras
 *   ON (their <video> fills the slot naturally), but will leave unstyled
 *   card elements visible if participant_card.js is still loaded.
 *   For a full revert, remove all Phase 2 JS files and DOM elements too.
 *
 * NEW — added as part of participant awareness feature (Phase 2)
 * ============================================================
 */

/* ─────────────────────────────────────────────────────────────
 * 1. VIDEO SLOT
 * The .video-slot div replaces bare <video class="video-stream">
 * elements in the thumbnail strip.  It carries the same flex and
 * sizing properties as .video-stream so the layout is identical to
 * the pre-existing strip; only the internal structure changes.
 *
 * When video is ON  : the slot shows <video.video-stream>
 * When video is OFF : the slot shows <div.participant-card>
 * ───────────────────────────────────────────────────────────── */

/* Video slot — aspect-ratio driven so width scales with the strip height.
   The strip has `container-type: inline-size; container-name: strip` in
   style_common.css, enabling the @container queries below for wider slots
   when the strip is roomy. No more fixed %-widths or margins. */
/* Slot width is derived from VIEWPORT only (svh — small viewport height,
   the stable form that does not jitter when the URL bar shows/hides).
   Width = strip-height × 16/9, plus a clamp floor/ceiling. Crucially, no
   container queries and no cqi units, so adding or removing a tile NEVER
   recomputes any other tile's width or height. */
.video-slot {
    flex: 0 0 auto;
    position: relative;
    /* R-D: FIXED strip height; WIDTH follows the source orientation. A portrait camera makes a
       narrow tile, a landscape camera a wide one — both at the same height. The box takes the
       source aspect (set as --tile-ar from videoWidth/videoHeight), so the video is not cropped. */
    block-size: 100%;
    inline-size: auto;
    aspect-ratio: var(--tile-ar, 16 / 9);
    max-inline-size: 82vw;                 /* an extreme-portrait tile still cannot dominate the row */
    min-inline-size: 60px;
    border-radius: var(--corner-radius, 8px);
    background-color: black;
    cursor: pointer;
    scroll-snap-align: start;
    overflow: hidden;
}

/* R-D: the strip has ONE fixed height (the originally-designed height). Tiles fill it and vary in
   WIDTH only. ID specificity beats the `.video-list { block-size:auto }` in style_stage_fix.css.
   CRITICAL NUANCE: floated tiles remain DOM children of the strip (position:fixed), so the strip
   is NOT :empty when every tile is dragged out. The fixed height therefore applies only while at
   least one DOCKED tile exists; with zero docked tiles the strip collapses to nothing and the
   centre stage expands to the full canvas. display:none is NOT usable here — it would unrender
   the floating (fixed-position) children. */
#video-list-container { flex: 0 0 auto; }
#video-list-container:has(.video-slot:not(.is-floating)) {
    block-size: clamp(96px, 20svh, 156px);
}
#video-list-container:not(:has(.video-slot:not(.is-floating))) {
    block-size: 0;
    min-block-size: 0;
    padding: 0;
    border: 0;
    overflow: visible;           /* the floating children must keep rendering */
}
/* The stage↔strip spacing is the STRIP'S OWN top margin, not the grid gap — because a grid gap
   would keep a 4-8px band even when the strip is 0-height. (A `:has()` nested inside another
   `:has()` is invalid CSS, so the "kill the gap when empty" cannot be expressed on the container;
   expressing the spacing on the strip with a single :has() is the correct form.) */
.main-container { row-gap: 0; }
#video-list-container:has(.video-slot:not(.is-floating)) {
    margin-block-start: var(--stage-gap, 5px);
}

/*
 * When a <video.video-stream> lives inside a .video-slot, override
 * the standalone width/height rules from style_desktop.css and
 * style_mobile.css so the video fills its slot completely.
 * The higher specificity (.video-slot .video-stream vs .video-stream)
 * ensures this rule wins without !important.
 */
.video-slot .video-stream {
    width: 100%;
    height: 100%;
    margin: 0;
}

/* ─────────────────────────────────────────────────────────────
 * 1b. CARD NAME EDIT — pencil icon + inline input on self card
 * ───────────────────────────────────────────────────────────── */

/* Edit button — always visible, large enough to recognize as interactive.
   Sits inline next to the name. Touch-target inflated via padding. */
.card-name-edit-btn {
    appearance: none;
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: rgba(255, 255, 255, 0.92);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 6px;
    border-radius: 6px;
    transition: background 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
    flex-shrink: 0;
}
.card-name-edit-btn:hover  { background: rgba(255, 255, 255, 0.18); transform: scale(1.06); }
.card-name-edit-btn:active { transform: scale(0.94); }

.card-name-input {
    background: rgba(0, 0, 0, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.30);
    border-radius: 8px;
    color: #ffffff;
    font-size: clamp(13px, 2.2cqi, 18px);
    font-weight: 600;
    padding: 6px 10px;
    outline: none;
    width: calc(100% - 24px);
    max-width: 240px;
    text-align: center;
    font-family: inherit;
}
.card-name-input:focus {
    border-color: rgba(255, 255, 255, 0.55);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.12);
}

/* ─────────────────────────────────────────────────────────────
 * 2. PARTICIPANT CARD (thumbnail)
 * Fills the full slot and mirrors the dimensions of .video-stream.
 * ───────────────────────────────────────────────────────────── */

/* Issue 3 — redesigned video-off card.
   - Avatar dominant (~50% of tile height, centered).
   - Name large, full-width with side padding, single line, ellipsis.
   - Edit button always visible inline next to the name.
   - Timer in the top-right corner as a small unit.
   - Participant color drives the avatar gradient and a subtle border tint
     via the inline --pc CSS variable set by participant_card.js. */
.participant-card {
    --pc: #5b6ee8;
    --pc-bg: color-mix(in srgb, var(--pc) 18%, rgba(8,10,14,0.94));
    --pc-edge: color-mix(in srgb, var(--pc) 55%, transparent);

    container-type: inline-size;
    container-name: pcard;

    width: 100%;
    height: 100%;
    background: var(--pc-bg, rgba(8, 10, 14, 0.94));
    border: 1px solid var(--pc-edge, rgba(255, 255, 255, 0.10));
    border-radius: var(--corner-radius, 8px);
    color: #ffffff;
    box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.35);
    position: relative;
    overflow: hidden;
    box-sizing: border-box;

    /* Avatar + name row centered as a vertical group inside the tile. */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: clamp(8px, 4cqi, 16px);
    gap: clamp(6px, 3cqi, 12px);
}

/* Color-mix has wide modern support. For older browsers fall back to a flat tint. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .participant-card {
        background: rgba(8, 10, 14, 0.94);
        border-color: rgba(255, 255, 255, 0.16);
    }
}

/*
 * Speaking ring — an absolutely positioned border that glows green
 * while the Web Audio API detects sound from this participant.
 * The 'speaking' class is toggled by start_speaking_indicator()
 * in participant_card.js at each animation frame.
 */
.card-speaking-ring {
    position: absolute;
    inset: 0;                /* top:0; right:0; bottom:0; left:0 */
    border-radius: var(--corner-radius, 8px);
    border: 2px solid transparent;
    pointer-events: none;    /* never intercepts clicks */
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
    z-index: 10;
}

.card-speaking-ring.speaking {
    border-color: rgba(0, 255, 120, 0.78);
    box-shadow: 0 0 10px rgba(0, 255, 120, 0.32);
}

/* Avatar — dominant element. Container queries scale it with tile size.
   Hooks for an <img> child are reserved (zero extra work) so future photo
   support can drop in an <img class="card-avatar-img"> without redesign. */
.card-avatar {
    aspect-ratio: 1 / 1;
    inline-size: clamp(48px, 42cqi, 110px);
    border-radius: 50%;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--pc) 92%, white 8%),
        color-mix(in srgb, var(--pc) 60%, black 40%));
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: clamp(18px, 18cqi, 44px);
    font-weight: 700;
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
    box-shadow:
        0 0 0 2px rgba(255, 255, 255, 0.08),
        0 8px 20px rgba(0, 0, 0, 0.30),
        inset 0 1px 0 rgba(255, 255, 255, 0.18);
    overflow: hidden;
    position: relative;
}
.card-avatar-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

/* Name row — name + edit pencil inline. Full-width with comfortable side
   padding so it never crashes into the tile edges. */
.card-name-row {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(6px, 1.5cqi, 10px);
    padding: 0 clamp(6px, 3cqi, 14px);
    box-sizing: border-box;
    min-width: 0;
}

.card-name {
    font-size: clamp(13px, 6cqi, 22px);
    font-weight: 650;
    color: #ffffff;
    text-transform: capitalize;
    line-height: 1.15;
    letter-spacing: 0.15px;
    text-shadow: 0 1px 3px oklch(0% 0 0 / 0.55);   /* #5: legible over any video */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex-shrink: 1;
    user-select: none;
}

/* Tiny corner timestamp — supplementary, never dominant. */
.card-timer {
    position: absolute;
    top: 6px;
    right: 8px;
    font-size: clamp(9px, 2.4cqi, 12px);
    font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', 'Roboto Mono', Menlo, Consolas, monospace;
    font-variant-numeric: tabular-nums;              /* #5: modern, crisp — no more Courier */
    color: rgba(255, 255, 255, 0.82);
    background: rgba(0, 0, 0, 0.38);
    padding: 2px 6px;
    border-radius: 999px;
    letter-spacing: 0.4px;
    pointer-events: none;
    z-index: 5;
}

/* Pre-redesign card-edit-btn margin override — it sits in the row now. */
.card-name-edit-btn { margin-top: 0; }

/* Mute button — circular icon button matching app icon style */
.card-controls {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Per-peer mute — repositioned to bottom-left corner so it never crowds
   the name row. Always visible; touch target is 32px (mobile inflates to 40). */
.card-controls {
    position: absolute;
    bottom: 6px;
    left: 6px;
    display: flex;
    align-items: center;
    z-index: 5;
}

.peer-mute-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background-color: rgba(0, 0, 0, 0.45);
    background-image: url('./assets/icons/svg/mic.svg');
    background-repeat: no-repeat;
    background-position: center;
    background-size: 15px 15px;
    border: 1px solid rgba(255, 255, 255, 0.18);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.peer-mute-btn:hover { background-color: rgba(0, 0, 0, 0.65); transform: scale(1.06); }

/* Muted state: red tint, uses pre-existing mic_close.svg */
.peer-mute-btn.muted {
    background-color: rgba(255, 55, 55, 0.24);
    background-image: url('./assets/icons/svg/mic_close.svg');
    border-color: rgba(255, 55, 55, 0.40);
}

/* ─────────────────────────────────────────────────────────────
 * 3. MAIN PARTICIPANT CARD
 * Positioned in the same space as #main-video.  Both elements
 * are shown/hidden exclusively — never simultaneously.
 * Dimensions match .main-video exactly (style_common.css).
 * ───────────────────────────────────────────────────────────── */

.main-participant-card {
    --pc: #5b6ee8;
    --pc-bg: color-mix(in srgb, var(--pc) 14%, rgba(8,10,14,0.94));
    --pc-edge: color-mix(in srgb, var(--pc) 40%, transparent);

    grid-row: 1;
    inline-size: 100%;
    block-size: 100%;
    min-block-size: 0;

    border-radius: var(--corner-radius, 8px);
    background: var(--pc-bg, rgba(8, 10, 14, 0.94));
    border: 1px solid var(--pc-edge, rgba(255, 255, 255, 0.12));

    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    position: relative;
    overflow: hidden;
    cursor: pointer;
    box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.35);
}

/* Speaking ring for the main card — larger glow than thumbnail */
.main-card-ring {
    position: absolute;
    inset: 0;
    border-radius: var(--corner-radius, 8px);
    border: 3px solid transparent;
    pointer-events: none;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
    z-index: 10;
}

.main-card-ring.speaking {
    border-color: rgba(0, 255, 120, 0.72);
    box-shadow: 0 0 28px rgba(0, 255, 120, 0.20);
}

/* Large avatar for the main card — uses participant color */
.main-card-avatar {
    width: 110px;
    height: 110px;
    border-radius: 50%;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--pc) 92%, white 8%),
        color-mix(in srgb, var(--pc) 60%, black 40%));
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 46px;
    font-weight: 700;
    color: #ffffff;
    margin-bottom: 22px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
    box-shadow:
        0 0 0 3px rgba(255, 255, 255, 0.06),
        0 12px 30px rgba(0, 0, 0, 0.35),
        inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

/* Large nickname label */
.main-card-name {
    font-size: 26px;
    font-weight: 600;
    color: #e0f7fa;
    text-transform: capitalize;
    margin-bottom: 8px;
    letter-spacing: 0.3px;
}

/* Large timer */
.main-card-timer {
    font-size: 15px;
    color: rgba(255, 255, 255, 0.7);                 /* #5: was a harsh pure-cyan */
    font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', 'Roboto Mono', Menlo, Consolas, monospace;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.5px;
    margin-bottom: 20px;
}

/* Controls row for the large card */
.main-card-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
}

/* Larger mute button for the main card */
.main-card-controls .peer-mute-btn {
    width: 44px;
    height: 44px;
    background-size: 22px 22px;
}

/* ─────────────────────────────────────────────────────────────
 * 4. TOAST NOTIFICATIONS
 * Stack in the top-right corner, slide in from the right,
 * auto-dismiss with a slide-out transition.
 * ───────────────────────────────────────────────────────────── */

/* Fixed container; pointer-events: none so it never blocks clicks */
.notification-container {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}

/* Individual toast: starts off-screen (translateX > 100%) */
.notification-toast {
    background: rgba(8, 8, 12, 0.96);
    border: 1px solid rgba(0, 255, 255, 0.26);
    border-radius: 10px;
    padding: 11px 16px;
    color: #ffffff;
    font-size: 13px;
    font-family: inherit;
    /* backdrop-filter removed — creates a compositing layer for every toast.
       Background raised to rgba(8,8,12,0.96) for equivalent visual legibility. */
    will-change: transform; /* promotes to own layer ONLY for the slide animation */
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 210px;
    max-width: 320px;

    /* Initial state: fully off-screen to the right */
    transform: translateX(140%);
    transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Adding the 'visible' class triggers the slide-in */
.notification-toast.visible {
    transform: translateX(0);
}

/* Icon colours */
.notification-join  .notif-icon { color: #00ff78; font-size: 14px; }
.notification-leave .notif-icon { color: #ff4d4d; font-size: 14px; }

.notif-msg {
    font-size: 13px;
    font-weight: 400;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Ensure correct layout on mobile (still top-right, slightly smaller) */
@media (max-width: 599px) {
    .notification-container {
        top: 10px;
        right: 10px;
    }

    .notification-toast {
        min-width: 140px;
        max-width: calc(100vw - 80px);
        font-size: 12px;
        padding: 9px 12px;
    }

    /* Thumbnail card text/avatar already scale via cqi clamp() — no override
       needed. Bump touch target on mobile only. */
    .main-card-name   { font-size: 18px; }
    .main-card-avatar { width: 60px; height: 60px; font-size: 22px; }
    .main-card-timer  { font-size: 12px; }

    .peer-mute-btn {
        min-width: 40px;
        min-height: 40px;
    }
}
