/* ─── Video (library-video-embed) ────────────────────────────────────────
 * One reserved box. Before the click: a poster and one centred play circle,
 * nothing else on the image (owner, 2026-09-24: "en enkel playknapp"; the
 * Mobbin session of the same day found the same in HoneyBook and Gamma).
 * After the click: the player fills the same box, so nothing on the page moves.
 *
 * Colour: the block paints almost nothing of its own. Surfaces derive from the
 * theme through currentColor. The ONE exception is the play circle and its
 * focus ring, which sit on a photograph, not on a theme surface - theme colours
 * say nothing about contrast against an arbitrary picture. They use the same
 * fixed light-on-dark media-overlay values as gc-lightbox.css, and the circle is
 * its own contrast surface, so it reads on any poster. */

.gc-video-embed {
    box-sizing: border-box;
    margin-inline: 0;
}
/* Core's own embed block keeps 1em under itself, at one class
 * (`.wp-block-embed`). Twenty Sixteen resets figure margins to zero, and two
 * videos in a row then touched (devclassic, 2026-09-25). One class, like core:
 * it beats a bare `figure {}` reset; the author's own margin (inline) still
 * decides. */
.gc-video-embed {
    margin-block-end: 1em;
}

.gc-video-embed__box {
    position: relative;
    aspect-ratio: var(--gc-video-ratio, 16 / 9);
    inline-size: 100%;
    overflow: hidden;
    border-radius: inherit;
    background: color-mix(in srgb, currentColor 8%, transparent);
}

.gc-video-embed__poster,
.gc-video-embed__frame,
.gc-video-embed__video,
.gc-video-embed__blank {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    margin: 0;
    border: 0;
}

.gc-video-embed__poster {
    object-fit: cover;
    max-inline-size: none;
}

.gc-video-embed__video {
    object-fit: contain;
}

/* No poster anywhere: a quiet panel carrying the title, never an empty box and
 * never a picture fetched from the video site. */
.gc-video-embed__blank {
    display: flex;
    align-items: flex-end;
    padding: clamp(0.75rem, 4%, 1.5rem);
    box-sizing: border-box;
    background: color-mix(in srgb, currentColor 12%, transparent);
}
.gc-video-embed__blank-title {
    font-weight: 600;
    line-height: 1.3;
    max-inline-size: 75%;
}

/* ─── The play button ─────────────────────────────────────────────────────
 * The link IS the circle and carries `data-part="cta-play"`, so the Styles
 * sidebar's "play button" part lands on the element that also takes hover and
 * keyboard focus. The rest of the poster starts the video through the
 * view-script, so the picture is still the target.
 *
 * Two tiers, because an authored part style must win over this resting look.
 * Colour, background, border and radius stay UNLAYERED here: a theme's own
 * unlayered `a {}` rules would beat anything layered, and the part engine
 * re-emits exactly those four UNLAYERED + !important, so an authored value still
 * wins. Size and shadow sit in `@layer gc-look`, below every part layer, so an
 * authored width or shadow replaces them without a fight. */
.gc-video-embed__play {
    position: absolute;
    /* Centring, not a reading direction: physical on purpose, so the circle
     * does not jump sides on a right-to-left page. */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: block;
    border-radius: 50%;
    background-color: rgba( 255, 255, 255, 0.94 );
    color: rgb( 20, 22, 27 );
    text-decoration: none;
    cursor: pointer;
    outline: none;
    -webkit-tap-highlight-color: transparent;
    transition: transform 160ms cubic-bezier(0.25, 1, 0.5, 1), box-shadow 160ms cubic-bezier(0.25, 1, 0.5, 1);
}

@layer gc-look {
    .gc-video-embed__play {
        /* One length, a percentage of the box's WIDTH, and a square from it.
         * Setting the height to the same percentage resolved against the box's
         * height and drew an oval (measured on csdev 2026-09-25). */
        inline-size: clamp(3.25rem, 12%, 5.5rem);
        aspect-ratio: 1;
        box-shadow:
            0 0 0 1px rgba( 20, 22, 27, 0.18 ),
            0 4px 18px rgba( 20, 22, 27, 0.35 );
    }

    .gc-video-embed__play:hover {
        box-shadow:
            0 0 0 1px rgba( 20, 22, 27, 0.22 ),
            0 6px 24px rgba( 20, 22, 27, 0.45 );
    }

    .gc-video-embed__caption {
        margin-block-start: 0.6em;
        font-size: 0.875em;
        text-align: start;
    }
}

.gc-video-embed__box > .gc-video-embed__poster,
.gc-video-embed__box > .gc-video-embed__blank {
    cursor: pointer;
}

/* The triangle is the button's own text colour, so "text colour" on the play
 * button part recolours it. A media "play" glyph points the same way in every
 * script, so it is deliberately NOT mirrored on right-to-left pages; the small
 * offset centres it optically, and is physical for that reason. */
.gc-video-embed__play::before {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    inline-size: 34%;
    block-size: 38%;
    left: 8%;
    background: currentColor;
    clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.gc-video-embed__play:hover {
    transform: translate(-50%, -50%) scale(1.07);
}

/* Focus: a dark ring inside a light ring, so it holds 3:1 against a light
 * poster, a dark poster, and the circle itself. Unlayered with !important so an
 * authored shadow on the part cannot switch the keyboard ring off. */
.gc-video-embed__play:focus-visible {
    box-shadow:
        0 0 0 3px rgb( 20, 22, 27 ),
        0 0 0 6px rgb( 255, 255, 255 ) !important;
}

.gc-video-embed__play:active {
    transform: translate(-50%, -50%) scale(0.95);
}

/* Loading after the click: the triangle becomes a turning arc in place, and
 * the box keeps its size. */
.gc-video-embed.is-loading .gc-video-embed__play::before {
    left: 0;
    inline-size: 42%;
    block-size: 42%;
    background: none;
    clip-path: none;
    border-radius: 50%;
    border: 3px solid color-mix(in srgb, currentColor 25%, transparent);
    border-block-start-color: currentColor;
    animation: gc-video-spin 800ms linear infinite;
}

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

/* ─── Floating while scrolling (author option, off by default) ─────────────
 * Only the playing frame floats; the reserved box stays in the text so the page
 * does not jump. Narrow enough to never cover more than a corner, and it
 * shrinks with the viewport (WCAG 1.4.10 at 320px). */
.gc-video-embed__box.is-floating .gc-video-embed__stage {
    position: fixed;
    z-index: 100;
    /* Clear the stage's own `inset: 0` first, or its top/left win over the
     * bottom/end below and the player floats to the top-left corner
     * (measured on csdev 2026-09-25). */
    inset: auto;
    inset-block-end: 1rem;
    inset-inline-end: 1rem;
    inline-size: min(22rem, calc(100vw - 2rem));
    aspect-ratio: var(--gc-video-ratio, 16 / 9);
    box-shadow: 0 8px 32px rgba( 20, 22, 27, 0.4 );
}
/* The rounding sits on the player itself, not on a clipping stage: the stage
 * must NOT clip, because the close button hangs outside it (below). */
.gc-video-embed__box.is-floating .gc-video-embed__stage > iframe,
.gc-video-embed__box.is-floating .gc-video-embed__stage > video {
    border-radius: 0.5rem;
}
.gc-video-embed__stage {
    position: absolute;
    inset: 0;
}

/* The close button hangs ABOVE the floating player, never on it. YouTube's
 * rules forbid anything "in front of any part of a YouTube embedded player,
 * including player controls", and Vimeo's forbid obscuring its player; the first
 * build put this button over the player's corner (caught 2026-09-25). */
.gc-video-embed__unfloat {
    position: absolute;
    z-index: 1;
    inset-block-end: calc(100% + 0.4rem);
    inset-inline-end: 0;
    display: none;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba( 20, 22, 27, 0.78 );
    color: rgb( 255, 255, 255 );
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}
.gc-video-embed__box.is-floating .gc-video-embed__unfloat {
    display: block;
}
.gc-video-embed__unfloat:focus-visible {
    outline: 3px solid rgb( 255, 255, 255 );
    outline-offset: 2px;
}

/* ─── Pop-up window (author option) ────────────────────────────────────── */
.gc-video-embed-dialog {
    inline-size: min(70rem, 92vw);
    max-inline-size: none;
    padding: 0;
    border: 0;
    background: transparent;
    overflow: visible;
}
.gc-video-embed-dialog::backdrop {
    background: rgba( 24, 26, 31, 0.86 );
}
/* The width is capped by the HEIGHT too, so a tall video (9:16) or a short
 * window never pushes the player off screen: `var()` substitutes "9 / 16" as
 * tokens, which makes `85vh * 9 / 16` a valid calc. */
.gc-video-embed-dialog__stage {
    position: relative;
    aspect-ratio: var(--gc-video-ratio, 16 / 9);
    inline-size: min(100%, calc(85vh * var(--gc-video-ratio, 16 / 9)));
    margin-inline: auto;
}
.gc-video-embed-dialog__stage > iframe,
.gc-video-embed-dialog__stage > video {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    border: 0;
}
.gc-video-embed-dialog__close {
    position: absolute;
    inset-block-end: calc(100% + 0.5rem);
    inset-inline-end: 0;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba( 20, 22, 27, 0.72 );
    color: rgb( 255, 255, 255 );
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}
.gc-video-embed-dialog__close:focus-visible {
    outline: 3px solid rgb( 255, 255, 255 );
    outline-offset: 2px;
}
/* The window while a hidden address is on its way: the play circle's turning
 * arc, on the window's own stage. */
.gc-video-embed-dialog__stage.is-loading::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    inline-size: 3rem;
    block-size: 3rem;
    border-radius: 50%;
    border: 3px solid rgba( 255, 255, 255, 0.25 );
    border-block-start-color: rgb( 255, 255, 255 );
    animation: gc-video-spin 800ms linear infinite;
    pointer-events: none;
}

/* ─── When a video cannot start ───────────────────────────────────────────
 * Centred on the picture or the player, the way Prime Video, Zoom and Telegram
 * show a player error (Mobbin, 2026-10-02), so it never covers a started
 * player's controls. The block's neutral pair (the play circle's) reads on any
 * poster and any theme. It wraps, has room for the longest translation, and
 * keeps its button at a 44px target. Empty, it stays in the page with no size:
 * a status region must exist BEFORE its words arrive to be heard (NVDA,
 * 2026-10-01). */
.gc-video-embed__notice {
    position: absolute;
    z-index: 4;
    inset: 0;
    margin: auto;
    inline-size: fit-content;
    block-size: fit-content;
    max-inline-size: min(28rem, calc(100% - 2rem));
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    padding: 0.75rem 1rem;
    border-radius: 0.5rem;
    background: rgba( 20, 22, 27, 0.94 );
    color: rgb( 255, 255, 255 );
    font-size: 1rem;
    line-height: 1.4;
    text-align: start;
}
.gc-video-embed__notice:empty {
    padding: 0;
    background: none;
}
/* The play circle steps back while a message stands over it: the message's own
 * button is the way on (seen 2026-10-02, the circle peeked out around it). */
.gc-video-embed__box:has( > .gc-video-embed__notice:not(:empty) ) > .gc-video-embed__play {
    visibility: hidden;
}
.gc-video-embed__notice-text {
    flex: 1 1 12rem;
    margin: 0;
    color: inherit;
    overflow-wrap: anywhere;
}

/* ─── The Cairnstone player (Plyr) ─────────────────────────────────────
 * Plyr's own look ships in gc-plyr.css. These rules only seat it in the
 * reserved box and hide the controls the author switched off for the current
 * moment (before play / while playing, toggled by the view-script). */
.gc-video-embed__box > .plyr,
.gc-video-embed__stage > .plyr,
.gc-video-embed-dialog__stage > .plyr {
    position: absolute;
    inset: 0;
    block-size: 100%;
}
.gc-video-embed .plyr video,
.gc-video-embed-dialog .plyr video {
    block-size: 100%;
}
.gc-video-embed .gc-vp-off,
.gc-video-embed-dialog .gc-vp-off {
    display: none !important;
}
/* A narrow player keeps the controls that matter. Measured at 320px on
 * 2026-10-01: the player was 246px wide, the bar did not fit, so Restart,
 * Back 10s and half of Play sat outside the left edge (one link in the tab order
 * scrolled out of sight) and the timeline shrank to 3px (WCAG 1.4.10). Below
 * 480px the bar drops what the timeline already does (restart, the 10-second
 * jumps, which its arrow keys repeat) and the volume slider (mute stays); below
 * 300px the elapsed time goes too, so the timeline keeps room to be used. The
 * author's own choice of controls still applies on top. */
.gc-video-embed .plyr,
.gc-video-embed-dialog .plyr {
    container: gc-plyr / inline-size;
    /* Plyr's own blue (#00b2ff) was the big play button's fill, every control's
     * hover and focus fill, and the focus ring. White on it measured 2.38:1 on
     * 2026-10-01, under the 3:1 a control's icon owes (WCAG 1.4.11), and a blue
     * ring is as faint on a light frame; a fixed hue also breaks the library's
     * no-hue rule. The player now uses the neutral pair this block already uses
     * for its play circle before play: near-white fills with a dark icon, and a
     * two-tone focus ring that reads on light and dark frames alike. */
    --plyr-color-main: rgb( 255, 255, 255 );
    --plyr-video-control-color-hover: rgb( 20, 22, 27 );
    --plyr-video-control-background-hover: rgba( 255, 255, 255, 0.94 );
}
.gc-video-embed .plyr :focus-visible,
.gc-video-embed-dialog .plyr :focus-visible {
    outline: 2px solid rgb( 255, 255, 255 ) !important;
    outline-offset: 0 !important;
    box-shadow: 0 0 0 4px rgb( 20, 22, 27 ) !important;
}
/* The ticked item in the settings menu: Plyr marks it in the main colour, which
 * is now white, on a white menu. */
.gc-video-embed .plyr__menu__container .plyr__control[role="menuitemradio"][aria-checked="true"]::before,
.gc-video-embed-dialog .plyr__menu__container .plyr__control[role="menuitemradio"][aria-checked="true"]::before {
    background: rgb( 20, 22, 27 );
}
@container gc-plyr (max-width: 480px) {
    .plyr__controls [data-plyr="restart"],
    .plyr__controls [data-plyr="rewind"],
    .plyr__controls [data-plyr="fast-forward"],
    .plyr__controls .plyr__volume input[data-plyr="volume"] {
        display: none !important;
    }
}
@container gc-plyr (max-width: 300px) {
    .plyr__controls .plyr__time {
        display: none !important;
    }
}

/* Before play, a YouTube or Vimeo video shows the buttons that start it. */
/* Left to right in every language, like the player it stands in for (Plyr
 * forces `direction: ltr`): a media timeline does not mirror. */
.gc-video-embed__prebar {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    display: flex;
    align-items: center;
    direction: ltr;
    gap: 0.25rem;
    padding: 0.5rem 0.625rem;
    background: linear-gradient( to top, rgba( 0, 0, 0, 0.6 ), rgba( 0, 0, 0, 0 ) );
}
.gc-video-embed__pre {
    display: inline-grid;
    place-items: center;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0.25rem;
    background: transparent;
    color: rgb( 255, 255, 255 );
    cursor: pointer;
}
.gc-video-embed__pre svg {
    inline-size: 1.125rem;
    block-size: 1.125rem;
    fill: currentColor;
}
.gc-video-embed__pre:hover {
    background: rgba( 255, 255, 255, 0.18 );
}
.gc-video-embed__pre:focus-visible {
    outline: 3px solid rgb( 255, 255, 255 );
    outline-offset: -3px;
}
.gc-video-embed__prebar a.gc-video-embed__pre {
    text-decoration: none;
}
/* The timeline takes the free space, as it does in the player. */
.gc-video-embed__pre-track {
    flex: 1 1 auto;
    min-inline-size: 3rem;
    block-size: 2.75rem;
    margin: 0;
    padding: 0 0.5rem;
    border: 0;
    background: transparent;
    cursor: pointer;
}
.gc-video-embed__pre-track > span {
    display: block;
    block-size: 0.3125rem;
    border-radius: 999px;
    background: rgba( 255, 255, 255, 0.35 );
}
.gc-video-embed__pre-track:focus-visible {
    outline: 3px solid rgb( 255, 255, 255 );
    outline-offset: -3px;
}
.gc-video-embed__pre-time {
    padding-inline: 0.25rem;
    color: rgb( 255, 255, 255 );
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
}
.gc-video-embed__pre-volume {
    inline-size: 5rem;
    accent-color: rgb( 255, 255, 255 );
}

/* No big play button chosen for before play: out of sight, but still the
 * keyboard's way in, so it reappears the moment it takes focus. */
.gc-video-embed__play--quiet:not(:focus-visible) {
    opacity: 0;
}

/* ─── Background video ────────────────────────────────────────────────── */
.gc-video-embed--mode-background .gc-video-embed__box {
    display: grid;
    overflow: visible;
}
/* The picture layer clips instead of the box, so blocks placed on top can make
 * the section taller than its shape and the box grows with them. */
.gc-video-embed__bg {
    position: absolute;
    inset: 0;
    overflow: hidden;
    border-radius: inherit;
    container-type: size;
    pointer-events: none;
}
.gc-video-embed__bg > .gc-video-embed__video {
    object-fit: cover;
}
/* Until the first frame paints (or for good, if it never does) the section is
 * dark, not the page's pale wash: blocks placed on a video are almost always
 * light text, and light text on the pale wash measured unreadable on csdev
 * 2026-09-25. Media surface, same fixed value as the pop-up's scrim. */
.gc-video-embed--mode-background .gc-video-embed__bg {
    background: rgb( 20, 22, 27 );
}
/* The author's "darken the video" amount, over the picture and under the blocks. */
.gc-video-embed__bg::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba( 0, 0, 0, var( --gc-video-dim, 0 ) );
}
/* A frame cannot "cover" like a picture, so it is sized to the larger of the
 * two fits and centred: `var()` turns "16 / 9" into tokens, which makes these
 * valid calc() expressions. */
.gc-video-embed__bg > iframe {
    position: absolute;
    top: 50%;
    left: 50%;
    inline-size: max( 100cqw, calc( 100cqh * var( --gc-video-ratio, 16 / 9 ) ) );
    block-size: max( 100cqh, calc( 100cqw / ( var( --gc-video-ratio, 16 / 9 ) ) ) );
    border: 0;
    transform: translate( -50%, -50% );
}
.gc-video-embed__content {
    position: relative;
    z-index: 1;
    align-self: center;
    padding: clamp( 1rem, 5%, 3rem );
}
.gc-video-embed__bgtoggle {
    position: absolute;
    z-index: 2;
    inset-block-end: 0.75rem;
    inset-inline-end: 0.75rem;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba( 20, 22, 27, 0.72 );
    color: rgb( 255, 255, 255 );
    cursor: pointer;
}
/* Pause bars while playing, a play triangle while paused. */
.gc-video-embed__bgtoggle::before {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    inline-size: 0.875rem;
    block-size: 0.875rem;
    background:
        linear-gradient( to right, currentColor 0 35%, transparent 35% 65%, currentColor 65% 100% );
}
.gc-video-embed__bgtoggle.is-paused::before {
    left: 10%;
    background: currentColor;
    clip-path: polygon( 0 0, 100% 50%, 0 100% );
}
.gc-video-embed__bgtoggle:focus-visible {
    outline: 3px solid rgb( 255, 255, 255 );
    outline-offset: 2px;
}

/* ─── Timed content ─────────────────────────────────────────────────────
 * Shown with scripting off; once the script arms it, only from its moment. */
.gc-video-embed__cue {
    margin-block-start: 0.75rem;
}
.gc-video-embed__cue.is-armed:not(.is-on) {
    display: none;
}

/* ─── Chapters ──────────────────────────────────────────────────────────── */
.gc-video-embed__chapters ol {
    margin: 0.75rem 0 0;
    padding: 0;
    list-style: none;
}
.gc-video-embed__chapter {
    display: flex;
    gap: 0.75rem;
    align-items: baseline;
    min-block-size: 44px;
    box-sizing: border-box;
    padding-block: 0.5rem;
    color: inherit;
    text-decoration: none;
}
/* Themes often strip link outlines (Signify does); the keyboard still needs one. */
.gc-video-embed .gc-video-embed__chapter:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}
/* Underlined at rest: a row of times and names otherwise reads as a plain list,
 * and only a pointer user found out on hover that it jumps the video (visible
 * affordance, RUN-20261001-01). Hover and focus thicken it. */
.gc-video-embed__chapter-label {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
}
.gc-video-embed__chapter:hover .gc-video-embed__chapter-label,
.gc-video-embed__chapter:focus-visible .gc-video-embed__chapter-label {
    text-decoration-thickness: 2px;
}
.gc-video-embed__chapter-time {
    min-inline-size: 3.5em;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
/* A word boundary between the time and the chapter name. NVDA read the line as
 * "0:00Choose the base stones" on 2026-10-01: the link is a flex row, so the
 * space between the two spans in the markup is never rendered and never reaches
 * the text stream. A preserved space inside the time's own text does (the
 * pattern in skills/cs/block.md section 0, and gc-comparison-table.css). */
.gc-video-embed__chapter-time::after {
    content: " ";
    white-space: pre;
}

/* ─── Card look: title and length on the picture ──────────────────────── */
.gc-video-embed__card {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    padding: clamp( 0.75rem, 3%, 1.25rem );
    background: linear-gradient( to top, rgba( 0, 0, 0, 0.65 ), rgba( 0, 0, 0, 0 ) 55% );
    color: rgb( 255, 255, 255 );
    pointer-events: none;
}
.gc-video-embed__card-title {
    font-weight: 600;
    line-height: 1.3;
}
.gc-video-embed__card-length {
    flex: 0 0 auto;
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    background: rgba( 0, 0, 0, 0.7 );
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
}

/* ─── Play-button shapes (the default is the circle) ──────────────────── */
.gc-video-embed--icon-square .gc-video-embed__play {
    border-radius: 0.75rem;
}
@layer gc-look {
    .gc-video-embed--icon-pill .gc-video-embed__play {
        aspect-ratio: 3 / 2;
    }
}
.gc-video-embed--icon-pill .gc-video-embed__play {
    border-radius: 999px;
}
.gc-video-embed.gc-video-embed--icon-outline a.gc-video-embed__play {
    --gc-video-play-fill: transparent;
    --gc-video-play-ink: rgb( 255, 255, 255 );
    border: 3px solid rgb( 255, 255, 255 ) !important;
}
.gc-video-embed.gc-video-embed--icon-bare a.gc-video-embed__play {
    --gc-video-play-fill: transparent;
    --gc-video-play-ink: rgb( 255, 255, 255 );
    box-shadow: none;
    filter: drop-shadow( 0 2px 6px rgba( 0, 0, 0, 0.55 ) );
}
/* Outline and bare draw white on the picture: their contrast comes from the
 * picture, so both keep a dark halo. */
.gc-video-embed--icon-outline .gc-video-embed__play {
    filter: drop-shadow( 0 2px 8px rgba( 0, 0, 0, 0.5 ) );
}

/* ─── Hover effects ───────────────────────────────────────────────────── */
.gc-video-embed--hover-none .gc-video-embed__play:hover {
    transform: translate( -50%, -50% );
}
.gc-video-embed--hover-glow .gc-video-embed__play:hover {
    transform: translate( -50%, -50% );
    box-shadow: 0 0 0 6px rgba( 255, 255, 255, 0.35 ), 0 0 28px rgba( 255, 255, 255, 0.6 );
}
.gc-video-embed--hover-zoom .gc-video-embed__play:hover {
    transform: translate( -50%, -50% );
}
.gc-video-embed--hover-zoom .gc-video-embed__poster {
    transition: transform 400ms cubic-bezier( 0.25, 1, 0.5, 1 );
}
.gc-video-embed--hover-zoom .gc-video-embed__box:hover .gc-video-embed__poster {
    transform: scale( 1.05 );
}

/* ─── Expand into free space once playing ─────────────────────────────── */
/* Width and move are measured by the view-script against the window. The move
 * is a translate (physical), so a theme's centring margins cannot undo it. */
.gc-video-embed--expand.is-expanded {
    position: relative;
    z-index: 1;
    inline-size: var( --gc-video-expand-w, 100% );
    max-inline-size: none;
    translate: var( --gc-video-expand-shift, 0 ) 0;
}

/* ─── The video has gone: stored picture, title and a link ────────────── */
.gc-video-embed__decay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
}
.gc-video-embed__decay > p {
    position: relative;
    z-index: 1;
    margin: 0;
    padding: 0.75rem 1rem;
    inline-size: 100%;
    box-sizing: border-box;
    background: rgba( 20, 22, 27, 0.85 );
    color: rgb( 255, 255, 255 );
}
.gc-video-embed__decay a {
    color: inherit;
    text-decoration: underline;
}

/* ─── Narrower than the column, at its start, centre or end ────────────
 * On the block's CONTENT, not the block: block themes centre every direct
 * child of a constrained layout with `margin: auto !important` and size it
 * from the wide container (measured on Twenty Twenty-Five 2026-09-25: 60% at
 * the end came out 56% and centred). The figure keeps the column the theme
 * gives it; the video, caption and the rest are narrowed and placed inside. */
.gc-video-embed.gc-video-embed--narrow > * {
    inline-size: var( --gc-video-w, 100% );
    max-inline-size: 100%;
    box-sizing: border-box;
}
.gc-video-embed.gc-video-embed--place-start > * {
    margin-inline-start: 0;
    margin-inline-end: auto;
}
.gc-video-embed.gc-video-embed--place-center > * {
    margin-inline: auto;
}
.gc-video-embed.gc-video-embed--place-end > * {
    margin-inline-start: auto;
    margin-inline-end: 0;
}

/* ─── Watermark over the site's own file ────────────────────────────── */
.gc-video-embed__watermark {
    position: absolute;
    z-index: 2;
    max-inline-size: 22%;
    max-block-size: 22%;
    inline-size: auto;
    block-size: auto;
    object-fit: contain;
    pointer-events: none;
}
.gc-video-embed__watermark--top-left { inset-block-start: 4%; inset-inline-start: 3%; }
.gc-video-embed__watermark--top-right { inset-block-start: 4%; inset-inline-end: 3%; }
.gc-video-embed__watermark--bottom-left { inset-block-end: 14%; inset-inline-start: 3%; }
.gc-video-embed__watermark--bottom-right { inset-block-end: 14%; inset-inline-end: 3%; }
.gc-video-embed__watermark--center {
    top: 50%;
    left: 50%;
    transform: translate( -50%, -50% );
}

/* ─── The picture again while paused ────────────────────────────────── */
.gc-video-embed__pause-poster {
    position: absolute;
    inset: 0;
    z-index: 3;
    inline-size: 100%;
    block-size: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    background-color: rgb( 20, 22, 27 );
    background-position: center;
    background-size: cover;
    cursor: pointer;
}
.gc-video-embed__pause-poster[hidden] {
    display: none;
}
.gc-video-embed__pause-poster::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    inline-size: clamp( 3.25rem, 12%, 5.5rem );
    aspect-ratio: 1;
    border-radius: 50%;
    transform: translate( -50%, -50% );
    background:
        rgba( 255, 255, 255, 0.94 )
        url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 5v14l11-7z' fill='%2314161b'/%3E%3C/svg%3E" )
        center / 45% no-repeat;
    box-shadow: 0 4px 18px rgba( 20, 22, 27, 0.35 );
}
.gc-video-embed__pause-poster:focus-visible {
    outline: 3px solid rgb( 255, 255, 255 );
    outline-offset: -6px;
}

/* ─── Password ──────────────────────────────────────────────────────── */
.gc-video-embed__lock {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0.5rem;
    padding: 1rem;
    background: rgba( 20, 22, 27, 0.78 );
    color: rgb( 255, 255, 255 );
    text-align: center;
}
/* The locked box grows with its form. Measured at 320px on 2026-10-01: the box
 * kept the video's shape (138px tall) while the form needed 168px, so the top
 * of the text and the Watch button were cut off (WCAG 1.4.10), worse with the
 * wrong-password line or larger text spacing (1.4.12). A grid cell now holds
 * the shape as its MINIMUM height and the form in the same cell, so the box is
 * as tall as the video or as the form, whichever is taller; the picture still
 * covers the whole box behind the scrim. */
.gc-video-embed--locked .gc-video-embed__box {
    display: grid;
    /* One column exactly as wide as the box: an `auto` track sized itself to
     * the longest line of text (511px in a 246px box) and cut it off. */
    grid-template-columns: minmax( 0, 1fr );
    aspect-ratio: auto;
}
.gc-video-embed--locked .gc-video-embed__box::before {
    content: "";
    grid-area: 1 / 1;
    aspect-ratio: var(--gc-video-ratio, 16 / 9);
}
.gc-video-embed--locked .gc-video-embed__lock {
    position: relative;
    inset: auto;
    grid-area: 1 / 1;
}
/* With no picture the blank stand-in prints the title at its foot, which the
 * scrim turns dark-on-dark and the grown form now lands on. */
.gc-video-embed--locked .gc-video-embed__blank-title {
    visibility: hidden;
}
.gc-video-embed__lock-text {
    margin: 0;
    max-inline-size: 32ch;
}
/* "That password is not right." Bold rather than red: the panel is a dark
 * scrim over any picture, so a red would have to be measured against every
 * poster; the white text is already measured against the scrim. */
.gc-video-embed__lock-error {
    margin: 0;
    max-inline-size: 32ch;
    font-weight: 700;
}
.gc-video-embed__lock-label {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset( 50% );
    white-space: nowrap;
}
.gc-video-embed__lock-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
}
.gc-video-embed .gc-video-embed__lock-input {
    min-block-size: 44px;
    min-inline-size: 12rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid rgb( 255, 255, 255 );
    border-radius: 0.375rem;
    background: rgb( 20, 22, 27 );
    color: rgb( 255, 255, 255 );
}
.gc-video-embed .gc-video-embed__lock-button {
    min-block-size: 44px;
    padding: 0.5rem 1.25rem;
    border: 1px solid rgb( 255, 255, 255 );
    border-radius: 0.375rem;
    background: rgb( 255, 255, 255 );
    color: rgb( 20, 22, 27 );
    font-weight: 600;
    cursor: pointer;
}
.gc-video-embed .gc-video-embed__lock-input:focus-visible,
.gc-video-embed .gc-video-embed__lock-button:focus-visible {
    outline: 2px solid rgb( 255, 255, 255 );
    outline-offset: 2px;
}

/* ─── Questions (gc-video-quiz.js) ─────────────────────────────────────
 * Under the video, never over it (YouTube and Vimeo forbid overlays). Colours
 * come from the page's own text colour, so the panel reads on light and dark
 * themes alike; right and wrong are said in words, not by colour alone. */
.gc-video-quiz {
    margin-block-start: 0.75rem;
    padding: 1rem;
    border: 1px solid color-mix( in srgb, currentColor 35%, transparent );
    border-radius: 0.5rem;
}
.gc-video-quiz.is-right {
    border-color: color-mix( in srgb, rgb( 22, 163, 74 ) 70%, currentColor );
}
.gc-video-quiz.is-wrong {
    border-color: color-mix( in srgb, rgb( 220, 38, 38 ) 70%, currentColor );
}
.gc-video-quiz__set {
    margin: 0;
    padding: 0;
    border: 0;
    min-inline-size: 0;
}
.gc-video-quiz__question {
    padding: 0;
    margin-block-end: 0.5rem;
    font-weight: 600;
}
.gc-video-quiz__hint {
    margin: 0 0 0.5rem;
    font-size: 0.875em;
}
.gc-video-quiz__answer {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-block-size: 44px;
    cursor: pointer;
}
.gc-video-quiz__answer input {
    flex: 0 0 auto;
    inline-size: 1.125rem;
    block-size: 1.125rem;
    margin: 0;
}
.gc-video-quiz__feedback {
    margin: 0.5rem 0 0;
}
/* Empty, the line takes no room, but it must stay in the page: it is a status
 * region, and a region hidden with display:none is not in the accessibility
 * tree, so the text that later fills it arrived as a NEW region already full,
 * which NVDA does not announce. "Choose an answer first." went unheard that way
 * on 2026-10-01. */
.gc-video-quiz__feedback:empty {
    margin: 0;
}
.gc-video-quiz__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-block-start: 0.75rem;
}
/* The site's own button look: block themes style .wp-element-button, classic
 * themes style `button`. This fallback sits at zero specificity so either wins,
 * and only a theme with neither sees it. */
:where(.gc-video-quiz__button) {
    padding: 0.5rem 1.25rem;
    border: 1px solid currentColor;
    border-radius: 0.375rem;
    background: transparent;
    color: inherit;
    font: inherit;
}
.gc-video-quiz__button {
    min-block-size: 44px;
    cursor: pointer;
}
.gc-video-quiz__button[hidden] {
    display: none;
}
.gc-video-quiz__score,
.gc-video-quiz__verdict {
    margin: 0;
}
.gc-video-quiz__score {
    font-weight: 600;
}
.gc-video-embed.is-quiz-locked .gc-video-embed__box {
    opacity: 0.35;
    filter: grayscale( 1 );
}
.gc-video-quiz__locked {
    margin: 0.75rem 0 0;
    font-weight: 600;
}

/* ─── Holding off a theme that paints every button and link ─────────────
 * Measured on csdevdark (Signify, a classic theme) 2026-09-25: its content
 * `button` rule filled every control red with a white border and 13px 28px
 * padding, and its link colour turned the play triangle red. Plyr's resting
 * button rule sits at ONE class and loses to it; Plyr's hover, focus and open
 * states out-rank the theme on their own, so only the resting state is
 * restored here, with Plyr's own values. Our own buttons route their surface
 * through variables with !important (block.md, cascade combat), and set the
 * variable on their states. */

/* The facade's play link: the circle and its triangle. !important because
 * Signify's link rule stacks nine :not() classes (specificity 0,11,1), which no
 * sane selector out-ranks. A styled part still wins: the part engine re-emits
 * its colour and surface !important under five repeated hooks, which is the
 * higher specificity of the two. */
.gc-video-embed a.gc-video-embed__play {
    color: var( --gc-video-play-ink, rgb( 20, 22, 27 ) ) !important;
    background-color: var( --gc-video-play-fill, rgba( 255, 255, 255, 0.94 ) ) !important;
    text-decoration: none !important;
    border: 0 !important;
}

/* Plyr's own buttons (border, resting surface, bar padding) are held off the
 * theme in gc-base.css, since 2.4.71 shared with the Audio block. */
/* The big centre button: a round button in Plyr's main colour. */
.gc-video-embed .plyr button.plyr__control--overlaid,
.gc-video-embed-dialog .plyr button.plyr__control--overlaid {
    padding: calc( var( --plyr-control-spacing, 10px ) * 1.5 );
    border-radius: 100%;
    background: var( --plyr-video-control-background-hover, var( --plyr-color-main, #00b2ff ) );
    color: var( --plyr-video-control-color-hover, #fff );
}
/* Plyr puts a slash before the length whenever a time precedes it, even one
 * the author switched off. */
.gc-video-embed .plyr__time.gc-vp-off + .plyr__time::before,
.gc-video-embed-dialog .plyr__time.gc-vp-off + .plyr__time::before {
    content: none;
}

/* Our own buttons: surface through variables, !important, states set the var. */
.gc-video-embed button.gc-video-embed__pre,
.gc-video-embed button.gc-video-embed__pre-track,
.gc-video-embed button.gc-video-embed__bgtoggle,
.gc-video-embed button.gc-video-embed__unfloat,
.gc-video-embed-dialog button.gc-video-embed-dialog__close {
    padding: 0 !important;
    border: 0 !important;
    box-shadow: none !important;
    text-transform: none !important;
    letter-spacing: normal !important;
    min-width: 0 !important;
    min-height: 0 !important;
    color: var( --gc-video-btn-ink, rgb( 255, 255, 255 ) ) !important;
    background: var( --gc-video-btn-fill, transparent ) !important;
}
.gc-video-embed button.gc-video-embed__pre-track {
    padding: 0 0.5rem !important;
}
.gc-video-embed button.gc-video-embed__pre {
    border-radius: 0.25rem !important;
}
.gc-video-embed button.gc-video-embed__bgtoggle,
.gc-video-embed button.gc-video-embed__unfloat,
.gc-video-embed-dialog button.gc-video-embed-dialog__close {
    border-radius: 50% !important;
}
/* The picture shown while paused is a button too, and Signify painted it red
 * with its own padding (measured 2026-09-25). Its picture rides the inline
 * background-image, so only the colour and the box are held here. */
.gc-video-embed button.gc-video-embed__pause-poster {
    padding: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    min-width: 0 !important;
    min-height: 0 !important;
    background-color: rgb( 20, 22, 27 ) !important;
    background-position: center !important;
    background-size: cover !important;
    background-repeat: no-repeat !important;
    transition: none !important;
}
.gc-video-embed button.gc-video-embed__pre:hover {
    --gc-video-btn-fill: rgba( 255, 255, 255, 0.18 );
}
.gc-video-embed button.gc-video-embed__bgtoggle,
.gc-video-embed button.gc-video-embed__unfloat {
    --gc-video-btn-fill: rgba( 20, 22, 27, 0.78 );
}
.gc-video-embed-dialog button.gc-video-embed-dialog__close {
    --gc-video-btn-fill: rgba( 20, 22, 27, 0.72 );
}
/* "Try again": the light half of the pair, held against themes that paint every
 * button (Signify, measured 2026-09-25 on the controls above). */
.gc-video-embed button.gc-video-embed__notice-retry,
.gc-video-embed-dialog button.gc-video-embed__notice-retry {
    min-block-size: 2.75rem !important;
    min-width: 0 !important;
    padding: 0 1rem !important;
    border: 0 !important;
    border-radius: 999px !important;
    box-shadow: none !important;
    text-transform: none !important;
    letter-spacing: normal !important;
    font: inherit !important;
    font-weight: 600 !important;
    color: rgb( 20, 22, 27 ) !important;
    background: rgb( 255, 255, 255 ) !important;
    cursor: pointer;
}
.gc-video-embed button.gc-video-embed__notice-retry:focus-visible,
.gc-video-embed-dialog button.gc-video-embed__notice-retry:focus-visible {
    outline: 2px solid rgb( 255, 255, 255 ) !important;
    outline-offset: 2px !important;
}

@media (prefers-reduced-motion: reduce) {
    .gc-video-embed button.gc-video-embed__pause-poster,
    .gc-video-embed__play,
    .gc-video-embed--hover-zoom .gc-video-embed__poster {
        transition: none;
    }
    .gc-video-embed--hover-zoom .gc-video-embed__box:hover .gc-video-embed__poster {
        transform: none;
    }
    .gc-video-embed__play:hover,
    .gc-video-embed__play:active {
        transform: translate(-50%, -50%);
    }
    .gc-video-embed.is-loading .gc-video-embed__play::before,
    .gc-video-embed-dialog__stage.is-loading::after {
        animation: none;
    }
}
