/* Subtitle style picker — the animated preview inside each option card.
 *
 * Lives in its own file rather than app.css so the picker can be edited (or
 * reverted) without touching the shared sheet.
 *
 * Every entrance below mirrors one the renderer performs; the timings are the
 * preview's own, since a looping thumbnail has no speech to key off. */

/* Satoshi is not on Google Fonts, so it is self-hosted — the same two faces the
   renderer ships, copied from remotion-composer/public/fonts/satoshi/. Only the
   `chunk` preset draws in it by default, but the font picker offers it against
   every preset, so both weights are here.
   Licence: Fontshare Free Font Licence, see the LICENSE file beside the woff2. */
@font-face {
  font-family: 'Satoshi';
  src: url('/fonts/satoshi/Satoshi-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Satoshi';
  src: url('/fonts/satoshi/Satoshi-Black.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

.sub-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  /* FIXED, not min-: a preset whose sample runs to two lines would otherwise
     grow its own panel, and the grid would stretch every card in that row to
     match — so one long sample makes a whole row taller than its neighbours. */
  height: 60px;
  padding: 8px 10px;
  border-radius: 8px;
  /* Fixed mid-grey, NOT a theme token: this panel stands in for video, and the
     captions on it are white-on-footage in every theme. Tying it to --bg-card
     would put white text on a near-black card in the dark theme (where the app
     actually runs) and hide the outline that keeps captions legible. */
  background: linear-gradient(160deg, #5a606a 0%, #33383f 100%);
  overflow: hidden;
}

.sub-preview-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 0.28em;
  text-align: center;
  max-width: 100%;
  /* The renderer never hyphenates a caption; neither should the sample. */
  word-break: keep-all;
}

.sub-word {
  display: inline-block;
  transition: color 120ms linear;
}

/* The active word on `tiktok` scales up as well as recolouring. */
.sub-word.is-popped {
  animation: sub-word-pop 260ms cubic-bezier(0.2, 1.4, 0.4, 1) both;
}
@keyframes sub-word-pop {
  from { transform: scale(0.82); }
  60%  { transform: scale(1.08); }
  to   { transform: scale(1); }
}

/* ---- entrances, one per registry `entrance` value ------------------------ */

.sub-enter-none { }

.sub-enter-lift {
  animation: sub-lift 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes sub-lift {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0);   opacity: 1; }
}

.sub-enter-pop {
  animation: sub-pop 280ms cubic-bezier(0.2, 1.4, 0.4, 1) both;
}
@keyframes sub-pop {
  from { transform: scale(0.7);  opacity: 0; }
  60%  { transform: scale(1.06); opacity: 1; }
  to   { transform: scale(1);    opacity: 1; }
}

.sub-enter-pop_rotate {
  animation: sub-pop-rotate 300ms cubic-bezier(0.2, 1.4, 0.4, 1) both;
}
@keyframes sub-pop-rotate {
  from { transform: scale(0.7) rotate(-3deg);  opacity: 0; }
  60%  { transform: scale(1.08) rotate(1.5deg); opacity: 1; }
  to   { transform: scale(1) rotate(-3deg);     opacity: 1; }
}

.sub-enter-slide_up {
  animation: sub-slide-up 320ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes sub-slide-up {
  from { transform: translateY(14px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

/* ---- the grid ------------------------------------------------------------ */

/* The style cards sit inside a wrapper that carries the hover/focus handlers.
   `display: contents` drops the wrapper's box so the CARD stays the grid item —
   without it the cards no longer stretch to a common height and the row breaks
   up. Pointer and focus events still reach the wrapper by bubbling. */
.option-grid.subtitle-styles > .sub-card-hit { display: contents; }

/* TWO columns, not three: ten presets over three columns leaves a single
   stranded card on a fourth row, and the wider card gives the sample room to
   stay on one line — which is what stops the previews looking ragged against
   each other. Five rows of two fills exactly. */
.option-grid.subtitle-styles {
  grid-template-columns: 1fr 1fr;
}

.option-grid.subtitle-styles .opt-card {
  /* One padding value all round, and the same value between the title and the
     preview. The gap used to be 4px against 13px of padding, which is what
     read as cramped. */
  padding: 12px;
  gap: 12px;
}

/* A font card is its own specimen: the name, set in the face it names. No
   description and no separate sample line — those said the same thing twice
   more and made the cards read as a wall of identical text.
   The FACE itself is an inline style on the name (OptionCard's `nameStyle`),
   not a rule here: `.opt-card` declares its own font-family, so a face set on
   any ancestor is overridden before it reaches the text. */
.sub-font-card { display: contents; }

/* Seven fonts over three columns strands one on its own row. Auto is not a
   face — it is "leave it alone" — so it takes the full width as its own row,
   and the six real faces then fill two rows of three exactly. */
.option-grid.subtitle-fonts .sub-font-card:first-child .opt-card {
  grid-column: 1 / -1;
}

.sub-font-card .opt-card {
  align-items: center;
  justify-content: center;
  min-height: 62px;
  padding: 14px 10px;
}
.sub-font-card .opt-head { justify-content: center; width: 100%; }
.sub-font-card .opt-name {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* The style grid is already two columns; the fonts drop from three so their
   names have room rather than ellipsing on a narrow screen. */
@media (max-width: 560px) {
  .option-grid.subtitle-styles { grid-template-columns: 1fr; }
  .option-grid.subtitle-fonts { grid-template-columns: 1fr 1fr; }
}

/* Someone who has asked the OS for less motion gets the static first frame —
   the component also stops its timer, so this only covers the entrances. */
@media (prefers-reduced-motion: reduce) {
  .sub-enter-lift,
  .sub-enter-pop,
  .sub-enter-pop_rotate,
  .sub-enter-slide_up,
  .sub-word.is-popped {
    animation: none;
  }
}
