/* The player: a picture with a bar of controls on it.
   
   Shared by the watch page and the review that follows a recording, because a
   recording should not change its clothes between being made and being
   watched. Everything here is about the player itself; what sits inside the
   bar on the watch page — the comment track, the captions, the keyboard
   badge — stays with that page.

   It carries the dark half of the palette whatever the page is set to: the
   bar sits against a picture that is black under either theme. */

/* The shell does the clipping, so the picture, the comment track and the
   controls share one rounded edge instead of each carrying half of it. */
/* Glass, in one place, because the control bar and the keyboard badge have to
   be the same material.

   Light rather than dark: both sit over a recording, and a dark panel over a
   screen recording — which is mostly white — comes out as a grey slab with no
   sense of anything behind it. Tinting towards white and lifting the
   brightness keeps the picture showing through, and the ink on top goes dark
   so it reads over a bright recording and a dark one alike. */
.player-shell {
  --glass: rgba(255, 255, 255, 0.42);
  /* Brightness goes *down*, never up. Lifting it pushes a pale recording past
     white, and everything that was a shape in the blur — a window edge, a line
     of text — clips to the same 255 and the panel turns into a plain white
     box. Holding it under 1 keeps those differences intact, which is the only
     reason to blur the picture rather than just cover it. The blur is small
     for the same reason: enough to soften, not enough to average away. */
  --glass-blur: 14px;
  --glass-filter: blur(var(--glass-blur)) saturate(200%) brightness(0.92);
  --glass-ink: #14171e;
  --glass-ink-soft: rgba(20, 23, 30, 0.55);
  --glass-hover: rgba(20, 23, 30, 0.1);
  --glass-hover-strong: rgba(20, 23, 30, 0.18);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--monitor);
  box-shadow: var(--shadow-raise);
}
.screen {
  position: relative;
  background: var(--stage);
  overflow: hidden;
  aspect-ratio: 16 / 9;
}
.screen video { width: 100%; height: 100%; display: block; object-fit: contain; background: var(--stage); }
/* The button a recording ends on, over the last frame and under the
   control bar, which stays usable. */
.cta-end { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column;
           align-items: center; justify-content: center; gap: 14px; padding: 16px;
           background: rgba(0, 0, 0, 0.55); }
.cta-end[hidden] { display: none; }
.player-shell.cta-shown:not(.is-playing) .screen-tap::before,
.player-shell.cta-shown:not(.is-playing) .screen-tap::after { opacity: 0; }
.cta-end-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; max-width: 100%; }
.cta-go { display: inline-flex; align-items: center; gap: 10px; max-width: 100%; padding: 13px 26px 13px 18px;
          border-radius: 12px; background: var(--brand, #2a7d94);
          color: #fff; font-size: 17px; font-weight: 600; text-decoration: none; overflow-wrap: anywhere;
          text-align: center; box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35); }
.cta-go + .cta-go { background: rgba(255, 255, 255, 0.14); backdrop-filter: blur(8px);
                    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35); }
.cta-go .cta-tile { width: 34px; height: 34px; flex: none; display: grid; place-items: center; border-radius: 10px; background: #fff; }
.cta-go .cta-logo { width: 24px; height: 24px; object-fit: contain; display: block; border-radius: 5px; }
.cta-go .cta-tile .cta-letter { width: 34px; height: 34px; border-radius: 10px; }
.cta-go .cta-text { display: grid; gap: 2px; text-align: left; line-height: 1.15; }
.cta-go .cta-text small { font-size: 12px; font-weight: 500; opacity: .75; }
.cta-go .cta-arrow { width: 16px; height: 16px; flex: none; opacity: .8; }
.cta-go .cta-arrow svg { width: 100%; height: 100%; display: block; }
.cta-go:hover { filter: brightness(1.08); }
.cta-go:focus-visible, .cta-again:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.cta-again { padding: 6px 12px; border: 0; border-radius: 8px; background: none; color: #fff;
             font: inherit; font-size: 14px; opacity: 0.85; cursor: pointer; }
.cta-again:hover { opacity: 1; text-decoration: underline; }
/* A reaction floating up over the picture as it is sent. */
.moment-pop {
  position: absolute; bottom: 22%; z-index: 4; font-size: 42px; pointer-events: none;
  animation: moment-rise 1.1s ease-out forwards;
}
@keyframes moment-rise {
  from { opacity: 0; transform: translateY(24px) scale(0.6); }
  20% { opacity: 1; transform: translateY(0) scale(1.1); }
  to { opacity: 0; transform: translateY(-130px) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .moment-pop { animation-duration: 0.6s; }
}
.player-shell.is-processing:not(.is-playing) .screen-tap::before,
.player-shell.is-processing:not(.is-playing) .screen-tap::after { opacity: 0; }
.player-shell.is-processing .player-bar { visibility: hidden; }
.screen-note { position: absolute; inset: 0; display: grid; place-items: center; padding: 24px;
               text-align: center; color: #fff; font-size: 15px; pointer-events: none; }
.screen-tap { position: absolute; inset: 0; border: none; background: none; cursor: pointer; }

/* A paused picture says nothing about what to do with it. The badge is the
   invitation, and it gets out of the way the moment the recording runs. */
.screen-tap::before,
.screen-tap::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease, transform 180ms ease;
}
.screen-tap::before {
  width: 74px; height: 74px;
  margin: -37px 0 0 -37px;
  border-radius: 50%;
  background: rgba(12, 15, 22, 0.52);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
}
.screen-tap::after {
  margin: -13px 0 0 -8px;
  border-left: 22px solid rgba(255, 255, 255, 0.96);
  border-top: 13px solid transparent;
  border-bottom: 13px solid transparent;
}
.player-shell:not(.is-playing) .screen-tap::before,
.player-shell:not(.is-playing) .screen-tap::after { opacity: 1; }
.player-shell:not(.is-playing) .screen-tap:hover::before { transform: scale(1.06); }

/* Fullscreen takes the whole player, not the bare picture, so the controls
   and the comment track go with it. */
.player-shell:fullscreen {
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-radius: 0;
  background: var(--stage);
}
.player-shell:fullscreen .screen { flex: 1; min-height: 0; aspect-ratio: auto; }

/* Frosted, so the picture reads through the bar instead of being cut off by
   it, and gone once the pointer has been still for a moment — on a paused
   recording it stays, because there is nothing to get out of the way of. */
.player-bar {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  /* Where the rail sits inside the track, and so where the glass begins. */
  --rail-top: 15px;
  transition: opacity 220ms ease, transform 220ms ease;
}
/* Pointing at the timeline: its labels (the time, the chapter, a comment)
   come up over the picture, above the captions rather than under them. */
.player-bar:has(.track:hover, .track.is-scrubbing, .marker:hover, .marker:focus-visible) { z-index: 5; }
/* The glass starts at the rail, not at the top of the track: above the line
   are only the comment pins, and they read better against the recording than
   against a panel laid over it. Drawn as a pseudo-element rather than on the
   bar itself so it can start partway down; the track and the playbar are
   positioned, so they paint over it. */
.player-bar::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: var(--rail-top);
  bottom: 0;
  background: var(--glass);
  backdrop-filter: var(--glass-filter);
  -webkit-backdrop-filter: var(--glass-filter);
  pointer-events: none;
}
.player-shell.is-idle .player-bar {
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
}
.player-shell.is-idle .screen { cursor: none; }

.playbar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 8px 2px;
  color: var(--glass-ink);
}
.playbar .spacer { flex: 1; }

/* Round, flat, and only lit when the pointer is on them: the controls are
   next to the picture, not competing with it. */
.pbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: none;
  color: var(--glass-ink);
  cursor: pointer;
  transition: background 120ms ease, transform 120ms ease;
}
.pbtn:hover { background: var(--glass-hover); }
.pbtn:active { transform: scale(0.93); }
.pbtn:focus-visible { outline: 2px solid var(--cobalt-ink); outline-offset: 2px; }
.pbtn svg { width: 15px; height: 15px; display: block; }
.pbtn-lg { width: 28px; height: 28px; }

/* The captions button: a boxed CC, underlined in the accent while captions
   are on, as on YouTube, and faded while they are off. */
.pbtn-cc { position: relative; width: 30px; border-radius: 8px; }
.pbtn-cc svg { width: 19px; height: 19px; }
.pbtn-cc::after {
  content: ""; position: absolute; left: 7px; right: 7px; bottom: 1px; height: 2.5px;
  border-radius: 2px; background: var(--cobalt); transform: scaleX(1);
  transition: transform 140ms ease;
}
.pbtn-cc[aria-pressed="false"] { opacity: .62; }
.pbtn-cc[aria-pressed="false"]::after { transform: scaleX(0); }
.player-shell.captions-off .captions { display: none; }
.pbtn-lg svg { width: 18px; height: 18px; }

/* One button, two icons: which one shows is the player's state, so nothing
   has to rewrite the button's contents on every play and pause. */
/* Matched through .pbtn, so these outrank the rule that lays the icons out
   above — a bare .i-pause loses to .pbtn svg and both icons show at once. */
.pbtn .i-pause,
.player-shell.is-playing .pbtn .i-play { display: none; }
.player-shell.is-playing .pbtn .i-pause { display: block; }
.pbtn .i-mute,
.player-shell.is-muted .pbtn .i-vol { display: none; }
.player-shell.is-muted .pbtn .i-mute { display: block; }

/* Where the picture is, and how long it runs. Bare on the glass like the
   icons around it, not boxed: the moment you are at in full ink and the
   length behind it in the soft one, so the number that changes reads first.
   Figures are tabular, so nothing beside it shifts while the seconds tick. */
.player-shell .playbar .tc {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 26px;
  padding: 0 6px;
  color: var(--glass-ink);
  font: 600 12.5px/1 var(--ui);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.player-shell .playbar .tc-of { color: var(--glass-ink-soft); font-weight: 400; }
.player-shell .playbar .tc-total { color: var(--glass-ink-soft); font-weight: 500; }

/* The speed picker is select.js's dropdown, made of the same glass as the bar:
   a pill that reads like the buttons beside it, and a list that opens upwards,
   since below the bar is the edge of the player. Written through the shell so
   it outranks the page's own rule for a dropdown on a dark surface. */
.player-shell .playbar .choice-trigger {
  width: auto;
  min-width: 36px;
  height: 26px;
  padding: 0 8px;
  justify-content: center;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--glass-ink);
  font: 600 12.5px/1 var(--ui);
  font-variant-numeric: tabular-nums;
  transition: background-color 120ms ease;
}
/* Until the script has drawn it, the native <select> wears the same look,
   so the page never shows the browser's own dark box and arrow while it
   loads. */
.player-shell .playbar select:not(.choice-native) {
  appearance: none;
  -webkit-appearance: none;
  min-width: 36px;
  height: 26px;
  padding: 0 8px;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--glass-ink);
  font: 600 12.5px/1 var(--ui);
  font-variant-numeric: tabular-nums;
  text-align: center;
  text-align-last: center;
  cursor: pointer;
}
.player-shell .playbar .choice-trigger:hover,
.player-shell .playbar .choice-trigger[aria-expanded="true"] { background: var(--glass-hover); }
/* A word on the bar, the way the icons are pictures on it: the list it opens
   is the only sign it is a menu that it needs. */
.player-shell .playbar .choice-mark { display: none; }
.player-shell .playbar .choice-trigger:focus-visible { outline: 2px solid var(--cobalt-ink); outline-offset: 2px; }
.player-shell .playbar .choice-list {
  top: auto;
  bottom: calc(100% + 8px);
  left: auto;
  right: 0;
  min-width: 96px;
  padding: 4px;
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: var(--glass-filter);
  -webkit-backdrop-filter: var(--glass-filter);
  box-shadow: 0 10px 30px -10px rgba(10, 20, 24, 0.45);
}
.player-shell .playbar .choice-option {
  padding: 6px 8px;
  color: var(--glass-ink);
  font: 500 13px/1.2 var(--ui);
  font-variant-numeric: tabular-nums;
}
.player-shell .playbar .choice-option:hover,
.player-shell .playbar .choice-option:focus-visible { background: var(--glass-hover); }
.player-shell .playbar .choice-option[aria-selected="true"] { color: var(--brand-solid); font-weight: 650; }
.player-shell .playbar .choice-tick { width: 14px; height: 14px; }

/* The slider stays out of the way until the pointer comes near it, which is
   how every player people already use behaves. */
.volume { display: flex; align-items: center; }
.playbar input[type="range"] {
  width: 0;
  opacity: 0;
  height: 4px;
  margin: 0;
  accent-color: var(--cobalt);
  cursor: pointer;
  transition: width 160ms ease, opacity 160ms ease, margin 160ms ease;
}
.volume:hover input[type="range"],
.volume:focus-within input[type="range"] { width: 82px; opacity: 1; margin: 0 8px 0 2px; }



/* What a keyboard shortcut did, in the middle of the picture: quick to
   arrive, slower to leave, and never in the way of a click.

   Built like the panel macOS shows for volume — a square of heavy frosted
   glass with one large glyph in it — because that is the shape people already
   read as "the machine heard you, and this is all it means". */
.hud {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 17px;
  /* Square, and wider only when its words need it (Arabic is longer). */
  min-width: 136px; width: auto; padding-inline: 14px; box-sizing: border-box;
  height: 136px;
  border-radius: 28px;
  /* Mostly filter, barely any tint. A heavy blur over a flat white screen
     recording comes out as one even tone, and a dark layer painted over that
     is a grey slab, not glass — so the dimming is done with brightness(),
     which dims the picture itself and leaves its shape and colour showing
     through, and the blur is kept small enough that there is still something
     to see. */
  /* A lighter blur than the bar's. The bar is a strip across a busy edge of
     the picture and wants the detail behind it quietened; the badge is a
     small panel in the middle of it, and keeping the picture legible through
     it is what makes it look like glass rather than a sticker. */
  --glass-blur: 7px;
  /* No tint at all: the panel is the picture itself, blurred and held a shade
     back, and nothing painted over it. The edge is carried by the hairline
     and the shadow instead. */
  --glass: transparent;
  background: var(--glass);
  backdrop-filter: var(--glass-filter);
  -webkit-backdrop-filter: var(--glass-filter);
  /* The hairline is what keeps frosted glass from dissolving into a pale
     picture; the shadow is what lifts it off a dark one. */
  box-shadow: 0 12px 44px rgba(0, 0, 0, 0.28), inset 0 0 0 1px rgba(255, 255, 255, 0.4);
  color: var(--glass-ink);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.86);
  pointer-events: none;
  transition: opacity 300ms ease, transform 300ms ease;
}
.hud.is-on {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  /* In at once, out at leisure. */
  transition-duration: 80ms;
}
/* With no tint behind it, the ink has only the recording to sit on, and a
   recording can be any colour it likes. Three tight shadows stacked make a
   hard white edge rather than a halo — an outline reads as part of the glyph,
   where a glow reads as something gone wrong with the blur. Over a pale
   frame it costs nothing, being the colour of what is already there. */
.hud svg,
.hud .hud-bar {
  filter: drop-shadow(0 0 1px #ffffff) drop-shadow(0 0 1px #ffffff)
          drop-shadow(0 0 2px rgba(255, 255, 255, 0.9));
}
.hud svg { width: 56px; height: 56px; display: block; }
.hud-label {
  font: 600 14px/1 var(--mono);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 1px #ffffff, 0 0 1px #ffffff, 0 0 3px rgba(255, 255, 255, 0.9);
  white-space: nowrap;
}
/* The player runs left to right; Arabic words in it still read right to
   left, in the Arabic typeface rather than the monospaced one. */
html[dir="rtl"] .hud-label { direction: rtl; unicode-bidi: isolate; font-family: var(--ui); line-height: 1.3; }

/* Volume as macOS counts it: sixteen notches rather than a number, so the
   level is read at a glance instead of out loud. */
.hud-bar { display: flex; gap: 2px; }
.hud-bar i { width: 5px; height: 11px; border-radius: 1.5px; background: rgba(20, 23, 30, 0.25); }
.hud-bar i.on { background: var(--glass-ink); }

/* A picture filling the room takes a panel to match. */
.player-shell:fullscreen .hud {
  width: 180px; height: 180px;
  border-radius: 36px;
  gap: 22px;
}
.player-shell:fullscreen .hud svg { width: 74px; height: 74px; }
.player-shell:fullscreen .hud-bar i { width: 7px; height: 14px; }

/* Two badges in the middle of one picture is one too many. */
.player-shell.hud-on .screen-tap::before,
.player-shell.hud-on .screen-tap::after { opacity: 0; }

/* --- a plain scrubber ------------------------------------------------------- */

/* The watch page scrubs on the comment track, which carries a marker for every
   note anyone left. A recording that has only just been made has none, so it
   gets this instead: the same geometry, nothing in it. */
.scrub {
  position: relative;
  height: 22px;
  cursor: pointer;
  touch-action: none;
  user-select: none;
}
.scrub-rail,
.scrub-fill {
  position: absolute;
  left: 0;
  top: var(--rail-top);
  height: 4px;
  border-radius: 3px;
  pointer-events: none;
}
.scrub-rail { right: 0; background: rgba(20, 23, 30, 0.22); }
.scrub-fill { width: 0; background: var(--cobalt); }
.scrub-head {
  position: absolute;
  top: 12px;
  width: 10px; height: 10px;
  margin-left: -5px;
  border-radius: 50%;
  background: #ffffff;
  border: 2px solid var(--cobalt);
  pointer-events: none;
}

/* Over a player whose recording cannot load until the video store's free
   daily allowance resets: when, and that it comes back by itself. */
.store-rest {
  position: absolute; inset: 50% auto auto 50%; transform: translate(-50%, -50%);
  z-index: 6; width: min(360px, calc(100% - 32px));
  display: grid; gap: 6px; text-align: center;
  padding: 16px 20px; border-radius: 18px;
  background: rgba(8, 18, 22, 0.72); color: #fff;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  font-size: 13.5px; line-height: 1.5;
}
.store-rest strong { font-size: 16px; }
.store-rest span { color: rgba(255, 255, 255, 0.86); }
