/*
 * E04 Quilted Patchwork, on the shared core (rebuild on the generated art, Nov 7, 2026).
 *
 * A patchwork quilt for a family recipe channel. Every control is the quilting Gemini generated for this
 * design (sheets2/e04-quilt-sheet.jpg): round quilted patches with running stitches and cream applique
 * glyphs (crimson play and pause, denim volume, mute and fullscreen, sage captions), the piped cord with
 * its running stitch as the seek (crimson played, cream ahead), and the plain red tufted knob as the
 * playhead (the sheet's spare without the X, which reads as "close"). A plain dark scrim (not fabric)
 * under the row keeps the time readable over any frame.
 *
 * Seek: a stretched middle would smear the running stitch into long dashes, so each cord is its two
 * sewn ends plus a tile of whole stitch periods, repeated with background-repeat: round. The crimson
 * cord is clipped at the fill over the cream one; the knob covers the join.
 *
 * Signature, buttons sink like padding: a press dents the patch (a shaded hollow comes up inside it and
 * the patch settles 3%) in 90ms, and the padding fills back in over 280ms with no bounce. Reduced motion:
 * the dent is shading only.
 */

@font-face {
  font-family: "Bitter";
  src: url(fonts/Bitter-700.woff2) format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

.sk-root[data-skin="e04"] {
  --media-accent-color: #b72f3e;
  --media-accent-text-color: #fff6e6;
  --media-border-radius: 18px;
  --media-font-family: "Bitter", Georgia, serif;

  --qp-crimson: #7e1927;
  --qp-cream: #f4e7cf;
  --qp-ink: #2a0d12;

  /* the cord: 110px tall in the art; its sewn ends are 39px of that */
  --qp-cord-h: 30px;

  --sk-pad: 8px;
  --sk-hit: 56px;
  --sk-icon: 56px;
  --sk-btn-radius: 50%;
  --sk-ink: #fff6e6;
  --sk-ink-2: #f1e7d1;
  --sk-surface: #4a1520;
  --sk-surface-solid: #4a1520;
  --sk-blur: 0px;
  --sk-hairline: transparent;
  --sk-shadow: 0 3px 6px rgb(0 0 0 / .25), 0 12px 26px rgb(0 0 0 / .28);
  --sk-cc-on: var(--qp-cream);
  --sk-focus: #fff6e6;
  --sk-focus-gap: #2a0d12;
  --sk-error-accent: var(--qp-cream);
  /* a plain dark scrim (not fabric) under the row */
  --qp-scrim-a: .86;
  --sk-scrim: linear-gradient(to top, rgb(28 10 14 / var(--qp-scrim-a)) 0, rgb(28 10 14 / calc(var(--qp-scrim-a) * .72)) 70px, rgb(28 10 14 / 0) 156px);
  /* captions (Nov 15, 2026): the 56px patches' tops (70px up) + a one-line cue + a gap; see the clearance block at the end */
  --sk-cue-clearance: 120px;

  --qp-bar-pad: 14px;
  --qp-bar-h: calc(var(--sk-hit) + var(--qp-bar-pad) * 2);
}

.sk-root[data-skin="e04"] > mux-video {
  font-family: "Inter", system-ui, sans-serif;
}

/* ---------- The row of patches ---------- */

.qp-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--qp-bar-h);
  padding: var(--qp-bar-pad) calc(18px + var(--sk-hit) + 8px) var(--qp-bar-pad) 18px;
  color: var(--sk-ink);
}

/* Patches: the art is the whole button */
.sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs) {
  transition: none;
}
.sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs) .sk-icon {
  filter: drop-shadow(0 2px 3px rgb(0 0 0 / .35));
  transition: filter 280ms ease-out, scale 280ms ease-out;
}
.sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs):hover .sk-icon {
  filter: drop-shadow(0 3px 5px rgb(0 0 0 / .38)) brightness(1.07);
  transition-duration: var(--sk-enter);
}
/* Signature: the padding sinks. A shaded hollow comes up inside the patch as it settles. */
.sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs)::before {
  content: "";
  position: absolute;
  inset: 12%;
  z-index: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 46%, rgb(20 4 8 / .42), rgb(20 4 8 / .16) 55%, rgb(20 4 8 / 0) 72%);
  mix-blend-mode: multiply;
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms ease-out;
}
.sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs):active::before {
  opacity: 1;
  transition-duration: 90ms;
}
.sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs):active .sk-icon {
  filter: drop-shadow(0 1px 1px rgb(0 0 0 / .35)) brightness(.92);
  transition-duration: 90ms;
}
@media (prefers-reduced-motion: no-preference) {
  .sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs):active .sk-icon {
    scale: .97;
  }
}

/* Focus: a cream ring outside a dark gap, round with the patch */
.sk-root[data-skin="e04"] .sk-btn:focus-visible {
  box-shadow: 0 0 0 var(--sk-focus-off) var(--sk-focus-gap);
}

/* Captions: on = a cream bar under the patch; off = ONE signal only, in the entry's
   own material (Gus's direction, Nov 7): a RED PATCH straight across the medallion,
   a horizontal band of the entry's crimson cloth laid across the face, stitched
   along both long edges in cream thread like the patch's own rim stitching.
   No dimming; the mute patch carries the same band. */
.sk-root[data-skin="e04"] .sk-cc::after {
  z-index: 2;
  bottom: -8px;
  width: 20px;
  height: 4px;
  border-radius: 2px;
  box-shadow: 0 0 0 1.5px var(--qp-ink);
}
.sk-root[data-skin="e04"] .sk-patch-off {
  display: none;
}
.sk-root[data-skin="e04"]:not([data-captions]) .sk-cc .sk-patch-off,
.sk-root[data-skin="e04"][data-muted] .sk-mute .sk-patch-off {
  display: block;
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 2;
  /* Nov 15, 2026: sized from the patch, 52 x 13px on the 56px desktop patch (Gus's U27 size, unchanged there), so its
     tips stay inside the rim on the 48px mid and 44px phone patches too (a fixed 52px band overhung them by 3 to 5px) */
  width: calc(var(--sk-icon) * 52 / 56);
  height: calc(var(--sk-icon) * 13 / 56);
  translate: -50% -50%;
  rotate: -24deg;
  background-color: #7e1927;
  background-image:
    repeating-linear-gradient(90deg, #f4e7cf 0 5px, transparent 5px 10px),
    repeating-linear-gradient(90deg, #f4e7cf 0 5px, transparent 5px 10px),
    linear-gradient(180deg, #93222f, #7e1927 55%, #6d1420);
  background-size: 100% 1.5px, 100% 1.5px, 100% 100%;
  background-position: left 1.5px, left calc(100% - 1.5px), center;
  background-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px rgb(42 13 18 / .45), 0 1px 2px rgb(0 0 0 / .35);
  pointer-events: none;
}
/* the patch is a real child span (.sk-patch-off, in the entry markup): this
   entry's ::before belongs to the pressed-state hollow, which out-specified the
   band twice (U19), so the band no longer rides a pseudo slot */
/* (the muted-face restore sits with the mark above) */
/* Muted face (Gus's consistency rule, Nov 7): the Video.js v10 component
   swaps icon VISIBILITY itself when muted; CSS display rules, ours and the
   core's, never governed it (verified the hard way: computed display read
   none on buttons that were visibly painting). The one skin-side trap is
   hiding every icon on the muted root flag, which kills the component's
   own mute face too; the restore below, with !important, keeps exactly the
   mute face (the .sk-mute-face icon, the entry's own mute art) painting
   under the entry's mark, so muted matches captions-off exactly. */
.sk-root[data-skin="e04"][data-muted] .sk-mute .sk-icon { display: none !important; }
.sk-root[data-skin="e04"][data-muted] .sk-mute .sk-mute-face { display: block !important; }

/* Fullscreen: the row's last patch on desktop; top-right when narrow */
.sk-root[data-skin="e04"] .sk-controls > .sk-fs {
  position: absolute;
  right: 18px;
  bottom: var(--qp-bar-pad);
}

/* ---------- Time ---------- */

.qp-bar .sk-time {
  padding: 0 6px;
  font: 700 20px/1 var(--media-font-family);
  font-variant-numeric: tabular-nums lining-nums;
  text-shadow: 0 1px 2px rgb(18 4 8 / .85), 0 0 10px rgb(18 4 8 / .5);
}
.qp-bar .sk-time media-time-separator,
.qp-bar .sk-time media-time[data-type="duration"] {
  color: var(--sk-ink-2);
}

/* ---------- Seek: the piped cord ---------- */

.qp-bar .sk-seek {
  --sk-seek-hit: 48px;
  --sk-seek-radius: 24px;
  margin-inline: 8px;
}
.sk-root[data-skin="e04"] .sk-track,
.sk-root[data-skin="e04"] .sk-seek[data-interactive] .sk-track {
  height: var(--qp-cord-h);
  border-radius: 0;
  background: none;
  overflow: visible;
  transition: none;
}
/* each cord: two sewn ends and whole stitch periods between them */
.sk-root[data-skin="e04"] .sk-track::before,
.sk-root[data-skin="e04"] .sk-track > :is(.sk-buffer, .sk-fill) {
  content: "";
  position: absolute;
  inset: 0;
  width: auto;
  padding: 0 calc(var(--qp-cord-h) * 39 / 110);
  border-radius: 0;
  background:
    url(art/seek-unplayed-capl.png) left center / auto 100% no-repeat,
    url(art/seek-unplayed-capr.png) right center / auto 100% no-repeat,
    url(art/seek-unplayed-tile.png) 0 0 / auto 100% round;
  background-origin: border-box, border-box, content-box;
  background-clip: border-box, border-box, content-box;
}
.sk-root[data-skin="e04"] .sk-track::before {
  filter: drop-shadow(0 2px 3px rgb(0 0 0 / .35)) brightness(.88);
}
.sk-root[data-skin="e04"] .sk-track > .sk-buffer {
  clip-path: inset(0 calc(100% - var(--media-slider-buffer, 0%)) 0 0);
}
.sk-root[data-skin="e04"] .sk-track > .sk-fill {
  background:
    url(art/seek-played-capl.png) left center / auto 100% no-repeat,
    url(art/seek-played-capr.png) right center / auto 100% no-repeat,
    url(art/seek-played-tile.png) 0 0 / auto 100% round;
  background-origin: border-box, border-box, content-box;
  background-clip: border-box, border-box, content-box;
  clip-path: inset(0 calc(100% - var(--media-slider-fill, 0%)) 0 0);
}
/* the playhead: the plain red tufted knob */
.sk-root[data-skin="e04"] .qp-bar .sk-seek .sk-thumb {
  --sk-thumb: 38px;
  background: url(art/knob.png) center / contain no-repeat;
  filter: drop-shadow(0 2px 3px rgb(0 0 0 / .4));
  /* thumb containment (Gus's rule, Nov 7): the core centers the thumb on the fill
     percentage, so unclamped it spills half its width past the track at 0% and 100%.
     Travel is clamped to [half width + 0px, 100% - half width - 0px] so the thumb
     stays fully inside its track at both ends, mid-drag grow included.
     Nov 15, 2026: moved out of the no-preference query below, where it had landed, so it
     also holds with reduced motion (the knob hung 19px off both ends of the cord there). */
  left: clamp(calc(var(--sk-thumb-w, var(--sk-thumb)) / 2 + 0px), var(--media-slider-fill), calc(100% - var(--sk-thumb-w, var(--sk-thumb)) / 2 - 0px));
}
@media (prefers-reduced-motion: no-preference) {
  .sk-root[data-skin="e04"] .qp-bar .sk-seek .sk-thumb {
    transition: scale 280ms ease-out;
  }
  /* the tufted knob presses in while dragged */
  .sk-root[data-skin="e04"] .qp-bar .sk-seek[data-dragging] .sk-thumb {
    scale: .92;
    transition-duration: 90ms;
  }
}

/* Volume: a short cord beside the speaker patch, the small knob as its thumb */
.qp-bar .sk-volume {
  gap: 0;
}
.sk-root[data-skin="e04"] .sk-volume-slider {
  --sk-vol-w: 100px;
  --qp-cord-h: 20px;
  margin-inline: 8px 4px;
}
.sk-root[data-skin="e04"] .sk-volume-slider .sk-track {
  height: var(--qp-cord-h);
}
.sk-root[data-skin="e04"] .sk-volume-slider .sk-thumb {
  /* thumb containment (Gus's rule, Nov 7): the core centers the thumb on the fill
     percentage, so unclamped it spills half its width past the track at 0% and 100%.
     Travel is clamped to [half width + 0px, 100% - half width - 0px] so the thumb
     stays fully inside its track at both ends, mid-drag grow included. */
  left: clamp(calc(var(--sk-thumb-w, var(--sk-thumb)) / 2 + 0px), var(--media-slider-fill), calc(100% - var(--sk-thumb-w, var(--sk-thumb)) / 2 - 0px));
  --sk-thumb: 26px;
  background: url(art/knob.png) center / contain no-repeat;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / .4));
}

/* Preview: the frame on a cream binding, the time on a crimson tag */
.qp-bar .sk-preview {
  bottom: calc(100% + 12px);
}
.qp-bar .sk-preview-image {
  --sk-preview-radius: 8px;
  border: 4px solid var(--qp-cream);
  box-shadow: var(--sk-shadow);
}
.qp-bar .sk-preview-time {
  padding: 6px 10px 5px;
  border-radius: 999px;
  background: var(--qp-crimson);
  font: 700 14px/1 var(--media-font-family);
}

/* ---------- Center play: the crimson play patch (decorative; the row's Play is the real one) ---------- */

.sk-root[data-skin="e04"] .sk-center {
  padding-bottom: var(--qp-bar-h);
}
.sk-root[data-skin="e04"] .qp-disc {
  --sk-icon: 132px;
  position: relative;
  display: grid;
  place-items: center;
  width: var(--sk-icon);
  height: var(--sk-icon);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}
.sk-root[data-skin="e04"] .qp-disc .sk-icon {
  filter: drop-shadow(0 6px 12px rgb(0 0 0 / .35));
  transition: filter 280ms ease-out, scale 280ms ease-out;
}
.sk-root[data-skin="e04"] .qp-disc:hover .sk-icon {
  filter: drop-shadow(0 6px 12px rgb(0 0 0 / .35)) brightness(1.06);
}
.sk-root[data-skin="e04"] .qp-disc::before {
  content: "";
  position: absolute;
  inset: 14%;
  z-index: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 46%, rgb(20 4 8 / .4), rgb(20 4 8 / 0) 70%);
  mix-blend-mode: multiply;
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms ease-out;
}
.sk-root[data-skin="e04"] .qp-disc:active::before {
  opacity: 1;
  transition-duration: 90ms;
}
@media (prefers-reduced-motion: no-preference) {
  .sk-root[data-skin="e04"] .qp-disc:active .sk-icon {
    scale: .97;
    transition-duration: 90ms;
  }
}

/* ---------- Designed states ---------- */

.sk-root[data-skin="e04"] .sk-spinner {
  width: 70px;
  height: 70px;
  background: none;
  box-shadow: none;
}
.sk-root[data-skin="e04"] .sk-spinner .sk-icon {
  width: 70px;
  height: 70px;
  filter: drop-shadow(0 4px 8px rgb(0 0 0 / .4));
}
.sk-root[data-skin="e04"] .sk-error {
  gap: 8px;
  padding: 22px 8px 8px;
  border-radius: 18px;
  background: var(--qp-crimson);
  box-shadow: inset 0 0 0 3px rgb(244 231 207 / .55), var(--sk-shadow);
}
.sk-root[data-skin="e04"] .sk-error-title {
  padding-inline: 14px;
  font: 700 20px/1.2 var(--media-font-family);
}
.sk-root[data-skin="e04"] .sk-error-text {
  padding-inline: 14px;
  color: #fbeee0;
  font-family: "Inter", system-ui, sans-serif;
}
.sk-root[data-skin="e04"] .sk-error-close {
  width: 100%;
  height: 48px;
  margin-top: 8px;
  border-radius: 10px;
  background: var(--qp-cream);
  color: var(--qp-ink);
  font: 700 17px/1 var(--media-font-family);
}
.sk-root[data-skin="e04"] .sk-error-close:focus-visible {
  outline-color: var(--qp-cream);
}
.sk-root[data-skin="e04"] .sk-empty p {
  padding: 12px 20px;
  background: var(--qp-crimson);
  font: 700 16px/1 var(--media-font-family);
}

/* ---------- Mid widths ---------- */

@container sk (max-width: 819px) {
  .sk-root[data-skin="e04"] :is(.sk-controls, .sk-center) {
    --sk-hit: 48px;
    --sk-icon: 48px;
    --qp-bar-pad: 12px;
    --qp-cord-h: 26px;
    --qp-bar-h: calc(var(--sk-hit) + var(--qp-bar-pad) * 2);
  }
  .sk-root[data-skin="e04"] .qp-disc {
    --sk-icon: 110px;
  }
}
@container sk (max-width: 679px) {
  .sk-root[data-skin="e04"] .sk-volume-slider {
    display: none;
  }
}

/* ---------- Narrow: two rows (the cord on top); fullscreen at the top-right ---------- */

@container sk (max-width: 519px) {
  .sk-root[data-skin="e04"] :is(.sk-controls, .sk-center) {
    --sk-hit: 44px;
    --sk-icon: 44px;
    --qp-cord-h: 22px;
    --qp-bar-pad: 8px;
    --qp-bar-h: calc(var(--qp-bar-pad) * 2 + 30px + 4px + var(--sk-hit));
  }
  .qp-bar {
    display: grid;
    grid-template-columns: var(--sk-hit) var(--sk-hit) auto 1fr var(--sk-hit);
    grid-template-rows: 30px var(--sk-hit);
    gap: 4px 8px;
    padding: var(--qp-bar-pad) 12px;
  }
  .qp-bar .sk-seek {
    grid-column: 1 / -1;
    grid-row: 1;
    --sk-seek-hit: 30px;
    margin-inline: 4px;
  }
  .qp-bar .sk-play { grid-column: 1; grid-row: 2; }
  .qp-bar .sk-volume { grid-column: 2; grid-row: 2; }
  .qp-bar .sk-time { grid-column: 3; grid-row: 2; font-size: 17px; }
  .qp-bar .sk-cc { grid-column: 5; grid-row: 2; }
  .sk-root[data-skin="e04"] .qp-bar .sk-seek .sk-thumb {
    --sk-thumb: 30px;
  }
  .sk-root[data-skin="e04"] .sk-controls > .sk-fs {
    top: 10px;
    right: 10px;
    bottom: auto;
  }
  .sk-root[data-skin="e04"] .qp-disc {
    --sk-icon: 76px;
  }
  .sk-root[data-skin="e04"][data-started]:not([data-ended]) .qp-disc {
    opacity: 0;
    pointer-events: none;
  }
  /* touch (Nov 15, 2026): the core's 44px seek hit box reached 3px into the patches below; 38px fills the 30px row and
     its 4px gaps */
  @media (pointer: coarse) {
    .qp-bar .sk-seek {
      height: 38px;
    }
  }
  /* the hover preview fits above the cord on phone-size players (Nov 15, 2026); the core thumbnail sizes itself from
     max-width, and its 96px min-width would not fit a 328px player */
  .qp-bar .sk-preview-image {
    min-width: 56px;
    max-width: min(158px, 100cqw - 266px);
  }
}

/* ---------- Caption clearance (Nov 15, 2026) ----------
   Chrome 157 has no VTTCue.lineAlign, so a cue hangs one cue-height below the core's line. Each value is the top of
   the highest control + a one-line cue + a gap: one row of 56px patches 70px up (120, at the top of this file), the mid
   row of 48px patches 60px up (104, the old value, which already cleared there), the narrow layout's cord 86px up (114).
   The root can't query its own width, so these follow the viewport (player = viewport - 32px): the mid layout (players
   520 to 819px) is viewports 552 to 851px; a classic scrollbar can only move a mid player into the one-row value, which
   just lifts the cue higher. */
@media (max-width: 851px) {
  .sk-root[data-skin="e04"] {
    --sk-cue-clearance: 104px;
  }
}
@media (max-width: 551px) {
  .sk-root[data-skin="e04"] {
    --sk-cue-clearance: 114px;
  }
}
/* Fullscreen: Chrome sizes the cue from the player's smaller side (a one-line box is about 6% of it) while the bar
   keeps its size, so the clearance follows vmin (the viewport is the player here). Registering the property makes the
   computed value a px length, which is what the core's parseFloat reads. */
@property --sk-cue-clearance {
  syntax: "<length>";
  inherits: true;
  initial-value: 104px;
}
.sk-root[data-skin="e04"]:fullscreen {
  --sk-cue-clearance: calc(80px + 6.75vmin);
}
@media (max-width: 519px) {
  .sk-root[data-skin="e04"]:fullscreen {
    --sk-cue-clearance: calc(98px + 6.75vmin);
  }
}

/* ---------- Preference fallbacks ---------- */

@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .sk-root[data-skin="e04"] {
    --sk-scrim: linear-gradient(to top, rgb(28 10 14) 0, rgb(28 10 14) calc(var(--qp-bar-h) + 6px), rgb(28 10 14 / 0) calc(var(--qp-bar-h) + 6px));
  }
}
@media (prefers-contrast: more) {
  .sk-root[data-skin="e04"] {
    --sk-focus-w: 3px;
  }
  .qp-bar .sk-time {
    text-shadow: none;
  }
}
@media (forced-colors: active) {
  .qp-bar {
    border-top: 2px solid CanvasText;
    background: Canvas;
  }
  .sk-root[data-skin="e04"] .qp-bar .sk-track {
    outline: 1px solid CanvasText;
  }
  .sk-root[data-skin="e04"] .sk-track > .sk-buffer {
    background: repeating-linear-gradient(90deg, CanvasText 0 1px, Canvas 1px 4px);
    forced-color-adjust: none;
  }
  .sk-root[data-skin="e04"] .sk-track > .sk-fill {
    background: Highlight;
    forced-color-adjust: none;
  }
  .sk-root[data-skin="e04"] :is(.qp-bar .sk-btn, .sk-fs)::before,
  .sk-root[data-skin="e04"] .qp-disc::before {
    display: none;
  }
  .sk-root[data-skin="e04"] :is(.sk-error, .sk-empty p) {
    border: 2px solid CanvasText;
    background: Canvas;
    box-shadow: none;
  }
  .sk-root[data-skin="e04"] .sk-error-close {
    border: 2px solid ButtonText;
    background: ButtonFace;
    color: ButtonText;
  }
}
