/* Exactly the screen's height (not at least) and never scrolled: a gallery taller than the
   screen is simply cropped. Being the sticky fades' scroll container (hidden still counts), it
   holds them at the screen's edges rather than at the edges of a box as tall as the gallery.
   Safe centering falls back to the top once the gallery overflows, so the crop starts there. */
.content-root {
  box-sizing: border-box;
  height: 100vh;
  height: 100dvh;
  background: oklch(0.14 0.006 40);
  font-family: 'Helvetica Neue', Arial, sans-serif;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  justify-content: safe center;
}

.content-root.hidden {
  display: none;
}

/* Holds the top-right control and, once signed in, the balance and the videos link on the
   same line. It spans the full column so the three can be spread across it, which is why it
   lets pointer events through to the slider underneath and only the button takes them. */
.top-bar {
  position: absolute;
  top: var(--viewport-inset);
  left: var(--viewport-inset);
  right: var(--viewport-inset);
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  font-family: 'Helvetica Neue', Arial, sans-serif;
  pointer-events: none;
}

.top-bar .login-btn {
  pointer-events: auto;
}

.top-bar-balance,
.top-bar-videos {
  pointer-events: auto;
  cursor: pointer;
}

.top-bar-signed-in {
  justify-content: space-between;
}

/* The balance and the name sit at the two edges, so the middle item is centered on the bar
   itself rather than by the flex distribution, which would offset it by their widths. */
.top-bar-videos {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* Same type as the signed-in name they share the row with (see .login-btn-profile, which takes
   it from .login-btn below), so the row reads as one line of text. */
.top-bar-item {
  padding: 10px 0;
  color: oklch(0.97 0.003 40);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.04em;
}

.top-bar:not(.top-bar-signed-in) .top-bar-item {
  display: none;
}

.login-btn {
  box-sizing: border-box;
  padding: 10px 20px;
  border: none;
  background: oklch(0.63 0.22 25);
  color: oklch(0.98 0.003 40);
  font-family: 'Helvetica Neue', Arial, sans-serif;
  font-size: 14px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}

/* On the main screen the same-size control is only a faint mono outline, so it sits in
   the corner without competing with the primary Download button. Inset shadow (not a
   border) keeps the box identical to the filled variant. The signed-in name skips this. */
.login-btn-quiet:not(.login-btn-profile) {
  background: none;
  color: oklch(0.5 0.006 40);
  box-shadow: inset 0 0 0 1px oklch(0.5 0.006 40);
  opacity: 0.4;
}

/* The signed-in variant is a name rather than a call to action, so it sheds the button
   styling and reads as plain text with the avatar next to it, keeping the button's type. */
.login-btn-profile {
  display: block;
  padding: 10px 0;
  white-space: nowrap;
  background: none;
  color: oklch(0.97 0.003 40);
  text-transform: none;
}

/* Over the gallery the whole row is white, glyphs included, and each item is underlined in
   the accent red instead. The offset clears the descenders so the line sits below the words
   rather than through them. */
body > .top-bar .top-bar-item,
body > .top-bar .login-btn-profile {
  text-decoration: underline;
  text-decoration-color: oklch(0.63 0.22 25);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

/* The three items belong to the same row, so on the main page they all take the tone of
   its quiet Sign in instead of the white they wear over the gallery. */
.slide .top-bar-item,
.slide .login-btn-profile {
  color: oklch(0.5 0.006 40);
  opacity: 0.4;
}

.slide .login-avatar::before {
  background: currentColor;
}

/* The icon reads as the first letter of the name, so it is inline and sized off the font: the
   drawn shape fills 3/4 of the SVG box (see profile.svg), so this box carries a shape a shade
   taller than the font's cap height (0.714em), which the rounded silhouette needs to look the
   same weight as the letters. An empty inline-block rests with its bottom margin edge on the
   baseline, so dropping that edge by the box's own bottom eighth lands the shape itself on the
   baseline, level with the letters after it. */
.login-avatar {
  position: relative;
  display: inline-block;
  width: 1.08em;
  height: 1.08em;
  margin-right: 4px;
  margin-bottom: -0.135em;
}

/* The SVG is used as a mask rather than an image, so the shape is painted by this background
   rather than carrying a colour of its own. It masks a child rather than the span itself, since
   a mask on the span would clip the underline drawn beside it below as well. */
.login-avatar::before {
  content: "";
  display: block;
  height: 100%;
  background: oklch(0.97 0.003 40);
  mask: url("profile.svg") center / contain no-repeat;
  -webkit-mask: url("profile.svg") center / contain no-repeat;
}

/* A text underline is not drawn across an inline block, so the icon's own stretch of the name's
   line -- and the gap from it over to the word -- is drawn here instead, at the same distance
   below the baseline: the icon's box ends 0.135em past it (see the margin above) and the line
   starts 3px past it. */
body > .top-bar .login-avatar::after {
  content: "";
  position: absolute;
  left: 0;
  right: -4px;
  top: calc(100% + 3px - 0.135em);
  height: 2px;
  background: oklch(0.63 0.22 25);
}

/* On the content view the bar is moved onto the body so it can stay in the corner
   while the gallery scrolls; fixed (not absolute) is what keeps it there. */
body > .top-bar {
  position: fixed;
}

/* Above 768px the viewport is the centered column rather than the window (see .gallery below),
   so the bar is capped and centered on it, with the same inset off its left edge as on mobile
   -- as padding, since the box itself has to reach the edge now. The right inset is only kept
   by the signed-in row: with no screen edge past the column, the Sign in button is flush with
   its right edge instead. */
@media (min-width: 768px) {
  .top-bar {
    left: 0;
    right: 0;
    margin: 0 auto;
    box-sizing: border-box;
    max-width: var(--viewport-width);
    padding-left: var(--viewport-inset);
  }

  .top-bar-signed-in {
    padding-right: var(--viewport-inset);
  }
}

/* Sticky (not fixed) so the fade sits right at the gallery's own top/bottom edge even
   when the gallery is short and centered away from the viewport edges, while still
   holding at the screen's edges once the gallery overflows and is cropped. The
   negative margin overlaps the fade onto the gallery instead of pushing it away. */
.content-fade {
  position: sticky;
  left: 0;
  right: 0;
  flex-shrink: 0;
  height: clamp(56px, 14vh, 140px);
  pointer-events: none;
  z-index: 5;
}

.content-fade-top {
  top: 0;
  margin-bottom: clamp(-140px, -14vh, -56px);
  background: linear-gradient(to bottom, oklch(0.14 0.006 40) 0%, transparent 100%);
}

.content-fade-bottom {
  bottom: 0;
  margin-top: clamp(-140px, -14vh, -56px);
  background: linear-gradient(to top, oklch(0.14 0.006 40) 0%, transparent 100%);
}

.eyebrow-white {
  color: oklch(0.97 0.003 40);
}

/* Fixed overlay (instead of a normal flow section) so the gallery is visible and
   scrollable underneath it, rather than being pushed below a full-height hero block. */
.content-hero {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  pointer-events: none;
}

.content-hero .page {
  background: transparent;
  pointer-events: none;
}

/* Re-enable interaction only for the button; everything else lets clicks/taps pass
   through to the gallery below. */
.content-hero .btn {
  pointer-events: auto;
}

/* Containing block for .content-hero-headline-overlay: its real height comes from the
   hidden 4-line text sizer rendered inside it (see content.js), not from this text. */
.content-hero-headline {
  position: relative;
}

/* The title and the video's details sit in the same overlay, so the details line follows
   right under the 2-line title while the box keeps the main page's 4-line height. */
.content-hero-headline-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

.content-hero-headline-text {
  white-space: nowrap;
}

/* .eyebrow normally has a 3px left padding as an optical nudge; remove it here so the
   code line shares the exact same left edge as the headline below it. */
.content-hero .eyebrow {
  padding-left: 0;
}

/* Sitting inside the headline means inheriting its uppercase and tight line-height, neither
   of which suits a details line. Fades in once the resolution and duration are known
   (see loadVideoInfo). */
.content-hero-subtext {
  color: oklch(0 0 0);
  line-height: normal;
  text-transform: none;
  /* A plate behind the text, only as wide as the text itself, so the details stay readable
     over whatever frame happens to sit behind them. */
  width: fit-content;
  padding: 4px 8px;
  /* Optical nudge so the plate reads as flush with the headline above it. */
  margin-left: 3.5px;
  background: oklch(0.97 0.003 40);
  opacity: 0;
  transition: opacity 240ms ease;
}

.content-hero-subtext.visible {
  opacity: 1;
}

/* Keeps an element's box (and thus its layout height) while hiding it visually and
   removing it from hit-testing, so it can act as an invisible spacer. */
.placeholder-hidden {
  visibility: hidden;
}

.gallery {
  box-sizing: border-box;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

@media (min-width: 768px) {
  .gallery {
    max-width: var(--viewport-width);
    margin: 0 auto;
  }
}

.gallery-img {
  display: block;
  width: 100%;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  opacity: 0;
  transition: opacity 0.6s ease;
}

.gallery-img.visible {
  opacity: 1;
}

.no-images {
  color: oklch(0.5 0.006 40);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  margin-top: clamp(48px, 12vh, 96px);
}
