Skins
Packaged player designs that include both UI components and their styles.
A skin wraps the media component and provides the player’s complete interface. It combines a specific set of UI components with the styles that arrange and present them.
Packaged and ejected skins
When you choose a skin you have two options for how you use it: packaged or ejected. It’s usually easiest to start with a packaged skin and later eject its internal components into your project when you need more customization.
Packaged skins cover common visual changes through documented CSS custom properties. Packaged video skins also let you replace the poster. When you need more than that, eject and change the components and styles directly.
| Packaged | Ejected |
|---|---|
| Single component | Many UI components |
| Documented CSS custom properties | Components and styles you own |
| Future design updates auto-applied by bumping the version | Future design updates manually applied, or intentionally ignored |
Packaged skin
<script type="module">
import '@videojs/html/video/player';
import '@videojs/html/video/skin';
</script>
<video-player>
<video-skin>
<video src="video.mp4"></video>
</video-skin>
</video-player>import { Video, VideoPlayer, VideoSkin } from '@videojs/react/video';
import '@videojs/react/video/skin.css';
export function Player() {
return (
<VideoPlayer>
<VideoSkin>
<Video src="video.mp4" />
</VideoSkin>
</VideoPlayer>
);
}Don’t depend on elements, class names, or undocumented custom properties inside a packaged skin. They may change between releases.
Ejected skin
An ejected skin exposes its UI components and styles as app code that you own. You can add, remove, rearrange, or restyle any part of it.
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-beta.32/video.js"></script>
<link rel="stylesheet" href="./player.css">
<video-player poster="https://image.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/thumbnail.webp">
<media-container class="media-skin media-container video-skin" data-theme="default" data-preset="video">
<slot>
</slot>
<media-poster class="media-poster">
<img alt="" decoding="async" />
</media-poster>
<media-buffering-indicator class="media-buffering-indicator">
<media-icon name="spinner" class="media-buffering-indicator-spinner-icon">
</media-icon>
</media-buffering-indicator>
<media-error-dialog class="media-dialog-root">
<media-dialog-backdrop class="media-dialog-backdrop">
</media-dialog-backdrop>
<media-dialog-popup class="media-dialog-popup">
<div class="media-dialog-content">
<media-dialog-title class="media-dialog-title">
</media-dialog-title>
<media-dialog-description class="media-dialog-description">
</media-dialog-description>
</div>
<div class="media-dialog-actions">
<media-dialog-close class="media-button media-dialog-close">
</media-dialog-close>
</div>
</media-dialog-popup>
</media-error-dialog>
<media-controls>
<media-controls-backdrop class="video-controls-backdrop">
</media-controls-backdrop>
<media-controls-content class="video-controls video-controls-content">
<media-tooltip-group>
<media-controls-group class="video-controls-primary">
<media-play-button class="media-button media-play-button" id="vjs-2LlEBWp8-0-trigger">
<media-icon name="restart" class="media-button-icon media-play-button-restart-icon">
</media-icon>
<media-icon name="play" class="media-button-icon media-play-button-play-icon">
</media-icon>
<media-icon name="pause" class="media-button-icon media-play-button-pause-icon">
</media-icon>
</media-play-button>
<media-tooltip trigger="vjs-2LlEBWp8-0-trigger" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-tooltip-label>
</media-tooltip-label>
<media-tooltip-shortcut class="media-tooltip-shortcut">
</media-tooltip-shortcut>
</media-tooltip>
<media-mute-button commandfor="vjs-w7EFSLPI-0-popup" class="media-button media-mute-button video-controls-volume-button" id="vjs-2LlEBWp8-0-2-trigger">
<media-icon name="volume-off" class="media-button-icon media-mute-button-off-icon">
</media-icon>
<media-icon name="volume-low" class="media-button-icon media-mute-button-low-icon">
</media-icon>
<media-icon name="volume-high" class="media-button-icon media-mute-button-high-icon">
</media-icon>
</media-mute-button>
<media-tooltip trigger="vjs-2LlEBWp8-0-2-trigger" delay="0" disabled sticky side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-tooltip-label>
</media-tooltip-label>
<media-tooltip-shortcut class="media-tooltip-shortcut">
</media-tooltip-shortcut>
</media-tooltip>
<media-volume-popover open-on-hover delay="200" close-delay="100" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-volume-popover" id="vjs-w7EFSLPI-0-popup">
<media-volume-slider class="media-slider media-volume-slider" thumb-alignment="edge" orientation="vertical">
<media-slider-track class="media-slider-track">
<media-slider-fill class="media-slider-fill">
</media-slider-fill>
</media-slider-track>
<media-slider-thumb class="media-slider-thumb media-volume-slider-thumb">
</media-slider-thumb>
</media-volume-slider>
</media-volume-popover>
<media-controls-group class="video-time-slider-group">
<media-time class="media-time-value video-time-value" type="current">
</media-time>
<media-time-slider class="media-slider media-time-slider">
<media-time-slider-chapters class="media-time-slider-chapters">
<template>
<div class="media-time-slider-chapter">
<media-slider-track class="media-slider-track media-time-slider-chapter-track">
<media-slider-buffer class="media-slider-buffer">
</media-slider-buffer>
<media-slider-fill class="media-slider-fill">
</media-slider-fill>
</media-slider-track>
</div>
</template>
</media-time-slider-chapters>
<media-slider-thumb class="media-slider-thumb media-time-slider-thumb">
</media-slider-thumb>
<media-slider-preview class="media-slider-preview" overflow="visible">
<div class="media-slider-preview-content media-popup-surface media-slider-thumbnail">
<media-slider-thumbnail class="media-slider-thumbnail-image">
</media-slider-thumbnail>
<media-icon name="spinner" class="media-slider-thumbnail-spinner-icon">
</media-icon>
</div>
<div class="media-slider-preview-content media-time-slider-preview-content">
<media-time-slider-chapter-title class="media-time-slider-chapter-title">
</media-time-slider-chapter-title>
<media-slider-value class="media-time-slider-value" type="pointer">
</media-slider-value>
</div>
</media-slider-preview>
</media-time-slider>
<media-time class="media-time-toggle video-time-value" type="remaining" toggle>
</media-time>
</media-controls-group>
<media-captions-button class="media-button media-captions-button video-controls-captions-button" id="vjs-2LlEBWp8-0-3-trigger">
<media-icon name="captions-off" class="media-button-icon media-captions-button-off-icon">
</media-icon>
<media-icon name="captions-on" class="media-button-icon media-captions-button-on-icon">
</media-icon>
</media-captions-button>
<media-tooltip trigger="vjs-2LlEBWp8-0-3-trigger" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-tooltip-label>
</media-tooltip-label>
<media-tooltip-shortcut class="media-tooltip-shortcut">
</media-tooltip-shortcut>
</media-tooltip>
<button commandfor="vjs--FkLpPw4-0-popup" class="media-button media-settings-menu-trigger video-controls-settings-button" id="vjs-2LlEBWp8-0-4-trigger">
<media-icon name="gear" class="media-button-icon media-settings-menu-trigger-icon">
</media-icon>
<media-text class="media-settings-menu-trigger-label" token="menu.settings">Settings</media-text>
</button>
<media-tooltip trigger="vjs-2LlEBWp8-0-4-trigger" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-text token="menu.settings">Settings</media-text>
</media-tooltip>
<media-menu side="top" align="center" class="media-popup media-popup-surface media-menu-popup media-menu-resizable-popup" id="vjs--FkLpPw4-0-popup">
<media-menu-content class="media-menu-content">
<media-menu-item commandfor="vjs-9u7bYsN5-0-content" class="media-menu-trigger-item">
<media-icon name="switches" class="media-menu-trigger-item-icon">
</media-icon>
<media-text token="menu.quality">Quality</media-text>
<span class="media-menu-hint">
<span data-part="value" class="media-menu-hint-label">
</span>
<media-icon name="chevron" class="media-menu-forward-chevron">
</media-icon>
</span>
</media-menu-item>
<media-menu-content class="media-menu-content" id="vjs-9u7bYsN5-0-content">
<media-menu-item class="media-menu-back-item">
<media-icon name="chevron" class="media-menu-back-chevron">
</media-icon>
<media-text token="menu.quality">Quality</media-text>
</media-menu-item>
<media-menu-separator class="media-menu-separator">
</media-menu-separator>
<media-quality-radio-group class="media-menu-radio-group">
<template>
<media-menu-radio-item class="media-menu-radio-item">
<span>
<span data-part="label">
</span>
<sup data-part="tier" class="media-menu-tier">
</sup>
</span>
<span data-part="badge" class="media-menu-badge">
</span>
<media-menu-item-indicator force-mount class="media-menu-item-indicator">
<media-icon name="check" class="media-menu-radio-item-icon">
</media-icon>
</media-menu-item-indicator>
</media-menu-radio-item>
</template>
</media-quality-radio-group>
</media-menu-content>
<media-menu-item commandfor="vjs-ieXR5ng0-0-content" class="media-menu-trigger-item">
<media-icon name="speech" class="media-menu-trigger-item-icon">
</media-icon>
<media-text token="menu.audio">Audio</media-text>
<span class="media-menu-hint">
<span data-part="value" class="media-menu-hint-label">
</span>
<media-icon name="chevron" class="media-menu-forward-chevron">
</media-icon>
</span>
</media-menu-item>
<media-menu-content class="media-menu-content" id="vjs-ieXR5ng0-0-content">
<media-menu-item class="media-menu-back-item">
<media-icon name="chevron" class="media-menu-back-chevron">
</media-icon>
<media-text token="menu.audio">Audio</media-text>
</media-menu-item>
<media-menu-separator class="media-menu-separator">
</media-menu-separator>
<media-audio-track-radio-group class="media-menu-radio-group">
<template>
<media-menu-radio-item class="media-menu-radio-item">
<span data-part="label">
</span>
<media-menu-item-indicator force-mount class="media-menu-item-indicator">
<media-icon name="check" class="media-menu-radio-item-icon">
</media-icon>
</media-menu-item-indicator>
</media-menu-radio-item>
</template>
</media-audio-track-radio-group>
</media-menu-content>
<media-menu-item commandfor="vjs-aHbCtmyv-0-content" class="media-menu-trigger-item">
<media-icon name="speed" class="media-menu-trigger-item-icon">
</media-icon>
<media-text token="menu.speed">Speed</media-text>
<span class="media-menu-hint">
<span data-part="value" class="media-menu-hint-label">
</span>
<media-icon name="chevron" class="media-menu-forward-chevron">
</media-icon>
</span>
</media-menu-item>
<media-menu-content class="media-menu-content" id="vjs-aHbCtmyv-0-content">
<media-menu-item class="media-menu-back-item">
<media-icon name="chevron" class="media-menu-back-chevron">
</media-icon>
<media-text token="menu.speed">Speed</media-text>
</media-menu-item>
<media-menu-separator class="media-menu-separator">
</media-menu-separator>
<media-playback-rate-radio-group class="media-menu-radio-group">
<template>
<media-menu-radio-item class="media-menu-radio-item">
<span data-part="label">
</span>
<media-menu-item-indicator force-mount class="media-menu-item-indicator">
<media-icon name="check" class="media-menu-radio-item-icon">
</media-icon>
</media-menu-item-indicator>
</media-menu-radio-item>
</template>
</media-playback-rate-radio-group>
</media-menu-content>
<media-menu-item commandfor="vjs-VFLiqDY6-0-content" class="media-menu-trigger-item">
<media-icon name="captions-off" class="media-menu-trigger-item-icon">
</media-icon>
<media-text token="menu.captions">Captions</media-text>
<span class="media-menu-hint">
<span data-part="value" class="media-menu-hint-label">
</span>
<media-icon name="chevron" class="media-menu-forward-chevron">
</media-icon>
</span>
</media-menu-item>
<media-menu-content class="media-menu-content" id="vjs-VFLiqDY6-0-content">
<media-menu-item class="media-menu-back-item">
<media-icon name="chevron" class="media-menu-back-chevron">
</media-icon>
<media-text token="menu.captions">Captions</media-text>
</media-menu-item>
<media-menu-separator class="media-menu-separator">
</media-menu-separator>
<media-captions-radio-group class="media-menu-radio-group">
<template>
<media-menu-radio-item class="media-menu-radio-item">
<span data-part="label">
</span>
<media-menu-item-indicator force-mount class="media-menu-item-indicator">
<media-icon name="check" class="media-menu-radio-item-icon">
</media-icon>
</media-menu-item-indicator>
</media-menu-radio-item>
</template>
</media-captions-radio-group>
</media-menu-content>
</media-menu-content>
</media-menu>
</media-controls-group>
<media-controls-group class="video-controls-secondary">
<media-cast-button class="media-button media-cast-button" id="vjs-2LlEBWp8-0-5-trigger">
<media-icon name="cast-enter" class="media-button-icon media-cast-button-enter-icon">
</media-icon>
<media-icon name="cast-exit" class="media-button-icon media-cast-button-exit-icon">
</media-icon>
</media-cast-button>
<media-tooltip trigger="vjs-2LlEBWp8-0-5-trigger" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-tooltip-label>
</media-tooltip-label>
<media-tooltip-shortcut class="media-tooltip-shortcut">
</media-tooltip-shortcut>
</media-tooltip>
<media-airplay-button class="media-button media-airplay-button" id="vjs-2LlEBWp8-0-6-trigger">
<media-icon name="airplay-enter" class="media-button-icon media-airplay-button-enter-icon">
</media-icon>
<media-icon name="airplay-exit" class="media-button-icon media-airplay-button-exit-icon">
</media-icon>
</media-airplay-button>
<media-tooltip trigger="vjs-2LlEBWp8-0-6-trigger" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-tooltip-label>
</media-tooltip-label>
<media-tooltip-shortcut class="media-tooltip-shortcut">
</media-tooltip-shortcut>
</media-tooltip>
<media-pip-button class="media-button media-pip-button" id="vjs-2LlEBWp8-0-7-trigger">
<media-icon name="pip-enter" class="media-button-icon media-pip-button-enter-icon">
</media-icon>
<media-icon name="pip-exit" class="media-button-icon media-pip-button-exit-icon">
</media-icon>
</media-pip-button>
<media-tooltip trigger="vjs-2LlEBWp8-0-7-trigger" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-tooltip-label>
</media-tooltip-label>
<media-tooltip-shortcut class="media-tooltip-shortcut">
</media-tooltip-shortcut>
</media-tooltip>
<media-fullscreen-button class="media-button media-fullscreen-button" id="vjs-2LlEBWp8-0-8-trigger">
<media-icon name="fullscreen-enter" class="media-button-icon media-fullscreen-button-enter-icon">
</media-icon>
<media-icon name="fullscreen-exit" class="media-button-icon media-fullscreen-button-exit-icon">
</media-icon>
</media-fullscreen-button>
<media-tooltip trigger="vjs-2LlEBWp8-0-8-trigger" side="top" class="media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip">
<media-tooltip-label>
</media-tooltip-label>
<media-tooltip-shortcut class="media-tooltip-shortcut">
</media-tooltip-shortcut>
</media-tooltip>
</media-controls-group>
</media-tooltip-group>
</media-controls-content>
</media-controls>
<media-hotkey keys="Space" action="togglePaused">
</media-hotkey>
<media-hotkey keys="k" action="togglePaused">
</media-hotkey>
<media-hotkey keys="m" action="toggleMuted">
</media-hotkey>
<media-hotkey keys="ArrowRight" action="seekStep">
</media-hotkey>
<media-hotkey keys="ArrowLeft" action="seekStep">
</media-hotkey>
<media-hotkey keys="l" action="seekStep">
</media-hotkey>
<media-hotkey keys="j" action="seekStep">
</media-hotkey>
<media-hotkey keys="ArrowUp" action="volumeStep">
</media-hotkey>
<media-hotkey keys="ArrowDown" action="volumeStep">
</media-hotkey>
<media-hotkey keys="0-9" action="seekToPercent">
</media-hotkey>
<media-hotkey keys="Home" action="seekToPercent" value="0">
</media-hotkey>
<media-hotkey keys="End" action="seekToPercent" value="100">
</media-hotkey>
<media-hotkey keys=">" action="speedUp">
</media-hotkey>
<media-hotkey keys="<" action="speedDown">
</media-hotkey>
<media-hotkey keys="f" action="toggleFullscreen">
</media-hotkey>
<media-hotkey keys="c" action="toggleSubtitles">
</media-hotkey>
<media-hotkey keys="i" action="togglePictureInPicture">
</media-hotkey>
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center">
</media-gesture>
<media-gesture type="tap" action="toggleControls" pointer="touch">
</media-gesture>
<media-gesture type="doubletap" action="seekStep" region="left">
</media-gesture>
<media-gesture type="doubletap" action="toggleFullscreen" region="center">
</media-gesture>
<media-gesture type="doubletap" action="seekStep" region="right">
</media-gesture>
<media-status-announcer class="media-status-announcer">
</media-status-announcer>
<div class="video-status-indicators">
<media-volume-indicator class="media-indicator media-volume-indicator">
<media-volume-indicator-fill class="media-indicator-content media-volume-indicator-fill">
<media-icon name="volume-high" class="media-volume-indicator-high-icon">
</media-icon>
<media-icon name="volume-low" class="media-volume-indicator-low-icon">
</media-icon>
<media-icon name="volume-off" class="media-volume-indicator-off-icon">
</media-icon>
<media-volume-indicator-value class="media-volume-indicator-value">
</media-volume-indicator-value>
</media-volume-indicator-fill>
</media-volume-indicator>
<media-status-indicator actions="toggleSubtitles,toggleFullscreen,togglePictureInPicture" class="media-indicator media-status-indicator">
<div class="media-indicator-content media-status-indicator-content">
<media-icon name="captions-on" class="media-status-indicator-captions-on-icon">
</media-icon>
<media-icon name="captions-off" class="media-status-indicator-captions-off-icon">
</media-icon>
<media-icon name="fullscreen-enter" class="media-status-indicator-fullscreen-enter-icon">
</media-icon>
<media-icon name="fullscreen-exit" class="media-status-indicator-fullscreen-exit-icon">
</media-icon>
<media-icon name="pip-enter" class="media-status-indicator-pip-enter-icon">
</media-icon>
<media-icon name="pip-exit" class="media-status-indicator-pip-exit-icon">
</media-icon>
<media-status-indicator-value class="media-status-indicator-value">
</media-status-indicator-value>
</div>
</media-status-indicator>
<media-seek-indicator class="media-seek-indicator">
<media-icon name="chevron" class="media-seek-indicator-icon">
</media-icon>
<media-seek-indicator-value class="media-seek-indicator-value">
</media-seek-indicator-value>
</media-seek-indicator>
<media-status-indicator actions="togglePaused" class="media-playback-status-indicator">
<media-icon name="play" class="media-playback-status-indicator-play-icon">
</media-icon>
<media-icon name="pause" class="media-playback-status-indicator-pause-icon">
</media-icon>
</media-status-indicator>
</div>
</media-container>
</video-player>/* -------------------------------------------------------------------------- */
/* Global styles for the host document, outside of the Shadow DOM */
/* -------------------------------------------------------------------------- */
video-player,
live-video-player,
media-i18n,
media-dialog,
media-alert-dialog,
media-error-dialog,
media-controls {
display: contents;
}
/*
Required to override any default video and image styles (such as
Tailwind's CSS reset) and ensure they fill the container as expected.
*/
media-container video,
media-container [slot="poster"] {
display: block;
width: 100%;
height: 100%;
}
media-container video::-webkit-media-text-track-container {
z-index: 1;
font-family: inherit;
scale: 0.98;
translate: 0 var(--media-caption-track-y, 0);
transition: translate var(--media-caption-track-duration, 0) ease-out;
transition-delay: var(--media-caption-track-delay, 0);
}
/* -------------------------------------------------------------------------- */
/* Shared styles for all HTML skins */
/* -------------------------------------------------------------------------- */
media-tooltip-group,
media-dialog,
media-alert-dialog,
media-error-dialog,
media-controls {
display: contents;
}
:host {
/* `display:grid` fixes a weird issue with Safari when setting aspect-ratio */
display: grid;
width: 100%;
}
media-container {
min-width: 0;
min-height: 0;
}
/* Hide the volume popover when its slider is unavailable. */
.media-popover--volume:has(media-volume-slider[data-hidden]) {
display: none;
}
@layer base {
@scope (.media-skin) {
:scope,
*,
:before,
:after {
box-sizing: border-box;
}
button {
font: inherit;
color: inherit;
text-transform: none;
letter-spacing: inherit;
appearance: none;
background: none;
margin: 0;
}
img,
svg,
media-icon {
max-width: 100%;
margin: 0;
display: block;
}
svg[fill="currentColor"] {
fill: currentColor;
}
svg[fill="none"] {
fill: none;
}
svg[stroke="currentColor"] {
stroke: currentColor;
}
video {
border-radius: inherit;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
width: 100%;
max-width: 100%;
height: 100%;
margin: 0;
display: block;
}
media-icon > svg {
width: 100%;
height: 100%;
}
media-tooltip-group,
media-dialog,
media-alert-dialog,
media-error-dialog,
media-controls {
display: contents;
}
[hidden][hidden] {
display: none !important;
}
}
@media (prefers-reduced-motion: no-preference) {
.media-skin {
interpolate-size: allow-keywords;
}
}
}
@layer components {
@scope (.media-skin) {
:scope {
--media-caption-track-duration: var(--media-duration-controls);
--media-caption-track-delay: 25ms;
--media-caption-track-y: calc(var(--media-spacing) * -2);
}
video::-webkit-media-text-track-container {
z-index: 20;
scale: 0.98;
translate: 0 var(--media-caption-track-y);
transition: translate var(--media-caption-track-duration) ease-out;
transition-delay: var(--media-caption-track-delay);
font-family: inherit;
}
:scope[data-controls-visible] {
--media-caption-track-y: var(--media-caption-controls-y);
}
@container media-root (width >= 42rem) {
:scope[data-theme="minimal"][data-controls-visible] video {
--media-caption-track-y: calc(var(--media-spacing) * -12);
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-buffering-indicator {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
color: var(--media-controls-foreground);
place-content: center;
display: none;
position: absolute;
}
.media-buffering-indicator:not([data-visible]) {
--media-spinner-animation: none;
}
.media-buffering-indicator:before {
inset: calc(var(--media-spacing) * 0);
background-color: var(--media-backdrop);
content: "";
backdrop-filter: var(--media-backdrop-filter-indicator);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-buffering-indicator:before {
background-color: color-mix(in oklab, var(--media-backdrop) 35%, transparent);
}
}
.media-buffering-indicator[data-visible] {
display: grid;
}
.media-buffering-indicator-spinner-icon {
z-index: 30;
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
position: relative;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-button {
width: var(--media-control-size);
height: var(--media-control-size);
min-height: calc(var(--media-spacing) * 0);
cursor: pointer;
touch-action: manipulation;
border-radius: var(--media-control-radius);
padding: calc(var(--media-spacing) * 0);
text-align: center;
color: inherit;
outline-offset: -2px;
transition-property: background-color, color, outline-offset, scale;
transition-duration: var(--media-duration);
will-change: scale;
-webkit-user-select: none;
user-select: none;
corner-shape: var(--media-control-corner-shape);
text-shadow: inherit;
background-color: #0000;
border-style: solid;
border-width: 0;
outline: 2px solid #0000;
flex-shrink: 0;
place-items: center;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: grid;
}
.media-button:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-button:not([aria-disabled="true"]):active {
scale: 0.97;
}
.media-button[aria-disabled="true"] {
cursor: not-allowed;
opacity: 0.5;
}
@media (prefers-reduced-motion: reduce) {
.media-button {
will-change: auto;
transition-property: background-color, color;
scale: 1;
}
}
.media-button:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-button:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-dialog-actions {
gap: calc(var(--media-spacing) * 2);
flex-shrink: 0;
display: flex;
}
.media-dialog-backdrop {
inset: calc(var(--media-spacing) * 0);
z-index: 40;
background-color: var(--media-backdrop);
opacity: 1;
backdrop-filter: var(--media-backdrop-filter-dialog);
transition-property: opacity;
transition-duration: 0.15s;
transition-delay: var(--media-delay-dialog);
transition-duration: var(--media-duration-dialog);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-dialog-backdrop {
background-color: color-mix(in oklab, var(--media-backdrop) 20%, transparent);
}
}
.media-dialog-backdrop:not([data-open]) {
display: none;
}
.media-dialog-backdrop[data-ending-style] {
transition-delay: 0s;
transition-duration: var(--media-duration-slower);
}
.media-dialog-backdrop:is([data-starting-style], [data-ending-style]) {
opacity: 0;
}
.media-dialog-close {
height: var(--media-control-size);
width: 100%;
padding-inline: calc(var(--media-spacing) * 4);
padding-block: calc(var(--media-spacing) * 2);
flex: 1;
font-weight: 500;
background-color: var(--media-primary) !important;
color: var(--media-primary-foreground) !important;
}
.media-dialog-content {
min-height: calc(var(--media-spacing) * 0);
gap: calc(var(--media-spacing) * 2);
padding-inline: calc(var(--media-spacing) * 2);
padding-top: calc(var(--media-spacing) * 2);
padding-bottom: calc(var(--media-spacing) * 1.5);
flex-direction: column;
display: flex;
overflow-y: auto;
}
.media-dialog-description {
margin: calc(var(--media-spacing) * 0);
overflow-wrap: anywhere;
opacity: 0.7;
}
.media-dialog-popup {
z-index: 50;
max-height: calc(100% - 0.5rem);
width: var(--media-dialog-width);
max-width: var(--media-dialog-max-width);
gap: calc(var(--media-spacing) * 3);
border-radius: var(--media-dialog-radius);
background-color: var(--media-popover);
padding: calc(var(--media-spacing) * 3);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-delay: var(--media-delay-dialog);
transition-duration: var(--media-duration-dialog);
text-shadow: var(--media-text-shadow-dialog);
outline-style: none;
flex-direction: column;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: flex;
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
}
@media (forced-colors: active) {
.media-dialog-popup {
outline-offset: 2px;
outline: 2px solid #0000;
}
}
.media-dialog-popup:not([data-open]) {
display: none;
}
.media-dialog-popup:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
.media-dialog-popup[data-ending-style] {
transition-delay: 0s;
transition-duration: var(--media-duration-slower);
}
.media-dialog-popup:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-popup-scale) var(--media-hidden-popup-scale);
opacity: 0;
}
.media-dialog-title {
margin: calc(var(--media-spacing) * 0);
font-size: calc(var(--media-spacing) * 3.75);
font-weight: 600;
line-height: 1.25;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-container,
:scope.media-container {
isolation: isolate;
border-radius: var(--media-video-border-radius);
background-color: var(--media-background);
width: 100%;
height: 100%;
font-family: var(--media-font-family, "Inter Variable", Inter, ui-sans-serif, system-ui, sans-serif);
font-size: calc(var(--media-spacing) * 3.25);
-webkit-font-smoothing: auto;
-moz-osx-font-smoothing: auto;
outline-offset: -4px;
transition-property: outline-offset, outline-color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
--spacing: var(--media-spacing);
outline: 2px solid #0000;
line-height: 1.5;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: block;
position: relative;
overflow: clip;
container: media-root / size;
}
.media-container:after,
:scope.media-container:after {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
z-index: 10;
border-radius: inherit;
content: "";
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
inset 0 0 0 1px var(--media-frame-border);
position: absolute;
}
.media-container:focus-visible,
:scope.media-container:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-container:fullscreen:after,
:scope.media-container:fullscreen:after {
content: "";
display: none;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-poster {
pointer-events: none;
border-radius: inherit;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
width: 100%;
height: 100%;
transition-property: opacity;
transition-duration: 0.15s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: var(--media-duration-slower);
position: absolute;
inset: 0;
}
.media-poster:not([data-visible]) {
opacity: 0;
}
.media-poster img {
border-radius: inherit;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
width: 100%;
height: 100%;
position: absolute;
inset: 0;
}
.media-poster:is(img):not([src]):not([srcset]) {
visibility: hidden;
}
}
.media-poster > slot::slotted(img) {
border-radius: inherit;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
width: 100%;
height: 100%;
position: absolute;
inset: 0;
}
.media-poster > slot::slotted(img:not([src]):not([srcset])),
.media-poster > slot > img:not([src]):not([srcset]) {
visibility: hidden;
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-seek-indicator {
place-content: center;
gap: calc(var(--media-spacing) * 1);
padding: calc(var(--media-spacing) * 4);
text-align: center;
grid-row-start: 1;
grid-column-start: 2;
display: grid;
}
.media-seek-indicator[data-direction="backward"] {
grid-column-start: 1;
justify-self: flex-start;
}
.media-seek-indicator[data-direction="forward"] {
grid-column-start: 3;
justify-self: flex-end;
}
@container media-root (width >= 42rem) {
.media-seek-indicator {
padding: calc(var(--media-spacing) * 6);
}
}
.media-seek-indicator-icon {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
transition-property: translate, opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: none;
}
@scope (.media-seek-indicator) {
&[data-direction] .media-seek-indicator-icon {
display: block;
}
}
@scope (.media-seek-indicator) {
&[data-direction="backward"] .media-seek-indicator-icon {
scale: -1 1;
}
}
@scope (.media-seek-indicator) {
&[data-direction="backward"][data-starting-style] .media-seek-indicator-icon {
translate: var(--media-hidden-seek-offset) 0;
}
}
@scope (.media-seek-indicator) {
&[data-direction="forward"][data-starting-style] .media-seek-indicator-icon {
translate: calc(var(--media-hidden-seek-offset) * -1) 0;
}
}
@scope (.media-seek-indicator) {
&:is([data-starting-style], [data-ending-style]) .media-seek-indicator-icon {
opacity: 0;
}
}
.media-seek-indicator-value {
font-variant-numeric: tabular-nums;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-status-announcer {
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
position: absolute;
overflow: hidden;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-indicator {
pointer-events: none;
top: calc(var(--media-spacing) * 3);
transform-origin: top;
border-radius: var(--media-control-radius);
background-color: var(--media-backdrop);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
transition-duration: var(--media-duration-fast);
font-weight: 500;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-indicator {
background-color: color-mix(in oklab, var(--media-backdrop) 25%, transparent);
}
}
.media-indicator:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
.media-indicator[data-ending-style] {
translate: 0 var(--media-hidden-indicator-offset);
}
@media (pointer: coarse) {
.media-indicator {
will-change: scale, translate, opacity;
transition-property: scale, translate, opacity;
}
}
@media (pointer: fine) {
.media-indicator {
will-change: scale, translate, filter, opacity;
transition-property: scale, translate, filter, opacity;
}
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
.media-indicator {
background-color: var(--media-background);
}
}
.media-indicator:is([data-starting-style], [data-ending-style]) {
opacity: 0;
transition-duration: var(--media-duration-indicator);
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
@media (pointer: fine) {
.media-indicator:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-indicator-scale) var(--media-hidden-indicator-scale);
filter: blur(var(--media-hidden-blur));
}
}
.media-indicator-content {
justify-content: space-between;
align-items: center;
gap: calc(var(--media-spacing) * 2);
padding-inline: calc(var(--media-spacing) * 2.5);
padding-block: calc(var(--media-spacing) * 1);
}
.media-playback-status-indicator {
background-color: var(--media-backdrop);
padding: calc(var(--media-spacing) * 4);
text-align: center;
backdrop-filter: var(--media-backdrop-filter-indicator);
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
border-radius: 9999px;
grid-row-start: 1;
grid-column-start: 2;
place-content: center;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: grid;
}
@supports (color: color-mix(in lab, red, red)) {
.media-playback-status-indicator {
background-color: color-mix(in oklab, var(--media-backdrop) 35%, transparent);
}
}
.media-playback-status-indicator[data-ending-style] {
transition-duration: var(--media-duration-fast);
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
.media-playback-status-indicator:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-playback-scale) var(--media-hidden-playback-scale);
opacity: 0;
}
.media-playback-status-indicator-pause-icon {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
grid-row-start: 1;
grid-column-start: 1;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
@scope (.media-playback-status-indicator) {
&[data-status="pause"] .media-playback-status-indicator-pause-icon {
opacity: 1;
scale: 1;
}
}
.media-playback-status-indicator-play-icon {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
grid-row-start: 1;
grid-column-start: 1;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
@scope (.media-playback-status-indicator) {
&[data-status="play"] .media-playback-status-indicator-play-icon {
opacity: 1;
translate: 1px;
scale: 1;
}
}
.media-status-indicator-captions-off-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="captions-off"] .media-status-indicator-captions-off-icon {
display: block;
}
}
.media-status-indicator-captions-on-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="captions-on"] .media-status-indicator-captions-on-icon {
display: block;
}
}
.media-status-indicator-content {
width: 100%;
display: flex;
}
.media-status-indicator-fullscreen-enter-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="fullscreen"] .media-status-indicator-fullscreen-enter-icon {
display: block;
}
}
.media-status-indicator-fullscreen-exit-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="exit-fullscreen"] .media-status-indicator-fullscreen-exit-icon {
display: block;
}
}
.media-status-indicator-pip-enter-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="pip"] .media-status-indicator-pip-enter-icon {
display: block;
}
}
.media-status-indicator-pip-exit-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="exit-pip"] .media-status-indicator-pip-exit-icon {
display: block;
}
}
.media-status-indicator-value {
mix-blend-mode: difference;
margin-left: auto;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@supports (color: color-mix(in lab, red, red)) {
}
@media (pointer: coarse) {
}
@media (pointer: fine) {
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
}
@media (pointer: fine) {
}
.media-volume-indicator {
width: min(80%, 12rem);
transform: translateX(0);
}
@media (prefers-reduced-motion: no-preference) {
.media-volume-indicator:is([data-min], [data-max]):not([data-starting-style], [data-ending-style]) {
transition: transform 0.3s linear(0, -24 20%, 16 40%, -8 60%, 4 80%, 1);
transform: translateX(0.25px);
}
}
.media-volume-indicator-fill {
border-radius: inherit;
background-image: linear-gradient(currentColor, currentColor);
background-size: var(--media-volume-fill, 0%) 100%;
width: 100%;
transition-property: background-size;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
background-position: 0;
background-repeat: no-repeat;
transition-timing-function: linear;
display: flex;
}
.media-volume-indicator-high-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-volume-indicator) {
&[data-level="high"] .media-volume-indicator-high-icon {
display: block;
}
}
.media-volume-indicator-low-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-volume-indicator) {
&[data-level="low"] .media-volume-indicator-low-icon {
display: block;
}
}
.media-volume-indicator-off-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-volume-indicator) {
&[data-level="off"] .media-volume-indicator-off-icon {
display: block;
}
}
.media-volume-indicator-value {
mix-blend-mode: difference;
margin-left: auto;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.video-status-indicators {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
color: var(--media-controls-foreground);
grid-template-columns: repeat(3, minmax(0, 1fr));
place-items: center;
display: grid;
position: absolute;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-airplay-button:not([data-airplay-state="connected"]) {
--media-icon-airplay-fill-animation: none;
--media-icon-airplay-triangle-animation: none;
}
.media-airplay-button-enter-icon {
opacity: 0;
}
@scope (.media-airplay-button) {
&:not([data-airplay-state="connected"]) .media-airplay-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-airplay-button-exit-icon {
opacity: 0;
}
@scope (.media-airplay-button) {
&[data-airplay-state="connected"] .media-airplay-button-exit-icon {
opacity: 1;
scale: 1;
}
}
.media-button-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
grid-row-start: 1;
grid-column-start: 1;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-popup {
margin: calc(var(--media-spacing) * 0);
color: inherit;
border-style: solid;
border-width: 0;
overflow: visible;
}
.media-popup[data-ending-style] {
transform: none;
}
.media-popup[data-starting-style] {
transform: translate(var(--media-popup-translate-x-distance, 0), var(--media-popup-translate-y-distance, 0));
}
.media-popup[data-side="bottom"] {
transform-origin: top;
--media-popup-translate-y-distance: calc(var(--media-popup-translate-distance) * -1);
}
.media-popup[data-side="left"] {
transform-origin: 100%;
--media-popup-translate-x-distance: var(--media-popup-translate-distance);
}
.media-popup[data-side="right"] {
transform-origin: 0;
--media-popup-translate-x-distance: calc(var(--media-popup-translate-distance) * -1);
}
.media-popup[data-side="top"] {
transform-origin: bottom;
--media-popup-translate-y-distance: var(--media-popup-translate-distance);
}
.media-popup:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-popup-scale) var(--media-hidden-popup-scale);
opacity: 0;
filter: blur(var(--media-hidden-popup-blur));
}
.media-popup-safe-area:before {
pointer-events: auto;
content: "";
position: absolute;
}
.media-popup-safe-area[data-side="bottom"]:before {
inset-inline: calc(var(--media-spacing) * 0);
content: "";
height: var(--media-popup-side-offset);
bottom: 100%;
}
.media-popup-safe-area[data-side="left"]:before {
inset-block: calc(var(--media-spacing) * 0);
content: "";
width: var(--media-popup-side-offset);
left: 100%;
}
.media-popup-safe-area[data-side="right"]:before {
inset-block: calc(var(--media-spacing) * 0);
content: "";
width: var(--media-popup-side-offset);
right: 100%;
}
.media-popup-safe-area[data-side="top"]:before {
inset-inline: calc(var(--media-spacing) * 0);
content: "";
height: var(--media-popup-side-offset);
top: 100%;
}
.media-popup-surface {
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
}
.media-popup-surface:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
.media-popup-transition {
transition-property: opacity, filter, transform, scale;
transition-duration: var(--media-duration-fast);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-popup-transition[data-ending-style] {
transition-duration: var(--media-duration-instant);
}
.media-tooltip {
border-radius: var(--media-control-radius);
padding-inline: calc(var(--media-spacing) * 2.5);
padding-block: calc(var(--media-spacing) * 1);
font-size: calc(var(--media-spacing) * 3.25);
white-space: nowrap;
--media-popup-side-offset: var(--media-tooltip-side-offset);
}
.media-tooltip[data-open] {
align-items: center;
gap: calc(var(--media-spacing) * 1);
display: flex;
}
.media-tooltip-shortcut {
border-radius: calc(var(--media-spacing) * 1);
background-color: var(--media-muted);
text-align: center;
min-width: 1.5em;
font-family: inherit;
font-size: calc(var(--media-spacing) * 2.75);
padding: 0.1em;
font-weight: 600;
line-height: 1.25;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-captions-button-off-icon {
opacity: 0;
}
@scope (.media-captions-button) {
&:not([data-active]) .media-captions-button-off-icon {
opacity: 1;
scale: 1;
}
}
.media-captions-button-on-icon {
opacity: 0;
}
@scope (.media-captions-button) {
&[data-active] .media-captions-button-on-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-cast-button-enter-icon {
opacity: 0;
}
@scope (.media-cast-button) {
&:not([data-cast-state="connected"]) .media-cast-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-cast-button-exit-icon {
opacity: 0;
}
@scope (.media-cast-button) {
&[data-cast-state="connected"] .media-cast-button-exit-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-fullscreen-button-enter-icon {
opacity: 0;
}
@scope (.media-fullscreen-button) {
&:not([data-fullscreen]) .media-fullscreen-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-fullscreen-button-exit-icon {
opacity: 0;
}
@scope (.media-fullscreen-button) {
&[data-fullscreen] .media-fullscreen-button-exit-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-pip-button-enter-icon {
opacity: 0;
}
@scope (.media-pip-button) {
&:not([data-pip]) .media-pip-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-pip-button-exit-icon {
opacity: 0;
}
@scope (.media-pip-button) {
&[data-pip] .media-pip-button-exit-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-play-button-pause-icon {
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
}
@scope (.media-play-button) {
&[data-started]:not([data-paused]):not([data-ended]) .media-play-button-pause-icon {
opacity: 1;
scale: 1;
}
}
.media-play-button-play-icon {
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
}
@scope (.media-play-button) {
&:not([data-ended]):not([data-started]) .media-play-button-play-icon,
&:not([data-ended])[data-paused] .media-play-button-play-icon {
opacity: 1;
scale: 1;
}
}
.media-play-button-restart-icon {
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
}
@scope (.media-play-button) {
&[data-ended] .media-play-button-restart-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-mute-button-high-icon {
opacity: 0;
}
@scope (.media-mute-button) {
&:not([data-muted]):not([data-volume-level="low"]) .media-mute-button-high-icon {
opacity: 1;
scale: 1;
}
}
.media-mute-button-low-icon {
opacity: 0;
}
@scope (.media-mute-button) {
&:not([data-muted])[data-volume-level="low"] .media-mute-button-low-icon {
opacity: 1;
scale: 1;
}
}
.media-mute-button-off-icon {
opacity: 0;
}
@scope (.media-mute-button) {
&[data-muted] .media-mute-button-off-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-slider-buffer {
pointer-events: none;
border-radius: inherit;
transition-property: clip-path;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slider);
background-color: currentColor;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-buffer {
background-color: color-mix(in oklab, currentcolor 20%, transparent);
}
}
@scope (.media-slider) {
&[data-dragging] .media-slider-buffer,
&[data-seeking] .media-slider-buffer {
transition-duration: 0s;
}
}
.media-slider-buffer[data-orientation="horizontal"] {
inset-block: calc(var(--media-spacing) * 0);
left: calc(var(--media-spacing) * 0);
width: 100%;
clip-path: inset(0 calc(100% - var(--media-slider-buffer)) 0 0 round var(--media-control-radius));
}
.media-slider-buffer[data-orientation="vertical"] {
inset-inline: calc(var(--media-spacing) * 0);
bottom: calc(var(--media-spacing) * 0);
height: 100%;
clip-path: inset(calc(100% - var(--media-slider-buffer)) 0 0 0 round var(--media-control-radius));
}
.media-slider-fill {
pointer-events: none;
border-radius: inherit;
background-color: var(--media-primary);
transition-property: clip-path;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slider);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-fill,
&[data-seeking] .media-slider-fill {
transition-duration: 0s;
}
}
.media-slider-fill[data-orientation="horizontal"] {
inset-block: calc(var(--media-spacing) * 0);
left: calc(var(--media-spacing) * 0);
width: 100%;
clip-path: inset(0 calc(100% - var(--media-slider-fill)) 0 0 round var(--media-control-radius));
}
@scope (.media-slider) {
&[data-dragging] .media-slider-fill[data-orientation="horizontal"] {
clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--media-control-radius));
}
}
.media-slider-fill[data-orientation="vertical"] {
inset-inline: calc(var(--media-spacing) * 0);
bottom: calc(var(--media-spacing) * 0);
height: 100%;
clip-path: inset(calc(100% - var(--media-slider-fill)) 0 0 0 round var(--media-control-radius));
}
@scope (.media-slider) {
&[data-dragging] .media-slider-fill[data-orientation="vertical"] {
clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--media-control-radius));
}
}
.media-slider-thumb {
top: 50%;
left: var(--media-slider-fill);
z-index: 10;
width: calc(var(--media-spacing) * 3);
height: calc(var(--media-spacing) * 3);
border-radius: var(--media-control-radius);
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
var(--media-shadow-thumb);
outline-offset: -4px;
transition-property: opacity, height, width, outline-offset, left, top, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slider);
-webkit-user-select: none;
user-select: none;
background-color: currentColor;
outline: 4px solid #0000;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
translate: -50% -50%;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-thumb {
transition-property: opacity, height, width, outline-offset, scale;
transition-duration: 0.15s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
scale: 0.9;
}
}
.media-slider-thumb:after {
pointer-events: none;
inset: calc(var(--media-spacing) * -1);
border-radius: inherit;
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
content: "";
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
scale: 0.5;
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 0 2px;
}
@media (hover: hover) {
.media-slider-thumb:hover {
outline-offset: 0px;
outline-color: currentColor;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-thumb:hover {
outline-color: color-mix(in oklab, currentcolor 15%, transparent);
}
}
}
.media-slider-thumb:focus-visible {
outline-offset: 0px;
outline-color: currentColor;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-thumb:focus-visible {
outline-color: color-mix(in oklab, currentcolor 15%, transparent);
}
}
.media-slider-thumb:focus-visible:after {
content: "";
opacity: 1;
scale: 1;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-thumb[data-orientation="horizontal"] {
left: var(--media-slider-pointer);
}
}
.media-slider-thumb[data-orientation="vertical"] {
top: calc(100% - var(--media-slider-fill));
left: 50%;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-thumb[data-orientation="vertical"] {
top: calc(100% - var(--media-slider-pointer));
}
}
.media-slider-track {
isolation: isolate;
-webkit-user-select: none;
user-select: none;
background-color: currentColor;
border-radius: 9999px;
width: 100%;
position: relative;
overflow: hidden;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-track {
background-color: color-mix(in oklab, currentcolor 20%, transparent);
}
}
.media-slider-track[data-orientation="horizontal"] {
height: calc(var(--media-spacing) * 1);
}
.media-slider-track[data-orientation="vertical"] {
height: 100%;
width: calc(var(--media-spacing) * 1);
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-slider {
cursor: pointer;
border-radius: 9999px;
outline-style: none;
flex: 1;
justify-content: center;
align-items: center;
display: flex;
position: relative;
}
@media (forced-colors: active) {
.media-slider {
outline-offset: 2px;
outline: 2px solid #0000;
}
}
.media-slider[data-orientation="horizontal"] {
height: var(--media-slider-height, calc(var(--media-spacing) * 8));
min-width: calc(var(--media-spacing) * 20);
}
.media-slider[data-orientation="vertical"] {
height: calc(var(--media-spacing) * 20);
width: calc(var(--media-spacing) * 8);
min-width: calc(var(--media-spacing) * 0);
}
.media-volume-slider-thumb {
opacity: 1;
scale: 1;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-volume-popover {
border-radius: var(--media-control-radius);
padding-inline: calc(var(--media-spacing) * 0);
padding-block: calc(var(--media-spacing) * 3);
--media-popup-side-offset: var(--media-popover-side-offset);
}
.media-volume-popover[data-side="right"] {
padding: calc(var(--media-spacing) * 0);
padding-inline: calc(var(--media-spacing) * 3);
--media-popover-side-offset: 0rem;
border-radius: 0;
box-shadow: none !important;
backdrop-filter: none !important;
background-color: #0000 !important;
}
.media-volume-popover[data-side="right"]:after {
content: "";
display: none;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (forced-colors: active) {
}
.media-slider-preview {
height: calc(var(--media-spacing) * 1);
min-width: var(--media-slider-preview-max-width);
--media-slider-preview-max-height: var(--media-slider-preview-max-width);
--media-slider-preview-max-width: min(calc(var(--media-spacing) * 36), 100cqi);
position: relative;
}
.media-slider-preview:before {
pointer-events: none;
z-index: 1;
width: calc(var(--media-spacing) * 1);
height: calc(var(--media-spacing) * 1);
border-radius: var(--media-control-radius);
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
content: "";
background-color: currentColor;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
scale: 0.5;
}
.media-slider-preview[data-pointing]:not([data-dragging]):before {
content: "";
opacity: 1;
scale: 1;
}
@container media-root (width >= 42rem) {
.media-slider-preview {
--media-slider-preview-max-width: min(calc(var(--media-spacing) * 48), 100cqi);
}
}
.media-slider-preview-content {
max-width: var(--media-slider-preview-max-width);
transform-origin: bottom;
translate: -50% var(--media-hidden-preview-offset);
scale: var(--media-hidden-preview-scale) var(--media-hidden-preview-scale);
opacity: 0;
filter: blur(var(--media-hidden-blur));
transition-property: filter, opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
:where(.media-slider):has(:focus-visible) .media-slider-preview-content,
:where(.media-slider-preview)[data-pointing] .media-slider-preview-content {
opacity: 1;
filter: none;
scale: 1;
}
.media-slider-thumbnail {
pointer-events: none;
bottom: calc(100% + var(--media-slider-preview-offset));
border-radius: var(--media-popup-radius);
background-color: var(--media-backdrop);
left: 50%;
overflow: hidden;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-thumbnail {
background-color: color-mix(in oklab, var(--media-backdrop) 90%, transparent);
}
}
.media-slider-thumbnail:has([data-loading]) {
aspect-ratio: 16 / 9;
width: var(--media-slider-preview-max-width);
}
.media-slider-thumbnail-image {
max-height: var(--media-slider-preview-max-height);
max-width: var(--media-slider-preview-max-width);
border-radius: inherit;
transition-property: opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: block;
position: relative;
overflow: clip;
}
.media-slider-thumbnail-image:after {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
border-radius: inherit;
content: "";
background-image: var(--media-thumbnail-gradient);
position: absolute;
}
.media-slider-thumbnail-image[data-loading] {
opacity: 0;
}
.media-slider-thumbnail-spinner-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
opacity: 0;
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
transition-property: opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
}
@scope (.media-slider-thumbnail) {
&:not(:has([role="img"][data-loading])) .media-slider-thumbnail-spinner-icon {
--media-spinner-animation: none;
}
}
@scope (.media-slider-thumbnail) {
&:has([role="img"][data-loading]) .media-slider-thumbnail-spinner-icon {
opacity: 1;
}
}
.media-time-slider-chapter {
inset: calc(var(--media-spacing) * 0);
min-height: calc(var(--media-spacing) * 0);
min-width: calc(var(--media-spacing) * 0);
--media-chapter-inset-end: 0.5;
--media-chapter-inset-start: 0.5;
justify-content: center;
align-items: center;
display: flex;
position: absolute;
}
.media-time-slider-chapter:first-child {
--media-chapter-inset-start: 0;
}
.media-time-slider-chapter:last-child {
--media-chapter-inset-end: 0;
}
.media-time-slider-chapter[data-orientation="horizontal"] {
clip-path: inset(0 calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start));
}
.media-time-slider-chapter[data-orientation="vertical"] {
clip-path: inset(calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start) 0);
}
.media-time-slider-chapter-title {
max-width: var(--media-slider-preview-max-width);
min-width: calc(var(--media-spacing) * 0);
text-overflow: ellipsis;
white-space: nowrap;
padding-inline: calc(var(--media-spacing) * 6);
overflow: hidden;
}
.media-time-slider-chapter-title:empty {
display: none;
}
.media-time-slider-chapter-track {
transition-property: height, width;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-time-slider-chapter-track[data-orientation="horizontal"] {
clip-path: inset(
0 calc(100% - var(--media-slider-chapter-end) + var(--media-spacing) * var(--media-chapter-inset-end)) 0
calc(var(--media-slider-chapter-start) + var(--media-spacing) * var(--media-chapter-inset-start)) round
var(--media-control-radius)
);
}
@scope (.media-time-slider-chapter) {
&[data-highlighted] .media-time-slider-chapter-track[data-orientation="horizontal"] {
height: calc(var(--media-spacing) * 1.75);
}
}
.media-time-slider-chapter-track[data-orientation="vertical"] {
clip-path: inset(
calc(100% - var(--media-slider-chapter-end) + var(--media-spacing) * var(--media-chapter-inset-end)) 0
calc(var(--media-slider-chapter-start) + var(--media-spacing) * var(--media-chapter-inset-start)) 0 round
var(--media-control-radius)
);
}
@scope (.media-time-slider-chapter) {
&[data-highlighted] .media-time-slider-chapter-track[data-orientation="vertical"] {
width: calc(var(--media-spacing) * 1.75);
}
}
.media-time-slider-chapters {
width: 100%;
height: 100%;
min-height: calc(var(--media-spacing) * 0);
min-width: calc(var(--media-spacing) * 0);
border-radius: inherit;
flex: 1;
align-items: center;
display: flex;
position: relative;
}
.media-time-slider-preview-content {
bottom: calc(100% + var(--media-slider-preview-label-offset));
font-variant-numeric: tabular-nums;
flex-direction: column;
align-items: center;
display: flex;
left: 50%;
}
.media-time-slider-thumb {
opacity: 0;
scale: 0.8;
}
.media-time-slider-thumb:focus-visible,
.media-time-slider-thumb[data-interactive] {
opacity: 1;
}
@media (pointer: fine) {
@media (hover: hover) {
@scope (.media-slider) {
&:hover .media-time-slider-thumb {
opacity: 1;
scale: 1;
}
}
}
}
.media-time-slider-value {
font-variant-numeric: tabular-nums;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-menu-back-chevron {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
rotate: 180deg;
}
@scope (.media-menu-back-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-back-chevron {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-back-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-back-chevron {
color: inherit;
}
}
}
.media-menu-back-chevron:dir(rtl) {
rotate: 0deg;
scale: 1;
}
.media-menu-forward-chevron {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
}
@scope (.media-menu-trigger-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-forward-chevron {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-trigger-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-forward-chevron {
color: inherit;
}
}
}
.media-menu-forward-chevron:dir(rtl) {
scale: -1 1;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-menu-item-indicator {
opacity: 0;
flex-shrink: 0;
margin-inline-start: auto;
margin-inline-end: calc(var(--media-spacing) * -1);
}
@scope (.media-menu-radio-item) {
&[aria-checked="true"] .media-menu-item-indicator {
opacity: 1;
}
}
.media-menu-radio-item {
cursor: pointer;
justify-content: space-between;
align-items: center;
gap: calc(var(--media-spacing) * 1.5);
border-radius: var(--media-menu-item-radius);
padding-inline: calc(var(--media-spacing) * 2);
padding-block: calc(var(--media-spacing) * 1.5);
text-align: start;
white-space: nowrap;
color: inherit;
font-variant-numeric: tabular-nums;
outline-offset: -2px;
transition-property: background-color, color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
-webkit-user-select: none;
user-select: none;
text-shadow: 0 1px 0 var(--media-shadow-current-color);
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
position: relative;
}
.media-menu-radio-item:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-menu-radio-item[aria-disabled="true"] {
pointer-events: none;
cursor: not-allowed;
opacity: 0.5;
}
.media-menu-radio-item[data-availability="unavailable"],
.media-menu-radio-item[data-availability="unsupported"] {
display: none;
}
.media-menu-radio-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-menu-radio-item:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
@supports (top: anchor(top)) {
.media-menu-radio-item {
transition-duration: var(--media-duration-instant);
}
.media-menu-radio-item[data-highlighted] {
anchor-name: --media-menu-item-highlight-anchor;
}
.media-menu-radio-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
@media (hover: hover) {
.media-menu-radio-item:hover:where(:not([aria-disabled="true"])) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
}
}
.media-menu-radio-item-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
}
@scope (.media-menu-radio-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-radio-item-icon {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-radio-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-radio-item-icon {
color: inherit;
}
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-menu-back-item {
margin-bottom: calc(var(--media-spacing) * 0.5);
cursor: pointer;
align-items: center;
gap: calc(var(--media-spacing) * 1.5);
border-radius: var(--media-menu-item-radius);
width: 100%;
padding-inline: calc(var(--media-spacing) * 2);
padding-block: calc(var(--media-spacing) * 1.5);
text-align: start;
white-space: nowrap;
outline-offset: -2px;
transition-property: background-color, color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
-webkit-user-select: none;
user-select: none;
text-shadow: 0 1px 0 var(--media-shadow-current-color);
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
position: relative;
}
.media-menu-back-item:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-menu-back-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-menu-back-item:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
@supports (top: anchor(top)) {
.media-menu-back-item {
transition-duration: var(--media-duration-instant);
}
.media-menu-back-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
transition-duration: var(--media-duration-slow);
}
@media (hover: hover) {
.media-menu-back-item:hover:where(:not([aria-disabled="true"])) {
transition-duration: var(--media-duration-slow);
}
}
}
.media-menu-content {
max-height: inherit;
overscroll-behavior: none;
transition-property: translate, filter;
transition-duration: 0.15s;
transition-duration: var(--media-duration-menu);
anchor-scope: --media-menu-item-highlight-anchor;
outline-style: none;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
overflow: auto;
}
@media (forced-colors: active) {
.media-menu-content {
outline-offset: 2px;
outline: 2px solid #0000;
}
}
.media-menu-content:not([data-submenu]) {
inset-inline: calc(var(--media-spacing) * 1);
top: calc(var(--media-spacing) * 1);
gap: calc(var(--media-spacing) * 0.5);
flex-direction: column;
display: flex;
}
.media-menu-content[data-submenu] {
inset-inline: calc(var(--media-spacing) * 0);
top: calc(var(--media-spacing) * 0);
z-index: 10;
max-height: inherit;
padding: calc(var(--media-spacing) * 1);
}
.media-menu-content:not([data-submenu])[data-child-open] {
filter: blur(var(--media-hidden-blur));
translate: -100%;
}
.media-menu-content:not([data-submenu])[data-child-open]:before {
content: "";
display: none;
}
.media-menu-content[data-submenu]:is([data-starting-style], [data-ending-style]) {
pointer-events: none;
filter: blur(var(--media-hidden-blur));
overflow: hidden;
translate: 100%;
}
@supports (top: anchor(top)) {
.media-menu-content:before {
content: "";
position-anchor: --media-menu-item-highlight-anchor;
inset: anchor(inside);
overflow-anchor: none;
pointer-events: none;
border-radius: var(--media-menu-item-radius);
background-color: var(--media-accent);
transition: inset var(--media-duration-fast) ease-in-out;
position: absolute;
}
.media-menu-content:has([data-highlighted=""]):before {
content: "";
transition-duration: 0s;
}
}
.media-menu-content:not([data-submenu])[data-child-open]:dir(rtl) {
translate: 100%;
}
.media-menu-content[data-submenu]:is([data-starting-style], [data-ending-style]):dir(rtl) {
translate: -100%;
}
.media-menu-hint {
min-width: calc(var(--media-spacing) * 0);
align-items: center;
gap: calc(var(--media-spacing) * 1);
color: currentColor;
margin-inline-start: auto;
padding-inline-start: calc(var(--media-spacing) * 2);
display: inline-flex;
}
@supports (color: color-mix(in lab, red, red)) {
.media-menu-hint {
color: color-mix(in oklab, currentcolor 65%, transparent);
}
}
.media-menu-hint-label {
max-width: calc(var(--media-spacing) * 24);
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.media-menu-radio-group {
max-height: inherit;
gap: calc(var(--media-spacing) * 0.5);
anchor-scope: --media-menu-item-highlight-anchor;
flex-direction: column;
display: flex;
}
@supports (top: anchor(top)) {
.media-menu-radio-group:before {
content: "";
position-anchor: --media-menu-item-highlight-anchor;
inset: anchor(inside);
overflow-anchor: none;
pointer-events: none;
border-radius: var(--media-menu-item-radius);
background-color: var(--media-accent);
transition: inset var(--media-duration-fast) ease-in-out;
position: absolute;
}
.media-menu-radio-group:has([data-highlighted=""]):before {
content: "";
transition-duration: 0s;
}
}
.media-menu-separator {
margin-block: calc(var(--media-spacing) * 1);
border-bottom-style: solid;
border-bottom-width: 1px;
border-color: var(--media-border);
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
var(--media-shadow-separator);
display: block;
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
.media-menu-separator {
border-color: var(--media-foreground);
}
@supports (color: color-mix(in lab, red, red)) {
.media-menu-separator {
border-color: color-mix(in oklab, var(--media-foreground) 25%, transparent);
}
}
}
.media-menu-trigger-item {
cursor: pointer;
justify-content: space-between;
align-items: center;
gap: calc(var(--media-spacing) * 1.5);
border-radius: var(--media-menu-item-radius);
padding-inline: calc(var(--media-spacing) * 2);
padding-block: calc(var(--media-spacing) * 1.5);
text-align: start;
white-space: nowrap;
color: inherit;
font-variant-numeric: tabular-nums;
outline-offset: -2px;
transition-property: background-color, color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
-webkit-user-select: none;
user-select: none;
text-shadow: 0 1px 0 var(--media-shadow-current-color);
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
position: relative;
}
.media-menu-trigger-item:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-menu-trigger-item[aria-disabled="true"] {
pointer-events: none;
cursor: not-allowed;
opacity: 0.5;
}
.media-menu-trigger-item[data-availability="unavailable"],
.media-menu-trigger-item[data-availability="unsupported"] {
display: none;
}
.media-menu-trigger-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-menu-trigger-item:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
@supports (top: anchor(top)) {
.media-menu-trigger-item {
transition-duration: var(--media-duration-instant);
}
.media-menu-trigger-item[data-highlighted] {
anchor-name: --media-menu-item-highlight-anchor;
}
.media-menu-trigger-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
@media (hover: hover) {
.media-menu-trigger-item:hover:where(:not([aria-disabled="true"])) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
}
}
.media-menu-trigger-item-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
}
@scope (.media-menu-trigger-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-trigger-item-icon {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-trigger-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-trigger-item-icon {
color: inherit;
}
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (hover: hover) {
}
@supports (top: anchor(top)) {
@media (hover: hover) {
}
}
.media-menu-badge {
border-radius: var(--media-control-radius);
background-color: var(--media-accent);
padding-inline: calc(var(--media-spacing) * 1.5);
font-size: 0.7em;
font-weight: 600;
}
@media (forced-colors: active) {
}
@supports (top: anchor(top)) {
}
@supports (color: color-mix(in lab, red, red)) {
}
@supports (top: anchor(top)) {
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
@supports (color: color-mix(in lab, red, red)) {
}
}
.media-menu-tier {
color: currentColor;
padding-inline-start: calc(var(--media-spacing) * 0.5);
padding-top: 1px;
font-size: 0.7em;
font-weight: 600;
line-height: 1;
}
@supports (color: color-mix(in lab, red, red)) {
.media-menu-tier {
color: color-mix(in oklab, currentcolor 70%, transparent);
}
}
@media (hover: hover) {
}
@supports (top: anchor(top)) {
@media (hover: hover) {
}
}
@scope (.media-menu-trigger-item) {
}
@media (hover: hover) {
@scope (.media-menu-trigger-item) {
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (forced-colors: active) {
}
@supports (top: anchor(top)) {
}
.media-menu-popup {
margin: calc(var(--media-spacing) * 0);
height: var(--media-menu-height);
max-height: min(
var(--media-menu-available-height, calc(var(--media-spacing) * 56)),
calc(var(--media-spacing) * 56)
);
width: var(--media-menu-width);
max-width: var(--media-menu-available-width);
min-width: calc(var(--media-spacing) * 44);
overscroll-behavior: none;
border-radius: var(--media-popup-radius);
padding: calc(var(--media-spacing) * 1);
transition-property: opacity, filter, transform, scale;
transition-duration: var(--media-duration-fast);
--media-popup-side-offset: var(--media-popover-side-offset);
border-style: solid;
border-width: 0;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
overflow: hidden !important;
}
.media-menu-popup:is([data-starting-style], [data-ending-style]) {
transition-property: opacity, filter, transform, scale;
transition-duration: var(--media-duration-fast);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-menu-resizable-popup {
transition-property: opacity, filter, transform, scale, width, height;
transition-duration:
var(--media-duration-fast), var(--media-duration-fast), var(--media-duration-fast), var(--media-duration-fast),
var(--media-duration-menu), var(--media-duration-menu);
}
.media-settings-menu-trigger-icon {
transition-property: transform, translate, scale, rotate;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
@scope (.media-settings-menu-trigger) {
&[aria-expanded="true"] .media-settings-menu-trigger-icon {
rotate: 90deg;
}
}
@media (prefers-reduced-motion: reduce) {
.media-settings-menu-trigger-icon {
transition-property: none !important;
}
}
.media-settings-menu-trigger-label {
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
position: absolute;
overflow: hidden;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.video-controls-backdrop {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
z-index: 10;
border-radius: inherit;
background-image: var(--media-controls-gradient);
transition-property: opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration-controls);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
.video-controls-backdrop:not([data-visible]) {
opacity: 0;
}
@container media-root (width < 32rem) {
.video-controls-captions-button {
display: none;
}
}
.video-controls-content {
padding: calc(var(--media-spacing) * 1);
color: var(--media-controls-foreground);
transition-property: filter, opacity, scale, translate;
transition-duration: 0.15s;
transition-duration: calc(var(--media-duration-controls) / 2);
text-shadow: 0 1px 0 var(--media-shadow-current-color);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: contents;
}
@container media-root (width >= 32rem) {
.video-controls-content {
inset-inline: calc(var(--media-spacing) * 2);
bottom: calc(var(--media-spacing) * 2);
z-index: 10;
border-radius: var(--media-controls-radius);
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
align-items: center;
display: flex;
position: absolute;
}
.video-controls-content:not([data-visible]) {
pointer-events: none;
translate: 0 var(--media-hidden-offset);
scale: var(--media-hidden-scale) var(--media-hidden-scale);
opacity: 0;
transition-duration: var(--media-duration-controls);
}
.video-controls-content:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
@media (pointer: fine) {
.video-controls-content:not([data-visible]) {
filter: blur(var(--media-hidden-blur));
}
}
}
@container media-root (width >= 42rem) {
.video-controls-content {
inset-inline: calc(var(--media-spacing) * 3);
bottom: calc(var(--media-spacing) * 3);
}
}
.video-controls-primary {
inset-inline: calc(var(--media-spacing) * 2);
bottom: calc(var(--media-spacing) * 2);
z-index: 10;
transform-origin: bottom;
border-radius: var(--media-controls-radius);
padding: calc(var(--media-spacing) * 1);
transition-property: filter, opacity, scale, translate;
transition-duration: 0.15s;
transition-duration: calc(var(--media-duration-controls) / 2);
align-items: center;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: flex;
position: absolute;
}
@container media-root (width >= 32rem) {
.video-controls-primary {
display: contents;
}
}
@container media-root (width < 32rem) {
.video-controls-primary {
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
}
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-primary {
pointer-events: none;
translate: 0 var(--media-hidden-offset);
scale: var(--media-hidden-scale) var(--media-hidden-scale);
opacity: 0;
transition-duration: var(--media-duration-controls);
}
}
.video-controls-primary:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
@media (pointer: fine) {
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-primary {
filter: blur(var(--media-hidden-blur));
}
}
}
}
.video-controls-secondary {
top: calc(var(--media-spacing) * 2);
right: calc(var(--media-spacing) * 2);
z-index: 10;
transform-origin: top;
border-radius: var(--media-controls-radius);
padding: calc(var(--media-spacing) * 1);
transition-property: filter, opacity, scale, translate;
transition-duration: 0.15s;
transition-duration: calc(var(--media-duration-controls) / 2);
align-items: center;
gap: 1px;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: flex;
position: absolute;
}
@container media-root (width >= 32rem) {
.video-controls-secondary {
padding: calc(var(--media-spacing) * 0);
position: static;
}
}
@container media-root (width < 32rem) {
.video-controls-secondary {
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
}
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-secondary {
pointer-events: none;
translate: 0 calc(var(--media-hidden-offset) * -1);
scale: var(--media-hidden-scale) var(--media-hidden-scale);
opacity: 0;
transition-duration: var(--media-duration-controls);
}
}
.video-controls-secondary:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
@media (pointer: fine) {
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-secondary {
filter: blur(var(--media-hidden-blur));
}
}
}
}
@container media-root (width >= 32rem) {
.video-controls-settings-button {
margin-inline-start: 1px;
}
}
.video-controls-volume-button {
margin-inline-start: 1px;
}
.video-time-slider-group {
align-items: center;
gap: calc(var(--media-spacing) * 2.5);
padding-inline: calc(var(--media-spacing) * 2);
flex: 1;
display: flex;
container: media-time / inline-size;
}
@container media-root (width >= 32rem) {
.video-time-slider-group {
padding-inline: calc(var(--media-spacing) * 3);
}
}
@container media-time (width < 16rem) {
.video-time-value {
display: none;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-time-toggle {
cursor: pointer;
font-variant-numeric: tabular-nums;
outline-offset: -2px;
transition-property: outline-color, outline-offset;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
border-radius: 0.25rem;
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-time-toggle:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-time-value {
font-variant-numeric: tabular-nums;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (pointer: fine) {
.video-skin:not([data-controls-visible]),
:scope.video-skin:not([data-controls-visible]) {
cursor: none;
}
}
}
}
@layer utilities;
@layer base.theme {
.media-skin {
--media-background: oklch(0% 0 0);
--media-foreground: oklch(100% 0 0);
--media-controls: oklch(0% 0 0 / 0.35);
--media-controls-foreground: var(--media-foreground);
--media-popover: oklch(100% 0 0 / 0.1);
--media-popover-foreground: var(--media-foreground);
--media-primary: var(--media-accent-color, var(--media-default-accent-color));
--media-primary-foreground: var(
--media-accent-text-color,
contrast-color(var(--media-accent-color, var(--media-default-accent-color)))
);
--media-accent: var(--media-accent-color, color-mix(in oklab, var(--media-default-accent-color) 10%, transparent));
--media-accent-foreground: var(
--media-accent-text-color,
contrast-color(var(--media-accent-color, var(--media-internal-accent-text-fallback, oklch(0% 0 0))))
);
--media-muted: oklch(100% 0 0 / 0.15);
--media-muted-foreground: oklch(100% 0 0 / 0.65);
--media-border: oklch(0% 0 0 / 0.1);
--media-ring: oklch(100% 0 0);
--media-backdrop: oklch(0% 0 0);
--media-live-color: oklch(65% 0.22 27);
--media-shadow-surface: 0 1px 3px 0 oklch(0% 0 0 / 0.15), 0 1px 2px -1px oklch(0% 0 0 / 0.15);
--media-shadow-surface-inset: inset 0 1px 0 0 #ffffff1a, inset 0 0 0 1px #ffffff0d;
--media-shadow-thumb: 0 0 0 1px #0000001a, 0 1px 3px 0 #00000059, 0 1px 2px -1px #00000059;
--media-shadow-tooltip: 0 0 0 1px var(--media-border), var(--media-shadow-surface);
--media-shadow-separator: 0 1px 0 0 oklch(100% 0 0 / 0.075);
--media-shadow-current-color: oklch(from currentColor 0 0 0 / clamp(0, calc((l - 0.5) * 0.5), 0.15));
--media-shadow-subtle-current-color: oklch(from var(--media-shadow-current-color) l c h / calc(alpha * 0.4));
--media-text-shadow-dialog: 0 1px 0 #00000040;
--media-backdrop-filter-surface: blur(16px) saturate(150%);
--media-backdrop-filter-indicator: blur(8px);
--media-backdrop-filter-dialog: blur(16px) saturate(150%);
--media-control-corner-shape: round;
--media-control-radius: calc(infinity * 1px);
--media-control-size: calc(var(--media-spacing) * 9);
--media-controls-radius: var(--media-control-radius);
--media-default-accent-color: oklch(100% 0 0);
--media-duration-instant: 50ms;
--media-duration-fast: 0.1s;
--media-duration: 0.15s;
--media-duration-slow: 0.2s;
--media-duration-slower: 0.25s;
--media-duration-controls: 0.1s;
--media-duration-dialog: 0.35s;
--media-duration-indicator: var(--media-duration-slower);
--media-duration-menu: 0.25s;
--media-duration-slider: var(--media-duration-fast);
--media-delay-dialog: 0.1s;
--media-hidden-scale: 0.95;
--media-hidden-blur: 8px;
--media-hidden-offset: calc(var(--media-spacing) * 1);
--media-hidden-icon-scale: 0;
--media-hidden-indicator-scale: 0.9;
--media-hidden-indicator-offset: -25%;
--media-hidden-playback-scale: 0.85;
--media-hidden-popup-scale: 0.95;
--media-hidden-popup-blur: 4px;
--media-hidden-preview-scale: 0.8;
--media-hidden-preview-offset: calc(var(--media-spacing) * 2);
--media-hidden-seek-offset: 60%;
--media-menu-item-radius: calc(var(--media-spacing) * 2);
--media-popover-boundary-offset: calc(var(--media-spacing) * 3);
--media-popover-side-offset: calc(var(--media-spacing) * 3);
--media-popup-radius: calc(var(--media-spacing) * 3);
--media-popup-translate-distance: calc(var(--media-spacing) * 2);
--media-tooltip-boundary-offset: var(--media-popover-boundary-offset);
--media-tooltip-side-offset: var(--media-popover-side-offset);
--media-dialog-radius: calc(var(--media-spacing) * 7);
--media-dialog-width: calc(100% - var(--media-spacing) * 6);
--media-dialog-max-width: calc(var(--media-spacing) * 72);
--media-slider-preview-label-offset: calc(var(--media-spacing) * 10.5);
--media-video-border-radius: var(--media-border-radius, 28px);
--media-scale: 1;
--media-scrollbar-thumb-color: oklch(from currentColor l c h / 0.3);
--media-spacing: calc(var(--media-scale-unit, 16px) * var(--media-scale) / 4);
scrollbar-color: var(--media-scrollbar-thumb-color) transparent;
scrollbar-width: thin;
}
.media-skin::-webkit-scrollbar-thumb {
background: var(--media-scrollbar-thumb-color);
border-radius: 9999px;
}
.media-skin:fullscreen {
--media-object-fit: contain;
--media-video-border-radius: 0;
}
@media (width >= 1280px) {
.media-skin:fullscreen {
--media-scale: 1.25;
}
}
@media (width >= 1536px) {
.media-skin:fullscreen {
--media-scale: 1.5;
}
}
@media (width >= 1920px) {
.media-skin:fullscreen {
--media-scale: 1.75;
}
}
.media-skin[data-theme="minimal"] {
--media-control-corner-shape: squircle;
--media-control-radius: calc(var(--media-spacing) * 2);
--media-control-size: calc(var(--media-spacing) * 9.5);
--media-controls-radius: calc(var(--media-spacing) * 3);
--media-popover: oklch(0% 0 0 / 0.5);
--media-border: oklch(100% 0 0 / 0.1);
--media-shadow-surface: 0 1px 2px oklch(0% 0 0 / 0.2);
--media-shadow-thumb: 0 0 0 1px #00000026, 0 1px 3px 0 #00000026, 0 1px 2px -1px #00000026;
--media-text-shadow-dialog: 0 1px 0 #00000080;
--media-backdrop-filter-dialog: blur(16px) saturate(120%);
--media-shadow-tooltip:
0 0 0 1px var(--media-border), 0 4px 6px -1px oklch(0% 0 0 / 0.2), 0 2px 4px -2px oklch(0% 0 0 / 0.2);
--media-duration-dialog: var(--media-duration);
--media-duration-indicator: 0.4s;
--media-hidden-offset: 100%;
--media-hidden-indicator-offset: -100%;
--media-menu-item-radius: calc(var(--media-spacing) * 1.5);
--media-popover-boundary-offset: calc(var(--media-spacing) * 2);
--media-popover-side-offset: calc(var(--media-spacing) * 5);
--media-popup-radius: calc(var(--media-spacing) * 2.5);
--media-popup-translate-distance: calc(var(--media-spacing) * 2);
--media-dialog-width: 100%;
--media-dialog-max-width: calc(var(--media-spacing) * 64);
--media-slider-preview-label-offset: calc(var(--media-spacing) * 5);
--media-video-border-radius: var(--media-border-radius, 12px);
}
.media-skin:is([data-preset="video"], [data-preset="live-video"]) {
--media-frame-border: var(--media-border-color, light-dark(#0000001a, #ffffff26));
--media-controls-gradient: linear-gradient(
to top in oklab,
oklch(from var(--media-backdrop) l c h / 0.5),
oklch(from var(--media-backdrop) l c h / 0.3) 25%,
transparent
);
--media-caption-controls-y: calc(var(--media-spacing) * -14);
--media-slider-preview-offset: calc(var(--media-spacing) * 9);
--media-thumbnail-gradient: linear-gradient(
to top,
oklch(from var(--media-backdrop) l c h / 0.5),
oklch(from var(--media-backdrop) l c h / 0.1),
transparent
);
}
.media-skin:is([data-preset="video"], [data-preset="live-video"])[data-theme="minimal"] {
--media-frame-border: var(--media-border-color, light-dark(#00000026, #ffffff26));
--media-controls-gradient: linear-gradient(
to top in oklab,
oklch(from var(--media-backdrop) l c h / 0.7),
oklch(from var(--media-backdrop) l c h / 0.5) calc(var(--media-spacing) * 30),
transparent
);
--media-indicator-gradient: linear-gradient(
to bottom,
oklch(from var(--media-backdrop) l c h / 0.35),
oklch(from var(--media-backdrop) l c h / 0.2) calc(var(--media-spacing) * 12),
transparent
);
--media-caption-controls-y: calc(var(--media-spacing) * -18);
--media-slider-preview-offset: calc(var(--media-spacing) * 11);
}
}
@layer base.preferences {
@media (pointer: fine) and (prefers-reduced-motion: no-preference) {
.media-skin:not([data-controls-visible]) {
--media-duration-controls: 0.3s;
}
}
@media (pointer: coarse) and (prefers-reduced-motion: no-preference) {
.media-skin:not([data-controls-visible]) {
--media-duration-controls: 0.15s;
}
}
@media (prefers-reduced-motion: reduce) {
.media-skin {
--media-duration-fast: var(--media-duration-instant);
--media-duration: var(--media-duration-instant);
--media-duration-slow: var(--media-duration-instant);
--media-duration-slower: var(--media-duration-instant);
--media-duration-controls: var(--media-duration-instant);
--media-duration-dialog: var(--media-duration-instant);
--media-duration-indicator: var(--media-duration-instant);
--media-duration-menu: 0s;
--media-duration-slider: 0s;
--media-delay-dialog: 0s;
--media-hidden-scale: 1;
--media-hidden-blur: 0px;
--media-hidden-offset: 0px;
--media-hidden-icon-scale: 1;
--media-hidden-indicator-scale: 1;
--media-hidden-indicator-offset: 0px;
--media-hidden-playback-scale: 1;
--media-hidden-popup-scale: 1;
--media-hidden-popup-blur: 0px;
--media-hidden-preview-scale: 1;
--media-hidden-preview-offset: 0px;
--media-hidden-seek-offset: 0px;
--media-popup-translate-distance: 0px;
--media-spinner-animation: none;
--media-icon-airplay-fill-animation: none;
--media-icon-airplay-triangle-animation: none;
}
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
.media-skin {
--media-popover: var(--media-background);
--media-scrollbar-thumb-color: oklch(from currentColor l c h / 0.8);
--media-backdrop-filter-surface: none;
--media-backdrop-filter-indicator: none;
--media-backdrop-filter-dialog: none;
--media-shadow-surface-inset: inset 0 1px 0 0 #ffffff40, inset 0 0 0 1px #ffffff20;
scrollbar-width: auto;
}
}
@media (forced-colors: active) {
.media-skin {
--media-border: CanvasText;
--media-frame-border: CanvasText;
--media-popover: Canvas;
--media-popover-foreground: CanvasText;
--media-ring: CanvasText;
--media-shadow-surface-inset: inset 0 1px 0 0 CanvasText, inset 0 0 0 1px CanvasText;
}
}
}
'use client';
import { type ComponentProps, type SVGProps, type ReactElement, type ReactNode, type CSSProperties } from 'react';
import { ErrorDialog as ErrorDialogPrimitive, Container as ContainerPrimitive, Poster as PosterPrimitive, Gesture, Hotkey, BufferingIndicator as BufferingIndicatorPrimitive, Tooltip, AirPlayButton as AirPlayButtonPrimitive, CaptionsButton as CaptionsButtonPrimitive, CastButton as CastButtonPrimitive, FullscreenButton as FullscreenButtonPrimitive, PiPButton as PiPButtonPrimitive, PlayButton as PlayButtonPrimitive, VolumeSlider as VolumeSliderPrimitive, MuteButton as MuteButtonPrimitive, VolumePopover as VolumePopoverPrimitive, TimeSlider as TimeSliderPrimitive, Slider, Menu, Text as TextPrimitive, AudioTrackRadioGroup, CaptionsRadioGroup, PlaybackRateRadioGroup, QualityRadioGroup, Controls, Time, StatusAnnouncer as StatusAnnouncerPrimitive, SeekIndicator as SeekIndicatorPrimitive, StatusIndicator as StatusIndicatorPrimitive, VolumeIndicator as VolumeIndicatorPrimitive } from '@videojs/react';
import { Video } from '@videojs/react/video';
import './player.css';
import { Player } from './player';
import { SpinnerIcon as SpinnerIconPrimitive, AirPlayEnterIcon as AirPlayEnterIconPrimitive, AirPlayExitIcon as AirPlayExitIconPrimitive, CaptionsOffIcon as CaptionsOffIconPrimitive, CaptionsOnIcon as CaptionsOnIconPrimitive, CastEnterIcon as CastEnterIconPrimitive, CastExitIcon as CastExitIconPrimitive, FullscreenEnterIcon as FullscreenEnterIconPrimitive, FullscreenExitIcon as FullscreenExitIconPrimitive, PipEnterIcon as PipEnterIconPrimitive, PipExitIcon as PipExitIconPrimitive, RestartIcon as RestartIconPrimitive, PlayIcon as PlayIconPrimitive, PauseIcon as PauseIconPrimitive, VolumeOffIcon as VolumeOffIconPrimitive, VolumeLowIcon as VolumeLowIconPrimitive, VolumeHighIcon as VolumeHighIconPrimitive, ChevronIcon as ChevronIconPrimitive, CheckIcon as CheckIconPrimitive, SpeechIcon as SpeechIconPrimitive, SpeedIcon as SpeedIconPrimitive, SwitchesIcon as SwitchesIconPrimitive, GearIcon as GearIconPrimitive } from '@videojs/react/icons';
import { type VolumeSliderProps as CoreVolumeSliderProps, type SliderPreviewOverflow } from '@videojs/core';
import { audioText, captionsText, speedText, qualityText, settingsText } from '@videojs/core/i18n/text/menu';
import { type Poster } from '@videojs/react';
type ContainerProps = ContainerPrimitive.Props;
function Container({ children, className, ...props }: ContainerProps) {
return (
<ContainerPrimitive className={`media-skin media-container ${className ?? ''}`} {...props}>
{children}
</ContainerPrimitive>
);
}
interface PosterProps extends Omit<PosterPrimitive.Props, 'children' | 'render'> {
children?: PosterPrimitive.Props['render'];
}
function Poster({ children, className, src, ...props }: PosterProps = {}) {
return (
<PosterPrimitive
render={children}
className={(state) => `media-poster ${resolveClassName(className, state)}`}
src={src}
{...props}
/>
);
}
interface DefaultVideoSkinProps extends Omit<NonNullable<ComponentProps<typeof Container>>, 'children'> {
src: string;
poster?: string | undefined;
renderPoster?: NonNullable<ComponentProps<typeof Poster>>['children'];
}
type BufferingIndicatorProps = Omit<BufferingIndicatorPrimitive.Props, 'children'>;
function BufferingIndicator({ className, ...props }: BufferingIndicatorProps = {}) {
return (
<BufferingIndicatorPrimitive
className={(state) => `media-buffering-indicator ${resolveClassName(className, state)}`}
{...props}
>
<SpinnerIconPrimitive className={'media-buffering-indicator-spinner-icon'} />
</BufferingIndicatorPrimitive>
);
}
type ButtonProps = ComponentProps<'button'>;
interface ButtonTooltipProps extends Tooltip.RootProps {
children: ReactElement;
label?: ReactNode;
}
function ButtonTooltip({ children, label, ...props }: ButtonTooltipProps) {
return (
<Tooltip.Root {...props}>
<Tooltip.Trigger render={children} />
<Tooltip.Popup
className={'media-popup media-popup-safe-area media-popup-transition media-popup-surface media-tooltip'}
>
{label ?? <Tooltip.Label />}
{!label && <Tooltip.Shortcut className={'media-tooltip-shortcut'} />}
</Tooltip.Popup>
</Tooltip.Root>
);
}
type PlayButtonProps = Omit<PlayButtonPrimitive.Props, 'children'>;
function PlayButton({ className, ...props }: PlayButtonProps = {}) {
return (
<PlayButtonPrimitive
render={<Button />}
className={(state) => `media-play-button ${resolveClassName(className, state)}`}
{...props}
>
<RestartIconPrimitive className={'media-button-icon media-play-button-restart-icon'} />
<PlayIconPrimitive className={'media-button-icon media-play-button-play-icon'} />
<PauseIconPrimitive className={'media-button-icon media-play-button-pause-icon'} />
</PlayButtonPrimitive>
);
}
interface VolumePopoverProps extends Omit<VolumePopoverPrimitive.RootProps, 'children'> {
className?: ClassValue;
orientation?: CoreVolumeSliderProps['orientation'];
showTooltip?: boolean;
}
type MuteButtonProps = Omit<MuteButtonPrimitive.Props, 'children'>;
function MuteButton({ className, ...props }: MuteButtonProps = {}) {
return (
<MuteButtonPrimitive
render={<Button />}
className={(state) => `media-mute-button ${resolveClassName(className, state)}`}
{...props}
>
<VolumeOffIconPrimitive className={'media-button-icon media-mute-button-off-icon'} />
<VolumeLowIconPrimitive className={'media-button-icon media-mute-button-low-icon'} />
<VolumeHighIconPrimitive className={'media-button-icon media-mute-button-high-icon'} />
</MuteButtonPrimitive>
);
}
type VolumeSliderProps = Omit<VolumeSliderPrimitive.RootProps, 'children'>;
function VolumeSlider({ className, ...props }: VolumeSliderProps = {}) {
return (
<VolumeSliderPrimitive.Root
className={(state) => `media-slider media-volume-slider ${resolveClassName(className, state)}`}
thumbAlignment="edge"
{...props}
>
<VolumeSliderPrimitive.Track render={<SliderTrack />}>
<VolumeSliderPrimitive.Fill render={<SliderFill />} />
</VolumeSliderPrimitive.Track>
<VolumeSliderPrimitive.Thumb render={<SliderThumb />} className={'media-volume-slider-thumb'} />
</VolumeSliderPrimitive.Root>
);
}
interface TimeSliderProps extends Omit<TimeSliderPrimitive.RootProps, 'children'> {
previewOverflow?: SliderPreviewOverflow | undefined;
}
function TimeSlider({ className, previewOverflow = 'visible', ...props }: TimeSliderProps = {}) {
return (
<TimeSliderPrimitive.Root
className={(state) => `media-slider media-time-slider ${resolveClassName(className, state)}`}
{...props}
>
<TimeSliderPrimitive.Chapters
className={'media-time-slider-chapters'}
renderChapter={(props) => (
<div className={'media-time-slider-chapter'} {...props}>
<TimeSliderPrimitive.Track render={<SliderTrack />} className={'media-time-slider-chapter-track'}>
<TimeSliderPrimitive.Buffer render={<SliderBuffer />} />
<TimeSliderPrimitive.Fill render={<SliderFill />} />
</TimeSliderPrimitive.Track>
</div>
)}
></TimeSliderPrimitive.Chapters>
<TimeSliderPrimitive.Thumb render={<SliderThumb />} className={'media-time-slider-thumb'} />
<TimeSliderPrimitive.Preview className={'media-slider-preview'} overflow={previewOverflow}>
<div className={'media-slider-preview-content media-popup-surface media-slider-thumbnail'}>
<Slider.Thumbnail className={'media-slider-thumbnail-image'} />
<SpinnerIconPrimitive className={'media-slider-thumbnail-spinner-icon'} />
</div>
<div className={'media-slider-preview-content media-time-slider-preview-content'}>
<TimeSliderPrimitive.ChapterTitle className={'media-time-slider-chapter-title'} />
<TimeSliderPrimitive.Value className={'media-time-slider-value'} type="pointer" />
</div>
</TimeSliderPrimitive.Preview>
</TimeSliderPrimitive.Root>
);
}
type CaptionsButtonProps = Omit<CaptionsButtonPrimitive.Props, 'children'>;
function CaptionsButton({ className, ...props }: CaptionsButtonProps = {}) {
return (
<CaptionsButtonPrimitive
render={<Button />}
className={(state) => `media-captions-button ${resolveClassName(className, state)}`}
{...props}
>
<CaptionsOffIconPrimitive className={'media-button-icon media-captions-button-off-icon'} />
<CaptionsOnIconPrimitive className={'media-button-icon media-captions-button-on-icon'} />
</CaptionsButtonPrimitive>
);
}
interface SettingsMenuProps extends Menu.RootProps {
className?: ClassValue;
}
function SettingsMenu({ children, className, ...props }: SettingsMenuProps) {
return (
<Menu.Root side="top" align="center" {...props}>
<ButtonTooltip label={<TextPrimitive token={settingsText.key}>{settingsText.text}</TextPrimitive>} side="top">
<Menu.Trigger
render={<Button />}
className={(state) => `media-settings-menu-trigger ${resolveClassName(className, state)}`}
>
<GearIconPrimitive className={'media-button-icon media-settings-menu-trigger-icon'} />
<TextPrimitive className={'media-settings-menu-trigger-label'} token={settingsText.key}>
{settingsText.text}
</TextPrimitive>
</Menu.Trigger>
</ButtonTooltip>
<Menu.Popup
keepMounted
className={'media-popup media-popup-surface media-menu-popup media-menu-resizable-popup'}
>
<Menu.Content className={'media-menu-content'}>{children}</Menu.Content>
</Menu.Popup>
</Menu.Root>
);
}
type VideoSettingsMenuProps = Omit<NonNullable<ComponentProps<typeof SettingsMenu>>, 'children'>;
type QualityMenuProps = Omit<Menu.RootProps, 'children'>;
interface MenuChevronProps {
back?: boolean;
className?: ClassValue;
}
function MenuChevron({ back = false, className }: MenuChevronProps = {}) {
return (
<ChevronIconPrimitive className={`${back ? 'media-menu-back-chevron' : 'media-menu-forward-chevron'} ${className ?? ''}`} />
);
}
type RadioItemProps = Menu.RadioItemProps;
function RadioItem({ children, className, ...props }: RadioItemProps) {
return (
<Menu.RadioItem className={(state) => `media-menu-radio-item ${resolveClassName(className, state)}`} {...props}>
{children}
<Menu.ItemIndicator forceMount className={'media-menu-item-indicator'}>
<CheckIconPrimitive className={'media-menu-radio-item-icon'} />
</Menu.ItemIndicator>
</Menu.RadioItem>
);
}
function QualityMenu({ ...props }: QualityMenuProps = {}) {
return (
<Menu.Root {...props}>
<QualityRadioGroup.Root>
<Menu.Trigger className={'media-menu-trigger-item'}>
<SwitchesIconPrimitive className={'media-menu-trigger-item-icon'} />
<TextPrimitive token={qualityText.key}>{qualityText.text}</TextPrimitive>
<span className={'media-menu-hint'}>
<QualityRadioGroup.Value className={'media-menu-hint-label'} />
<MenuChevron />
</span>
</Menu.Trigger>
<Menu.Content className={'media-menu-content'}>
<Menu.Item className={'media-menu-back-item'}>
<MenuChevron back />
<TextPrimitive token={qualityText.key}>{qualityText.text}</TextPrimitive>
</Menu.Item>
<Menu.Separator className={'media-menu-separator'} />
<QualityRadioGroup.Options
className={'media-menu-radio-group'}
renderItem={(props, item) => (
<RadioItem {...props}>
<span>
<span>{item.label}</span>
{item.tier ? <sup className={'media-menu-tier'}>{item.tier}</sup> : null}
</span>
{item.badge ? <span className={'media-menu-badge'}>{item.badge}</span> : null}
</RadioItem>
)}
></QualityRadioGroup.Options>
</Menu.Content>
</QualityRadioGroup.Root>
</Menu.Root>
);
}
type AudioTrackMenuProps = Omit<Menu.RootProps, 'children'>;
function AudioTrackMenu({ ...props }: AudioTrackMenuProps = {}) {
return (
<Menu.Root {...props}>
<AudioTrackRadioGroup.Root>
<Menu.Trigger className={'media-menu-trigger-item'}>
<SpeechIconPrimitive className={'media-menu-trigger-item-icon'} />
<TextPrimitive token={audioText.key}>{audioText.text}</TextPrimitive>
<span className={'media-menu-hint'}>
<AudioTrackRadioGroup.Value className={'media-menu-hint-label'} />
<MenuChevron />
</span>
</Menu.Trigger>
<Menu.Content className={'media-menu-content'}>
<Menu.Item className={'media-menu-back-item'}>
<MenuChevron back />
<TextPrimitive token={audioText.key}>{audioText.text}</TextPrimitive>
</Menu.Item>
<Menu.Separator className={'media-menu-separator'} />
<AudioTrackRadioGroup.Options
className={'media-menu-radio-group'}
renderItem={(props, item) => (
<RadioItem {...props}>
<span>{item.label}</span>
</RadioItem>
)}
></AudioTrackRadioGroup.Options>
</Menu.Content>
</AudioTrackRadioGroup.Root>
</Menu.Root>
);
}
type PlaybackRateSubmenuProps = Omit<Menu.RootProps, 'children'>;
function PlaybackRateSubmenu({ ...props }: PlaybackRateSubmenuProps = {}) {
return (
<Menu.Root {...props}>
<PlaybackRateRadioGroup.Root>
<Menu.Trigger className={'media-menu-trigger-item'}>
<SpeedIconPrimitive className={'media-menu-trigger-item-icon'} />
<TextPrimitive token={speedText.key}>{speedText.text}</TextPrimitive>
<span className={'media-menu-hint'}>
<PlaybackRateRadioGroup.Value className={'media-menu-hint-label'} />
<MenuChevron />
</span>
</Menu.Trigger>
<Menu.Content className={'media-menu-content'}>
<Menu.Item className={'media-menu-back-item'}>
<MenuChevron back />
<TextPrimitive token={speedText.key}>{speedText.text}</TextPrimitive>
</Menu.Item>
<Menu.Separator className={'media-menu-separator'} />
<PlaybackRateRadioGroup.Options
className={'media-menu-radio-group'}
renderItem={(props, item) => (
<RadioItem {...props}>
<span>{item.label}</span>
</RadioItem>
)}
></PlaybackRateRadioGroup.Options>
</Menu.Content>
</PlaybackRateRadioGroup.Root>
</Menu.Root>
);
}
type CaptionsSubmenuProps = Omit<Menu.RootProps, 'children'>;
function CaptionsSubmenu({ ...props }: CaptionsSubmenuProps = {}) {
return (
<Menu.Root {...props}>
<CaptionsRadioGroup.Root>
<Menu.Trigger className={'media-menu-trigger-item'}>
<CaptionsOffIconPrimitive className={'media-menu-trigger-item-icon'} />
<TextPrimitive token={captionsText.key}>{captionsText.text}</TextPrimitive>
<span className={'media-menu-hint'}>
<CaptionsRadioGroup.Value className={'media-menu-hint-label'} />
<MenuChevron />
</span>
</Menu.Trigger>
<Menu.Content className={'media-menu-content'}>
<Menu.Item className={'media-menu-back-item'}>
<MenuChevron back />
<TextPrimitive token={captionsText.key}>{captionsText.text}</TextPrimitive>
</Menu.Item>
<Menu.Separator className={'media-menu-separator'} />
<CaptionsRadioGroup.Options
className={'media-menu-radio-group'}
renderItem={(props, item) => (
<RadioItem {...props}>
<span>{item.label}</span>
</RadioItem>
)}
></CaptionsRadioGroup.Options>
</Menu.Content>
</CaptionsRadioGroup.Root>
</Menu.Root>
);
}
function VideoSettingsMenu(props: VideoSettingsMenuProps = {}) {
return (
<SettingsMenu {...props}>
<QualityMenu />
<AudioTrackMenu />
<PlaybackRateSubmenu />
<CaptionsSubmenu />
</SettingsMenu>
);
}
type CastButtonProps = Omit<CastButtonPrimitive.Props, 'children'>;
function CastButton({ className, ...props }: CastButtonProps = {}) {
return (
<CastButtonPrimitive
render={<Button />}
className={(state) => `media-cast-button ${resolveClassName(className, state)}`}
{...props}
>
<CastEnterIconPrimitive className={'media-button-icon media-cast-button-enter-icon'} />
<CastExitIconPrimitive className={'media-button-icon media-cast-button-exit-icon'} />
</CastButtonPrimitive>
);
}
type AirPlayButtonProps = Omit<AirPlayButtonPrimitive.Props, 'children'>;
function AirPlayButton({ className, ...props }: AirPlayButtonProps = {}) {
return (
<AirPlayButtonPrimitive
render={<Button />}
className={(state) => `media-airplay-button ${resolveClassName(className, state)}`}
{...props}
>
<AirPlayEnterIconPrimitive className={'media-button-icon media-airplay-button-enter-icon'} />
<AirPlayExitIconPrimitive className={'media-button-icon media-airplay-button-exit-icon'} />
</AirPlayButtonPrimitive>
);
}
type PiPButtonProps = Omit<PiPButtonPrimitive.Props, 'children'>;
function PiPButton({ className, ...props }: PiPButtonProps = {}) {
return (
<PiPButtonPrimitive
render={<Button />}
className={(state) => `media-pip-button ${resolveClassName(className, state)}`}
{...props}
>
<PipEnterIconPrimitive className={'media-button-icon media-pip-button-enter-icon'} />
<PipExitIconPrimitive className={'media-button-icon media-pip-button-exit-icon'} />
</PiPButtonPrimitive>
);
}
type FullscreenButtonProps = Omit<FullscreenButtonPrimitive.Props, 'children'>;
function FullscreenButton({ className, ...props }: FullscreenButtonProps = {}) {
return (
<FullscreenButtonPrimitive
render={<Button />}
className={(state) => `media-fullscreen-button ${resolveClassName(className, state)}`}
{...props}
>
<FullscreenEnterIconPrimitive className={'media-button-icon media-fullscreen-button-enter-icon'} />
<FullscreenExitIconPrimitive className={'media-button-icon media-fullscreen-button-exit-icon'} />
</FullscreenButtonPrimitive>
);
}
function DefaultVideoControls() {
return (
<Controls.Root>
<Controls.Backdrop className={'video-controls-backdrop'} />
<Controls.Content className={'video-controls video-controls-content'}>
<Tooltip.Provider>
<Controls.Group className={'video-controls-primary'}>
<ButtonTooltip side="top">
<PlayButton />
</ButtonTooltip>
<VolumePopover className={'video-controls-volume-button'} />
<Controls.Group className={'video-time-slider-group'}>
<Time.Value className={'media-time-value video-time-value'} type="current" />
<TimeSlider />
<Time.Value className={'media-time-toggle video-time-value'} type="remaining" toggle />
</Controls.Group>
<ButtonTooltip side="top">
<CaptionsButton className={'video-controls-captions-button'} />
</ButtonTooltip>
<VideoSettingsMenu className={'video-controls-settings-button'} />
</Controls.Group>
<Controls.Group className={'video-controls-secondary'}>
<ButtonTooltip side="top">
<CastButton />
</ButtonTooltip>
<ButtonTooltip side="top">
<AirPlayButton />
</ButtonTooltip>
<ButtonTooltip side="top">
<PiPButton />
</ButtonTooltip>
<ButtonTooltip side="top">
<FullscreenButton />
</ButtonTooltip>
</Controls.Group>
</Tooltip.Provider>
</Controls.Content>
</Controls.Root>
);
}
interface VideoHotkeysProps {
disabled?: boolean | undefined;
}
interface PlaybackHotkeysProps {
disabled?: boolean | undefined;
}
function PlaybackHotkeys({ disabled = false }: PlaybackHotkeysProps = {}) {
return (
<>
<Hotkey disabled={disabled} keys="Space" action="togglePaused" />
<Hotkey disabled={disabled} keys="k" action="togglePaused" />
<Hotkey disabled={disabled} keys="m" action="toggleMuted" />
<Hotkey disabled={disabled} keys="ArrowRight" action="seekStep" />
<Hotkey disabled={disabled} keys="ArrowLeft" action="seekStep" />
<Hotkey disabled={disabled} keys="l" action="seekStep" />
<Hotkey disabled={disabled} keys="j" action="seekStep" />
<Hotkey disabled={disabled} keys="ArrowUp" action="volumeStep" />
<Hotkey disabled={disabled} keys="ArrowDown" action="volumeStep" />
<Hotkey disabled={disabled} keys="0-9" action="seekToPercent" />
<Hotkey disabled={disabled} keys="Home" action="seekToPercent" value={0} />
<Hotkey disabled={disabled} keys="End" action="seekToPercent" value={100} />
<Hotkey disabled={disabled} keys=">" action="speedUp" />
<Hotkey disabled={disabled} keys="<" action="speedDown" />
</>
);
}
function VideoHotkeys({ disabled = false }: VideoHotkeysProps = {}) {
return (
<>
<PlaybackHotkeys disabled={disabled} />
<Hotkey disabled={disabled} keys="f" action="toggleFullscreen" />
<Hotkey disabled={disabled} keys="c" action="toggleSubtitles" />
<Hotkey disabled={disabled} keys="i" action="togglePictureInPicture" />
</>
);
}
interface VideoGesturesProps {
disabled?: boolean | undefined;
}
function VideoGestures({ disabled = false }: VideoGesturesProps = {}) {
return (
<>
<Gesture disabled={disabled} type="tap" action="togglePaused" pointer="mouse" region="center" />
<Gesture disabled={disabled} type="tap" action="toggleControls" pointer="touch" />
<Gesture disabled={disabled} type="doubletap" action="seekStep" region="left" />
<Gesture disabled={disabled} type="doubletap" action="toggleFullscreen" region="center" />
<Gesture disabled={disabled} type="doubletap" action="seekStep" region="right" />
</>
);
}
type VideoStatusIndicatorsProps = Omit<ComponentProps<'div'>, 'children'>;
type StatusAnnouncerProps = Omit<StatusAnnouncerPrimitive.Props, 'children'>;
function StatusAnnouncer({ className, ...props }: StatusAnnouncerProps = {}) {
return (
<StatusAnnouncerPrimitive
className={(state) => `media-status-announcer ${resolveClassName(className, state)}`}
{...props}
/>
);
}
type VolumeIndicatorProps = Omit<VolumeIndicatorPrimitive.RootProps, 'children'>;
function VolumeIndicator({ className, ...props }: VolumeIndicatorProps = {}) {
return (
<VolumeIndicatorPrimitive.Root
className={(state) => `media-indicator media-volume-indicator ${resolveClassName(className, state)}`}
{...props}
>
<VolumeIndicatorPrimitive.Fill className={'media-indicator-content media-volume-indicator-fill'}>
<VolumeHighIconPrimitive className={'media-volume-indicator-high-icon'} />
<VolumeLowIconPrimitive className={'media-volume-indicator-low-icon'} />
<VolumeOffIconPrimitive className={'media-volume-indicator-off-icon'} />
<VolumeIndicatorPrimitive.Value className={'media-volume-indicator-value'} />
</VolumeIndicatorPrimitive.Fill>
</VolumeIndicatorPrimitive.Root>
);
}
type StatusIndicatorProps = Omit<StatusIndicatorPrimitive.RootProps, 'children'>;
const TOP_STATUS_ACTIONS = ['toggleSubtitles', 'toggleFullscreen', 'togglePictureInPicture'] as const;
function StatusIndicator({ className, ...props }: StatusIndicatorProps = {}) {
return (
<StatusIndicatorPrimitive.Root
actions={TOP_STATUS_ACTIONS}
className={(state) => `media-indicator media-status-indicator ${resolveClassName(className, state)}`}
{...props}
>
<div className={'media-indicator-content media-status-indicator-content'}>
<CaptionsOnIconPrimitive className={'media-status-indicator-captions-on-icon'} />
<CaptionsOffIconPrimitive className={'media-status-indicator-captions-off-icon'} />
<FullscreenEnterIconPrimitive className={'media-status-indicator-fullscreen-enter-icon'} />
<FullscreenExitIconPrimitive className={'media-status-indicator-fullscreen-exit-icon'} />
<PipEnterIconPrimitive className={'media-status-indicator-pip-enter-icon'} />
<PipExitIconPrimitive className={'media-status-indicator-pip-exit-icon'} />
<StatusIndicatorPrimitive.Value className={'media-status-indicator-value'} />
</div>
</StatusIndicatorPrimitive.Root>
);
}
type SeekIndicatorProps = Omit<SeekIndicatorPrimitive.RootProps, 'children'>;
function SeekIndicator({ className, ...props }: SeekIndicatorProps = {}) {
return (
<SeekIndicatorPrimitive.Root
className={(state) => `media-seek-indicator ${resolveClassName(className, state)}`}
{...props}
>
<ChevronIconPrimitive className={'media-seek-indicator-icon'} />
<SeekIndicatorPrimitive.Value className={'media-seek-indicator-value'} />
</SeekIndicatorPrimitive.Root>
);
}
type PlaybackStatusIndicatorProps = Omit<StatusIndicatorPrimitive.RootProps, 'children'>;
const PLAYBACK_STATUS_ACTIONS = ['togglePaused'] as const;
function PlaybackStatusIndicator({ className, ...props }: PlaybackStatusIndicatorProps = {}) {
return (
<StatusIndicatorPrimitive.Root
actions={PLAYBACK_STATUS_ACTIONS}
className={(state) => `media-playback-status-indicator ${resolveClassName(className, state)}`}
{...props}
>
<PlayIconPrimitive className={'media-playback-status-indicator-play-icon'} />
<PauseIconPrimitive className={'media-playback-status-indicator-pause-icon'} />
</StatusIndicatorPrimitive.Root>
);
}
function VideoStatusIndicators({ className, ...props }: VideoStatusIndicatorsProps = {}) {
return (
<>
<StatusAnnouncer />
<div className={`video-status-indicators ${className ?? ''}`} {...props}>
<VolumeIndicator />
<StatusIndicator />
<SeekIndicator />
<PlaybackStatusIndicator />
</div>
</>
);
}
function DefaultVideoSkin({ children, className, renderPoster, ...props }: DefaultVideoSkinProps = {}) {
return (
<Container className={`video-skin ${className ?? ''}`} data-theme="default" data-preset="video" {...props}>
{children}
<Poster>{renderPoster}</Poster>
<BufferingIndicator />
<ErrorDialog />
<DefaultVideoControls />
<VideoHotkeys />
<VideoGestures />
<VideoStatusIndicators />
</Container>
);
}
const Skin = DefaultVideoSkin;
// ================================================================
// Player
// ================================================================
export interface VideoPlayerProps {
children?: ReactNode;
style?: CSSProperties;
className?: string;
renderPoster?: Poster.Props['render'];
}
export function VideoSkin(props: VideoSkinProps) {
return <Skin {...props} />;
}
// ================================================================
// Components
// ================================================================
function Button({ className, ...props }: ButtonProps) {
return <button className={`media-button ${className ?? ''}`} {...props} />;
}
type SliderTrackProps = ComponentProps<'div'>;
function SliderTrack({ className, ...props }: SliderTrackProps) {
return <div className={`media-slider-track ${className ?? ''}`} {...props} />;
}
type SliderFillProps = ComponentProps<'div'>;
function SliderFill({ className, ...props }: SliderFillProps) {
return <div className={`media-slider-fill ${className ?? ''}`} {...props} />;
}
type SliderThumbProps = ComponentProps<'div'>;
function SliderThumb({ className, ...props }: SliderThumbProps) {
return <div className={`media-slider-thumb ${className ?? ''}`} {...props} />;
}
function VolumePopover({
className,
showTooltip = false,
side = 'top',
orientation = 'vertical',
...props
}: VolumePopoverProps = {}) {
return (
<VolumePopoverPrimitive.Root openOnHover delay={200} closeDelay={100} side={side} {...props}>
<ButtonTooltip delay={0} disabled={!showTooltip} sticky side="top">
<VolumePopoverPrimitive.Trigger render={<MuteButton className={`${className ?? ''}`} />} />
</ButtonTooltip>
<VolumePopoverPrimitive.Popup
className={'media-popup media-popup-safe-area media-popup-transition media-popup-surface media-volume-popover'}
>
<VolumeSlider orientation={orientation} />
</VolumePopoverPrimitive.Popup>
</VolumePopoverPrimitive.Root>
);
}
type SliderBufferProps = ComponentProps<'div'>;
function SliderBuffer({ className, ...props }: SliderBufferProps) {
return <div className={`media-slider-buffer ${className ?? ''}`} {...props} />;
}
// ================================================================
// Error Dialog
// ================================================================
function ErrorDialog() {
return (
<ErrorDialogPrimitive.Root>
<ErrorDialogPrimitive.Backdrop className={'media-dialog-backdrop'} />
<ErrorDialogPrimitive.Popup className={'media-dialog-popup'}>
<div className={'media-dialog-content'}>
<ErrorDialogPrimitive.Title className={'media-dialog-title'} />
<ErrorDialogPrimitive.Description className={'media-dialog-description'} />
</div>
<div className={'media-dialog-actions'}>
<ErrorDialogPrimitive.Close render={<Button />} className={'media-dialog-close'} />
</div>
</ErrorDialogPrimitive.Popup>
</ErrorDialogPrimitive.Root>
);
}
import { createPlayer } from '@videojs/react';
import { videoFeatures } from '@videojs/react/video';
export const { Player } = createPlayer({ features: videoFeatures });
@layer base {
@scope (.media-skin) {
:scope,
*,
:before,
:after {
box-sizing: border-box;
}
button {
font: inherit;
color: inherit;
text-transform: none;
letter-spacing: inherit;
appearance: none;
background: none;
margin: 0;
}
img,
svg,
media-icon {
max-width: 100%;
margin: 0;
display: block;
}
svg[fill="currentColor"] {
fill: currentColor;
}
svg[fill="none"] {
fill: none;
}
svg[stroke="currentColor"] {
stroke: currentColor;
}
video {
border-radius: inherit;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
width: 100%;
max-width: 100%;
height: 100%;
margin: 0;
display: block;
}
media-icon > svg {
width: 100%;
height: 100%;
}
media-tooltip-group,
media-dialog,
media-alert-dialog,
media-error-dialog,
media-controls {
display: contents;
}
[hidden][hidden] {
display: none !important;
}
}
@media (prefers-reduced-motion: no-preference) {
.media-skin {
interpolate-size: allow-keywords;
}
}
}
@layer components {
@scope (.media-skin) {
:scope {
--media-caption-track-duration: var(--media-duration-controls);
--media-caption-track-delay: 25ms;
--media-caption-track-y: calc(var(--media-spacing) * -2);
}
video::-webkit-media-text-track-container {
z-index: 20;
scale: 0.98;
translate: 0 var(--media-caption-track-y);
transition: translate var(--media-caption-track-duration) ease-out;
transition-delay: var(--media-caption-track-delay);
font-family: inherit;
}
:scope[data-controls-visible] {
--media-caption-track-y: var(--media-caption-controls-y);
}
@container media-root (width >= 42rem) {
:scope[data-theme="minimal"][data-controls-visible] video {
--media-caption-track-y: calc(var(--media-spacing) * -12);
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-buffering-indicator {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
color: var(--media-controls-foreground);
place-content: center;
display: none;
position: absolute;
}
.media-buffering-indicator:not([data-visible]) {
--media-spinner-animation: none;
}
.media-buffering-indicator:before {
inset: calc(var(--media-spacing) * 0);
background-color: var(--media-backdrop);
content: "";
backdrop-filter: var(--media-backdrop-filter-indicator);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-buffering-indicator:before {
background-color: color-mix(in oklab, var(--media-backdrop) 35%, transparent);
}
}
.media-buffering-indicator[data-visible] {
display: grid;
}
.media-buffering-indicator-spinner-icon {
z-index: 30;
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
position: relative;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-button {
width: var(--media-control-size);
height: var(--media-control-size);
min-height: calc(var(--media-spacing) * 0);
cursor: pointer;
touch-action: manipulation;
border-radius: var(--media-control-radius);
padding: calc(var(--media-spacing) * 0);
text-align: center;
color: inherit;
outline-offset: -2px;
transition-property: background-color, color, outline-offset, scale;
transition-duration: var(--media-duration);
will-change: scale;
-webkit-user-select: none;
user-select: none;
corner-shape: var(--media-control-corner-shape);
text-shadow: inherit;
background-color: #0000;
border-style: solid;
border-width: 0;
outline: 2px solid #0000;
flex-shrink: 0;
place-items: center;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: grid;
}
.media-button:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-button:not([aria-disabled="true"]):active {
scale: 0.97;
}
.media-button[aria-disabled="true"] {
cursor: not-allowed;
opacity: 0.5;
}
@media (prefers-reduced-motion: reduce) {
.media-button {
will-change: auto;
transition-property: background-color, color;
scale: 1;
}
}
.media-button:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-button:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-dialog-actions {
gap: calc(var(--media-spacing) * 2);
flex-shrink: 0;
display: flex;
}
.media-dialog-backdrop {
inset: calc(var(--media-spacing) * 0);
z-index: 40;
background-color: var(--media-backdrop);
opacity: 1;
backdrop-filter: var(--media-backdrop-filter-dialog);
transition-property: opacity;
transition-duration: 0.15s;
transition-delay: var(--media-delay-dialog);
transition-duration: var(--media-duration-dialog);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-dialog-backdrop {
background-color: color-mix(in oklab, var(--media-backdrop) 20%, transparent);
}
}
.media-dialog-backdrop:not([data-open]) {
display: none;
}
.media-dialog-backdrop[data-ending-style] {
transition-delay: 0s;
transition-duration: var(--media-duration-slower);
}
.media-dialog-backdrop:is([data-starting-style], [data-ending-style]) {
opacity: 0;
}
.media-dialog-close {
height: var(--media-control-size);
width: 100%;
padding-inline: calc(var(--media-spacing) * 4);
padding-block: calc(var(--media-spacing) * 2);
flex: 1;
font-weight: 500;
background-color: var(--media-primary) !important;
color: var(--media-primary-foreground) !important;
}
.media-dialog-content {
min-height: calc(var(--media-spacing) * 0);
gap: calc(var(--media-spacing) * 2);
padding-inline: calc(var(--media-spacing) * 2);
padding-top: calc(var(--media-spacing) * 2);
padding-bottom: calc(var(--media-spacing) * 1.5);
flex-direction: column;
display: flex;
overflow-y: auto;
}
.media-dialog-description {
margin: calc(var(--media-spacing) * 0);
overflow-wrap: anywhere;
opacity: 0.7;
}
.media-dialog-popup {
z-index: 50;
max-height: calc(100% - 0.5rem);
width: var(--media-dialog-width);
max-width: var(--media-dialog-max-width);
gap: calc(var(--media-spacing) * 3);
border-radius: var(--media-dialog-radius);
background-color: var(--media-popover);
padding: calc(var(--media-spacing) * 3);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-delay: var(--media-delay-dialog);
transition-duration: var(--media-duration-dialog);
text-shadow: var(--media-text-shadow-dialog);
outline-style: none;
flex-direction: column;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: flex;
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
}
@media (forced-colors: active) {
.media-dialog-popup {
outline-offset: 2px;
outline: 2px solid #0000;
}
}
.media-dialog-popup:not([data-open]) {
display: none;
}
.media-dialog-popup:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
.media-dialog-popup[data-ending-style] {
transition-delay: 0s;
transition-duration: var(--media-duration-slower);
}
.media-dialog-popup:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-popup-scale) var(--media-hidden-popup-scale);
opacity: 0;
}
.media-dialog-title {
margin: calc(var(--media-spacing) * 0);
font-size: calc(var(--media-spacing) * 3.75);
font-weight: 600;
line-height: 1.25;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-container,
:scope.media-container {
isolation: isolate;
border-radius: var(--media-video-border-radius);
background-color: var(--media-background);
width: 100%;
height: 100%;
font-family: var(--media-font-family, "Inter Variable", Inter, ui-sans-serif, system-ui, sans-serif);
font-size: calc(var(--media-spacing) * 3.25);
-webkit-font-smoothing: auto;
-moz-osx-font-smoothing: auto;
outline-offset: -4px;
transition-property: outline-offset, outline-color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
--spacing: var(--media-spacing);
outline: 2px solid #0000;
line-height: 1.5;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: block;
position: relative;
overflow: clip;
container: media-root / size;
}
.media-container:after,
:scope.media-container:after {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
z-index: 10;
border-radius: inherit;
content: "";
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
inset 0 0 0 1px var(--media-frame-border);
position: absolute;
}
.media-container:focus-visible,
:scope.media-container:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-container:fullscreen:after,
:scope.media-container:fullscreen:after {
content: "";
display: none;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-poster {
pointer-events: none;
border-radius: inherit;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
width: 100%;
height: 100%;
transition-property: opacity;
transition-duration: 0.15s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: var(--media-duration-slower);
position: absolute;
inset: 0;
}
.media-poster:not([data-visible]) {
opacity: 0;
}
.media-poster img {
border-radius: inherit;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
width: 100%;
height: 100%;
position: absolute;
inset: 0;
}
.media-poster:is(img):not([src]):not([srcset]) {
visibility: hidden;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-seek-indicator {
place-content: center;
gap: calc(var(--media-spacing) * 1);
padding: calc(var(--media-spacing) * 4);
text-align: center;
grid-row-start: 1;
grid-column-start: 2;
display: grid;
}
.media-seek-indicator[data-direction="backward"] {
grid-column-start: 1;
justify-self: flex-start;
}
.media-seek-indicator[data-direction="forward"] {
grid-column-start: 3;
justify-self: flex-end;
}
@container media-root (width >= 42rem) {
.media-seek-indicator {
padding: calc(var(--media-spacing) * 6);
}
}
.media-seek-indicator-icon {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
transition-property: translate, opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: none;
}
@scope (.media-seek-indicator) {
&[data-direction] .media-seek-indicator-icon {
display: block;
}
}
@scope (.media-seek-indicator) {
&[data-direction="backward"] .media-seek-indicator-icon {
scale: -1 1;
}
}
@scope (.media-seek-indicator) {
&[data-direction="backward"][data-starting-style] .media-seek-indicator-icon {
translate: var(--media-hidden-seek-offset) 0;
}
}
@scope (.media-seek-indicator) {
&[data-direction="forward"][data-starting-style] .media-seek-indicator-icon {
translate: calc(var(--media-hidden-seek-offset) * -1) 0;
}
}
@scope (.media-seek-indicator) {
&:is([data-starting-style], [data-ending-style]) .media-seek-indicator-icon {
opacity: 0;
}
}
.media-seek-indicator-value {
font-variant-numeric: tabular-nums;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-status-announcer {
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
position: absolute;
overflow: hidden;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-indicator {
pointer-events: none;
top: calc(var(--media-spacing) * 3);
transform-origin: top;
border-radius: var(--media-control-radius);
background-color: var(--media-backdrop);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
transition-duration: var(--media-duration-fast);
font-weight: 500;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-indicator {
background-color: color-mix(in oklab, var(--media-backdrop) 25%, transparent);
}
}
.media-indicator:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
.media-indicator[data-ending-style] {
translate: 0 var(--media-hidden-indicator-offset);
}
@media (pointer: coarse) {
.media-indicator {
will-change: scale, translate, opacity;
transition-property: scale, translate, opacity;
}
}
@media (pointer: fine) {
.media-indicator {
will-change: scale, translate, filter, opacity;
transition-property: scale, translate, filter, opacity;
}
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
.media-indicator {
background-color: var(--media-background);
}
}
.media-indicator:is([data-starting-style], [data-ending-style]) {
opacity: 0;
transition-duration: var(--media-duration-indicator);
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
@media (pointer: fine) {
.media-indicator:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-indicator-scale) var(--media-hidden-indicator-scale);
filter: blur(var(--media-hidden-blur));
}
}
.media-indicator-content {
justify-content: space-between;
align-items: center;
gap: calc(var(--media-spacing) * 2);
padding-inline: calc(var(--media-spacing) * 2.5);
padding-block: calc(var(--media-spacing) * 1);
}
.media-playback-status-indicator {
background-color: var(--media-backdrop);
padding: calc(var(--media-spacing) * 4);
text-align: center;
backdrop-filter: var(--media-backdrop-filter-indicator);
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
border-radius: 9999px;
grid-row-start: 1;
grid-column-start: 2;
place-content: center;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: grid;
}
@supports (color: color-mix(in lab, red, red)) {
.media-playback-status-indicator {
background-color: color-mix(in oklab, var(--media-backdrop) 35%, transparent);
}
}
.media-playback-status-indicator[data-ending-style] {
transition-duration: var(--media-duration-fast);
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
.media-playback-status-indicator:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-playback-scale) var(--media-hidden-playback-scale);
opacity: 0;
}
.media-playback-status-indicator-pause-icon {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
grid-row-start: 1;
grid-column-start: 1;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
@scope (.media-playback-status-indicator) {
&[data-status="pause"] .media-playback-status-indicator-pause-icon {
opacity: 1;
scale: 1;
}
}
.media-playback-status-indicator-play-icon {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 1.5);
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
grid-row-start: 1;
grid-column-start: 1;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
@scope (.media-playback-status-indicator) {
&[data-status="play"] .media-playback-status-indicator-play-icon {
opacity: 1;
translate: 1px;
scale: 1;
}
}
.media-status-indicator-captions-off-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="captions-off"] .media-status-indicator-captions-off-icon {
display: block;
}
}
.media-status-indicator-captions-on-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="captions-on"] .media-status-indicator-captions-on-icon {
display: block;
}
}
.media-status-indicator-content {
width: 100%;
display: flex;
}
.media-status-indicator-fullscreen-enter-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="fullscreen"] .media-status-indicator-fullscreen-enter-icon {
display: block;
}
}
.media-status-indicator-fullscreen-exit-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="exit-fullscreen"] .media-status-indicator-fullscreen-exit-icon {
display: block;
}
}
.media-status-indicator-pip-enter-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="pip"] .media-status-indicator-pip-enter-icon {
display: block;
}
}
.media-status-indicator-pip-exit-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-status-indicator) {
&[data-status="exit-pip"] .media-status-indicator-pip-exit-icon {
display: block;
}
}
.media-status-indicator-value {
mix-blend-mode: difference;
margin-left: auto;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@supports (color: color-mix(in lab, red, red)) {
}
@media (pointer: coarse) {
}
@media (pointer: fine) {
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
}
@media (pointer: fine) {
}
.media-volume-indicator {
width: min(80%, 12rem);
transform: translateX(0);
}
@media (prefers-reduced-motion: no-preference) {
.media-volume-indicator:is([data-min], [data-max]):not([data-starting-style], [data-ending-style]) {
transition: transform 0.3s linear(0, -24 20%, 16 40%, -8 60%, 4 80%, 1);
transform: translateX(0.25px);
}
}
.media-volume-indicator-fill {
border-radius: inherit;
background-image: linear-gradient(currentColor, currentColor);
background-size: var(--media-volume-fill, 0%) 100%;
width: 100%;
transition-property: background-size;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
background-position: 0;
background-repeat: no-repeat;
transition-timing-function: linear;
display: flex;
}
.media-volume-indicator-high-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-volume-indicator) {
&[data-level="high"] .media-volume-indicator-high-icon {
display: block;
}
}
.media-volume-indicator-low-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-volume-indicator) {
&[data-level="low"] .media-volume-indicator-low-icon {
display: block;
}
}
.media-volume-indicator-off-icon {
mix-blend-mode: difference;
flex-shrink: 0;
display: none;
}
@scope (.media-volume-indicator) {
&[data-level="off"] .media-volume-indicator-off-icon {
display: block;
}
}
.media-volume-indicator-value {
mix-blend-mode: difference;
margin-left: auto;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.video-status-indicators {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
color: var(--media-controls-foreground);
grid-template-columns: repeat(3, minmax(0, 1fr));
place-items: center;
display: grid;
position: absolute;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-airplay-button:not([data-airplay-state="connected"]) {
--media-icon-airplay-fill-animation: none;
--media-icon-airplay-triangle-animation: none;
}
.media-airplay-button-enter-icon {
opacity: 0;
}
@scope (.media-airplay-button) {
&:not([data-airplay-state="connected"]) .media-airplay-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-airplay-button-exit-icon {
opacity: 0;
}
@scope (.media-airplay-button) {
&[data-airplay-state="connected"] .media-airplay-button-exit-icon {
opacity: 1;
scale: 1;
}
}
.media-button-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
grid-row-start: 1;
grid-column-start: 1;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-popup {
margin: calc(var(--media-spacing) * 0);
color: inherit;
border-style: solid;
border-width: 0;
overflow: visible;
}
.media-popup[data-ending-style] {
transform: none;
}
.media-popup[data-starting-style] {
transform: translate(var(--media-popup-translate-x-distance, 0), var(--media-popup-translate-y-distance, 0));
}
.media-popup[data-side="bottom"] {
transform-origin: top;
--media-popup-translate-y-distance: calc(var(--media-popup-translate-distance) * -1);
}
.media-popup[data-side="left"] {
transform-origin: 100%;
--media-popup-translate-x-distance: var(--media-popup-translate-distance);
}
.media-popup[data-side="right"] {
transform-origin: 0;
--media-popup-translate-x-distance: calc(var(--media-popup-translate-distance) * -1);
}
.media-popup[data-side="top"] {
transform-origin: bottom;
--media-popup-translate-y-distance: var(--media-popup-translate-distance);
}
.media-popup:is([data-starting-style], [data-ending-style]) {
scale: var(--media-hidden-popup-scale) var(--media-hidden-popup-scale);
opacity: 0;
filter: blur(var(--media-hidden-popup-blur));
}
.media-popup-safe-area:before {
pointer-events: auto;
content: "";
position: absolute;
}
.media-popup-safe-area[data-side="bottom"]:before {
inset-inline: calc(var(--media-spacing) * 0);
content: "";
height: var(--media-popup-side-offset);
bottom: 100%;
}
.media-popup-safe-area[data-side="left"]:before {
inset-block: calc(var(--media-spacing) * 0);
content: "";
width: var(--media-popup-side-offset);
left: 100%;
}
.media-popup-safe-area[data-side="right"]:before {
inset-block: calc(var(--media-spacing) * 0);
content: "";
width: var(--media-popup-side-offset);
right: 100%;
}
.media-popup-safe-area[data-side="top"]:before {
inset-inline: calc(var(--media-spacing) * 0);
content: "";
height: var(--media-popup-side-offset);
top: 100%;
}
.media-popup-surface {
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
}
.media-popup-surface:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
.media-popup-transition {
transition-property: opacity, filter, transform, scale;
transition-duration: var(--media-duration-fast);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-popup-transition[data-ending-style] {
transition-duration: var(--media-duration-instant);
}
.media-tooltip {
border-radius: var(--media-control-radius);
padding-inline: calc(var(--media-spacing) * 2.5);
padding-block: calc(var(--media-spacing) * 1);
font-size: calc(var(--media-spacing) * 3.25);
white-space: nowrap;
--media-popup-side-offset: var(--media-tooltip-side-offset);
}
.media-tooltip[data-open] {
align-items: center;
gap: calc(var(--media-spacing) * 1);
display: flex;
}
.media-tooltip-shortcut {
border-radius: calc(var(--media-spacing) * 1);
background-color: var(--media-muted);
text-align: center;
min-width: 1.5em;
font-family: inherit;
font-size: calc(var(--media-spacing) * 2.75);
padding: 0.1em;
font-weight: 600;
line-height: 1.25;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-captions-button-off-icon {
opacity: 0;
}
@scope (.media-captions-button) {
&:not([data-active]) .media-captions-button-off-icon {
opacity: 1;
scale: 1;
}
}
.media-captions-button-on-icon {
opacity: 0;
}
@scope (.media-captions-button) {
&[data-active] .media-captions-button-on-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-cast-button-enter-icon {
opacity: 0;
}
@scope (.media-cast-button) {
&:not([data-cast-state="connected"]) .media-cast-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-cast-button-exit-icon {
opacity: 0;
}
@scope (.media-cast-button) {
&[data-cast-state="connected"] .media-cast-button-exit-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-fullscreen-button-enter-icon {
opacity: 0;
}
@scope (.media-fullscreen-button) {
&:not([data-fullscreen]) .media-fullscreen-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-fullscreen-button-exit-icon {
opacity: 0;
}
@scope (.media-fullscreen-button) {
&[data-fullscreen] .media-fullscreen-button-exit-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-pip-button-enter-icon {
opacity: 0;
}
@scope (.media-pip-button) {
&:not([data-pip]) .media-pip-button-enter-icon {
opacity: 1;
scale: 1;
}
}
.media-pip-button-exit-icon {
opacity: 0;
}
@scope (.media-pip-button) {
&[data-pip] .media-pip-button-exit-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-play-button-pause-icon {
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
}
@scope (.media-play-button) {
&[data-started]:not([data-paused]):not([data-ended]) .media-play-button-pause-icon {
opacity: 1;
scale: 1;
}
}
.media-play-button-play-icon {
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
}
@scope (.media-play-button) {
&:not([data-ended]):not([data-started]) .media-play-button-play-icon,
&:not([data-ended])[data-paused] .media-play-button-play-icon {
opacity: 1;
scale: 1;
}
}
.media-play-button-restart-icon {
scale: var(--media-hidden-icon-scale) var(--media-hidden-icon-scale);
opacity: 0;
}
@scope (.media-play-button) {
&[data-ended] .media-play-button-restart-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-mute-button-high-icon {
opacity: 0;
}
@scope (.media-mute-button) {
&:not([data-muted]):not([data-volume-level="low"]) .media-mute-button-high-icon {
opacity: 1;
scale: 1;
}
}
.media-mute-button-low-icon {
opacity: 0;
}
@scope (.media-mute-button) {
&:not([data-muted])[data-volume-level="low"] .media-mute-button-low-icon {
opacity: 1;
scale: 1;
}
}
.media-mute-button-off-icon {
opacity: 0;
}
@scope (.media-mute-button) {
&[data-muted] .media-mute-button-off-icon {
opacity: 1;
scale: 1;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-slider-buffer {
pointer-events: none;
border-radius: inherit;
transition-property: clip-path;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slider);
background-color: currentColor;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-buffer {
background-color: color-mix(in oklab, currentcolor 20%, transparent);
}
}
@scope (.media-slider) {
&[data-dragging] .media-slider-buffer,
&[data-seeking] .media-slider-buffer {
transition-duration: 0s;
}
}
.media-slider-buffer[data-orientation="horizontal"] {
inset-block: calc(var(--media-spacing) * 0);
left: calc(var(--media-spacing) * 0);
width: 100%;
clip-path: inset(0 calc(100% - var(--media-slider-buffer)) 0 0 round var(--media-control-radius));
}
.media-slider-buffer[data-orientation="vertical"] {
inset-inline: calc(var(--media-spacing) * 0);
bottom: calc(var(--media-spacing) * 0);
height: 100%;
clip-path: inset(calc(100% - var(--media-slider-buffer)) 0 0 0 round var(--media-control-radius));
}
.media-slider-fill {
pointer-events: none;
border-radius: inherit;
background-color: var(--media-primary);
transition-property: clip-path;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slider);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-fill,
&[data-seeking] .media-slider-fill {
transition-duration: 0s;
}
}
.media-slider-fill[data-orientation="horizontal"] {
inset-block: calc(var(--media-spacing) * 0);
left: calc(var(--media-spacing) * 0);
width: 100%;
clip-path: inset(0 calc(100% - var(--media-slider-fill)) 0 0 round var(--media-control-radius));
}
@scope (.media-slider) {
&[data-dragging] .media-slider-fill[data-orientation="horizontal"] {
clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--media-control-radius));
}
}
.media-slider-fill[data-orientation="vertical"] {
inset-inline: calc(var(--media-spacing) * 0);
bottom: calc(var(--media-spacing) * 0);
height: 100%;
clip-path: inset(calc(100% - var(--media-slider-fill)) 0 0 0 round var(--media-control-radius));
}
@scope (.media-slider) {
&[data-dragging] .media-slider-fill[data-orientation="vertical"] {
clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--media-control-radius));
}
}
.media-slider-thumb {
top: 50%;
left: var(--media-slider-fill);
z-index: 10;
width: calc(var(--media-spacing) * 3);
height: calc(var(--media-spacing) * 3);
border-radius: var(--media-control-radius);
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
var(--media-shadow-thumb);
outline-offset: -4px;
transition-property: opacity, height, width, outline-offset, left, top, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slider);
-webkit-user-select: none;
user-select: none;
background-color: currentColor;
outline: 4px solid #0000;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
translate: -50% -50%;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-thumb {
transition-property: opacity, height, width, outline-offset, scale;
transition-duration: 0.15s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
scale: 0.9;
}
}
.media-slider-thumb:after {
pointer-events: none;
inset: calc(var(--media-spacing) * -1);
border-radius: inherit;
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
content: "";
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
scale: 0.5;
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 0 2px;
}
@media (hover: hover) {
.media-slider-thumb:hover {
outline-offset: 0px;
outline-color: currentColor;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-thumb:hover {
outline-color: color-mix(in oklab, currentcolor 15%, transparent);
}
}
}
.media-slider-thumb:focus-visible {
outline-offset: 0px;
outline-color: currentColor;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-thumb:focus-visible {
outline-color: color-mix(in oklab, currentcolor 15%, transparent);
}
}
.media-slider-thumb:focus-visible:after {
content: "";
opacity: 1;
scale: 1;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-thumb[data-orientation="horizontal"] {
left: var(--media-slider-pointer);
}
}
.media-slider-thumb[data-orientation="vertical"] {
top: calc(100% - var(--media-slider-fill));
left: 50%;
}
@scope (.media-slider) {
&[data-dragging] .media-slider-thumb[data-orientation="vertical"] {
top: calc(100% - var(--media-slider-pointer));
}
}
.media-slider-track {
isolation: isolate;
-webkit-user-select: none;
user-select: none;
background-color: currentColor;
border-radius: 9999px;
width: 100%;
position: relative;
overflow: hidden;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-track {
background-color: color-mix(in oklab, currentcolor 20%, transparent);
}
}
.media-slider-track[data-orientation="horizontal"] {
height: calc(var(--media-spacing) * 1);
}
.media-slider-track[data-orientation="vertical"] {
height: 100%;
width: calc(var(--media-spacing) * 1);
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-slider {
cursor: pointer;
border-radius: 9999px;
outline-style: none;
flex: 1;
justify-content: center;
align-items: center;
display: flex;
position: relative;
}
@media (forced-colors: active) {
.media-slider {
outline-offset: 2px;
outline: 2px solid #0000;
}
}
.media-slider[data-orientation="horizontal"] {
height: var(--media-slider-height, calc(var(--media-spacing) * 8));
min-width: calc(var(--media-spacing) * 20);
}
.media-slider[data-orientation="vertical"] {
height: calc(var(--media-spacing) * 20);
width: calc(var(--media-spacing) * 8);
min-width: calc(var(--media-spacing) * 0);
}
.media-volume-slider-thumb {
opacity: 1;
scale: 1;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-volume-popover {
border-radius: var(--media-control-radius);
padding-inline: calc(var(--media-spacing) * 0);
padding-block: calc(var(--media-spacing) * 3);
--media-popup-side-offset: var(--media-popover-side-offset);
}
.media-volume-popover[data-side="right"] {
padding: calc(var(--media-spacing) * 0);
padding-inline: calc(var(--media-spacing) * 3);
--media-popover-side-offset: 0rem;
border-radius: 0;
box-shadow: none !important;
backdrop-filter: none !important;
background-color: #0000 !important;
}
.media-volume-popover[data-side="right"]:after {
content: "";
display: none;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (forced-colors: active) {
}
.media-slider-preview {
height: calc(var(--media-spacing) * 1);
min-width: var(--media-slider-preview-max-width);
--media-slider-preview-max-height: var(--media-slider-preview-max-width);
--media-slider-preview-max-width: min(calc(var(--media-spacing) * 36), 100cqi);
position: relative;
}
.media-slider-preview:before {
pointer-events: none;
z-index: 1;
width: calc(var(--media-spacing) * 1);
height: calc(var(--media-spacing) * 1);
border-radius: var(--media-control-radius);
opacity: 0;
transition-property: opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
content: "";
background-color: currentColor;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
scale: 0.5;
}
.media-slider-preview[data-pointing]:not([data-dragging]):before {
content: "";
opacity: 1;
scale: 1;
}
@container media-root (width >= 42rem) {
.media-slider-preview {
--media-slider-preview-max-width: min(calc(var(--media-spacing) * 48), 100cqi);
}
}
.media-slider-preview-content {
max-width: var(--media-slider-preview-max-width);
transform-origin: bottom;
translate: -50% var(--media-hidden-preview-offset);
scale: var(--media-hidden-preview-scale) var(--media-hidden-preview-scale);
opacity: 0;
filter: blur(var(--media-hidden-blur));
transition-property: filter, opacity, scale;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
:where(.media-slider):has(:focus-visible) .media-slider-preview-content,
:where(.media-slider-preview)[data-pointing] .media-slider-preview-content {
opacity: 1;
filter: none;
scale: 1;
}
.media-slider-thumbnail {
pointer-events: none;
bottom: calc(100% + var(--media-slider-preview-offset));
border-radius: var(--media-popup-radius);
background-color: var(--media-backdrop);
left: 50%;
overflow: hidden;
}
@supports (color: color-mix(in lab, red, red)) {
.media-slider-thumbnail {
background-color: color-mix(in oklab, var(--media-backdrop) 90%, transparent);
}
}
.media-slider-thumbnail:has([data-loading]) {
aspect-ratio: 16 / 9;
width: var(--media-slider-preview-max-width);
}
.media-slider-thumbnail-image {
max-height: var(--media-slider-preview-max-height);
max-width: var(--media-slider-preview-max-width);
border-radius: inherit;
transition-property: opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: block;
position: relative;
overflow: clip;
}
.media-slider-thumbnail-image:after {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
border-radius: inherit;
content: "";
background-image: var(--media-thumbnail-gradient);
position: absolute;
}
.media-slider-thumbnail-image[data-loading] {
opacity: 0;
}
.media-slider-thumbnail-spinner-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
opacity: 0;
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
transition-property: opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
}
@scope (.media-slider-thumbnail) {
&:not(:has([role="img"][data-loading])) .media-slider-thumbnail-spinner-icon {
--media-spinner-animation: none;
}
}
@scope (.media-slider-thumbnail) {
&:has([role="img"][data-loading]) .media-slider-thumbnail-spinner-icon {
opacity: 1;
}
}
.media-time-slider-chapter {
inset: calc(var(--media-spacing) * 0);
min-height: calc(var(--media-spacing) * 0);
min-width: calc(var(--media-spacing) * 0);
--media-chapter-inset-end: 0.5;
--media-chapter-inset-start: 0.5;
justify-content: center;
align-items: center;
display: flex;
position: absolute;
}
.media-time-slider-chapter:first-child {
--media-chapter-inset-start: 0;
}
.media-time-slider-chapter:last-child {
--media-chapter-inset-end: 0;
}
.media-time-slider-chapter[data-orientation="horizontal"] {
clip-path: inset(0 calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start));
}
.media-time-slider-chapter[data-orientation="vertical"] {
clip-path: inset(calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start) 0);
}
.media-time-slider-chapter-title {
max-width: var(--media-slider-preview-max-width);
min-width: calc(var(--media-spacing) * 0);
text-overflow: ellipsis;
white-space: nowrap;
padding-inline: calc(var(--media-spacing) * 6);
overflow: hidden;
}
.media-time-slider-chapter-title:empty {
display: none;
}
.media-time-slider-chapter-track {
transition-property: height, width;
transition-duration: 0.15s;
transition-duration: var(--media-duration-slow);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-time-slider-chapter-track[data-orientation="horizontal"] {
clip-path: inset(
0 calc(100% - var(--media-slider-chapter-end) + var(--media-spacing) * var(--media-chapter-inset-end)) 0
calc(var(--media-slider-chapter-start) + var(--media-spacing) * var(--media-chapter-inset-start)) round
var(--media-control-radius)
);
}
@scope (.media-time-slider-chapter) {
&[data-highlighted] .media-time-slider-chapter-track[data-orientation="horizontal"] {
height: calc(var(--media-spacing) * 1.75);
}
}
.media-time-slider-chapter-track[data-orientation="vertical"] {
clip-path: inset(
calc(100% - var(--media-slider-chapter-end) + var(--media-spacing) * var(--media-chapter-inset-end)) 0
calc(var(--media-slider-chapter-start) + var(--media-spacing) * var(--media-chapter-inset-start)) 0 round
var(--media-control-radius)
);
}
@scope (.media-time-slider-chapter) {
&[data-highlighted] .media-time-slider-chapter-track[data-orientation="vertical"] {
width: calc(var(--media-spacing) * 1.75);
}
}
.media-time-slider-chapters {
width: 100%;
height: 100%;
min-height: calc(var(--media-spacing) * 0);
min-width: calc(var(--media-spacing) * 0);
border-radius: inherit;
flex: 1;
align-items: center;
display: flex;
position: relative;
}
.media-time-slider-preview-content {
bottom: calc(100% + var(--media-slider-preview-label-offset));
font-variant-numeric: tabular-nums;
flex-direction: column;
align-items: center;
display: flex;
left: 50%;
}
.media-time-slider-thumb {
opacity: 0;
scale: 0.8;
}
.media-time-slider-thumb:focus-visible,
.media-time-slider-thumb[data-interactive] {
opacity: 1;
}
@media (pointer: fine) {
@media (hover: hover) {
@scope (.media-slider) {
&:hover .media-time-slider-thumb {
opacity: 1;
scale: 1;
}
}
}
}
.media-time-slider-value {
font-variant-numeric: tabular-nums;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-menu-back-chevron {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
rotate: 180deg;
}
@scope (.media-menu-back-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-back-chevron {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-back-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-back-chevron {
color: inherit;
}
}
}
.media-menu-back-chevron:dir(rtl) {
rotate: 0deg;
scale: 1;
}
.media-menu-forward-chevron {
width: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
height: calc(var(--media-icon-size, calc(var(--media-spacing) * 4.5)) * 7 / 9);
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
}
@scope (.media-menu-trigger-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-forward-chevron {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-trigger-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-forward-chevron {
color: inherit;
}
}
}
.media-menu-forward-chevron:dir(rtl) {
scale: -1 1;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-menu-item-indicator {
opacity: 0;
flex-shrink: 0;
margin-inline-start: auto;
margin-inline-end: calc(var(--media-spacing) * -1);
}
@scope (.media-menu-radio-item) {
&[aria-checked="true"] .media-menu-item-indicator {
opacity: 1;
}
}
.media-menu-radio-item {
cursor: pointer;
justify-content: space-between;
align-items: center;
gap: calc(var(--media-spacing) * 1.5);
border-radius: var(--media-menu-item-radius);
padding-inline: calc(var(--media-spacing) * 2);
padding-block: calc(var(--media-spacing) * 1.5);
text-align: start;
white-space: nowrap;
color: inherit;
font-variant-numeric: tabular-nums;
outline-offset: -2px;
transition-property: background-color, color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
-webkit-user-select: none;
user-select: none;
text-shadow: 0 1px 0 var(--media-shadow-current-color);
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
position: relative;
}
.media-menu-radio-item:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-menu-radio-item[aria-disabled="true"] {
pointer-events: none;
cursor: not-allowed;
opacity: 0.5;
}
.media-menu-radio-item[data-availability="unavailable"],
.media-menu-radio-item[data-availability="unsupported"] {
display: none;
}
.media-menu-radio-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-menu-radio-item:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
@supports (top: anchor(top)) {
.media-menu-radio-item {
transition-duration: var(--media-duration-instant);
}
.media-menu-radio-item[data-highlighted] {
anchor-name: --media-menu-item-highlight-anchor;
}
.media-menu-radio-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
@media (hover: hover) {
.media-menu-radio-item:hover:where(:not([aria-disabled="true"])) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
}
}
.media-menu-radio-item-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
}
@scope (.media-menu-radio-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-radio-item-icon {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-radio-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-radio-item-icon {
color: inherit;
}
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-menu-back-item {
margin-bottom: calc(var(--media-spacing) * 0.5);
cursor: pointer;
align-items: center;
gap: calc(var(--media-spacing) * 1.5);
border-radius: var(--media-menu-item-radius);
width: 100%;
padding-inline: calc(var(--media-spacing) * 2);
padding-block: calc(var(--media-spacing) * 1.5);
text-align: start;
white-space: nowrap;
outline-offset: -2px;
transition-property: background-color, color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
-webkit-user-select: none;
user-select: none;
text-shadow: 0 1px 0 var(--media-shadow-current-color);
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
position: relative;
}
.media-menu-back-item:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-menu-back-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-menu-back-item:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
@supports (top: anchor(top)) {
.media-menu-back-item {
transition-duration: var(--media-duration-instant);
}
.media-menu-back-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
transition-duration: var(--media-duration-slow);
}
@media (hover: hover) {
.media-menu-back-item:hover:where(:not([aria-disabled="true"])) {
transition-duration: var(--media-duration-slow);
}
}
}
.media-menu-content {
max-height: inherit;
overscroll-behavior: none;
transition-property: translate, filter;
transition-duration: 0.15s;
transition-duration: var(--media-duration-menu);
anchor-scope: --media-menu-item-highlight-anchor;
outline-style: none;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
overflow: auto;
}
@media (forced-colors: active) {
.media-menu-content {
outline-offset: 2px;
outline: 2px solid #0000;
}
}
.media-menu-content:not([data-submenu]) {
inset-inline: calc(var(--media-spacing) * 1);
top: calc(var(--media-spacing) * 1);
gap: calc(var(--media-spacing) * 0.5);
flex-direction: column;
display: flex;
}
.media-menu-content[data-submenu] {
inset-inline: calc(var(--media-spacing) * 0);
top: calc(var(--media-spacing) * 0);
z-index: 10;
max-height: inherit;
padding: calc(var(--media-spacing) * 1);
}
.media-menu-content:not([data-submenu])[data-child-open] {
filter: blur(var(--media-hidden-blur));
translate: -100%;
}
.media-menu-content:not([data-submenu])[data-child-open]:before {
content: "";
display: none;
}
.media-menu-content[data-submenu]:is([data-starting-style], [data-ending-style]) {
pointer-events: none;
filter: blur(var(--media-hidden-blur));
overflow: hidden;
translate: 100%;
}
@supports (top: anchor(top)) {
.media-menu-content:before {
content: "";
position-anchor: --media-menu-item-highlight-anchor;
inset: anchor(inside);
overflow-anchor: none;
pointer-events: none;
border-radius: var(--media-menu-item-radius);
background-color: var(--media-accent);
transition: inset var(--media-duration-fast) ease-in-out;
position: absolute;
}
.media-menu-content:has([data-highlighted=""]):before {
content: "";
transition-duration: 0s;
}
}
.media-menu-content:not([data-submenu])[data-child-open]:dir(rtl) {
translate: 100%;
}
.media-menu-content[data-submenu]:is([data-starting-style], [data-ending-style]):dir(rtl) {
translate: -100%;
}
.media-menu-hint {
min-width: calc(var(--media-spacing) * 0);
align-items: center;
gap: calc(var(--media-spacing) * 1);
color: currentColor;
margin-inline-start: auto;
padding-inline-start: calc(var(--media-spacing) * 2);
display: inline-flex;
}
@supports (color: color-mix(in lab, red, red)) {
.media-menu-hint {
color: color-mix(in oklab, currentcolor 65%, transparent);
}
}
.media-menu-hint-label {
max-width: calc(var(--media-spacing) * 24);
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.media-menu-radio-group {
max-height: inherit;
gap: calc(var(--media-spacing) * 0.5);
anchor-scope: --media-menu-item-highlight-anchor;
flex-direction: column;
display: flex;
}
@supports (top: anchor(top)) {
.media-menu-radio-group:before {
content: "";
position-anchor: --media-menu-item-highlight-anchor;
inset: anchor(inside);
overflow-anchor: none;
pointer-events: none;
border-radius: var(--media-menu-item-radius);
background-color: var(--media-accent);
transition: inset var(--media-duration-fast) ease-in-out;
position: absolute;
}
.media-menu-radio-group:has([data-highlighted=""]):before {
content: "";
transition-duration: 0s;
}
}
.media-menu-separator {
margin-block: calc(var(--media-spacing) * 1);
border-bottom-style: solid;
border-bottom-width: 1px;
border-color: var(--media-border);
box-shadow:
0 0 #0000,
0 0 #0000,
0 0 #0000,
0 0 #0000,
var(--media-shadow-separator);
display: block;
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
.media-menu-separator {
border-color: var(--media-foreground);
}
@supports (color: color-mix(in lab, red, red)) {
.media-menu-separator {
border-color: color-mix(in oklab, var(--media-foreground) 25%, transparent);
}
}
}
.media-menu-trigger-item {
cursor: pointer;
justify-content: space-between;
align-items: center;
gap: calc(var(--media-spacing) * 1.5);
border-radius: var(--media-menu-item-radius);
padding-inline: calc(var(--media-spacing) * 2);
padding-block: calc(var(--media-spacing) * 1.5);
text-align: start;
white-space: nowrap;
color: inherit;
font-variant-numeric: tabular-nums;
outline-offset: -2px;
transition-property: background-color, color;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
-webkit-user-select: none;
user-select: none;
text-shadow: 0 1px 0 var(--media-shadow-current-color);
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
position: relative;
}
.media-menu-trigger-item:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-menu-trigger-item[aria-disabled="true"] {
pointer-events: none;
cursor: not-allowed;
opacity: 0.5;
}
.media-menu-trigger-item[data-availability="unavailable"],
.media-menu-trigger-item[data-availability="unsupported"] {
display: none;
}
.media-menu-trigger-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
@media (hover: hover) {
.media-menu-trigger-item:hover:where(:not([aria-disabled="true"])) {
background-color: var(--media-accent);
color: var(--media-accent-foreground);
}
}
@supports (top: anchor(top)) {
.media-menu-trigger-item {
transition-duration: var(--media-duration-instant);
}
.media-menu-trigger-item[data-highlighted] {
anchor-name: --media-menu-item-highlight-anchor;
}
.media-menu-trigger-item:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(
:not([aria-disabled="true"])
) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
@media (hover: hover) {
.media-menu-trigger-item:hover:where(:not([aria-disabled="true"])) {
transition-duration: var(--media-duration-slow);
background-color: #0000;
}
}
}
.media-menu-trigger-item-icon {
width: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
height: var(--media-icon-size, calc(var(--media-spacing) * 4.5));
color: var(--media-muted-foreground);
filter: drop-shadow(0 1px 0 var(--media-shadow-current-color));
flex-shrink: 0;
}
@scope (.media-menu-trigger-item) {
&:where(:focus-visible, [aria-expanded="true"], [data-highlighted]):where(:not([aria-disabled="true"]))
.media-menu-trigger-item-icon {
color: inherit;
}
}
@media (hover: hover) {
@scope (.media-menu-trigger-item) {
&:hover:where(:not([aria-disabled="true"])) .media-menu-trigger-item-icon {
color: inherit;
}
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (hover: hover) {
}
@supports (top: anchor(top)) {
@media (hover: hover) {
}
}
.media-menu-badge {
border-radius: var(--media-control-radius);
background-color: var(--media-accent);
padding-inline: calc(var(--media-spacing) * 1.5);
font-size: 0.7em;
font-weight: 600;
}
@media (forced-colors: active) {
}
@supports (top: anchor(top)) {
}
@supports (color: color-mix(in lab, red, red)) {
}
@supports (top: anchor(top)) {
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
@supports (color: color-mix(in lab, red, red)) {
}
}
.media-menu-tier {
color: currentColor;
padding-inline-start: calc(var(--media-spacing) * 0.5);
padding-top: 1px;
font-size: 0.7em;
font-weight: 600;
line-height: 1;
}
@supports (color: color-mix(in lab, red, red)) {
.media-menu-tier {
color: color-mix(in oklab, currentcolor 70%, transparent);
}
}
@media (hover: hover) {
}
@supports (top: anchor(top)) {
@media (hover: hover) {
}
}
@scope (.media-menu-trigger-item) {
}
@media (hover: hover) {
@scope (.media-menu-trigger-item) {
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (forced-colors: active) {
}
@supports (top: anchor(top)) {
}
.media-menu-popup {
margin: calc(var(--media-spacing) * 0);
height: var(--media-menu-height);
max-height: min(
var(--media-menu-available-height, calc(var(--media-spacing) * 56)),
calc(var(--media-spacing) * 56)
);
width: var(--media-menu-width);
max-width: var(--media-menu-available-width);
min-width: calc(var(--media-spacing) * 44);
overscroll-behavior: none;
border-radius: var(--media-popup-radius);
padding: calc(var(--media-spacing) * 1);
transition-property: opacity, filter, transform, scale;
transition-duration: var(--media-duration-fast);
--media-popup-side-offset: var(--media-popover-side-offset);
border-style: solid;
border-width: 0;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
overflow: hidden !important;
}
.media-menu-popup:is([data-starting-style], [data-ending-style]) {
transition-property: opacity, filter, transform, scale;
transition-duration: var(--media-duration-fast);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-menu-resizable-popup {
transition-property: opacity, filter, transform, scale, width, height;
transition-duration:
var(--media-duration-fast), var(--media-duration-fast), var(--media-duration-fast), var(--media-duration-fast),
var(--media-duration-menu), var(--media-duration-menu);
}
.media-settings-menu-trigger-icon {
transition-property: transform, translate, scale, rotate;
transition-duration: 0.15s;
transition-duration: var(--media-duration);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
@scope (.media-settings-menu-trigger) {
&[aria-expanded="true"] .media-settings-menu-trigger-icon {
rotate: 90deg;
}
}
@media (prefers-reduced-motion: reduce) {
.media-settings-menu-trigger-icon {
transition-property: none !important;
}
}
.media-settings-menu-trigger-label {
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
position: absolute;
overflow: hidden;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.video-controls-backdrop {
pointer-events: none;
inset: calc(var(--media-spacing) * 0);
z-index: 10;
border-radius: inherit;
background-image: var(--media-controls-gradient);
transition-property: opacity;
transition-duration: 0.15s;
transition-duration: var(--media-duration-controls);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
position: absolute;
}
.video-controls-backdrop:not([data-visible]) {
opacity: 0;
}
@container media-root (width < 32rem) {
.video-controls-captions-button {
display: none;
}
}
.video-controls-content {
padding: calc(var(--media-spacing) * 1);
color: var(--media-controls-foreground);
transition-property: filter, opacity, scale, translate;
transition-duration: 0.15s;
transition-duration: calc(var(--media-duration-controls) / 2);
text-shadow: 0 1px 0 var(--media-shadow-current-color);
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: contents;
}
@container media-root (width >= 32rem) {
.video-controls-content {
inset-inline: calc(var(--media-spacing) * 2);
bottom: calc(var(--media-spacing) * 2);
z-index: 10;
border-radius: var(--media-controls-radius);
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
align-items: center;
display: flex;
position: absolute;
}
.video-controls-content:not([data-visible]) {
pointer-events: none;
translate: 0 var(--media-hidden-offset);
scale: var(--media-hidden-scale) var(--media-hidden-scale);
opacity: 0;
transition-duration: var(--media-duration-controls);
}
.video-controls-content:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
@media (pointer: fine) {
.video-controls-content:not([data-visible]) {
filter: blur(var(--media-hidden-blur));
}
}
}
@container media-root (width >= 42rem) {
.video-controls-content {
inset-inline: calc(var(--media-spacing) * 3);
bottom: calc(var(--media-spacing) * 3);
}
}
.video-controls-primary {
inset-inline: calc(var(--media-spacing) * 2);
bottom: calc(var(--media-spacing) * 2);
z-index: 10;
transform-origin: bottom;
border-radius: var(--media-controls-radius);
padding: calc(var(--media-spacing) * 1);
transition-property: filter, opacity, scale, translate;
transition-duration: 0.15s;
transition-duration: calc(var(--media-duration-controls) / 2);
align-items: center;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: flex;
position: absolute;
}
@container media-root (width >= 32rem) {
.video-controls-primary {
display: contents;
}
}
@container media-root (width < 32rem) {
.video-controls-primary {
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
}
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-primary {
pointer-events: none;
translate: 0 var(--media-hidden-offset);
scale: var(--media-hidden-scale) var(--media-hidden-scale);
opacity: 0;
transition-duration: var(--media-duration-controls);
}
}
.video-controls-primary:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
@media (pointer: fine) {
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-primary {
filter: blur(var(--media-hidden-blur));
}
}
}
}
.video-controls-secondary {
top: calc(var(--media-spacing) * 2);
right: calc(var(--media-spacing) * 2);
z-index: 10;
transform-origin: top;
border-radius: var(--media-controls-radius);
padding: calc(var(--media-spacing) * 1);
transition-property: filter, opacity, scale, translate;
transition-duration: 0.15s;
transition-duration: calc(var(--media-duration-controls) / 2);
align-items: center;
gap: 1px;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
display: flex;
position: absolute;
}
@container media-root (width >= 32rem) {
.video-controls-secondary {
padding: calc(var(--media-spacing) * 0);
position: static;
}
}
@container media-root (width < 32rem) {
.video-controls-secondary {
background-color: var(--media-popover);
color: var(--media-popover-foreground);
box-shadow:
0 0 0 1px var(--media-surface-border, var(--media-border)),
var(--media-shadow-surface);
backdrop-filter: var(--media-backdrop-filter-surface);
}
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-secondary {
pointer-events: none;
translate: 0 calc(var(--media-hidden-offset) * -1);
scale: var(--media-hidden-scale) var(--media-hidden-scale);
opacity: 0;
transition-duration: var(--media-duration-controls);
}
}
.video-controls-secondary:after {
content: "";
z-index: 10;
pointer-events: none;
border-radius: inherit;
box-shadow: var(--media-shadow-surface-inset);
position: absolute;
inset: 0;
}
@media (pointer: fine) {
@scope (.video-controls-content) {
&:not([data-visible]) .video-controls-secondary {
filter: blur(var(--media-hidden-blur));
}
}
}
}
@container media-root (width >= 32rem) {
.video-controls-settings-button {
margin-inline-start: 1px;
}
}
.video-controls-volume-button {
margin-inline-start: 1px;
}
.video-time-slider-group {
align-items: center;
gap: calc(var(--media-spacing) * 2.5);
padding-inline: calc(var(--media-spacing) * 2);
flex: 1;
display: flex;
container: media-time / inline-size;
}
@container media-root (width >= 32rem) {
.video-time-slider-group {
padding-inline: calc(var(--media-spacing) * 3);
}
}
@container media-time (width < 16rem) {
.video-time-value {
display: none;
}
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
.media-time-toggle {
cursor: pointer;
font-variant-numeric: tabular-nums;
outline-offset: -2px;
transition-property: outline-color, outline-offset;
transition-duration: 0.15s;
transition-duration: var(--media-duration-fast);
border-radius: 0.25rem;
outline: 2px solid #0000;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.media-time-toggle:focus-visible {
outline-offset: 2px;
outline-color: var(--media-ring);
}
.media-time-value {
font-variant-numeric: tabular-nums;
}
}
@scope (.media-skin[data-theme="default"][data-preset="video"]) {
@media (pointer: fine) {
.video-skin:not([data-controls-visible]),
:scope.video-skin:not([data-controls-visible]) {
cursor: none;
}
}
}
}
@layer utilities;
@layer base.theme {
.media-skin {
--media-background: oklch(0% 0 0);
--media-foreground: oklch(100% 0 0);
--media-controls: oklch(0% 0 0 / 0.35);
--media-controls-foreground: var(--media-foreground);
--media-popover: oklch(100% 0 0 / 0.1);
--media-popover-foreground: var(--media-foreground);
--media-primary: var(--media-accent-color, var(--media-default-accent-color));
--media-primary-foreground: var(
--media-accent-text-color,
contrast-color(var(--media-accent-color, var(--media-default-accent-color)))
);
--media-accent: var(--media-accent-color, color-mix(in oklab, var(--media-default-accent-color) 10%, transparent));
--media-accent-foreground: var(
--media-accent-text-color,
contrast-color(var(--media-accent-color, var(--media-internal-accent-text-fallback, oklch(0% 0 0))))
);
--media-muted: oklch(100% 0 0 / 0.15);
--media-muted-foreground: oklch(100% 0 0 / 0.65);
--media-border: oklch(0% 0 0 / 0.1);
--media-ring: oklch(100% 0 0);
--media-backdrop: oklch(0% 0 0);
--media-live-color: oklch(65% 0.22 27);
--media-shadow-surface: 0 1px 3px 0 oklch(0% 0 0 / 0.15), 0 1px 2px -1px oklch(0% 0 0 / 0.15);
--media-shadow-surface-inset: inset 0 1px 0 0 #ffffff1a, inset 0 0 0 1px #ffffff0d;
--media-shadow-thumb: 0 0 0 1px #0000001a, 0 1px 3px 0 #00000059, 0 1px 2px -1px #00000059;
--media-shadow-tooltip: 0 0 0 1px var(--media-border), var(--media-shadow-surface);
--media-shadow-separator: 0 1px 0 0 oklch(100% 0 0 / 0.075);
--media-shadow-current-color: oklch(from currentColor 0 0 0 / clamp(0, calc((l - 0.5) * 0.5), 0.15));
--media-shadow-subtle-current-color: oklch(from var(--media-shadow-current-color) l c h / calc(alpha * 0.4));
--media-text-shadow-dialog: 0 1px 0 #00000040;
--media-backdrop-filter-surface: blur(16px) saturate(150%);
--media-backdrop-filter-indicator: blur(8px);
--media-backdrop-filter-dialog: blur(16px) saturate(150%);
--media-control-corner-shape: round;
--media-control-radius: calc(infinity * 1px);
--media-control-size: calc(var(--media-spacing) * 9);
--media-controls-radius: var(--media-control-radius);
--media-default-accent-color: oklch(100% 0 0);
--media-duration-instant: 50ms;
--media-duration-fast: 0.1s;
--media-duration: 0.15s;
--media-duration-slow: 0.2s;
--media-duration-slower: 0.25s;
--media-duration-controls: 0.1s;
--media-duration-dialog: 0.35s;
--media-duration-indicator: var(--media-duration-slower);
--media-duration-menu: 0.25s;
--media-duration-slider: var(--media-duration-fast);
--media-delay-dialog: 0.1s;
--media-hidden-scale: 0.95;
--media-hidden-blur: 8px;
--media-hidden-offset: calc(var(--media-spacing) * 1);
--media-hidden-icon-scale: 0;
--media-hidden-indicator-scale: 0.9;
--media-hidden-indicator-offset: -25%;
--media-hidden-playback-scale: 0.85;
--media-hidden-popup-scale: 0.95;
--media-hidden-popup-blur: 4px;
--media-hidden-preview-scale: 0.8;
--media-hidden-preview-offset: calc(var(--media-spacing) * 2);
--media-hidden-seek-offset: 60%;
--media-menu-item-radius: calc(var(--media-spacing) * 2);
--media-popover-boundary-offset: calc(var(--media-spacing) * 3);
--media-popover-side-offset: calc(var(--media-spacing) * 3);
--media-popup-radius: calc(var(--media-spacing) * 3);
--media-popup-translate-distance: calc(var(--media-spacing) * 2);
--media-tooltip-boundary-offset: var(--media-popover-boundary-offset);
--media-tooltip-side-offset: var(--media-popover-side-offset);
--media-dialog-radius: calc(var(--media-spacing) * 7);
--media-dialog-width: calc(100% - var(--media-spacing) * 6);
--media-dialog-max-width: calc(var(--media-spacing) * 72);
--media-slider-preview-label-offset: calc(var(--media-spacing) * 10.5);
--media-video-border-radius: var(--media-border-radius, 28px);
--media-scale: 1;
--media-scrollbar-thumb-color: oklch(from currentColor l c h / 0.3);
--media-spacing: calc(var(--media-scale-unit, 16px) * var(--media-scale) / 4);
scrollbar-color: var(--media-scrollbar-thumb-color) transparent;
scrollbar-width: thin;
}
.media-skin::-webkit-scrollbar-thumb {
background: var(--media-scrollbar-thumb-color);
border-radius: 9999px;
}
.media-skin:fullscreen {
--media-object-fit: contain;
--media-video-border-radius: 0;
}
@media (width >= 1280px) {
.media-skin:fullscreen {
--media-scale: 1.25;
}
}
@media (width >= 1536px) {
.media-skin:fullscreen {
--media-scale: 1.5;
}
}
@media (width >= 1920px) {
.media-skin:fullscreen {
--media-scale: 1.75;
}
}
.media-skin[data-theme="minimal"] {
--media-control-corner-shape: squircle;
--media-control-radius: calc(var(--media-spacing) * 2);
--media-control-size: calc(var(--media-spacing) * 9.5);
--media-controls-radius: calc(var(--media-spacing) * 3);
--media-popover: oklch(0% 0 0 / 0.5);
--media-border: oklch(100% 0 0 / 0.1);
--media-shadow-surface: 0 1px 2px oklch(0% 0 0 / 0.2);
--media-shadow-thumb: 0 0 0 1px #00000026, 0 1px 3px 0 #00000026, 0 1px 2px -1px #00000026;
--media-text-shadow-dialog: 0 1px 0 #00000080;
--media-backdrop-filter-dialog: blur(16px) saturate(120%);
--media-shadow-tooltip:
0 0 0 1px var(--media-border), 0 4px 6px -1px oklch(0% 0 0 / 0.2), 0 2px 4px -2px oklch(0% 0 0 / 0.2);
--media-duration-dialog: var(--media-duration);
--media-duration-indicator: 0.4s;
--media-hidden-offset: 100%;
--media-hidden-indicator-offset: -100%;
--media-menu-item-radius: calc(var(--media-spacing) * 1.5);
--media-popover-boundary-offset: calc(var(--media-spacing) * 2);
--media-popover-side-offset: calc(var(--media-spacing) * 5);
--media-popup-radius: calc(var(--media-spacing) * 2.5);
--media-popup-translate-distance: calc(var(--media-spacing) * 2);
--media-dialog-width: 100%;
--media-dialog-max-width: calc(var(--media-spacing) * 64);
--media-slider-preview-label-offset: calc(var(--media-spacing) * 5);
--media-video-border-radius: var(--media-border-radius, 12px);
}
.media-skin:is([data-preset="video"], [data-preset="live-video"]) {
--media-frame-border: var(--media-border-color, light-dark(#0000001a, #ffffff26));
--media-controls-gradient: linear-gradient(
to top in oklab,
oklch(from var(--media-backdrop) l c h / 0.5),
oklch(from var(--media-backdrop) l c h / 0.3) 25%,
transparent
);
--media-caption-controls-y: calc(var(--media-spacing) * -14);
--media-slider-preview-offset: calc(var(--media-spacing) * 9);
--media-thumbnail-gradient: linear-gradient(
to top,
oklch(from var(--media-backdrop) l c h / 0.5),
oklch(from var(--media-backdrop) l c h / 0.1),
transparent
);
}
.media-skin:is([data-preset="video"], [data-preset="live-video"])[data-theme="minimal"] {
--media-frame-border: var(--media-border-color, light-dark(#00000026, #ffffff26));
--media-controls-gradient: linear-gradient(
to top in oklab,
oklch(from var(--media-backdrop) l c h / 0.7),
oklch(from var(--media-backdrop) l c h / 0.5) calc(var(--media-spacing) * 30),
transparent
);
--media-indicator-gradient: linear-gradient(
to bottom,
oklch(from var(--media-backdrop) l c h / 0.35),
oklch(from var(--media-backdrop) l c h / 0.2) calc(var(--media-spacing) * 12),
transparent
);
--media-caption-controls-y: calc(var(--media-spacing) * -18);
--media-slider-preview-offset: calc(var(--media-spacing) * 11);
}
}
@layer base.preferences {
@media (pointer: fine) and (prefers-reduced-motion: no-preference) {
.media-skin:not([data-controls-visible]) {
--media-duration-controls: 0.3s;
}
}
@media (pointer: coarse) and (prefers-reduced-motion: no-preference) {
.media-skin:not([data-controls-visible]) {
--media-duration-controls: 0.15s;
}
}
@media (prefers-reduced-motion: reduce) {
.media-skin {
--media-duration-fast: var(--media-duration-instant);
--media-duration: var(--media-duration-instant);
--media-duration-slow: var(--media-duration-instant);
--media-duration-slower: var(--media-duration-instant);
--media-duration-controls: var(--media-duration-instant);
--media-duration-dialog: var(--media-duration-instant);
--media-duration-indicator: var(--media-duration-instant);
--media-duration-menu: 0s;
--media-duration-slider: 0s;
--media-delay-dialog: 0s;
--media-hidden-scale: 1;
--media-hidden-blur: 0px;
--media-hidden-offset: 0px;
--media-hidden-icon-scale: 1;
--media-hidden-indicator-scale: 1;
--media-hidden-indicator-offset: 0px;
--media-hidden-playback-scale: 1;
--media-hidden-popup-scale: 1;
--media-hidden-popup-blur: 0px;
--media-hidden-preview-scale: 1;
--media-hidden-preview-offset: 0px;
--media-hidden-seek-offset: 0px;
--media-popup-translate-distance: 0px;
--media-spinner-animation: none;
--media-icon-airplay-fill-animation: none;
--media-icon-airplay-triangle-animation: none;
}
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
.media-skin {
--media-popover: var(--media-background);
--media-scrollbar-thumb-color: oklch(from currentColor l c h / 0.8);
--media-backdrop-filter-surface: none;
--media-backdrop-filter-indicator: none;
--media-backdrop-filter-dialog: none;
--media-shadow-surface-inset: inset 0 1px 0 0 #ffffff40, inset 0 0 0 1px #ffffff20;
scrollbar-width: auto;
}
}
@media (forced-colors: active) {
.media-skin {
--media-border: CanvasText;
--media-frame-border: CanvasText;
--media-popover: Canvas;
--media-popover-foreground: CanvasText;
--media-ring: CanvasText;
--media-shadow-surface-inset: inset 0 1px 0 0 CanvasText, inset 0 0 0 1px CanvasText;
}
}
}
Skins, features, and presets
Each skin is built with specific features in mind. For example, a video skin renders fullscreen and picture-in-picture controls. An audio skin doesn’t.
You’ll find a preconfigured player, its typed hook, a skin, and the matching feature bundle exported from the same path. We call these paths presets.
| Import | Description | Details |
|---|---|---|
@videojs/html/video | General-purpose video player preset with full playback controls. | |
| ||
@videojs/html/audio | Audio-only player preset with playback and volume controls. | |
@videojs/html/background | Ambient background video preset with no user controls. | |
| ||
@videojs/html/live-audio | Live audio player preset — audio minus playback rate, plus the live feature, with a skin that swaps the time slider
and time displays for a Live button. | |
| ||
@videojs/html/live-video | Live video player preset — video minus playback rate, quality selection, and audio-track selection, plus the live
feature, with a skin that swaps the time slider and time displays for a Live button. | |
| ||
Styling
Packaged skins use vanilla CSS. Their documented CSS custom properties cover common visual changes.
Import the stylesheet listed for each skin in the preset table.
The skin registration entry point imports its styles automatically.
Either way the styles travel inside the skin’s JavaScript and apply when the element upgrades, so there is no stylesheet to add. The CDN publishes them as files as well, which matters when you want the player’s box styled before that upgrade — see Self-host the player.
To use Tailwind or change the underlying CSS, eject the skin and edit its styles in your app.
Shared limitations
- Skin spacing and icons use a fixed
16pxbase by default. Vanilla CSS font sizes use the same base, while Tailwind font sizes use rem units and assume a 16px root font size. - The default font stack includes
Inter, but we do not load the webfont for you. If Inter is unavailable, the skin uses system fonts.
Ejected vanilla CSS
- We use a BEM classname structure and every component classname is scoped with a
media-prefix.
Ejected Tailwind
- Ejected skins establish their own spacing scale but otherwise assume the default configuration. A future CLI eject command will support custom class prefixes. For now, edit the ejected skin to use your prefix.
- Ejected skins currently support Tailwind 4.3.x.