/* ID4 — Website #3
   One short page, flat and grayscale like the app: its greys, Geist, and its
   motion curves (mac/Sources/ID4/UI/Design: Palette, Typo, Motion). */

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

/* Animatable numbers: the clip's selection. Not inherited: they're set and
   eased only on the four parts that use them, so the card around them isn't
   restyled every frame while they move. */
@property --a { syntax: "<number>"; inherits: false; initial-value: 60; }
@property --b { syntax: "<number>"; inherits: false; initial-value: 76; }

:root {
  --bg: #0a0a0a;
  --panel: #111111;
  --raised: #181818;
  --thumb: #2a2a2a;
  --line: rgba(255, 255, 255, .08);
  --text: #ededed;
  --text-2: #9a9a9a;
  --text-3: #7a7a7a;
  --quiet: #5f5f5f;
  --strong: #f2f2f2;
  --on-strong: #0a0a0a;

  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-in: cubic-bezier(.55, 0, .75, .25);
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --spring: cubic-bezier(.34, 1.4, .64, 1);
  --spring-soft: cubic-bezier(.3, 1.18, .5, 1);
  --ease-smooth: cubic-bezier(.6, 0, .2, 1);
  /* Ease in-out cubic: the rolling words, the mark spelling itself out. */
  --ease-io: cubic-bezier(.65, 0, .35, 1);
  --d1: 120ms;
  --d2: 200ms;
  --d3: 320ms;
  --d4: 460ms;

  --page: min(1080px, calc(100% - 48px));
  /* Cinematic widescreen (21:9). A 2520×1080 or 3360×1440 recording fits exactly. */
  --video-ratio: 21 / 9;
  --font: "Geist", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;

  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  font-weight: 450;
  line-height: 1.5;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

::selection { background: rgba(255, 255, 255, .2); color: #fff; }

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
svg { display: block; }
h1, h2, p, dl, dd { margin: 0; }
button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid rgba(255, 255, 255, .9);
  outline-offset: 3px;
  border-radius: 10px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ───────────────────────── Nav ───────────────────────── */

@property --cut { syntax: "<length-percentage>"; inherits: false; initial-value: 0px; }

.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  padding: 12px 12px 0;
  pointer-events: none;
}

/* The frosted blur behind the pill. It is always the full width of the bar
   and never changes size (resizing a blur every frame is what makes a menu bar
   shimmer); a clip narrows it to the pill in step with the pill's own glide.
   It is only on once the pill shows, so nothing is blurred by a bar you
   can't see. */
.nav::before {
  content: "";
  position: absolute;
  top: 12px;
  left: 50%;
  width: min(1120px, calc(100% - 24px));
  height: 56px;
  translate: -50% 0;
  pointer-events: none;
  --cut: 0px;
  clip-path: inset(0 var(--cut) round 999px);
  transition: --cut 900ms var(--ease-smooth);
}
.nav.is-scrolled::before {
  --cut: calc(50% - 300px);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
}

.nav-inner {
  position: relative;
  pointer-events: auto;
  width: min(1120px, 100%);
  height: 56px;
  margin: 0 auto;
  padding: 0 20px 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0);
  background: rgba(17, 17, 17, 0);
  transition:
    width 900ms var(--ease-smooth),
    padding 900ms var(--ease-smooth),
    background-color 420ms var(--ease-out),
    border-color 420ms var(--ease-out);
}

.nav.is-scrolled .nav-inner {
  width: min(600px, 100%);
  padding: 0 9px 0 20px;
  background: rgba(17, 17, 17, .78);
  border-color: var(--line);
}
/* The state the page opens in (or comes back to) is set without a glide. */
.nav.is-instant .nav-inner, .nav.is-instant::before { transition: none !important; }

.nav-brand {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 4px;
  border-radius: 10px;
  color: var(--strong);
}

.nav-links { display: flex; align-items: center; gap: 6px; }
.nav-link {
  display: flex;
  align-items: center;
  height: 38px;
  padding: 0 14px;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text-2);
  transition: color var(--d2) var(--ease-out), background-color var(--d2) var(--ease-out);
}
.nav-link:hover { color: var(--text); background: rgba(255, 255, 255, .06); }
.nav-link[aria-current="page"] { color: var(--text); }

/* The mark, glyph by glyph, so it can spell itself out: ID4 → Internet
   Downloader 4. The added letters are Geist Bold sized to the mark's cap
   height (Geist's caps are .71em, and a .71em line puts the baseline right on
   the bottom edge, level with the drawn glyphs). */
.lg-row {
  --h: 19px;
  --u: calc(var(--h) / 407.0888);
  display: flex;
  align-items: flex-end;
  height: var(--h);
}
.lg { height: var(--h); flex: none; fill: currentColor; overflow: visible; }
.lg-spark { width: var(--h); }
.lg-i { width: calc(85.198 * var(--u)); margin-left: calc(58.58 * var(--u)); }
.lg-d { width: calc(340.852 * var(--u)); margin-left: calc(39.765 * var(--u)); }
.lg-4 { width: calc(324.8526 * var(--u)); margin-left: calc(9.877 * var(--u)); }
/* Closed, each word's room is zero wide and its letters wait below it,
   unseen and soft. On hover the line takes its full width at once
   (.is-wide) while "Downloader 4" and the 4 (.lg-move) slide out with
   transforms, and each letter lifts in as the edge uncovers it (site.js). */
/* Hidden outright until it opens, so the letters never show before site.js
   has split them (they would overlap the D and the 4). */
.lg-tail { flex: none; width: 0; pointer-events: none; visibility: hidden; }
.nav-brand.is-wide .lg-tail { width: auto; visibility: visible; }
.lg-move { display: flex; flex: none; align-items: flex-end; }
.lg-tail-in {
  display: block;
  white-space: pre;
  padding-left: .035em;
  font-size: calc(var(--h) * .98996 / .71);
  line-height: .71em;
  font-weight: 700;
  letter-spacing: -0.045em;
}
.lg-tail-in i {
  display: inline-block;
  font-style: normal;
  white-space: pre;
  opacity: 0;
  filter: blur(3px);
  transform: translateY(.22em);
}

/* ───────────────────────── Buttons ───────────────────────── */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  white-space: nowrap;
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: -0.012em;
  background: var(--strong);
  color: var(--on-strong);
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--d3) var(--spring), background-color var(--d2) var(--ease-out);
}
.btn:hover { background: #fff; }
.btn:active { transform: scale(.96); transition-duration: var(--d1); }

.btn-small {
  height: 38px;
  padding: 0 16px 0 13px;
  gap: 7px;
  font-size: 14.5px;
}
.btn-small .btn-glyph { width: 16px; height: 16px; margin-top: -2px; }

.btn-primary {
  height: 52px;
  padding: 0 26px 0 22px;
  font-size: 16.5px;
}

.btn-glyphs { position: relative; width: 20px; height: 20px; flex: none; margin-top: -2px; }
.btn-glyphs .btn-glyph {
  position: absolute;
  inset: 0;
  width: 20px;
  height: 20px;
  opacity: 0;
  transform: scale(.5);
  filter: blur(3px);
  transition: opacity var(--d3) var(--ease-out), transform var(--d4) var(--spring), filter var(--d3) var(--ease-out);
}
.btn-glyphs .btn-glyph.is-on { opacity: 1; transform: none; filter: none; }
.btn-glyphs [data-state="done"] { transform: translateY(-70%) scale(.6); }
.btn-glyphs [data-state="done"].is-on { transform: none; }
.btn-label { display: inline-block; }

/* ───────────────────────── Hero ───────────────────────── */

.hero {
  position: relative;
  width: var(--page);
  margin: 0 auto;
  padding-top: 148px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.hero-title {
  position: relative;
  font-size: clamp(38px, 10vw, 84px);
  line-height: .98;
  font-weight: 650;
  letter-spacing: -0.052em;
  color: var(--strong);
}

.hero-sub {
  position: relative;
  margin-top: 26px;
  font-size: clamp(18px, 1.6vw, 20px);
  line-height: 1.4;
  color: var(--text-2);
  white-space: nowrap;
}

/* On a phone it breaks after "anything", so only the second line changes
   width as the site rolls over. */
.sub-break { display: none; }
@media (max-width: 480px) { .sub-break { display: inline; } }

/* The site and its icon roll over like the paragraph's words (site.js). */
.site { white-space: nowrap; }
.site svg {
  display: inline-block;
  width: 1.05em;
  height: 1.05em;
  margin: 0 .3em 0 .1em;
  vertical-align: -0.19em;
}

.hero-cta { position: relative; margin-top: 40px; }

/* ───────────────────────── The video ───────────────────────── */

.stage {
  width: var(--page);
  margin: 84px auto 0;
}

/* It opens up to full width as it rises into view. */
.frame {
  position: relative;
  aspect-ratio: var(--video-ratio);
  border-radius: 24px;
  transform: scale(var(--grow, 1));
  transform-origin: 50% 0;
  will-change: transform;
}

.frame-inner {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  /* The video's first frame, so a slow connection sees it at once; the video
     fades in over it. */
  background: var(--panel) url("../img/frame-poster.jpg") center / cover no-repeat;
}

.frame-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 700ms var(--ease-out);
}
.frame.has-video .frame-video { opacity: 1; }

/* The edge catches light from the pointer. */
.frame-rim {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  padding: 1px;
  background:
    radial-gradient(440px circle at var(--mx, 50%) var(--my, -40%), rgba(255, 255, 255, .5), rgba(255, 255, 255, 0) 70%),
    linear-gradient(180deg, rgba(255, 255, 255, .12), rgba(255, 255, 255, .05) 40%, rgba(255, 255, 255, .03));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}

/* ───────────────────────── Statement ───────────────────────── */

.statement {
  width: var(--page);
  margin: 120px auto 0;
  text-align: center;
}
.say {
  font-size: clamp(24px, 3vw, 34px);
  line-height: 1.34;
  font-weight: 560;
  letter-spacing: -0.03em;
  color: var(--quiet);
}
.say-line { display: block; white-space: nowrap; }
/* A phone gets five set lines instead of three (see Smaller screens). */
.say-br { display: none; }
.slot { color: var(--text); font-weight: 600; white-space: nowrap; }
.slot svg {
  display: inline-block;
  width: .8em;
  height: .8em;
  margin: 0 .2em 0 .05em;
  vertical-align: -0.07em;
}

/* A window one line tall. A new word comes up from below as the old one
   leaves through the top, glyph by glyph, and the window eases to the new
   width (site.js). It reaches a little past its text on every side (padding
   cancelled by margin, so nothing around it moves), and its top and bottom
   edges fade out, so glyphs dissolve into the edge rather than being cut. */
.roll {
  --ry: .1em;
  --rx: .25em;
  position: relative;
  display: inline-block;
  white-space: nowrap;
  padding: var(--ry) var(--rx);
  margin: calc(var(--ry) * -1) calc(var(--rx) * -1);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 .24em, #000 calc(100% - .2em), transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 .24em, #000 calc(100% - .2em), transparent);
}
.roll-in { display: inline-block; white-space: nowrap; }
.roll-in.is-hidden { visibility: hidden; }
.roll-layer { position: absolute; inset: 0; pointer-events: none; }
.roll-g { position: absolute; white-space: pre; will-change: transform, opacity, filter; }
.roll-g.roll-el { line-height: 0; }
.roll-g.roll-el > svg { display: block; }
.tick { display: inline-flex; white-space: pre; }
.tick .roll { --rx: 0; }
.tick .roll, .tick .roll-in { white-space: pre; }
.swap { display: inline-block; }

/* ───────────────────────── Bento ───────────────────────── */
/* Two rows, side by side: the clip editor and the formats, then three
   smaller cards. Each card is its picture, centred in the room above, and its
   words along the bottom, so the titles in a row line up. */

.bento {
  width: var(--page);
  margin: 112px auto 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 16px;
}

.card {
  grid-column: span 4;
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: 400px;
  padding: 28px;
  border-radius: 28px;
  background: var(--panel);
  overflow: hidden;
}
.card-clip { grid-column: span 7; }
.card-clip .card-text p { max-width: 470px; }
.card-formats { grid-column: span 5; }

.vignette { align-self: center; min-width: 0; margin-bottom: 32px; }

.card-text h2 {
  font-size: 24px;
  line-height: 1.15;
  font-weight: 640;
  letter-spacing: -0.034em;
  color: var(--text);
}
.card-text p {
  margin-top: 8px;
  max-width: 340px;
  font-size: 16px;
  line-height: 1.45;
  color: var(--text-2);
  text-wrap: pretty;
}

/* Clip: the app's section editor. The "Most replayed" curve over the whole
   video (brighter where the section is), the filmstrip with the part you keep
   left bright, and Start / Length / End. */
.heat-hi, .strip-window, .strip-range, .strip-soft { transition: --a 1000ms var(--ease-io), --b 1000ms var(--ease-io); }
.heat {
  position: relative;
  height: 38px;
  margin-bottom: 14px;
  /* It fades out at both ends, line and fill, rather than stopping at an edge. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}
.heat svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.heat-area { fill: rgba(245, 245, 245, .10); }
.heat-line { fill: none; stroke: rgba(245, 245, 245, .32); stroke-width: 1; vector-effect: non-scaling-stroke; }
.heat-hi { position: absolute; inset: 0; clip-path: inset(0 calc((100 - var(--b)) * 1%) 0 calc(var(--a) * 1%)); }
.heat-hi .heat-area { fill: rgba(245, 245, 245, .32); }

.strip { position: relative; height: 88px; }
.strip-frames {
  display: flex;
  gap: 2px;
  height: 100%;
  border-radius: 14px;
  overflow: hidden;
}
.strip-frames img { flex: 1; min-width: 0; height: 100%; object-fit: cover; }
/* Everything outside the part you keep is dimmed: a window the shape of the
   handles' inside edge (their 12px inner corners), with the dark around it as
   its shadow, cut to the strip. So the frames show only inside the white
   border, right into its rounded corners, and never past them. */
.strip-dim {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 14px;
  pointer-events: none;
}
.strip-window {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--a) * 1%);
  right: calc((100 - var(--b)) * 1%);
  border-radius: 12px;
  box-shadow: 0 0 0 2000px rgba(10, 10, 10, .68);
}
/* What's left out goes soft as well as dark: sharp beside the handles, more
   blurred the further it is from the part you keep. Three copies of the strip
   (site.js), each more blurred than the last, show from further out. They are
   plain blurred pictures, not live blurs of the page, so nothing has to be
   re-blurred behind them while things move. */
.strip-soft {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 14px;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to right, #000 calc(var(--a) * 1% - var(--far)), transparent calc(var(--a) * 1% - var(--near)), transparent calc(var(--b) * 1% + var(--near)), #000 calc(var(--b) * 1% + var(--far)));
  mask-image: linear-gradient(to right, #000 calc(var(--a) * 1% - var(--far)), transparent calc(var(--a) * 1% - var(--near)), transparent calc(var(--b) * 1% + var(--near)), #000 calc(var(--b) * 1% + var(--far)));
}
.strip-soft .strip-frames { filter: blur(var(--sb)); }
.strip-soft-1 { --sb: 1.2px; --near: 4px; --far: 34px; }
.strip-soft-2 { --sb: 3px; --near: 34px; --far: 90px; }
.strip-soft-3 { --sb: 6px; --near: 90px; --far: 170px; }
.strip-range {
  position: absolute;
  top: -3px;
  bottom: -3px;
  left: calc(var(--a) * 1% - 3px);
  right: calc((100 - var(--b)) * 1% - 3px);
  border: 3px solid var(--strong);
  border-radius: 15px;
}
/* The grips: part of the border, rounded only on their outer side. They
   reach a pixel into the border so no seam shows between them. */
.strip-range::before, .strip-range::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 5px;
  height: 26px;
  margin-top: -13px;
  background: var(--strong);
}
.strip-range::before { left: -7px; border-radius: 2px 0 0 2px; }
.strip-range::after { right: -7px; border-radius: 0 2px 2px 0; }
@keyframes breathe { 50% { opacity: .45; } }

.clip-boxes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  gap: 10px;
  margin-top: 26px;
}
.clip-box {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 14px;
  align-items: center;
  padding: 10px 14px 10px 16px;
  border-radius: 13px;
  background: var(--raised);
  font-size: 13px;
  color: var(--text-2);
}
.clip-box svg { grid-row: span 2; width: 18px; height: 18px; color: var(--text-2); }
.clip-box b {
  font-size: 16px;
  font-weight: 560;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
}
.chip {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 36px;
  padding: 0 14px 0 12px;
  border-radius: 999px;
  background: var(--raised);
  color: var(--text-2);
  font-size: 14px;
  font-weight: 520;
  white-space: nowrap;
  transition: background-color var(--d3) var(--ease-out), color var(--d3) var(--ease-out), transform var(--d3) var(--spring);
}
.chip svg { width: 15px; height: 15px; }
.chip.is-on { background: var(--thumb); color: var(--text); }
.chip.is-pressed { transform: scale(.95); transition-duration: var(--d1); }

/* The app's segmented pill: a thumb that springs between the options. */
.pill {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--opts, 2), minmax(0, 1fr));
  padding: 4px;
  border-radius: 13px;
  background: var(--raised);
}
.pill-thumb {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc((100% - 8px) / var(--opts, 2));
  transform: translateX(calc(var(--at, 0) * 100%));
  border-radius: 10px;
  background: var(--thumb);
  transition: transform var(--d4) var(--spring-soft);
}
.pill-opt {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 38px;
  padding: 0 8px;
  border: 0;
  background: none;
  cursor: pointer;
  font-size: 14px;
  font-weight: 560;
  color: var(--text-3);
  transition: color var(--d3) var(--ease-out);
}
.pill-opt svg { width: 15px; height: 15px; }

/* Formats: the app's Format pill (Video, Audio, Transcript). The file below
   follows it: the video, its audio and then the song's instrumental (the
   wave loses its voice), then the transcript, its name rolling over. */
.pill-3 { --opts: 3; }
.fmt[data-fmt="audio"] .pill-thumb { --at: 1; }
.fmt[data-fmt="text"] .pill-thumb { --at: 2; }
.fmt[data-fmt="video"] [data-opt="video"],
.fmt[data-fmt="audio"] [data-opt="audio"],
.fmt[data-fmt="text"] [data-opt="text"] { color: var(--text); }

.fmt-file {
  margin-top: 12px;
  padding: 8px 8px 12px;
  border-radius: 18px;
  background: var(--raised);
}
.fmt-art {
  display: grid;
  height: 112px;
  border-radius: 12px;
  overflow: hidden;
  background: #0e0e0e;
}
.fmt-layer {
  grid-area: 1 / 1;
  min-width: 0;
  opacity: 0;
  transition: opacity var(--d2) var(--ease-in);
}
.fmt-layer.is-on { opacity: 1; transition: opacity var(--d3) var(--ease-out) 80ms; }
.fmt-video img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.04);
  transition: transform 900ms var(--ease-out);
}
.fmt-video.is-on img { transform: none; }

.fmt-wave {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 18px;
}
.fmt-wave i {
  width: 3px;
  height: 70px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .86);
  transform: scaleY(.05);
  transition: transform 160ms var(--ease-in);
}
.fmt-wave.is-on i {
  transform: scaleY(var(--s));
  transition: transform 620ms var(--spring-soft) calc(var(--i, 0) * 9ms + 60ms);
}
.fmt.is-quiet .fmt-wave.is-on i { transform: scaleY(var(--q)); }

.fmt-lines {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  padding: 0 18px;
  font-size: 13.5px;
  line-height: 1.55;
}
.fmt-lines time { width: 28px; flex: none; color: var(--text-3); font-variant-numeric: tabular-nums; }
.fmt-lines span { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text); }
.fmt-lines p {
  display: flex;
  gap: 12px;
  min-width: 0;
  white-space: nowrap;
  opacity: 0;
  filter: blur(3px);
  transform: translateY(4px);
  transition: opacity 120ms var(--ease-in), filter 120ms var(--ease-in), transform 0s linear 120ms;
}
.fmt-lines.is-on p {
  opacity: 1;
  filter: none;
  transform: none;
  transition: opacity 420ms var(--ease-out), filter 420ms var(--ease-out), transform 520ms var(--ease-out);
}
.fmt-lines.is-on p:nth-child(1) { transition-delay: 140ms; }
.fmt-lines.is-on p:nth-child(2) { transition-delay: 380ms; }
.fmt-lines.is-on p:nth-child(3) { transition-delay: 620ms; }

.fmt-meta {
  display: flex;
  flex-direction: column;
  padding: 11px 8px 0;
  font-size: 13.5px;
  line-height: 1.4;
}
.fmt-meta b { font-size: 14.5px; font-weight: 520; color: var(--text); white-space: nowrap; }
.fmt-meta small { font-size: inherit; color: var(--text-3); white-space: nowrap; }

/* Bulk: the app's review list. Each link is read (a breathing placeholder
   until it is), the total adds up, then they download side by side. */
.bulk-list {
  padding: 6px;
  border-radius: 16px;
  background: var(--raised);
  transition: opacity 360ms var(--ease-out);
}
.bulk.is-fading .bulk-list { opacity: 0; }
.bulk-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 8px 9px;
  font-size: 14px;
}
.bulk-thumb {
  position: relative;
  width: 40px;
  height: 23px;
  flex: none;
  overflow: hidden;
  border-radius: 5px;
  background: var(--thumb);
}
.bulk-thumb img { width: 100%; height: 100%; object-fit: cover; }
.bulk-title { position: relative; flex: 1; min-width: 0; }
.bulk-title b {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 450;
  color: var(--text);
}
.bulk-title .skel {
  position: absolute;
  left: 0;
  top: 50%;
  width: 72%;
  height: 8px;
  margin-top: -4px;
  border-radius: 4px;
  background: var(--thumb);
  opacity: 0;
}
.bulk-row em {
  font-style: normal;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.bulk-thumb img, .bulk-title b, .bulk-row em {
  transition: opacity var(--d3) var(--ease-out), transform var(--d3) var(--ease-out);
}
/* Not read yet: a placeholder where the title and size will be. */
.bulk.is-reading .bulk-row:not(.is-read) :is(.bulk-thumb img, .bulk-title b, em) {
  opacity: 0;
  transform: translateY(3px);
  transition: none;
}
.bulk.is-reading .bulk-row:not(.is-read) .skel { opacity: 1; }
.card.is-active .bulk.is-reading .bulk-row:not(.is-read) :is(.skel, .bulk-thumb) { animation: breathe 2200ms ease-in-out infinite; }
.bulk-done {
  position: absolute;
  right: 8px;
  width: 17px;
  height: 17px;
  color: var(--text);
  opacity: 0;
  scale: .4;
  transition: opacity var(--d3) var(--ease-out), scale var(--d4) var(--spring);
}
.bulk-row.is-done em { opacity: 0; }
.bulk-row.is-done .bulk-done { opacity: 1; scale: 1; }
.bulk-bar {
  position: absolute;
  height: 2px;
  border-radius: 1px;
  background: rgba(255, 255, 255, .07);
  left: 59px;
  right: 8px;
  bottom: 2px;
  overflow: hidden;
  opacity: 0;
  transition: opacity var(--d3) var(--ease-out);
}
.bulk-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--text);
  transform: scaleX(var(--pct, 0));
  transform-origin: left;
}
.bulk-row.is-loading .bulk-bar { opacity: 1; }
.bulk-row.is-loading .bulk-bar::after { --pct: 1; transition: transform var(--t, 900ms) cubic-bezier(.4, 0, .6, 1); }
.bulk-row.is-done .bulk-bar::after { --pct: 1; }
.bulk-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 14px 14px 0;
  font-size: 14px;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.bulk-total b { color: var(--text); font-weight: 600; font-size: 15px; }

/* Sites: a few of them; the tiles roll over to a few more. */
.tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}
.tile {
  display: grid;
  aspect-ratio: 1;
  border-radius: 14px;
  background: var(--raised);
  color: var(--text);
}
.tile .roll {
  --rx: 0;
  --ry: 0;
  display: grid;
  -webkit-mask-image: linear-gradient(to bottom, transparent 4%, #000 26%, #000 74%, transparent 96%);
  mask-image: linear-gradient(to bottom, transparent 4%, #000 26%, #000 74%, transparent 96%);
}
.tile .roll-in { display: grid; place-items: center; width: 100%; height: 100%; }
.tile svg { width: 26px; height: 26px; }

/* Only 95 MB: the app's own download. A meter of ticks fills in one smooth
   sweep (each tick's moment is set in site.js) as the number rolls up. */
.dl {
  padding: 16px 18px 20px 16px;
  border-radius: 18px;
  background: var(--raised);
}
.dl-row { display: flex; align-items: center; gap: 12px; }
.dl-icon { width: 40px; height: 40px; flex: none; }
.dl-text {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.dl-text b { font-size: 14.5px; font-weight: 520; color: var(--text); }
.dl-text small { font-size: inherit; }
.dl-count {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 18px;
  font-size: 15px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.dl-count b {
  font-size: 44px;
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: -0.045em;
  color: var(--text);
  font-variant-numeric: tabular-nums; /* the digits keep their width as it counts */
}
.dl-done {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--text);
  opacity: 0;
  scale: .4;
  transition: opacity var(--d3) var(--ease-out), scale var(--d4) var(--spring);
}
.dl.is-done .dl-done { opacity: 1; scale: 1; }

.meter {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 30px;
  margin: 14px 2px 0;
}
.meter i {
  width: 3px;
  height: 100%;
  border-radius: 2px;
  background: rgba(255, 255, 255, .1);
  transform: scaleY(.6);
  transition: background-color 260ms var(--ease-out), transform 420ms var(--spring);
}
.dl.is-done .meter i { background: var(--text); transform: none; }
.dl.is-empty .meter i {
  transition:
    background-color 260ms var(--ease-out) calc((40 - var(--i, 0)) * 5ms),
    transform 260ms var(--ease-out) calc((40 - var(--i, 0)) * 5ms);
}
.dl.is-filling .meter i {
  background: var(--text);
  transform: none;
  transition: background-color 200ms var(--ease-out) var(--d, 0ms), transform 460ms var(--spring) var(--d, 0ms);
}

/* ───────────────────────── Download ───────────────────────── */

.get {
  width: var(--page);
  margin: 128px auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.get h2 {
  font-size: clamp(32px, 4.6vw, 54px);
  line-height: 1.05;
  font-weight: 650;
  letter-spacing: -0.048em;
  margin-bottom: 32px;
  text-wrap: balance;
}

.facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  width: min(820px, 100%);
  margin-top: 56px;
}
.facts div { padding: 2px 16px; }
.facts div + div { border-left: 1px solid var(--line); }
.facts dt { font-size: 14.5px; color: var(--text-3); }
.facts dd { margin-top: 4px; font-size: 17px; font-weight: 560; letter-spacing: -0.015em; color: var(--text); }

/* Credit where it's due: ID4 downloads with yt-dlp. "Powered by", a hairline,
   then yt-dlp's own mark (">_dlp") large. All one gray, and still. */
.powered {
  display: inline-flex;
  align-items: center;
  gap: 20px;
  margin-top: 72px;
  padding: 8px 10px;
  border-radius: 14px;
  font-size: 16px;
  line-height: 22px;
  color: var(--text-3);
  transition: color var(--d3) var(--ease-out);
}
.powered-by { padding-right: 20px; border-right: 1px solid var(--line); }
.powered-mark {
  height: 38px;
  width: auto;
  aspect-ratio: 301.2 / 131.8;
  translate: 0 -5px; /* "dlp" sits on the text's baseline; the p's tail hangs below */
  fill: currentColor;
  overflow: visible;
}
.powered:hover { color: var(--text-2); }

/* ───────────────────────── Changelog ───────────────────────── */
/* After petal.bar/changelog: a quiet title over the releases, lined up with
   them, then each release as its version and date beside its notes. */

.log-hero {
  width: min(850px, calc(100% - 48px));
  margin: 0 auto;
  padding: 136px 0 0;
}
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--text-2);
  border-radius: 8px;
  padding-block: 10px; /* a taller tap target, with the layout unchanged */
  margin-block: -10px;
  transition: color var(--d2) var(--ease-in);
}
.back-link:hover { color: var(--text); }
.back-link svg { width: 14px; height: 14px; rotate: 90deg; transition: translate 350ms var(--ease-out); }
.back-link:hover svg, .back-link:focus-visible svg { translate: -3px 0; }

.log-hero h1 {
  margin: 28px 0 8px;
  font-size: 36px;
  line-height: 1.1;
  font-weight: 640;
  letter-spacing: -0.04em;
  color: var(--strong);
}
.log-hero > p { font-size: 16px; color: var(--text-3); }

.releases {
  width: min(850px, calc(100% - 48px));
  margin: 24px auto 0;
  padding: 0;
  list-style: none;
}
.release {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 32px;
  padding: 40px 0;
  scroll-margin-top: 110px;
}
.release-meta { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; }
.release-version {
  position: relative;
  overflow: hidden;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--raised);
  box-shadow: inset 0 1px rgba(255, 255, 255, .06);
  font-size: 14px;
  line-height: 20px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  transition: background-color 250ms, rotate 400ms var(--spring);
}
.release-date { font-size: 13px; color: var(--text-3); }

.release-body > h2 {
  font-size: 24px;
  line-height: 30px;
  font-weight: 640;
  letter-spacing: -0.03em;
  color: var(--text);
}
.release-summary { margin-top: 8px; max-width: 560px; font-size: 16px; line-height: 1.5; color: var(--text-2); text-wrap: pretty; }
.release-list {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
  font-size: 15.5px;
  line-height: 24px;
  color: var(--text-2);
}
.release-list li { position: relative; max-width: 580px; padding-left: 18px; text-wrap: pretty; }
.release-list li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 10.5px;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--text-3);
  transition: scale 400ms var(--ease-out), background-color 300ms;
}
@media (hover: hover) and (pointer: fine) {
  .release:hover .release-version { background: var(--thumb); rotate: -3deg; }
  .release-list li:hover::before { scale: 1.6; background: var(--text-2); }
}

/* Each release arrives in parts as it comes into view: its version, its
   title, then its notes one after another. */
.release :is(.release-meta, .release-body > h2, .release-summary, .release-list li) {
  transition: opacity 600ms var(--ease-out), transform 800ms var(--ease-expo);
}
.release .release-body > h2 { transition-delay: 60ms; }
.release .release-summary { transition-delay: 110ms; }
.release .release-list li { transition-delay: calc(150ms + var(--j, 0) * 45ms); }
.js .release:not(.is-in) :is(.release-meta, .release-body > h2, .release-summary, .release-list li) {
  opacity: 0;
  transform: translateY(10px);
}

/* ───────────────────────── The bottom edge ───────────────────────── */
/* A progressive blur along the bottom of the screen: six layers, each
   blurring more than the last over a lower band, so the blur deepens toward
   the edge. The layers are never faded (a blurred copy laid over the sharp
   page at part strength is what makes a haze, a glow): the scroll changes how
   much each one blurs instead (site.js). Under them the page fades softly
   into the background, so what's blurred sinks away rather than spreading. */
.edge {
  --to: to bottom;
  position: fixed;
  inset: auto 0 0;
  z-index: 40;
  height: 96px;
  pointer-events: none;
}
/* Off: six backdrop blurs stacked on each other, with their strength changing
   every frame of a scroll, made Chrome flicker (the same fault as a second
   blur under the menu bar). The soft fade below stays. */
.edge i {
  display: none;
  position: absolute;
  inset: 0;
  -webkit-backdrop-filter: blur(calc(var(--eb) * var(--edge, .5)));
  backdrop-filter: blur(calc(var(--eb) * var(--edge, .5)));
  -webkit-mask-image: linear-gradient(var(--to), transparent var(--m0), #000 var(--m1), #000 var(--m2), transparent var(--m3));
  mask-image: linear-gradient(var(--to), transparent var(--m0), #000 var(--m1), #000 var(--m2), transparent var(--m3));
}
.edge i:nth-child(1) { --eb: .3px; --m0: 0%; --m1: 16%; --m2: 33%; --m3: 50%; }
.edge i:nth-child(2) { --eb: .7px; --m0: 16%; --m1: 33%; --m2: 50%; --m3: 66%; }
.edge i:nth-child(3) { --eb: 1.4px; --m0: 33%; --m1: 50%; --m2: 66%; --m3: 83%; }
.edge i:nth-child(4) { --eb: 2.8px; --m0: 50%; --m1: 66%; --m2: 83%; --m3: 100%; }
.edge i:nth-child(5) { --eb: 5.5px; --m0: 66%; --m1: 83%; --m2: 100%; --m3: 101%; }
.edge i:nth-child(6) { --eb: 9px; --m0: 83%; --m1: 100%; --m2: 101%; --m3: 102%; }
.edge::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: calc(.55 + .45 * var(--edge, .5));
  background: linear-gradient(var(--to),
    rgba(10, 10, 10, 0) 0%,
    rgba(10, 10, 10, .05) 25%,
    rgba(10, 10, 10, .17) 45%,
    rgba(10, 10, 10, .36) 65%,
    rgba(10, 10, 10, .58) 85%,
    rgba(10, 10, 10, .78) 100%);
}

/* ───────────────────────── Footer ───────────────────────── */

.footer {
  position: relative;
  margin-top: 112px;
  overflow: hidden;
}

.footer-row {
  width: var(--page);
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  font-size: 15px;
  color: var(--text-2);
}
.footer-row a { padding-block: 10px; margin-block: -10px; transition: color var(--d2) var(--ease-out); border-radius: 8px; }
.footer-row a:hover { color: var(--text); }
/* The X picture beside the handle, as on newomp4.com. */
.footer-credit { display: inline-flex; align-items: center; gap: 8px; }
.footer-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid #3f3f3f;
  transition: border-color 300ms, scale 300ms var(--ease-out);
}
.footer-credit:hover .footer-avatar { border-color: #6e6e6e; scale: 1.05; }
@media (prefers-reduced-motion: reduce) { .footer-credit:hover .footer-avatar { scale: 1; } }
/* The small print, quiet under the credit. */
.footer-legal { width: var(--page); margin: 20px auto 0; }
.footer-legal p { font-size: 11px; line-height: 16px; color: var(--text-3); opacity: .75; text-wrap: pretty; }

.wordmark {
  position: relative;
  width: min(1180px, calc(100% - 32px));
  aspect-ratio: 1266.2123 / 407.0888;
  margin: 36px auto 0;
  margin-bottom: calc(min(1180px, 100vw - 32px) * -0.13);
}
.wordmark > div {
  position: absolute;
  inset: 0;
  -webkit-mask: url("../img/logo.svg") center / contain no-repeat;
  mask: url("../img/logo.svg") center / contain no-repeat;
}
.wordmark-base { background: linear-gradient(180deg, #151515 0%, #101010 50%, #0b0b0b 88%); }
/* The light trails the pointer and fades in slowly; site.js drives it. It's a
   soft disc drawn once, moved, faded and breathed (--lr is its radius) only
   with transforms and opacity, so following the pointer never repaints the
   wordmark. */
.wordmark-lit { opacity: var(--li, 0); will-change: opacity; }
.wordmark-lit i {
  position: absolute;
  left: 0;
  top: 0;
  width: 800px;
  height: 800px;
  margin: -400px 0 0 -400px;
  background: radial-gradient(
    circle closest-side,
    rgba(255, 255, 255, .095) 0%,
    rgba(255, 255, 255, .06) 25%,
    rgba(255, 255, 255, .028) 48%,
    rgba(255, 255, 255, .008) 66%,
    rgba(255, 255, 255, 0) 78%
  );
  transform: translate(var(--mx, 0px), var(--my, 0px)) scale(calc(var(--lr, 400) / 400));
  will-change: transform;
}

/* ───────────────────────── Arrivals ───────────────────────── */

/* Hidden at a hair above nothing (not 0), so the browser counts the headline
   as drawn from the start; once each part has arrived it holds no animation
   (fill `backwards`), so it doesn't stay on a layer of its own. */
.js:not(.ready) .arrive { opacity: .001; transform: translateY(14px); filter: blur(8px); }
.js.ready .arrive {
  animation: arrive 1000ms var(--ease-expo) backwards;
  animation-delay: calc(var(--i, 0) * 100ms + 60ms);
}
@keyframes arrive {
  from { opacity: .001; transform: translateY(14px); filter: blur(8px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}
.js:not(.ready) .stage.arrive { filter: none; transform: translateY(40px); }
.js.ready .stage.arrive { animation-name: arrive-stage; animation-duration: 1300ms; }
@keyframes arrive-stage {
  from { opacity: .001; transform: translateY(40px); }
  to { opacity: 1; transform: none; }
}

.js .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 900ms var(--ease-out) calc(var(--i, 0) * 80ms),
    transform 1100ms var(--ease-expo) calc(var(--i, 0) * 80ms);
}
.js .reveal.is-in { opacity: 1; transform: none; }

/* ───────────────────────── Smaller screens ───────────────────────── */

@media (max-width: 960px) {
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .card, .card-formats { grid-column: span 1; }
  .card-clip { grid-column: span 2; }
}

@media (max-width: 720px) {
  :root { --page: calc(100% - 32px); }
  /* Scrolled, the bar glides into a pill just big enough for the mark and
     Download, and Changelog steps out: it fades first, then gives up its room
     as the pill narrows. Coming back, the room opens and then it fades in. */
  .nav { --pill: 232px; padding: 8px 8px 0; }
  .nav::before { top: 8px; width: calc(100% - 16px); height: 52px; }
  .nav.is-scrolled::before { --cut: calc(50% - var(--pill) / 2); }
  .nav-inner { height: 52px; padding: 0 7px 0 16px; }
  .nav.is-scrolled .nav-inner { width: var(--pill); padding: 0 7px 0 14px; }
  .nav-links { gap: 0; }
  .nav-link {
    max-width: 120px;
    margin-right: 6px;
    padding: 0 12px;
    overflow: hidden;
    white-space: nowrap;
    transition:
      color var(--d2) var(--ease-out),
      background-color var(--d2) var(--ease-out),
      opacity 360ms var(--ease-out) 420ms,
      max-width 900ms var(--ease-smooth),
      padding 900ms var(--ease-smooth),
      margin 900ms var(--ease-smooth);
  }
  .nav.is-scrolled .nav-link {
    max-width: 0;
    margin-right: 0;
    padding: 0;
    opacity: 0;
    pointer-events: none;
    transition:
      color var(--d2) var(--ease-out),
      background-color var(--d2) var(--ease-out),
      opacity 200ms var(--ease-out),
      max-width 900ms var(--ease-smooth),
      padding 900ms var(--ease-smooth),
      margin 900ms var(--ease-smooth);
  }
  .log-hero { width: calc(100% - 32px); padding-top: 108px; }
  .log-hero h1 { margin-top: 24px; font-size: 30px; }
  .releases { width: calc(100% - 32px); margin-top: 16px; }
  .release { grid-template-columns: 1fr; gap: 14px; padding: 30px 0; }
  .release-meta { flex-direction: row; align-items: center; gap: 10px; }
  .hero { padding-top: 100px; }
  .hero-title { font-size: clamp(32px, 9.4vw, 40px); }
  .hero-sub { margin-top: 14px; font-size: 15.5px; }
  .hero-cta { margin-top: 22px; }
  .btn-primary { height: 44px; padding: 0 20px 0 17px; gap: 8px; font-size: 15px; }
  .btn-primary .btn-glyphs, .btn-primary .btn-glyphs .btn-glyph { width: 18px; height: 18px; }
  .stage { margin-top: 56px; }
  .frame { border-radius: 16px; }
  /* No lit edge on a phone: there is no pointer for it to follow. */
  .frame-rim { display: none; }
  .statement { margin-top: 64px; }
  /* Four set lines that never wrap: the breaks are the .say-br in the markup,
     not the three desktop lines. The size follows the screen so the longest
     line (the last, 369px at 20px) always fits. */
  .say { font-size: min(20px, calc((100vw - 32px) * .053)); white-space: nowrap; }
  .say-line { display: inline; }
  .say-br { display: inline; }
  .bento { grid-template-columns: 1fr; margin-top: 64px; gap: 10px; }
  .card, .card-clip, .card-formats { grid-column: auto; min-height: 0; padding: 20px 20px 22px; border-radius: 22px; }
  .vignette { margin-bottom: 22px; }
  .edge { height: 72px; }
  .card-text h2 { font-size: 20px; }
  .card-text p { margin-top: 6px; font-size: 15px; }
  .strip { height: 72px; }
  .clip-boxes { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .chip { grid-column: 1 / -1; justify-self: start; }
  .clip-box { padding: 9px 10px 9px 11px; column-gap: 10px; }
  .clip-box svg { width: 15px; height: 15px; }
  .get { margin-top: 72px; }
  .get h2 { font-size: 30px; margin-bottom: 22px; }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 20px; margin-top: 36px; }
  .facts div:nth-child(3) { border-left: 0; }
  .facts dt { font-size: 13.5px; }
  .facts dd { font-size: 16px; }
  .powered { margin-top: 40px; gap: 14px; font-size: 14px; }
  .powered-by { padding-right: 14px; }
  .powered-mark { height: 28px; translate: 0 -4px; }
  .footer { margin-top: 56px; }
  .footer-row { font-size: 14px; }
  .wordmark { margin-top: 24px; }
}

/* ───────────────────────── Reduce Motion ───────────────────────── */

@media (max-width: 360px) {
  .nav-inner { padding: 0 6px 0 14px; }
  .nav:not(.is-scrolled) .nav-link { padding: 0 9px; }
  .btn-small { padding: 0 13px 0 11px; }
  .clip-box { column-gap: 6px; padding: 9px 6px 9px 9px; }
}
/* A phone on its side: the bottom blur stays a thin strip. */
@media (max-height: 500px) {
  .edge { height: 56px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .arrive, .js .reveal {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
    transition: none !important;
  }
  .frame { transform: none !important; }
  .nav-inner, .nav::before { transition: none !important; }
  .pill-thumb { transition: none !important; }
  .fmt-wave i, .fmt-lines p, .meter i { transition: none !important; }
  .release :is(.release-meta, .release-body > *, .release-list li) { opacity: 1 !important; transform: none !important; transition: none !important; }
}
