/* Design direction: a quiet, monochrome page (graphite ink on near-white,
   or the inverse in dark mode) where the ONLY color is the live demo: a
   video in the icon's light (amber, pink, violet), plus (dark mode only, like the
   extension's ambient light) its glow and the light it spills onto the page. One bold element, everything else disciplined.
   Light by default; dark by system setting or the nav's toggle (theme.js).

   Palette: paper #FAFAFA, ink #111316, slate #5D636D, line (ink at low
   alpha); dark: #0A0A0B, #F3F3F4, #9B9CA3. Demo only, matching the icon:
   amber #FFB868, pink #FF6096, violet #7C68FF. */
:root {
  color-scheme: light;
  --bg: #fafafa;
  --surface: #ffffff;
  --bg-raised: #f1f1f2;
  --nav-bg: rgba(250, 250, 250, 0.82);
  --text: #111316;
  --text-dim: #5d636d;
  --border: rgba(17, 19, 22, 0.08);
  --line: rgba(17, 19, 22, 0.14);
  --line-strong: rgba(17, 19, 22, 0.28);
  /* "Accent" is ink: primary buttons, focus rings, the demo's divider. */
  --accent: #111316;
  --accent-hover: #2b2f36;
  --on-accent: #ffffff;
  --mock-bg: #ffffff;
  /* Translucent, like the extension's panes, so the mock ambient glow
     shows through them after the split. */
  --mock-pane: rgba(244, 244, 246, 0.72);
  /* Demo ambient glow: a soft pastel wash in light mode, like the
     extension's own light-theme glow (v1.3.4); dark mode sets these
     stronger. */
  --mock-glow: 0.45; /* glow inside the mock window, after the split */
  --spill: 0.28; /* glow spilling onto the page, after the split */
  --spill-hint: 0.05; /* faint spill before the split */
  /* Page backdrop: grain and layout rules in both themes; the projector
     beam and ambient drift are dark mode only (0 here). */
  --grain: 0.05;
  --rule: rgba(17, 19, 22, 0.06);
  --beam: transparent;
  --ambient-bg: 0;
  --ease: cubic-bezier(0.65, 0, 0.35, 1);
  --shadow-window: 0 0 0 1px rgba(17, 19, 22, 0.05), 0 2px 4px rgba(17, 19, 22, 0.04),
    0 16px 32px -12px rgba(17, 19, 22, 0.12), 0 56px 112px -40px rgba(17, 19, 22, 0.28);
  --font: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* Dark tokens, in two places with the same values: (1) the visitor's
   explicit choice or the system setting as applied by theme.js
   (html[data-theme="dark"]); (2) the system setting on its own, for when
   that script doesn't run, unless light was explicitly chosen. Keep the
   two blocks identical. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0a0a0b;
  --surface: #111113;
  --bg-raised: #18181b;
  --nav-bg: rgba(10, 10, 11, 0.8);
  --text: #f3f3f4;
  --text-dim: #9b9ca3;
  --border: rgba(255, 255, 255, 0.08);
  --line: rgba(255, 255, 255, 0.14);
  --line-strong: rgba(255, 255, 255, 0.3);
  --accent: #f3f3f4;
  --accent-hover: #ffffff;
  --on-accent: #0a0a0b;
  --mock-bg: #0f0f0f;
  --mock-pane: rgba(27, 27, 29, 0.6);
  --mock-glow: 0.85;
  --spill: 0.7;
  --spill-hint: 0.12;
  --grain: 0.06;
  --rule: rgba(255, 255, 255, 0.055);
  --beam: rgba(255, 255, 255, 0.08);
  --ambient-bg: 0.13;
  --shadow-window: 0 0 0 1px rgba(255, 255, 255, 0.07), 0 2px 4px rgba(0, 0, 0, 0.4),
    0 16px 32px -12px rgba(0, 0, 0, 0.5), 0 56px 112px -40px rgba(0, 0, 0, 0.9);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0a0a0b;
    --surface: #111113;
    --bg-raised: #18181b;
    --nav-bg: rgba(10, 10, 11, 0.8);
    --text: #f3f3f4;
    --text-dim: #9b9ca3;
    --border: rgba(255, 255, 255, 0.08);
    --line: rgba(255, 255, 255, 0.14);
    --line-strong: rgba(255, 255, 255, 0.3);
    --accent: #f3f3f4;
    --accent-hover: #ffffff;
    --on-accent: #0a0a0b;
    --mock-bg: #0f0f0f;
    --mock-pane: rgba(27, 27, 29, 0.6);
    --mock-glow: 0.85;
    --spill: 0.7;
    --spill-hint: 0.12;
    --grain: 0.06;
    --rule: rgba(255, 255, 255, 0.055);
    --beam: rgba(255, 255, 255, 0.08);
    --ambient-bg: 0.13;
    --shadow-window: 0 0 0 1px rgba(255, 255, 255, 0.07), 0 2px 4px rgba(0, 0, 0, 0.4),
      0 16px 32px -12px rgba(0, 0, 0, 0.5), 0 56px 112px -40px rgba(0, 0, 0, 0.9);
  }
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* Phone browsers enlarge text they think is too small for a wide block
     ("font boosting"). The mockups are wide blocks shrunk to fit, so
     their tiny labels were blown up out of proportion. Sizes here are
     chosen on purpose; keep them as written. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Phones could still scroll sideways into empty space: decorative glows
   reach past the content, and overflow-x: hidden on body alone doesn't
   stop that on every mobile browser. clip on both html and body does, and
   (unlike hidden) creates no scroll container, so the sticky nav and
   in-page links keep working. */
@supports (overflow: clip) {
  html,
  body {
    overflow-x: clip;
  }
}

h1,
h2,
h3 {
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

a {
  color: inherit;
}

img {
  display: block;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

.container {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 32px;
}

/* Page backdrop: quiet, cinematic texture behind everything, so the page
   isn't flat while the demos stay the one bold element. Fixed to the
   viewport, behind all content (z-index -1 in the root stacking context;
   body's own background paints on the canvas underneath).
   - Grain: fine film-like noise, both themes.
   - Rules: hairlines at the content edges and at the "split" (~68% across,
     like the video/side-pane divide), both themes, fading in below the nav.
   - Ambient: two faint, heavily blurred amber/pink glows drifting slowly,
     echoing the ambient-light feature. Dark mode only.
   - Beam (on .hero): a soft projector cone falling onto the hero mockup.
     Dark mode only. */
.page-fx {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.fx-ambient {
  position: absolute;
  inset: -20%;
  background: radial-gradient(38% 34% at 22% 30%, rgba(255, 184, 104, 1), transparent 70%),
    radial-gradient(40% 36% at 80% 72%, rgba(255, 96, 150, 1), transparent 70%);
  filter: blur(90px);
  opacity: var(--ambient-bg);
  animation: fxDrift 40s ease-in-out infinite alternate;
}

@keyframes fxDrift {
  from {
    transform: translate3d(-4%, -2%, 0) rotate(0deg);
  }
  to {
    transform: translate3d(4%, 3%, 0) rotate(8deg);
  }
}

.fx-rules {
  --edge: max(32px, 50% - 528px);
  position: absolute;
  inset: 0;
  background: linear-gradient(var(--rule), var(--rule)) var(--edge) 0 / 1px 100% no-repeat,
    linear-gradient(var(--rule), var(--rule)) calc(100% - var(--edge)) 0 / 1px 100% no-repeat,
    linear-gradient(var(--rule), var(--rule)) calc(var(--edge) + 0.68 * min(100% - 64px, 1056px)) 0 / 1px 100% no-repeat;
  -webkit-mask-image: linear-gradient(to bottom, transparent 64px, #000 220px);
  mask-image: linear-gradient(to bottom, transparent 64px, #000 220px);
}

.fx-grain {
  position: absolute;
  inset: 0;
  opacity: var(--grain);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* Projector beam: a narrow cone from the top of the page, widening down
   onto the hero mockup, plus a soft halo where it starts. */
.hero {
  position: relative;
}

.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -64px;
  left: 50%;
  /* Never wider than the window: on phones 1400px reached far past the
     right edge and the page could be scrolled sideways into it. */
  width: min(1400px, 100vw);
  height: 1100px;
  transform: translateX(-50%);
  pointer-events: none;
  background: conic-gradient(from 160deg at 50% 0%, transparent 0deg, var(--beam) 20deg, transparent 40deg),
    radial-gradient(30% 18% at 50% 0%, var(--beam), transparent 70%);
  filter: blur(36px);
  -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent 95%);
  mask-image: linear-gradient(to bottom, #000 40%, transparent 95%);
}

@media (max-width: 640px) {
  .fx-rules {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fx-ambient {
    animation: none;
  }

  .nav.cta-animate nav a.nav-cta {
    transition: background-color 0.15s ease;
  }
}

/* Nav */

.nav {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--nav-bg);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}

/* Border appears once the page is scrolled (script.js). */
.nav.is-scrolled {
  border-bottom-color: var(--border);
}

.nav-inner {
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
}

.brand img {
  border-radius: 6px;
}

.nav nav {
  display: flex;
  align-items: center;
  gap: 32px;
  font-size: 14px;
}

.nav nav a {
  text-decoration: none;
  color: var(--text-dim);
  transition: color 0.15s ease;
}

.nav nav a:hover {
  color: var(--text);
}

/* Last item, after the theme toggle. While the hero's own Add to Chrome
   button is on screen it folds away (script.js sets .hero-cta-visible), so
   the page never shows two at once; it unfolds once the hero scrolls off.
   Without the script it always shows. On phones (no install there) the
   plain Install link shows instead, which also keeps the nav short. */
.nav nav a.nav-cta {
  display: inline-flex;
  align-items: center;
  height: 32px;
  max-width: 160px;
  margin-left: -16px;
  padding: 0 14px;
  overflow: hidden;
  white-space: nowrap;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 13px;
  font-weight: 500;
  transition: background-color 0.15s ease;
}

.nav.cta-animate nav a.nav-cta {
  transition: background-color 0.15s ease, opacity 0.25s ease, visibility 0.3s,
    max-width 0.3s var(--ease), padding 0.3s var(--ease), margin 0.3s var(--ease);
}

.nav.hero-cta-visible nav a.nav-cta {
  max-width: 0;
  margin-left: -32px;
  padding: 0;
  opacity: 0;
  visibility: hidden;
}

.nav nav a.nav-cta:hover {
  background: var(--accent-hover);
  color: var(--on-accent);
}

.nav-install {
  display: none;
}

.nav-github {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.nav-github svg {
  width: 16px;
  height: 16px;
}

/* Theme toggle: shows the icon for the theme a click switches TO (moon
   in light, sun in dark). Hidden until theme.js has set data-theme, since
   without the script it couldn't do anything. */
.theme-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-left: -6px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

:root[data-theme] .theme-toggle {
  display: inline-flex;
}

.theme-toggle:hover {
  color: var(--text);
  border-color: var(--border);
}

.theme-toggle svg {
  width: 17px;
  height: 17px;
}

.theme-toggle .icon-sun,
:root[data-theme="dark"] .theme-toggle .icon-moon {
  display: none;
}

:root[data-theme="dark"] .theme-toggle .icon-sun {
  display: block;
}

/* Hero: left-aligned type as the main typographic moment, then the demo
   at full width. */

.hero {
  padding-top: 112px;
  padding-bottom: 96px;
}

.hero-text {
  max-width: 760px;
  margin-bottom: 80px;
}

.hero h1 {
  margin: 0 0 28px;
  max-width: 16ch;
  font-weight: 600;
  font-size: clamp(42px, 7vw, 86px);
  line-height: 0.98;
  letter-spacing: -0.048em;
}

.subtitle {
  margin: 0 0 40px;
  max-width: 34em;
  color: var(--text-dim);
  font-size: 19px;
  line-height: 1.55;
  letter-spacing: -0.005em;
}

.cta-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 46px;
  padding: 0 22px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.btn svg {
  width: 16px;
  height: 16px;
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
}

.btn-primary:hover {
  background: var(--accent-hover);
}

.btn-secondary {
  color: var(--text);
  border: 1px solid var(--line);
}

.btn-secondary:hover {
  border-color: var(--line-strong);
}

.hero-meta {
  margin: 20px 0 0;
  font-size: 14px;
  color: var(--text-dim);
}

/* Mockup: ONE mock browser window that plays through how the extension
   actually behaves (script.js drives the timeline via state classes on
   .morph-demo): regular YouTube -> scrolling loses the video -> the split
   layout -> lists scroll on their own -> dragging the divider -> collapsing
   a pane. Built as plain absolutely-positioned boxes transitioning
   left/top/width/height PERCENTAGES — no clip-path or custom-property
   animation (an earlier drag-slider built that way broke when deployed).

   Geometry: .morph-body (16:10 window minus the 37px browser bar) is
   ~1.70-1.75x as wide as it is tall on desktop, so a 16:9 video's height
   is ~0.955-0.985x its width percentage (~0.71x on mobile, see the media
   query). Every top/height below is worked out from that; re-derive them
   if the window's aspect ratio or the bar height changes. */

.morph-demo {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: 1032px;
  margin: 0 auto;
}

/* The mock video's ambient light spilling softly onto the page around
   the window once the layout splits, a faint hint of it before. Behind
   the window (z-index -1 inside .morph-demo's own stacking context). */
.morph-demo::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 12%;
  left: 2%;
  right: 2%;
  bottom: -2%;
  pointer-events: none;
  border-radius: 40px;
  background: radial-gradient(50% 60% at 30% 45%, rgba(255, 184, 104, 0.85), transparent 70%),
    radial-gradient(45% 55% at 56% 75%, rgba(255, 96, 150, 0.7), transparent 70%),
    radial-gradient(50% 60% at 82% 40%, rgba(124, 104, 255, 0.55), transparent 70%);
  filter: blur(72px);
  opacity: var(--spill-hint);
  transition: opacity 1s ease;
}

.morph-demo.is-after::before {
  opacity: var(--spill);
}

.morph-label {
  position: relative;
  height: 28px;
  margin-bottom: 14px;
}

.morph-caption {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-dim);
  transition: opacity 0.2s ease;
}

.morph-caption.is-changing {
  opacity: 0;
}

.compare-window {
  background: var(--mock-bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: var(--shadow-window);
  display: flex;
  flex-direction: column;
}

.compare-window-landscape {
  width: 100%;
  aspect-ratio: 16 / 10;
}

/* Browser bar: 36px + 1px border = the 37px the geometry note assumes.
   Right padding matches the dots' width so the URL pill sits centered. */
.compare-dots {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 53px 0 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-raised);
  flex-shrink: 0;
}

.compare-dots span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--line);
  flex-shrink: 0;
}

.mock-url {
  margin: 0 auto;
  width: min(46%, 320px);
  height: 20px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--mock-bg);
  font-size: 11px;
  line-height: 18px;
  text-align: center;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.morph-body {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: var(--mock-bg);
}

.morph-pane {
  position: absolute;
  transition: left 0.85s var(--ease), top 0.85s var(--ease), width 0.85s var(--ease), height 0.85s var(--ease),
    padding 0.6s ease, background-color 0.5s ease, border-color 0.5s ease, opacity 0.3s ease;
}

/* YouTube's masthead: stays fixed and opaque on top, so in the "scrolled"
   state the video slides up underneath it, as on the real page. After the
   split it turns transparent, as the extension makes it, so the ambient
   glow reaches the top. */
.mock-masthead {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  top: 0;
  height: 7%;
  padding: 0 2%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4%;
  background-color: var(--mock-bg);
  transition: background-color 0.6s ease;
}

.morph-demo.is-after .mock-masthead {
  background-color: transparent;
}

/* Ambient light: a soft glow in the mock video's own colors behind the
   whole window, fading in once the layout splits (the extension's glow
   follows YouTube's Ambient mode; this just shows the look). Same
   gradient colors (amber, pink, violet) and sceneDrift animation (same duration, started
   together) as .mock-scene, so the glow drifts in step with the video.
   First child of .morph-body with z-index auto, so it paints under the
   video and panes by tree order; inset -12% keeps the blurred edges
   outside the window. */
.mock-ambient {
  position: absolute;
  inset: -20%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease;
  background: radial-gradient(ellipse 42% 52% at 30% 45%, rgba(255, 184, 104, 0.85), transparent 70%),
    radial-gradient(ellipse 38% 48% at 50% 70%, rgba(255, 96, 150, 0.7), transparent 70%),
    radial-gradient(ellipse 55% 60% at 80% 40%, rgba(124, 104, 255, 0.45), transparent 70%);
  background-size: 100% 100%;
  filter: blur(48px);
  animation: ambientDrift 14s ease-in-out infinite alternate;
}

.morph-demo.is-after .mock-ambient {
  opacity: var(--mock-glow);
  transition-delay: 0.3s;
}

.mh-left,
.mh-right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.mh-menu {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.mh-menu i {
  display: block;
  width: 12px;
  height: 2px;
  border-radius: 1px;
  background: var(--line-strong);
}

.mh-logo {
  display: flex;
  align-items: center;
  gap: 5px;
}

/* Neutral, grayscale site mark (not YouTube's red play logo), so the
   mockups don't look like YouTube's own branding. */
.mh-logo-mark {
  width: 14px;
  height: 14px;
  border-radius: 4px;
  background: var(--line-strong);
}

.mh-logo-text {
  width: 38px;
  height: 7px;
  border-radius: 2px;
  background: var(--line-strong);
}

.mh-search {
  flex: 1;
  max-width: 42%;
  height: 52%;
  display: flex;
}

.mh-search-box {
  flex: 1;
  border: 1px solid var(--line);
  border-right: none;
  border-radius: 999px 0 0 999px;
}

.mh-search-btn {
  width: 14%;
  min-width: 24px;
  border: 1px solid var(--line);
  border-radius: 0 999px 999px 0;
  background: var(--bg-raised);
}

.mh-icon {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 2px solid var(--line-strong);
}

.mh-avatar {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: linear-gradient(135deg, #f59e0b, #ec4899);
}

/* The player: a drifting "scene" plus YouTube-style controls whose red
   progress bar keeps advancing in every state — the video keeps playing
   the whole time, which is the point. */
.morph-video {
  aspect-ratio: 16 / 9;
  border-radius: 8px;
  overflow: hidden;
  background: #000000;
  left: 3%;
  top: 9.5%;
  width: 58%;
}

.mock-scene {
  position: absolute;
  top: 0;
  left: 0;
  width: 140%;
  height: 140%;
  background: radial-gradient(ellipse 60% 70% at 30% 35%, rgba(255, 184, 104, 0.6), transparent 70%),
    radial-gradient(ellipse 50% 60% at 78% 70%, rgba(255, 96, 150, 0.5), transparent 70%),
    linear-gradient(160deg, #1d1430, #0b0a12 70%);
  background-size: 100% 100%;
  animation: sceneDrift 14s ease-in-out infinite alternate;
}

/* The drift moves the layer itself (transform), not its background: a
   background-position animation repaints the gradient, and re-blurs the
   glow layers, on every frame, which stuttered on phones (reported). The
   scene is 140% of the video and slides by the spare 40%; the glow reaches
   20% past the window on each side and slides by half of that. */
@keyframes sceneDrift {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-28.5714%, -28.5714%, 0);
  }
}

@keyframes ambientDrift {
  from {
    transform: translate3d(7.14%, 7.14%, 0);
  }
  to {
    transform: translate3d(-7.14%, -7.14%, 0);
  }
}

.mock-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 8% 3% 2.5%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent);
}

.mock-progress {
  height: 3px;
  margin-bottom: 7px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.28);
  overflow: hidden;
}

.mock-progress span {
  display: block;
  height: 100%;
  width: 82%;
  background: #ff0033;
  transform-origin: 0 50%;
  animation: mockPlay 40s linear infinite;
}

/* From 18% to 82% of the bar, as a transform (no layout per frame). */
@keyframes mockPlay {
  from {
    transform: scaleX(0.2195);
  }
  to {
    transform: scaleX(1);
  }
}

.mock-ctrl-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.mock-ctrl-row i {
  display: block;
  height: 7px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.85);
}

.mock-ctrl-row .c-pause {
  width: 3px;
  border-radius: 0;
  background: none;
  border-left: 2px solid rgba(255, 255, 255, 0.9);
  border-right: 2px solid rgba(255, 255, 255, 0.9);
}

.mock-ctrl-row .c-vol {
  width: 14px;
}

.mock-ctrl-row .c-time {
  width: 44px;
  opacity: 0.55;
}

.mock-ctrl-row .c-spacer {
  flex: 1;
  background: none;
}

.mock-ctrl-row .c-btn {
  width: 9px;
}

/* Main divider: invisible until the cursor hovers it, like the real one. */
.morph-divider {
  z-index: 2;
  width: 3px;
  margin-left: -1.5px;
  border-radius: 2px;
  background: var(--accent);
  left: 62.5%;
  top: 9.5%;
  height: 87.5%;
  opacity: 0;
}

/* Description / Recommended / Comments. Before the split they're plain
   page content (no box, no inset — like YouTube's own title block,
   sidebar and comments); the split gives each its pane chrome. */
.morph-desc,
.morph-rec,
.morph-comments {
  display: flex;
  flex-direction: column;
  gap: 7px;
  overflow: hidden;
  padding: 4px 0;
  border: 1px solid transparent;
  border-radius: 10px;
  background-color: transparent;
}

/* Before-state geometry (desktop): YouTube's own layout — title/channel
   and comments stacked under the video (3%-61% column), the recommended
   sidebar beside it (64%-97%), all starting at the video's top (9.5%,
   just under the masthead). Video bottom is ~64.9-66.6% (see geometry
   note above), so the title block starts at 68%. */
.morph-desc {
  left: 3%;
  top: 68%;
  width: 58%;
  height: 11%;
}

.morph-comments {
  left: 3%;
  top: 81%;
  width: 58%;
  height: 16%;
}

.morph-rec {
  left: 64%;
  top: 9.5%;
  width: 33%;
  height: 87.5%;
}

.morph-demo.is-after .morph-desc,
.morph-demo.is-after .morph-rec,
.morph-demo.is-after .morph-comments {
  padding: 7px 10px;
  border-color: var(--border);
  background-color: var(--mock-pane);
}

.mock-row-header {
  position: relative;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 14px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.caret {
  opacity: 0;
  transition: opacity 0.3s ease, transform 0.25s ease;
}

.morph-demo.is-after .caret {
  opacity: 1;
}

.morph-demo.comments-collapsed .morph-comments .caret {
  transform: rotate(-90deg);
}

/* Recommended header: YouTube's filter chips before the split, our pane
   label after — stacked in one grid cell and cross-faded. */
.rec-header {
  display: grid;
}

.rec-header > * {
  grid-area: 1 / 1;
  transition: opacity 0.3s ease;
}

.hdr-chips {
  display: flex;
  align-items: center;
  gap: 5px;
}

.hdr-chips i {
  display: block;
  width: 30px;
  height: 13px;
  border-radius: 6px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
}

.hdr-chips i:first-child {
  background: var(--text);
  border-color: var(--text);
  opacity: 0.85;
}

.hdr-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  opacity: 0;
}

.morph-demo.is-after .hdr-chips {
  opacity: 0;
}

.morph-demo.is-after .hdr-label {
  opacity: 1;
}

/* Title + channel row under the video; after the split it moves into the
   description pane, which starts collapsed to just its header (the real
   extension's default). */
.desc-full {
  display: flex;
  flex-direction: column;
  gap: 7px;
  transition: opacity 0.3s ease;
}

.mock-title {
  height: 9px;
  border-radius: 3px;
  background: var(--line-strong);
}

.channel-row {
  align-items: center;
}

.channel-row .stack-lines {
  flex: 0 1 34%;
}

.mock-sub-btn {
  margin-left: 6px;
  padding: 4px 9px;
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font-size: 9px;
  font-weight: 600;
  line-height: 1;
}

.desc-header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 8px 10px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.morph-demo.is-after .desc-full {
  opacity: 0;
}

.morph-demo.is-after .desc-header {
  opacity: 1;
  transition-delay: 0.35s;
}

/* Scrollable lists inside Recommended/Comments. Rows never shrink (the
   list clips instead), and script.js scrolls them via scrollTop to show
   they move independently of the video. pointer-events:none keeps a
   visitor's own scrolling from fighting the automated one. */
.morph-scroll-list {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  overflow-y: auto;
  overflow-x: hidden;
  scroll-behavior: smooth;
  scrollbar-width: none;
  pointer-events: none;
}

.morph-scroll-list::-webkit-scrollbar {
  display: none;
}

.item-row {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  flex-shrink: 0;
}

.stack-thumb {
  position: relative;
  width: 50px;
  height: 28px;
  border-radius: 5px;
  flex-shrink: 0;
}

/* Duration badge. */
.stack-thumb::after {
  content: "";
  position: absolute;
  right: 3px;
  bottom: 3px;
  width: 12px;
  height: 5px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.6);
}

.avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  flex-shrink: 0;
}

.stack-lines {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 1px;
}

/* Widths are set per line inline in the HTML, varied like real text. */
.stack-lines span {
  height: 5px;
  border-radius: 3px;
  background: var(--line);
}

.stack-lines .t {
  background: var(--line-strong);
}

.thumb-amber {
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.7), rgba(217, 119, 6, 0.35));
}

.thumb-rose {
  background: linear-gradient(135deg, rgba(244, 63, 94, 0.7), rgba(190, 24, 93, 0.35));
}

.thumb-cyan {
  background: linear-gradient(135deg, rgba(34, 211, 238, 0.7), rgba(8, 145, 178, 0.35));
}

.thumb-emerald {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.7), rgba(5, 150, 105, 0.35));
}

.thumb-violet {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.7), rgba(109, 40, 217, 0.35));
}

.thumb-sky {
  background: linear-gradient(135deg, rgba(56, 189, 248, 0.7), rgba(2, 132, 199, 0.35));
}

.thumb-lime {
  background: linear-gradient(135deg, rgba(163, 230, 53, 0.7), rgba(101, 163, 13, 0.35));
}

/* Fake cursor: an arrow, swapped for a resize glyph over the divider. Its
   left/top is the pointer's hotspot. Moves with the same duration/easing
   as the panes so a drag stays glued to the divider. */
.mock-cursor {
  position: absolute;
  z-index: 4;
  width: 16px;
  height: 16px;
  left: 86%;
  top: 104%;
  opacity: 0;
  pointer-events: none;
  transition: left 0.85s var(--ease), top 0.85s var(--ease), opacity 0.3s ease;
}

.mock-cursor svg {
  position: absolute;
  width: 16px;
  height: 16px;
  transition: opacity 0.15s ease, transform 0.12s ease;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35));
}

.cur-arrow {
  left: 0;
  top: 0;
  transform-origin: 0 0;
}

.cur-resize {
  left: -8px;
  top: -8px;
  opacity: 0;
}

.morph-demo.cursor-divider .mock-cursor,
.morph-demo.cursor-comments .mock-cursor,
.morph-demo.cursor-collapsed .mock-cursor {
  opacity: 1;
}

.morph-demo.cursor-divider .cur-arrow {
  opacity: 0;
}

.morph-demo.cursor-divider .cur-resize {
  opacity: 1;
}

.morph-demo.cursor-press .cur-arrow {
  transform: scale(0.8);
}

/* ---- State: scrolled (regular YouTube, page scrolled down) ----
   Everything moves up by the same 60% (one page scroll); the video ends
   fully hidden behind the masthead. Sidebar and comments grow downward
   so the page still reads as continuing past the bottom edge. */
.morph-demo.is-scrolled .morph-video {
  top: -50.5%;
}

.morph-demo.is-scrolled .morph-desc {
  top: 8%;
}

.morph-demo.is-scrolled .morph-comments {
  top: 21%;
  height: 76%;
}

.morph-demo.is-scrolled .morph-rec {
  top: -50.5%;
  height: 147.5%;
}

/* ---- State: after (the split) ----
   Uniform ~10px spacing (1% across, 1.7% down). Video centered in the
   content area below the masthead (7%-100%, center 53.5%). */
.morph-demo.is-after .morph-video {
  left: 1%;
  top: 21%;
  width: 67%;
}

.morph-demo.is-after .morph-divider {
  left: 68.5%;
  top: 8.7%;
  height: 89.6%;
}

.morph-demo.is-after .morph-desc {
  left: 69%;
  top: 8.7%;
  width: 30%;
  height: 5.5%;
}

.morph-demo.is-after .morph-rec {
  left: 69%;
  top: 15.9%;
  width: 30%;
  height: 40.3%;
}

.morph-demo.is-after .morph-comments {
  left: 69%;
  top: 57.9%;
  width: 30%;
  height: 40.4%;
}

/* Divider dragged left: horizontal only (left/width), so it combines
   cleanly with the vertical-only collapse rules below. */
.morph-demo.is-after.is-dragged .morph-video {
  top: 28.5%;
  width: 52%;
}

.morph-demo.is-after.is-dragged .morph-divider {
  left: 53.5%;
}

.morph-demo.is-after.is-dragged .morph-desc,
.morph-demo.is-after.is-dragged .morph-rec,
.morph-demo.is-after.is-dragged .morph-comments {
  left: 54%;
  width: 45%;
}

/* Comments collapsed to its header; Recommended grows into the space. */
.morph-demo.is-after.comments-collapsed .morph-rec {
  height: 75.2%;
}

.morph-demo.is-after.comments-collapsed .morph-comments {
  top: 92.8%;
  height: 5.5%;
}

/* Cursor positions (hotspot). Order matters: .is-dragged must come after
   .cursor-divider so it wins at equal specificity. */
.morph-demo.cursor-divider .mock-cursor {
  left: 68.5%;
  top: 50%;
}

.morph-demo.cursor-divider .morph-divider {
  opacity: 1;
}

.morph-demo.is-dragged .mock-cursor {
  left: 53.5%;
}

.morph-demo.cursor-comments .mock-cursor {
  left: 78%;
  top: 60.8%;
}

.morph-demo.cursor-collapsed .mock-cursor {
  left: 78%;
  top: 95.5%;
}

@media (prefers-reduced-motion: reduce) {
  .morph-pane,
  .morph-caption,
  .mock-cursor,
  .desc-full,
  .desc-header,
  .caret,
  .rec-header > *,
  .mock-masthead,
  .mock-ambient {
    transition: none !important;
  }

  .mock-scene,
  .mock-progress span,
  .mock-ambient {
    animation: none;
  }

  .mock-progress span {
    width: 18%;
  }

  .morph-scroll-list {
    scroll-behavior: auto;
  }
}

/* Sections */

.section {
  padding-top: 120px;
  padding-bottom: 120px;
}

.section-title {
  margin: 0;
  max-width: 20ch;
  font-weight: 600;
  font-size: clamp(32px, 4.6vw, 52px);
  line-height: 1.04;
  letter-spacing: -0.04em;
}

.section-lead {
  margin: 20px 0 0;
  max-width: 30em;
  color: var(--text-dim);
  font-size: 17px;
}

/* Video: the 37-second tour. A poster with a play button until clicked,
   then YouTube's player in the same 16:9 frame (script.js). */
.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  margin-top: 48px;
  border-radius: 14px;
  overflow: hidden;
  background: #120f26;
  box-shadow: var(--shadow-window);
}

.video-play {
  position: absolute;
  inset: 0;
  display: block;
  cursor: pointer;
}

.video-play img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease);
}

.video-play:hover img {
  transform: scale(1.015);
}

.video-play:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: -6px;
  border-radius: 14px;
}

.video-play-icon {
  position: absolute;
  left: 50%;
  top: 58%;
  width: 76px;
  height: 76px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  transform: translate(-50%, -50%);
  transition: transform 0.2s ease;
}

.video-play:hover .video-play-icon {
  transform: translate(-50%, -50%) scale(1.07);
}

.video-play-icon svg {
  width: 30px;
  height: 30px;
  margin-left: 4px;
  fill: #111316;
}

.video-frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  background: #000000;
  object-fit: contain;
}

@media (max-width: 640px) {
  .video-frame {
    margin-top: 32px;
    border-radius: 10px;
  }

  .video-play-icon {
    width: 56px;
    height: 56px;
  }

  .video-play-icon svg {
    width: 22px;
    height: 22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .video-play img,
  .video-play-icon {
    transition: none;
  }
}

/* Glow: the one section about the ambient light itself. A realistic
   mock of the split (the two-window demo's main window, reused as a still:
   .tw-window and everything inside it) with the glow turned up a little,
   spilling onto the page behind the window like the other demos. The mock
   gets the wider column so its fixed-size details keep their proportions. */
.glow-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.5fr);
  gap: 56px;
  align-items: center;
}

.glow-points {
  list-style: none;
  margin: 40px 0 0;
  padding: 0;
}

.glow-points li {
  padding: 16px 0;
  border-top: 1px solid var(--line);
  color: var(--text-dim);
  font-size: 15px;
}

.glow-points strong {
  color: var(--text);
  font-weight: 600;
}

.glow-stage {
  position: relative;
  isolation: isolate;
  aspect-ratio: 16 / 10;
}

/* The mock "video" changes scene every few seconds (three scenes: warm
   amber, violet, pink), and the glow changes with it: inside the window
   (.tw-ambient), in the video itself (.tw-scene) and spilling onto the page
   (.glow-spill) all cross-fade on the same 9s clock, each scene's layers
   sharing a class (.glow-a / -b / -c) and a start offset. The colors
   also drift faster here than in the other demos, and a soft highlight
   sweeps across the video, so it reads as something playing. */
.glow-spill {
  --glow-on: var(--spill);
  position: absolute;
  z-index: -1;
  inset: 4% -4% -6%;
  pointer-events: none;
  border-radius: 40px;
  filter: blur(72px);
  opacity: 0;
  animation: glowFade 9s linear infinite;
}

.glow-stage .tw-ambient {
  --glow-on: min(1, calc(var(--mock-glow) * 1.2));
  opacity: 0;
  background-size: 100% 100%;
  animation: ambientDrift 5s ease-in-out infinite alternate, glowFade 9s linear infinite;
}

.glow-stage .tw-scene {
  --glow-on: 1;
  opacity: 0;
  background-size: 100% 100%;
  transition: none;
  animation: sceneDrift 5s ease-in-out infinite alternate, glowFade 9s linear infinite;
}

/* Scene A leads the clock; B and C start a third and two thirds in. */
.glow-stage .glow-b {
  animation-delay: 0s, -6s;
}

.glow-stage .glow-c {
  animation-delay: 0s, -3s;
}

.glow-spill.glow-b {
  animation-delay: -6s;
}

.glow-spill.glow-c {
  animation-delay: -3s;
}

@keyframes glowFade {
  0%,
  27% {
    opacity: var(--glow-on);
  }
  35%,
  92% {
    opacity: 0;
  }
  100% {
    opacity: var(--glow-on);
  }
}

.glow-spill.glow-a,
.glow-stage .tw-ambient.glow-a {
  background-image: radial-gradient(ellipse 46% 56% at 28% 45%, rgba(255, 184, 104, 0.95), transparent 70%),
    radial-gradient(ellipse 40% 50% at 58% 72%, rgba(255, 96, 150, 0.8), transparent 70%),
    radial-gradient(ellipse 50% 58% at 82% 38%, rgba(124, 104, 255, 0.55), transparent 70%);
}

.glow-spill.glow-b,
.glow-stage .tw-ambient.glow-b {
  background-image: radial-gradient(ellipse 50% 60% at 60% 42%, rgba(124, 104, 255, 0.95), transparent 70%),
    radial-gradient(ellipse 40% 50% at 24% 68%, rgba(80, 170, 255, 0.7), transparent 70%),
    radial-gradient(ellipse 46% 56% at 84% 70%, rgba(255, 96, 150, 0.5), transparent 70%);
}

.glow-spill.glow-c,
.glow-stage .tw-ambient.glow-c {
  background-image: radial-gradient(ellipse 50% 60% at 40% 55%, rgba(255, 96, 150, 0.95), transparent 70%),
    radial-gradient(ellipse 42% 52% at 78% 34%, rgba(255, 184, 104, 0.8), transparent 70%),
    radial-gradient(ellipse 44% 54% at 16% 30%, rgba(124, 104, 255, 0.5), transparent 70%);
}

.glow-stage .tw-scene.glow-a {
  background-image: radial-gradient(ellipse 60% 70% at 30% 35%, rgba(255, 184, 104, 0.75), transparent 70%),
    radial-gradient(ellipse 50% 60% at 78% 70%, rgba(255, 96, 150, 0.6), transparent 70%),
    linear-gradient(160deg, #1d1430, #0b0a12 70%);
}

.glow-stage .tw-scene.glow-b {
  background-image: radial-gradient(ellipse 58% 68% at 64% 40%, rgba(124, 104, 255, 0.8), transparent 70%),
    radial-gradient(ellipse 46% 56% at 22% 70%, rgba(80, 170, 255, 0.55), transparent 70%),
    linear-gradient(200deg, #141a38, #0b0a12 70%);
}

.glow-stage .tw-scene.glow-c {
  background-image: radial-gradient(ellipse 60% 70% at 42% 58%, rgba(255, 96, 150, 0.8), transparent 70%),
    radial-gradient(ellipse 48% 58% at 80% 30%, rgba(255, 184, 104, 0.65), transparent 70%),
    linear-gradient(140deg, #2a1030, #0b0a12 70%);
}

/* A soft band of light crossing the video now and then. */
.glow-sweep {
  position: absolute;
  top: 0;
  left: 0;
  width: 300%;
  height: 100%;
  background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.14) 50%, transparent 65%);
  animation: glowSweep 4.5s ease-in-out infinite;
}

@keyframes glowSweep {
  from {
    transform: translate3d(-66.6667%, 0, 0);
  }
  to {
    transform: translate3d(0, 0, 0);
  }
}

.glow-window {
  left: 0;
  width: 100%;
}

.glow-stage .caret {
  opacity: 1;
}

.glow-stage .mock-progress .tw-progress {
  width: 42%;
  animation: none;
}

@media (max-width: 860px) {
  .glow-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 48px;
  }

  /* Stacked, the mock is as wide as the content: keep the spill inside it. */
  .glow-spill {
    inset: 4% 0 -6%;
  }
}

/* The mock also plays the "drag the divider to the edge" move on a loop,
   in CSS only: the cursor grabs the divider and pulls it to the window
   edge (the side pane dims, as in the extension), the pane closes and the
   video takes the width with its glow, then a click on the edge strip
   brings the pane back. One 14s timeline shared by every part, so the
   percentages below line up: 20-28 reach the divider, 28-42 drag, 42-48
   close, 48-74 video only, 74-80 click the strip and reopen. The .tw-*
   transitions are switched off here; the keyframes do the easing. */
.glow-stage .tw-video,
.glow-stage .tw-side {
  transition: none;
}

.glow-stage .tw-video {
  animation: glowVideo 14s var(--ease) infinite;
}

.glow-stage .tw-side {
  animation: glowSide 14s var(--ease) infinite;
}

.glow-divider {
  position: absolute;
  top: 8%;
  bottom: 8%;
  left: 66.4%;
  width: 3px;
  border-radius: 2px;
  background: var(--line-strong);
  opacity: 0;
  animation: glowDivider 14s var(--ease) infinite;
}

.glow-strip {
  position: absolute;
  top: 50%;
  right: 0.6%;
  width: 3px;
  height: 22%;
  border-radius: 2px;
  background: var(--line-strong);
  transform: translateY(-50%);
  opacity: 0;
  animation: glowStrip 14s ease infinite;
}

.glow-cursor {
  position: absolute;
  z-index: 5;
  left: 78%;
  top: 112%;
  width: 16px;
  height: 16px;
  opacity: 0;
  pointer-events: none;
  animation: glowCursor 14s var(--ease) infinite;
}

.glow-cursor svg {
  display: block;
  width: 16px;
  height: 16px;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35));
}

@keyframes glowVideo {
  0%,
  42% {
    left: 1.5%;
    width: 64%;
  }
  48%,
  76% {
    left: 5%;
    width: 90%;
  }
  82%,
  100% {
    left: 1.5%;
    width: 64%;
  }
}

@keyframes glowSide {
  0%,
  28% {
    opacity: 1;
    transform: none;
  }
  42% {
    opacity: 0.3;
    transform: translateX(6%);
  }
  48%,
  76% {
    opacity: 0;
    transform: translateX(40%);
  }
  82%,
  100% {
    opacity: 1;
    transform: none;
  }
}

@keyframes glowDivider {
  0%,
  22% {
    left: 66.4%;
    opacity: 0;
  }
  28% {
    left: 66.4%;
    opacity: 1;
  }
  42% {
    left: 97.5%;
    opacity: 1;
  }
  46%,
  100% {
    left: 97.5%;
    opacity: 0;
  }
}

@keyframes glowStrip {
  0%,
  46% {
    opacity: 0;
  }
  50%,
  75% {
    opacity: 1;
  }
  78%,
  100% {
    opacity: 0;
  }
}

@keyframes glowCursor {
  0%,
  18% {
    left: 78%;
    top: 112%;
    opacity: 0;
  }
  21% {
    left: 76%;
    top: 90%;
    opacity: 1;
  }
  28% {
    left: 66.4%;
    top: 50%;
    opacity: 1;
  }
  42%,
  46% {
    left: 97.5%;
    top: 50%;
    opacity: 1;
  }
  54% {
    left: 84%;
    top: 66%;
    opacity: 1;
  }
  68% {
    left: 84%;
    top: 66%;
    opacity: 1;
  }
  74%,
  78% {
    left: 98.6%;
    top: 50%;
    opacity: 1;
  }
  86%,
  100% {
    left: 88%;
    top: 112%;
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .glow-stage .tw-scene,
  .glow-stage .tw-ambient,
  .glow-spill,
  .glow-sweep,
  .glow-stage .tw-video,
  .glow-stage .tw-side {
    animation: none;
  }

  /* A still of the first scene. */
  .glow-stage .glow-a {
    opacity: var(--glow-on);
  }

  .glow-divider,
  .glow-strip,
  .glow-cursor {
    display: none;
  }
}

/* Features: plain columns (six, as 3 x 2), each opened by a hairline rule (the rule
   separates items; no boxes, shadows or hover effects). Color stays out
   of here on purpose: the demo above is the only colorful thing. Each
   icon plays a small loop of its feature (the .fi-* rules below). */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 48px 40px;
  margin-top: 64px;
}

.feature {
  padding-top: 28px;
  border-top: 1px solid var(--line);
}

.feature-icon {
  width: 22px;
  height: 22px;
  margin-bottom: 20px;
  color: var(--text);
}

.feature-icon svg {
  width: 22px;
  height: 22px;
  display: block;
}

/* Icon loops: opacity and transform only, always running (no hover, so
   they work on phones too). Lengths are in the icons' 24-unit viewBox. */
.feature-icon svg {
  overflow: visible;
}

.fi-scroll,
.fi-resize,
.fi-window {
  transform-box: fill-box;
  transform-origin: center;
}

/* The video stays put: lines scroll up the side column, the left is still. */
.fi-scroll {
  animation: fiScroll 2.4s linear infinite;
}

.fi-scroll-b {
  animation-delay: -1.2s;
}

@keyframes fiScroll {
  0% { transform: translateY(4px); opacity: 0; }
  25%, 75% { opacity: 1; }
  100% { transform: translateY(-4px); opacity: 0; }
}

/* Resize anything: the divider slides left and right. */
.fi-resize {
  animation: fiResize 3.6s ease-in-out infinite;
}

@keyframes fiResize {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-2.5px); }
  75% { transform: translateX(2.5px); }
}

/* Ambient light: the rays around the video breathe. */
.fi-rays {
  animation: fiRays 3.2s ease-in-out infinite;
}

@keyframes fiRays {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 1; }
}

/* Two windows: the second window slides out of the first. */
.fi-window {
  animation: fiWindow 4.8s ease-in-out infinite;
}

@keyframes fiWindow {
  0%, 12% { transform: translateX(-4px); opacity: 0; }
  32%, 84% { transform: translateX(0); opacity: 1; }
  100% { transform: translateX(-4px); opacity: 0; }
}

/* Adapts to the video: the normal split fades to the vertical-video one
   (a narrow video, with the two panes side by side) and back. */
.fi-layout-a {
  animation: fiLayout 6s ease-in-out infinite;
}

.fi-layout-b {
  animation: fiLayout 6s ease-in-out -3s infinite;
}

@keyframes fiLayout {
  0%, 40% { opacity: 1; }
  50%, 90% { opacity: 0; }
  100% { opacity: 1; }
}

/* Live streams: the signal pulses outward, inner ring first. */
.fi-wave {
  animation: fiWave 2.4s ease-in-out infinite;
}

.fi-wave-b {
  animation-delay: 0.4s;
}

@keyframes fiWave {
  0%, 100% { opacity: 0.25; }
  35% { opacity: 1; }
  70% { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
  .fi-scroll,
  .fi-resize,
  .fi-rays,
  .fi-window,
  .fi-layout-a,
  .fi-wave {
    animation: none;
  }

  .fi-layout-b {
    animation: none;
    opacity: 0;
  }
}

.feature h3 {
  margin: 0 0 8px;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.015em;
}

.feature p {
  margin: 0;
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.6;
}

/* Two-window demo (script.js drives it with state classes on #twDemo).
   The story: one window in the normal split -> the cursor opens the
   extension's toolbar panel and flips "Two windows" -> the main window
   shrinks to video only while its panes fade out and a second window
   slides in beside it holding them -> the cursor clicks a recommendation
   (both windows switch videos) and a timestamp (the video jumps). Windows
   and the video are absolutely positioned with percentage boxes, like the
   hero demo, so the change animates smoothly; the cursor is placed by
   script from the real elements' rectangles. Same footprint as the hero
   mockup (max 1032px wide, 16:10). */
.tw-demo {
  position: relative;
  isolation: isolate;
  max-width: 1032px;
  margin: 56px auto 0;
}

/* Ambient spill around the main window (softer in light mode). */
.tw-demo::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 10%;
  left: -2%;
  width: 76%;
  bottom: -4%;
  pointer-events: none;
  border-radius: 40px;
  background: radial-gradient(50% 60% at 35% 50%, rgba(255, 184, 104, 0.9), transparent 70%),
    radial-gradient(45% 55% at 65% 70%, rgba(255, 96, 150, 0.8), transparent 70%);
  filter: blur(72px);
  opacity: calc(var(--spill) * 1.15);
}

.tw-stage {
  position: relative;
  aspect-ratio: 16 / 10;
}

.tw-window {
  position: absolute;
  top: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--mock-bg);
  box-shadow: var(--shadow-window);
  transition: left 0.85s var(--ease), top 0.85s var(--ease), width 0.85s var(--ease),
    height 0.85s var(--ease), transform 0.85s var(--ease), opacity 0.5s ease;
}

/* One window (start): full frame. Two windows: video window on the left,
   second window sliding in on the right. */
.tw-main {
  left: 0;
  width: 100%;
}

.tw-demo.tw-two .tw-main {
  width: 70%;
}

.tw-pop {
  left: 71.6%;
  width: 28.4%;
  opacity: 0;
  transform: translateX(8%) scale(0.97);
}

.tw-demo.tw-two .tw-pop {
  opacity: 1;
  transform: none;
  transition-delay: 0.2s;
}

/* The extension's icon in the browser bar, and the toolbar panel it opens. */
.tw-bar {
  position: relative;
}

/* The extension's real icon (docs/icon.png = icons/icon128.png). */
.tw-ext-icon {
  position: absolute;
  right: 14px;
  top: 50%;
  width: 16px;
  height: 16px;
  transform: translateY(-50%);
  border-radius: 4px;
}

.tw-panel {
  position: absolute;
  z-index: 4;
  top: 42px;
  right: 8px;
  width: 210px;
  padding: 10px 12px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.3);
  font-size: 11px;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
}

.tw-demo.tw-panel-open .tw-panel {
  opacity: 1;
  transform: none;
}

.tw-panel-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}

.tw-panel-icon {
  width: 14px;
  height: 14px;
  border-radius: 3px;
}

.tw-panel-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--text);
}

.tw-switch {
  position: relative;
  width: 28px;
  height: 16px;
  border-radius: 999px;
  background: var(--line-strong);
  transition: background-color 0.2s ease;
}

.tw-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #ffffff;
  transition: transform 0.2s ease;
}

.tw-demo.tw-toggled .tw-switch {
  background: var(--accent);
}

.tw-demo.tw-toggled .tw-switch::after {
  transform: translateX(12px);
  background: var(--on-accent);
}

/* Main window body: ambient glow behind, mini top bar, then the content
   (video + side pane in the split; video alone, centered, in two windows). */
.tw-main-body {
  position: relative;
  isolation: isolate;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Ambient light inside the main window, one layer per demo video,
   cross-faded on switch (softer in light mode). */
.tw-ambient {
  position: absolute;
  z-index: -1;
  inset: -20%;
  pointer-events: none;
  filter: blur(48px);
  transition: opacity 0.6s ease;
  animation: ambientDrift 14s ease-in-out infinite alternate;
}

.tw-ambient-a {
  background: radial-gradient(ellipse 42% 52% at 32% 50%, rgba(255, 184, 104, 0.85), transparent 70%),
    radial-gradient(ellipse 38% 48% at 60% 70%, rgba(255, 96, 150, 0.7), transparent 70%),
    radial-gradient(ellipse 55% 60% at 80% 40%, rgba(124, 104, 255, 0.45), transparent 70%);
  background-size: 100% 100%;
  opacity: var(--mock-glow);
}

.tw-ambient-b {
  background: radial-gradient(ellipse 45% 55% at 62% 45%, rgba(124, 104, 255, 0.85), transparent 70%),
    radial-gradient(ellipse 40% 50% at 30% 70%, rgba(255, 184, 104, 0.55), transparent 70%),
    radial-gradient(ellipse 55% 60% at 80% 30%, rgba(255, 96, 150, 0.5), transparent 70%);
  background-size: 100% 100%;
  opacity: 0;
}

.tw-demo.tw-switched .tw-ambient-a {
  opacity: 0;
}

.tw-demo.tw-switched .tw-ambient-b {
  opacity: var(--mock-glow);
}

/* Mini YouTube top bar, as both real windows show. */
.tw-masthead {
  flex-shrink: 0;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 12px;
}

.tw-masthead .mh-search {
  max-width: 46%;
  height: 16px;
}

.tw-content {
  position: relative;
  flex: 1;
  min-height: 0;
}

.tw-video {
  position: absolute;
  left: 1.5%;
  top: 50%;
  width: 64%;
  aspect-ratio: 16 / 9;
  transform: translateY(-50%);
  overflow: hidden;
  border-radius: 8px;
  background: #000000;
  transition: left 0.85s var(--ease), top 0.85s var(--ease), width 0.85s var(--ease),
    transform 0.85s var(--ease);
}

.tw-demo.tw-two .tw-video {
  left: 3%;
  width: 94%;
}

/* The split's side pane, inside the main window; in two windows its panes
   fade out towards the second window. */
.tw-side {
  position: absolute;
  top: 1%;
  bottom: 2.5%;
  right: 1.5%;
  width: 31%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: opacity 0.45s ease, transform 0.85s var(--ease);
}

.tw-demo.tw-two .tw-side {
  opacity: 0;
  transform: translateX(14%);
}

/* Two "videos": A (the hero's amber-and-pink scene) and B (cooler, the
   one the cursor picks), cross-faded on switch. */
.tw-scene {
  position: absolute;
  top: 0;
  left: 0;
  width: 140%;
  height: 140%;
  transition: opacity 0.6s ease;
  animation: sceneDrift 14s ease-in-out infinite alternate;
}

.tw-scene-a {
  background: radial-gradient(ellipse 60% 70% at 30% 35%, rgba(255, 184, 104, 0.6), transparent 70%),
    radial-gradient(ellipse 50% 60% at 78% 70%, rgba(255, 96, 150, 0.5), transparent 70%),
    linear-gradient(160deg, #1d1430, #0b0a12 70%);
  background-size: 100% 100%;
}

.tw-scene-b {
  background: radial-gradient(ellipse 55% 65% at 65% 40%, rgba(124, 104, 255, 0.65), transparent 70%),
    radial-gradient(ellipse 45% 55% at 25% 72%, rgba(255, 184, 104, 0.4), transparent 70%),
    linear-gradient(200deg, #141a38, #0b0a12 70%);
  background-size: 100% 100%;
  opacity: 0;
}

.tw-demo.tw-switched .tw-scene-b {
  opacity: 1;
}

.tw-demo .mock-progress .tw-progress {
  width: 34%;
  animation: none;
  transition: width 0.6s ease;
}

.tw-demo.tw-switched .mock-progress .tw-progress {
  width: 3%;
}

.tw-demo.tw-seeked .mock-progress .tw-progress {
  width: 58%;
}

/* Second window: narrower, so its address pill takes more of the bar. */
.tw-pop .mock-url {
  width: 70%;
}

.tw-pop-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 8px 8px;
  overflow: hidden;
  transition: opacity 0.25s ease;
}

.tw-demo.tw-reloading .tw-pop-body {
  opacity: 0.2;
}

.tw-pane {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-height: 0;
  overflow: hidden;
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--mock-pane);
}

.tw-desc {
  flex: 0 0 auto;
}

.tw-rec {
  flex: 1.2 1 0;
}

.tw-comments {
  flex: 1 1 0;
}

.tw-demo .caret {
  opacity: 1;
}

.tw-pop .mock-title {
  height: 7px;
}

.tw-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.tw-list-b,
.tw-title-b,
.tw-demo.tw-switched .tw-list-a,
.tw-demo.tw-switched .tw-title-a {
  display: none;
}

.tw-demo.tw-switched .tw-list-b {
  display: flex;
}

.tw-demo.tw-switched .tw-title-b {
  display: block;
}

/* The clicked recommendation, and the timestamp link in a comment
   (YouTube's link blue, inside the demo only). */
.tw-demo.tw-press-rec .tw-target-rec {
  border-radius: 6px;
  outline: 2px solid var(--line-strong);
  outline-offset: 2px;
}

.stack-lines .tw-ts {
  align-self: flex-start;
  width: auto;
  height: auto;
  background: none;
  color: #3ea6ff;
  font-size: 9px;
  font-weight: 600;
  line-height: 1;
}

.tw-demo.tw-press-ts .tw-ts {
  text-decoration: underline;
}

.tw-cursor {
  position: absolute;
  z-index: 5;
  left: 90%;
  top: 104%;
  width: 16px;
  height: 16px;
  opacity: 0;
  pointer-events: none;
  transition: left 0.8s var(--ease), top 0.8s var(--ease), opacity 0.3s ease;
}

.tw-cursor svg {
  display: block;
  width: 16px;
  height: 16px;
  transform-origin: 0 0;
  transition: transform 0.12s ease;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35));
}

.tw-demo.tw-cursor-on .tw-cursor {
  opacity: 1;
}

.tw-demo.tw-press .tw-cursor svg {
  transform: scale(0.8);
}

/* Phones: windows stack. One window fills the frame with the video on top
   and the panes below; two windows put the video window on top and the
   second window underneath. */
@media (max-width: 640px) {
  .tw-demo {
    margin-top: 40px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tw-window,
  .tw-video,
  .tw-side,
  .tw-panel,
  .tw-scene,
  .tw-ambient,
  .tw-cursor,
  .tw-cursor svg,
  .tw-pop-body,
  .tw-demo .mock-progress .tw-progress {
    transition: none;
    animation: none;
  }
}

/* Settings: what you can change (left) beside a static replica of the
   extension's real toolbar panel (right). Deliberately not animated; the
   two demos above are the page's only motion. The replica uses the page's
   own tokens, so it follows light and dark like the real panel does. */
.settings-grid {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  gap: 72px;
  align-items: center;
}

.settings-list {
  margin: 40px 0 0;
  border-top: 1px solid var(--line);
}

.settings-list > div {
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}

.settings-list dt {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.settings-list dd {
  margin: 4px 0 0;
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.6;
}

.settings-list kbd {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  padding: 1px 6px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg-raised);
  color: var(--text);
}

.panel-mock {
  justify-self: center;
  width: 100%;
  max-width: 340px;
  padding: 16px 18px 12px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--shadow-window);
  font-size: 13px;
  line-height: 1.45;
}

.pm-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.pm-header img {
  border-radius: 5px;
}

.pm-name {
  flex: 1;
  font-size: 14px;
  font-weight: 600;
}

.pm-row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 12px 0;
}

.pm-row + .pm-row {
  border-top: 1px solid var(--border);
}

.pm-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pm-title {
  font-weight: 600;
}

.pm-desc,
.pm-slider-label {
  color: var(--text-dim);
}

.pm-switch {
  position: relative;
  flex: 0 0 auto;
  width: 36px;
  height: 20px;
  margin-top: 1px;
  border-radius: 999px;
  background: var(--line-strong);
}

.pm-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

.pm-switch.is-on {
  background: var(--accent);
}

.pm-switch.is-on::after {
  transform: translateX(16px);
  background: var(--on-accent);
}

/* Glow strength belongs to the Ambient light row above it. */
.pm-row.pm-slider-row {
  align-items: center;
  padding-top: 0;
  border-top: none;
}

.pm-slider {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--line);
}

.pm-slider::before {
  content: "";
  position: absolute;
  inset: 0 calc(100% - var(--v, 70%)) 0 0;
  border-radius: 2px;
  background: var(--accent);
}

.pm-slider i {
  position: absolute;
  left: var(--v, 70%);
  top: 50%;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, -50%);
}

.pm-slider-label {
  flex: 0 0 118px;
}

.pm-row.pm-slider-row + .pm-row.pm-slider-row {
  border-top: none;
}

/* One-line rows, like the real panel's compact rows. */
.pm-row.pm-compact {
  align-items: center;
  padding: 9px 0;
}

.pm-compact .pm-title {
  flex: 1;
}

.pm-compact .pm-switch {
  margin-top: 0;
}

.pm-select {
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
}

.pm-slider-value {
  flex: 0 0 auto;
  width: 36px;
  text-align: right;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* Group headings, as in the real panel (Layout, Glow, Panes). */
.pm-head {
  margin: 12px 0 0;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.pm-head + .pm-row {
  padding-top: 6px;
}

/* A one-line row with a slider (Transparency). */
.pm-row.pm-range-row {
  gap: 12px;
}

.pm-range-row .pm-title {
  flex: 0 0 auto;
}

.pm-footer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 12px;
}

.pm-links,
.pm-meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.pm-meta {
  justify-content: flex-end;
  font-size: 11px;
  opacity: 0.8;
}

@media (max-width: 860px) {
  .settings-grid {
    grid-template-columns: 1fr;
    gap: 48px;
  }
}

/* Install: heading + download on the left, the (genuinely sequential)
   numbered steps on the right. */
.install-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 72px;
  align-items: start;
}

.install-grid .btn {
  margin-top: 36px;
}

.steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
}

.steps li {
  counter-increment: step;
  position: relative;
  padding: 0 0 28px 52px;
  font-size: 16px;
}

.steps li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 14px;
  top: 34px;
  bottom: 4px;
  width: 1px;
  background: var(--border);
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -2px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}

.steps li:last-child {
  padding-bottom: 0;
}

.steps a {
  text-underline-offset: 3px;
}

.steps code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 14px;
}

.note {
  margin: 36px 0 0;
  padding-left: 52px;
  color: var(--text-dim);
  font-size: 14px;
}

/* Phones only: "Send me the link" (the extension needs a computer).
   Hidden in the HTML; script.js reveals it on touch-only screens. Plain
   block text so the hidden attribute still works. */
.phone-note {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-dim);
}

.note.phone-note {
  margin-top: 12px;
}

.share-btn {
  margin: 0 4px 0 6px;
  padding: 1px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-dim);
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.6;
  vertical-align: 1px;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.share-btn:hover {
  border-color: var(--line-strong);
  color: var(--text);
}

/* A finger-sized target. */
.phone-note .share-btn {
  margin: 4px 0 0;
  padding: 6px 14px;
  font-size: 14px;
  vertical-align: baseline;
}

.share-btn.is-done {
  color: var(--text);
}

/* FAQ: heading on the left, questions on the right (like Install), each
   a native <details> separated by hairline rules. No script and no
   animation; a plus turns into a minus when open. */
.faq-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 72px;
  align-items: start;
}

.faq-list {
  border-top: 1px solid var(--line);
}

.faq-item {
  border-bottom: 1px solid var(--line);
}

.faq-item summary {
  position: relative;
  padding: 20px 40px 20px 0;
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.01em;
  list-style: none;
  cursor: pointer;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

/* Plus / minus, drawn with two bars. */
.faq-item summary::before,
.faq-item summary::after {
  content: "";
  position: absolute;
  right: 4px;
  top: 50%;
  width: 12px;
  height: 1.5px;
  background: var(--text-dim);
  transition: transform 0.2s ease;
}

.faq-item summary::after {
  transform: rotate(90deg);
}

.faq-item[open] summary::after {
  transform: rotate(0deg);
}

.faq-item summary:hover::before,
.faq-item summary:hover::after {
  background: var(--text);
}

.faq-item p {
  margin: -4px 40px 22px 0;
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.65;
}

.faq-item a {
  color: var(--text);
  text-underline-offset: 3px;
}

.faq-item code,
.faq-item kbd {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  padding: 1px 6px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg-raised);
}

@media (max-width: 860px) {
  .faq-grid {
    grid-template-columns: 1fr;
    gap: 40px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .faq-item summary::before,
  .faq-item summary::after {
    transition: none;
  }
}

/* Reading pages (privacy policy). */
.prose {
  max-width: 720px;
}

.prose h2 {
  margin: 48px 0 12px;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.015em;
}

.prose p,
.prose li {
  color: var(--text-dim);
}

.prose ul {
  padding-left: 20px;
}

.prose li + li {
  margin-top: 8px;
}

.prose strong {
  color: var(--text);
  font-weight: 600;
}

.prose a {
  color: var(--text);
  text-underline-offset: 3px;
}

/* Buttons on a reading page (bye.html) keep their own colors. */
.prose a.btn {
  text-decoration: none;
}

.prose a.btn-primary {
  color: var(--on-accent);
}

.prose-meta {
  margin-top: 48px;
  font-size: 14px;
}

/* Footer */

.footer {
  border-top: 1px solid var(--border);
}

.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 32px;
  padding-bottom: 32px;
  color: var(--text-dim);
  font-size: 14px;
}

.footer-inner p {
  margin: 0;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 24px;
}

.footer-links a {
  text-decoration: none;
  transition: color 0.15s ease;
}

.footer-links a:hover {
  color: var(--text);
}

/* Six features: 3 x 2 on desktop, 2 x 3 on mid-size screens, one column on
   phones. */
@media (max-width: 1040px) and (min-width: 861px) {
  .feature-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 48px;
  }

  .feature {
    padding-bottom: 32px;
  }
}

@media (max-width: 860px) {
  .feature-grid {
    grid-template-columns: 1fr;
    gap: 0;
    margin-top: 48px;
  }

  .feature {
    padding-bottom: 28px;
  }

  .install-grid {
    grid-template-columns: 1fr;
    gap: 48px;
  }

  .section {
    padding-top: 88px;
    padding-bottom: 88px;
  }
}

/* Mockup loops stop while their mockup is off screen (script.js sets the
   class), so a phone only animates what is in view. */
.is-offscreen,
.is-offscreen *,
.is-offscreen::before,
.is-offscreen *::before,
.is-offscreen *::after {
  animation-play-state: paused !important;
}

/* Phones: every mockup keeps its landscape, desktop-sized window, because
   that is the only shape the extension works in (it stays off in narrow
   or portrait windows). The window is laid out at a fixed 760px design
   width and shrunk to fit (script.js sets --mock-zoom from the
   real width; the fallback suits a ~390px phone), so everything inside
   keeps its desktop proportions. The stacked, phone-shaped layouts that
   used to be here showed a window the extension would never split. */
@media (max-width: 640px) {
  .compare-window-landscape,
  .tw-stage,
  .glow-stage {
    /* Shrunk with a transform, not zoom: browsers enforce a minimum font
       size AFTER zoom, so the mock's small labels stopped shrinking and
       came out large next to everything else (reported). A transform
       scales the finished picture, text included. It doesn't change the
       layout box, so the negative margins take back the unused space
       (760 x 475 is the 16:10 window at the design width). */
    --mock-zoom: 0.44;
    width: 760px;
    transform: scale(var(--mock-zoom));
    transform-origin: 0 0;
    margin-right: calc(760px * (var(--mock-zoom) - 1));
    margin-bottom: calc(475px * (var(--mock-zoom) - 1));
    -webkit-text-size-adjust: none;
    text-size-adjust: none;
  }

  .morph-caption {
    font-size: 12px;
  }

  /* Page layout on phones (not the mockups). */
  .container {
    padding: 0 20px;
  }

  .nav nav {
    gap: 20px;
  }

  .nav-link-optional {
    display: none;
  }

  .nav nav a.nav-cta {
    display: none;
  }

  .nav-install {
    display: inline;
  }

  .hero {
    padding-top: 64px;
    padding-bottom: 64px;
  }

  .hero-text {
    margin-bottom: 48px;
  }

  .subtitle {
    font-size: 17px;
  }

  .section {
    padding-top: 72px;
    padding-bottom: 72px;
  }

  .footer-inner {
    flex-direction: column;
    text-align: center;
  }
}
