/* StravixVMS.Player — player + timeline styles.
   Ported from Stravix-Interview's wwwroot/css/multiview.css (the .camera-player* and
   .recording-timeline* rules), de-MudBlazor'd: every color that used to read a
   --mud-palette-* custom property now reads its own --stravix-player-* or --stravix-timeline-*
   property with the SAME fallback hex, so the package looks identical out of the box and a
   host can re-theme it by setting these on an ancestor — no MudBlazor (or any CSS
   framework) required. Load this stylesheet from the host page:
     <link rel="stylesheet" href="_content/StravixVMS.Player/css/player.css" /> */

/* ── Player ──────────────────────────────────────────────────────────────── */

/* Fills whatever box the host gives it and acts as the query container the fit box sizes
   against. Transparent so the letterbox area shows the host's own background. */
.stravix-player {
    --stravix-player-bar-h: 36px;
    position: relative;
    width: 100%;
    height: 100%;
    container-type: size;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    overflow: hidden;
    font-family: inherit;
}

/* With ShowControls off, no bar is rendered — stop reserving its height so the video fills
   the box (otherwise that strip becomes dead space below the video). */
.stravix-player--no-bar { --stravix-player-bar-h: 0px; }

/* No-bar mode skips the fit-box math entirely: under a percentage-height host chain that
   resolves to auto, 100cqh degrades and the min() collapses to its width branch — the video
   fills the width pinned to the top of the cell. Filling the host box directly lets
   object-fit: contain letterbox symmetrically, with no JS-computed aspect ratio needed. */
.stravix-player--no-bar .stravix-player__fit {
    width: 100%;
    height: 100%;
}

.stravix-player--no-bar .stravix-player__video-wrap {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
}

/* The fit box — the largest box of the video's aspect ratio (plus the bar's height) that
   fits the host's box, sized purely in CSS via container-query units. --stravix-player-ar
   (the video's intrinsic width/height) is set by videoPlayer.js on loadedmetadata; it
   defaults to 16:9 until metadata loads. The info bar sits directly below the video with no
   letterbox gap, and the area around the box is transparent. */
.stravix-player__fit {
    display: flex;
    flex-direction: column;
    width: min(100cqw, (100cqh - var(--stravix-player-bar-h)) * var(--stravix-player-ar, 1.7778));
    max-width: 100%;
    max-height: 100%;
}

/* Video area — sized to the video's aspect ratio so object-fit never letterboxes; the
   positioned parent for the overlay so the bar is never obscured. Carries the black ground
   so a tile with nothing loaded yet still reads as a video tile. */
.stravix-player__video-wrap {
    position: relative;
    width: 100%;
    aspect-ratio: var(--stravix-player-ar, 1.7778);
    min-height: 0;
    overflow: hidden;
    background: #000;
}

/* No background of its own, deliberately (DUM-522). The black ground belongs to the wrapper
   above; painting it here as well made the element itself opaque black the instant it lost
   its decoded frame, which is precisely the flash-to-black a stall must not produce. */
.stravix-player__video {
    width: 100%;
    height: 100%;
    object-fit: contain; /* box matches the video aspect, so this never letterboxes */
    display: block;
}

/* Fullscreen targets the video wrapper (so caption/name/mute overlays ride along). Drop
   the aspect-ratio box and fill the screen; the video letterboxes inside via
   object-fit:contain and the caption stays bottom-centred over it. */
.stravix-player__video-wrap:fullscreen {
    width: 100vw;
    height: 100vh;
    aspect-ratio: auto;
    background: #000;
}

.stravix-player__overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: rgba(0, 0, 0, 0.72);
    color: #ccc;
    text-align: center;
    font-size: 0.8rem;
}

/* Stalled is the one overlay state with something worth seeing underneath it: videoPlayer.js
   recovers a live stream in place rather than tearing the element down, so the last decoded
   frame is still painted. Scrim it only as much as the spinner and label need to stay
   readable — the full 0.72 wash would hide the very frame the recovery exists to keep.
   Error and Offline keep the heavy scrim: there is nothing behind them worth showing, and a
   stale frame must never be mistaken for live video. */
.stravix-player__overlay--stalled {
    background: rgba(0, 0, 0, 0.3);
    color: #eee;
}

.stravix-player__overlay--stalled .stravix-player__overlay-text {
    color: #fff;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
}

.stravix-player__overlay-text { color: #ccc; }
.stravix-player__overlay-text--error { color: #f88; max-width: 80%; }
.stravix-player__overlay-text--dim { color: #888; }

.stravix-player__spinner {
    width: 30px;
    height: 30px;
    border: 3px solid rgba(255, 255, 255, 0.25);
    border-top-color: #fff;
    border-radius: 50%;
    animation: stravix-player-spin 0.8s linear infinite;
}

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

.stravix-player__hint {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
}

/* Name / mute overlays float on the video itself, independent of the info bar. */
.stravix-player__name-overlay {
    position: absolute;
    top: 6px;
    left: 8px;
    z-index: 4;
    color: #fff;
    font-size: 0.75rem;
    font-weight: 600;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
    pointer-events: none;
    max-width: calc(100% - 16px);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── Tile affordance cluster (DUM-520) ────────────────────────────────────── */
/* Controls that float on the video itself rather than living in the info bar, so a host
   running ShowControls=false still gets them. A flex ROW, not a fixed slot: it lays out
   however many affordances the component gives it, so the next one to arrive costs no layout
   work here. Top-right, opposite the name overlay's top-left, and above both the state
   overlay and the caption so a control is never buried by a scrim.

   pointer-events is off on the cluster and back on for each child: the cluster spans a strip
   of the tile, and a host that puts a click-to-focus handler on the tile must keep getting
   those clicks everywhere except on an actual button. */
.stravix-player__affordances {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 6;
    display: flex;
    align-items: center;
    gap: 4px;
    pointer-events: none;
}

/* One affordance. Sized for a finger as well as a mouse, and carrying its own scrim, since
   unlike the info-bar icon buttons it sits directly on video that could be any colour. */
.stravix-player__tile-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: rgba(255, 255, 255, 0.92);
    cursor: pointer;
    pointer-events: auto;
    flex: 0 0 auto;
    transition: background-color 0.12s ease;
}

.stravix-player__tile-btn:hover { background: rgba(0, 0, 0, 0.78); }
.stravix-player__tile-btn:disabled { opacity: 0.45; cursor: default; }
.stravix-player__tile-btn svg { width: 17px; height: 17px; display: block; }

/* The "this affordance is currently active" treatment — an unmuted tile on a wall of muted
   ones has to be findable at a glance, because it is the one making noise. */
.stravix-player__tile-btn--on {
    background: var(--stravix-player-accent, #7c4dff);
    color: #fff;
}

.stravix-player__tile-btn--on:hover { background: var(--stravix-player-accent, #7c4dff); filter: brightness(1.15); }

/* Caption overlay — bottom-centred line(s) of text. Decorative: never intercepts clicks, so
   tile controls keep working underneath. Clamps to two lines so a long line can't grow the
   tile. */
.stravix-player__caption {
    position: absolute;
    bottom: 8px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 5;
    max-width: calc(100% - 24px);
    padding: 2px 8px;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    font-size: 0.8rem;
    line-height: 1.3;
    text-align: center;
    border-radius: 4px;
    pointer-events: none;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ── Info bar — always-visible strip below the video ──────────────────────── */
/* Accent normally; switches to the recording color while IsRecording is set. */

.stravix-player__info-bar {
    flex: 0 0 var(--stravix-player-bar-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 2px 0 8px;
    background: var(--stravix-player-accent, #7c4dff);
    gap: 4px;
    overflow: hidden;
}

.stravix-player__info-bar--recording {
    background: var(--stravix-player-recording, #f44336);
}

.stravix-player__bar-left {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
}

.stravix-player__bar-name {
    color: #fff;
    font-size: 0.72rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.stravix-player__bar-right {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

/* Compact volume slider in the bar next to the mute button. White accent so it's visible
   on the coloured bar. */
.stravix-player__volume {
    width: 72px;
    height: 4px;
    margin: 0 4px;
    accent-color: #fff;
    cursor: pointer;
    flex: 0 0 auto;
}

/* Status dot — white on the coloured bar: dim when not live, bright + glowing when live. */
.stravix-player__status {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.35);
    transition: background 0.3s ease;
}

.stravix-player__status--live {
    background: #fff;
    box-shadow: 0 0 5px rgba(255, 255, 255, 0.8);
}

/* Icon buttons (mute, snapshot, PiP, quality toggle) — plain, framework-free. */
.stravix-player__icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: rgba(255, 255, 255, 0.85);
    cursor: pointer;
    flex: 0 0 auto;
}

.stravix-player__icon-btn:hover { background: rgba(255, 255, 255, 0.15); }
.stravix-player__icon-btn:disabled { opacity: 0.5; cursor: default; }
.stravix-player__icon-btn svg { width: 18px; height: 18px; display: block; }

/* HD/SD quality toggle — text instead of an icon, so the round icon-button shape widens
   to fit two letters. */
.stravix-player__icon-btn--text {
    width: auto;
    min-width: 28px;
    border-radius: 10px;
    padding: 0 6px;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

/* Text buttons (Retry, quality-switch hint, and the overlay's own action). */
.stravix-player__text-btn {
    border: 1px solid rgba(255, 255, 255, 0.4);
    background: transparent;
    color: #fff;
    border-radius: 4px;
    padding: 4px 12px;
    font-size: 0.75rem;
    cursor: pointer;
}

.stravix-player__text-btn:hover { background: rgba(255, 255, 255, 0.12); }

.stravix-player__text-btn--filled {
    background: var(--stravix-player-accent, #7c4dff);
    border-color: transparent;
}

.stravix-player__text-btn--filled:hover { filter: brightness(1.1); }

/* ── Timeline ────────────────────────────────────────────────────────────── */

.stravix-timeline {
    position: relative;
    height: 64px;
    background: rgba(0, 0, 0, 0.85);
    flex-shrink: 0;
    overflow: visible;
    color: #ddd;
    font-size: 11px;
    font-family: inherit;
}

.stravix-timeline__host {
    /* vis-timeline sets `style="position: relative"` inline on the container element it
       owns. Use explicit width/height so the host fills the parent regardless. */
    width: 100%;
    height: 100%;
}

.stravix-timeline__skeleton {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.stravix-timeline__skeleton-events,
.stravix-timeline__skeleton-axis {
    background: rgba(255, 255, 255, 0.08);
    border-radius: 3px;
    animation: stravix-timeline-pulse 1.4s ease-in-out infinite;
}

.stravix-timeline__skeleton-events { flex: 0 0 20px; }
.stravix-timeline__skeleton-axis { flex: 1 1 auto; min-height: 0; }

@keyframes stravix-timeline-pulse {
    0%, 100% { opacity: 0.35; }
    50%      { opacity: 0.7; }
}

/* Off-screen cursor indicator — pinned to the active edge with an arrow and the time. */
.stravix-timeline__cursor-bubble {
    position: absolute;
    top: 4px;
    background: rgba(20, 20, 20, 0.92);
    color: #fff;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 11px;
    line-height: 16px;
    z-index: 5;
    pointer-events: none;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    gap: 4px;
}

.stravix-timeline__cursor-bubble--left  { left: 4px; }
.stravix-timeline__cursor-bubble--right { right: 4px; }
.stravix-timeline__cursor-arrow         { font-weight: bold; }

/* Floating cursor pill — JS-rendered sibling of the host. */
.stravix-timeline .st-cursor-pill {
    position: absolute;
    top: -10px;
    transform: translateX(-50%);
    background: rgba(20, 20, 20, 0.92);
    color: #fff;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 11px;
    line-height: 16px;
    white-space: nowrap;
    z-index: 6;
    pointer-events: none;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}

/* vis-timeline elements are JS-rendered; selectors target classes the lib emits, scoped
   under .stravix-timeline so they don't leak into the host page. */

.stravix-timeline .vis-timeline {
    border: none;
    background: transparent;
    font-family: inherit;
    color: #ddd;
}

.stravix-timeline .vis-panel.vis-top,
.stravix-timeline .vis-panel.vis-bottom,
.stravix-timeline .vis-panel.vis-left,
.stravix-timeline .vis-panel.vis-right,
.stravix-timeline .vis-panel.vis-center {
    border-color: rgba(255, 255, 255, 0.08);
}

.stravix-timeline .vis-time-axis .vis-text {
    color: #bbb;
}

.stravix-timeline .vis-time-axis .vis-grid.vis-minor {
    border-color: rgba(255, 255, 255, 0.06);
}

.stravix-timeline .vis-time-axis .vis-grid.vis-major {
    border-color: rgba(255, 255, 255, 0.12);
}

/* The default full-span (or per-source coverage) item. */
.stravix-timeline .vis-item.vis-range.recording-span {
    background-color: var(--stravix-timeline-coverage, #4caf50);
    border-color: var(--stravix-timeline-coverage-darken, #388e3c);
    border-radius: 2px;
    color: transparent;
    cursor: pointer;
    min-width: 2px;
}

.stravix-timeline .vis-item.vis-range.recording-span:hover {
    background-color: var(--stravix-timeline-coverage-hover, #66bb6a);
}

/* Note point items. vis-timeline renders a point item as a small dot with a label; we hide
   the label and color the dot so a note reads as a pin on the bar. */
.stravix-timeline .vis-item.vis-point.note-mark {
    color: transparent;
    cursor: pointer;
}

.stravix-timeline .vis-item.vis-point.note-mark .vis-dot {
    border-color: var(--stravix-timeline-note, #2196f3);
    border-width: 7px;
    background-color: var(--stravix-timeline-note, #2196f3);
    cursor: pointer;
}

.stravix-timeline .vis-item.vis-point.note-mark:hover .vis-dot {
    border-color: var(--stravix-timeline-note-hover, #64b5f6);
    background-color: var(--stravix-timeline-note-hover, #64b5f6);
}

/* The playback cursor custom-time line. */
.stravix-timeline .vis-custom-time.playback-cursor {
    background-color: var(--stravix-timeline-cursor, #ff9800);
    width: 2px;
    z-index: 4;
}

/* Editable segment ranges. Drawn translucent over the default span so the underlying
   footage block still reads. */
.stravix-timeline .vis-item.vis-range.clip-segment {
    background-color: color-mix(in srgb, var(--stravix-timeline-segment, #9c27b0) 55%, transparent);
    border-color: var(--stravix-timeline-segment, #9c27b0);
    border-radius: 2px;
    color: transparent;
    cursor: grab;
    min-width: 2px;
}

.stravix-timeline .vis-item.vis-range.clip-segment:hover {
    background-color: color-mix(in srgb, var(--stravix-timeline-segment, #9c27b0) 75%, transparent);
}

/* vis-timeline draws drag handles on an editable item's ends. */
.stravix-timeline .vis-item.clip-segment .vis-drag-left,
.stravix-timeline .vis-item.clip-segment .vis-drag-right {
    cursor: ew-resize;
}

/* Image marks — a point in the timeline, click-to-seek like a note. */
.stravix-timeline .vis-item.vis-point.clip-image {
    color: transparent;
    cursor: pointer;
}

.stravix-timeline .vis-item.vis-point.clip-image .vis-dot {
    border-color: var(--stravix-timeline-segment, #9c27b0);
    border-width: 7px;
    background-color: var(--stravix-timeline-segment, #9c27b0);
    cursor: pointer;
}

.stravix-timeline .vis-item.vis-point.clip-image:hover .vis-dot {
    border-color: var(--stravix-timeline-segment-hover, #ba68c8);
    background-color: var(--stravix-timeline-segment-hover, #ba68c8);
}

/* Ghost rectangle drawn while Shift+dragging a new segment onto the timeline. */
.stravix-timeline .st-segment-ghost {
    position: absolute;
    top: 0;
    bottom: 0;
    background: color-mix(in srgb, var(--stravix-timeline-segment, #9c27b0) 30%, transparent);
    border: 1px dashed var(--stravix-timeline-segment, #9c27b0);
    pointer-events: none;
    z-index: 5;
}
