/* /public/css/pages/shoutout-assistant.css
   World-class landing page for the free "CollabPals for YouTube" Chrome
   extension (/youtube-shoutout-extension). A cinematic dark hero with a
   floating, realistic product window, a light editorial body, and matching
   dark bookend bands. Shared components (.card, .banner, .badge) still carry
   their base look; everything here is bespoke layout, depth, and motion.
   Mobile-first; flawless at 375px. All color via design-system variables. */

.sa-page {
  width: 100%;
  overflow-x: hidden;
}

/* Shared inner container: every full-bleed section centers its content here */
.sa-wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px;
}

/* Admin dark-preview banner sits above the hero, contained */
.sa-admin { padding: 24px 0 0; }

/* ═══════════════════════════════════════════════════════
   HERO (dark, cinematic)
   ═══════════════════════════════════════════════════════ */
.sa-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: 72px 0 64px;
  background: linear-gradient(180deg, var(--surface-indigo-deep) 0%, var(--surface-indigo-dark) 100%);
}
/* Layered aurora glow blooms */
.sa-hero__aura {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(55% 45% at 50% -8%, rgba(var(--color-primary-rgb), 0.55), transparent 70%),
    radial-gradient(42% 40% at 86% 8%, rgba(var(--color-info-rgb), 0.30), transparent 72%),
    radial-gradient(46% 45% at 10% 24%, rgba(var(--color-primary-dark-rgb), 0.42), transparent 72%);
}
/* Faint dot-grid texture, masked to fade out toward the edges */
.sa-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1.4px);
  background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(72% 60% at 50% 0%, black, transparent 78%);
  mask-image: radial-gradient(72% 60% at 50% 0%, black, transparent 78%);
}
.sa-hero__inner { position: relative; text-align: center; }

.sa-brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 26px;
}
.sa-brand__tile {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-lg);
  background: var(--color-white);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.5);
}
.sa-brand__tile img { display: block; }
.sa-brand__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--font-size-base);
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.92);
}

.sa-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 15px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: rgba(255, 255, 255, 0.92);
  font-size: var(--font-size-sm);
  font-weight: 600;
  margin-bottom: 24px;
}
.sa-pill i { color: var(--color-primary-light); }

.sa-hero__title {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 6vw, 3.75rem);
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--color-white);
  margin: 0 0 18px;
}
.sa-grad {
  background: linear-gradient(100deg, var(--color-primary-light), var(--surface-indigo-medium));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.sa-hero__sub {
  font-size: var(--font-size-lg);
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.72);
  max-width: 600px;
  margin: 0 auto 30px;
}

/* ── CTA cluster (shared by hero + final band) ────────── */
.sa-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
.sa-badge-link {
  display: inline-block;
  border-radius: var(--radius-md);
  transition: transform var(--transition-fast) var(--ease-out);
}
.sa-badge-link:hover { transform: translateY(-2px); }
/* Tap-down. :hover never fires on touch and these badges open a new tab, so
   without this a phone user pressed the page's only action and got no
   acknowledgement at all. Shared on purpose: the hero, mid-page and final
   badges are the same element. */
.sa-badge-link:active { transform: scale(0.97); }
.sa-badge-img {
  display: block;
  width: 248px;
  height: 75px;
  max-width: 100%;
  border-radius: var(--radius-md);
  box-shadow: 0 14px 34px -12px rgba(0, 0, 0, 0.55);
}
.sa-soon { display: flex; flex-direction: column; align-items: center; gap: 10px; }
/* Pre-launch status chip, NOT a button. It used to be a filled gradient pill
   with a drop shadow, which read as the page's main call to action even though
   it is a span with nothing to click. Flat and outlined, it reads as the status
   it actually is. The real Chrome Web Store badge takes over at launch. */
.sa-soon__pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 22px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.82);
  font-weight: 600;
  font-size: var(--font-size-base);
}
.sa-soon__pill i { color: var(--color-primary-light); }
.sa-soon__note { margin: 0; font-size: var(--font-size-sm); color: rgba(255, 255, 255, 0.6); }
.sa-trust {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: rgba(255, 255, 255, 0.78);
}
.sa-trust i { color: var(--color-success); }

/* ═══════════════════════════════════════════════════════
   PRODUCT WINDOW (the floating showpiece)
   ═══════════════════════════════════════════════════════ */
.sa-stage { position: relative; z-index: 1; margin-top: 56px; }
.sa-window {
  max-width: 940px;
  margin: 0 auto;
  background: var(--color-white);
  border-radius: var(--radius-2xl);
  border: 1px solid rgba(255, 255, 255, 0.10);
  overflow: hidden;
  box-shadow:
    0 50px 100px -30px rgba(0, 0, 0, 0.65),
    0 0 0 1px rgba(255, 255, 255, 0.05),
    0 0 90px rgba(var(--color-primary-rgb), 0.22);
}
.sa-window__bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: var(--color-gray-100);
  border-bottom: 1px solid var(--border-subtle);
}
.sa-dots { display: inline-flex; gap: 7px; flex-shrink: 0; }
.sa-dots span { width: 11px; height: 11px; border-radius: 50%; background: var(--color-gray-300); }
.sa-url {
  flex: 1;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  background: var(--color-white);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  color: var(--color-gray-500);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.sa-url i { color: var(--color-gray-400); flex-shrink: 0; }
/* text-overflow cannot act on a flex container's own text, so the URL needs an
   inline-block of its own to truncate inside. Without this it hard-cuts
   mid-word on a phone with no ellipsis. */
.sa-url__text {
  display: inline-block;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.sa-window__body { display: flex; align-items: stretch; }

/* Left: the real YouTube box being filled in */
.sa-yt { flex: 1 1 60%; min-width: 0; }
.sa-yt__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border-subtle);
}
.sa-yt__logo {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--font-size-sm);
  letter-spacing: -0.02em;
  color: var(--color-gray-900);
}
.sa-yt__logo i { color: var(--color-brand-red); font-size: 1.05rem; }
.sa-yt__searchbar {
  width: 116px;
  height: 26px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-default);
  background: var(--color-gray-50);
  display: inline-flex;
  align-items: center;
  padding: 0 12px;
  color: var(--color-gray-400);
  font-size: var(--font-size-xs);
}
.sa-compose { padding: 20px 22px 22px; }
.sa-compose__head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.sa-avatar {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--color-primary-light), var(--color-primary-dark));
  box-shadow: var(--shadow-sm);
}
.sa-who b { display: block; font-size: var(--font-size-sm); font-weight: 700; color: var(--color-gray-900); }
.sa-who span { font-size: var(--font-size-xs); color: var(--color-gray-500); }
.sa-field {
  border: 1px solid var(--border-default);
  border-bottom: 2px solid var(--color-primary);
  border-radius: var(--radius-md);
  background: var(--color-white);
  padding: 14px 16px;
  min-height: 96px;
  box-shadow: var(--shadow-inner);
}
.sa-field p { margin: 0; font-size: var(--font-size-sm); line-height: 1.65; color: var(--color-gray-800); }
.sa-hl {
  background: var(--color-primary-soft);
  color: var(--color-primary-dark);
  font-weight: 600;
  border-radius: var(--radius-sm);
  padding: 1px 4px;
}
.sa-caret {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  vertical-align: -2px;
  margin-left: 1px;
  background: var(--color-primary);
  animation: sa-blink 1.1s step-end infinite;
}
@keyframes sa-blink { 50% { opacity: 0; } }
.sa-actions { display: flex; justify-content: flex-end; align-items: center; gap: 16px; margin-top: 18px; }
.sa-cancel { font-size: var(--font-size-sm); font-weight: 600; color: var(--color-gray-500); }
.sa-post {
  font-size: var(--font-size-sm);
  font-weight: 700;
  color: var(--color-white);
  background: var(--color-primary);
  padding: 9px 22px;
  border-radius: var(--radius-full);
  animation: sa-pulse 2.2s var(--ease-in-out) infinite;
}
@keyframes sa-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb), 0.45); }
  50% { box-shadow: 0 0 0 7px rgba(var(--color-primary-rgb), 0); }
}
.sa-hint { display: flex; align-items: center; gap: 8px; margin: 14px 0 0; font-size: var(--font-size-xs); color: var(--color-gray-500); }
.sa-hint i { color: var(--color-primary); }

/* Right: the CollabPals extension dock (dark) */
.sa-dock {
  flex: 0 0 38%;
  padding: 20px 20px 22px;
  color: var(--color-white);
  border-left: 1px solid var(--border-subtle);
  background: linear-gradient(170deg, var(--surface-indigo-dark), var(--surface-indigo-deep));
}
.sa-dock__head { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.sa-dock__logo {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-md);
  background: var(--color-white);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.sa-dock__name b { display: block; font-family: var(--font-display); font-size: var(--font-size-sm); font-weight: 700; line-height: 1.2; }
.sa-dock__name span { font-size: var(--font-size-xs); color: rgba(255, 255, 255, 0.5); }
.sa-dock__status { display: flex; align-items: center; gap: 9px; margin: 0 0 16px; font-size: var(--font-size-xs); color: rgba(255, 255, 255, 0.7); }
.sa-ping {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--color-success);
  animation: sa-ping 1.8s var(--ease-in-out) infinite;
}
@keyframes sa-ping {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--color-success-rgb), 0.55); }
  50% { box-shadow: 0 0 0 6px rgba(var(--color-success-rgb), 0); }
}
.sa-dock__list { list-style: none; margin: 0; padding: 0; }
.sa-dock__list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: var(--font-size-sm);
  line-height: 1.4;
  margin-bottom: 13px;
  color: rgba(255, 255, 255, 0.9);
}
.sa-dock__list i { margin-top: 2px; flex-shrink: 0; }
.sa-dock__list .sa-done i { color: var(--color-success); }
.sa-dock__list .sa-now i { color: var(--color-primary-light); }
.sa-dock__foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 18px 0 0;
  padding-top: 15px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: var(--font-size-xs);
  color: rgba(255, 255, 255, 0.72);
}

/* ═══════════════════════════════════════════════════════
   TRUST STRIP
   ═══════════════════════════════════════════════════════ */
.sa-strip { background: var(--surface-secondary); border-bottom: 1px solid var(--border-subtle); }
.sa-strip__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 14px 40px;
  padding: 22px 24px;
}
.sa-strip__item { display: inline-flex; align-items: center; gap: 9px; font-size: var(--font-size-sm); font-weight: 600; color: var(--color-gray-700); }
.sa-strip__item i { color: var(--color-primary); font-size: 1rem; }

/* ═══════════════════════════════════════════════════════
   SECTION SCAFFOLDING
   ═══════════════════════════════════════════════════════ */
.sa-section { padding: 80px 0; }
.sa-section--alt { background: var(--surface-secondary); }
.sa-head { text-align: center; max-width: 600px; margin: 0 auto 44px; }
.sa-head--left { text-align: left; max-width: 460px; margin: 0; }
.sa-eyebrow {
  display: inline-block;
  font-size: var(--font-size-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-label);
  color: var(--color-primary);
  margin-bottom: 12px;
}
.sa-eyebrow--light { color: var(--color-primary-light); }
.sa-title {
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 3.5vw, 2.25rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--color-gray-900);
  margin: 0 0 12px;
}
.sa-sub { font-size: var(--font-size-lg); line-height: 1.6; color: var(--color-gray-600); margin: 0; }

/* ── Steps ────────────────────────────────────────────── */
.sa-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.sa-step {
  background: var(--color-white);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-2xl);
  padding: 32px 26px;
  text-align: center;
  transition: transform var(--transition-fast) var(--ease-out),
              box-shadow var(--transition-fast) var(--ease-out),
              border-color var(--transition-fast) var(--ease-out);
}
.sa-step:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--border-strong); }
.sa-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-xl);
  margin-bottom: 18px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--font-size-xl);
  color: var(--color-white);
  background: linear-gradient(160deg, var(--color-primary-light), var(--color-primary-dark));
  box-shadow: 0 12px 26px -8px rgba(var(--color-primary-rgb), 0.6);
}
.sa-step__title { font-family: var(--font-display); font-weight: 700; font-size: var(--font-size-lg); color: var(--color-gray-900); margin: 0 0 9px; }
.sa-step__text { font-size: var(--font-size-sm); line-height: 1.65; color: var(--color-gray-600); margin: 0; }

/* ── Task types ───────────────────────────────────────── */
.sa-tasks { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
/* Three across for the capability grid, which has eight cards rather than four. */
.sa-tasks--three { grid-template-columns: repeat(3, 1fr); }
/* Names the surface the feature lives on, above its heading, so the reader can
   scan by where they already are rather than by feature name. */
.sa-task__where {
  display: block;
  margin-bottom: 6px;
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-primary);
}
/* Paid marker. Per the velvet rope rule the feature stays normally styled and
   the gold crown is the only premium signal. */
.sa-crown {
  display: block;
  margin-top: 10px;
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--color-gray-500);
}
.sa-crown i { color: var(--color-warning); margin-right: 5px; }
.sa-task {
  position: relative;
  overflow: hidden;
  background: var(--color-white);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-2xl);
  padding: 28px;
  transition: transform var(--transition-fast) var(--ease-out),
              box-shadow var(--transition-fast) var(--ease-out);
}
.sa-task::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 3px;
  background: linear-gradient(90deg, var(--color-primary-light), var(--color-primary));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--transition-normal) var(--ease-out);
}
.sa-task:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.sa-task:hover::before { transform: scaleX(1); }
.sa-task__icon {
  width: 52px;
  height: 52px;
  border-radius: var(--radius-xl);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xl);
  color: var(--color-primary);
  background: linear-gradient(160deg, var(--color-primary-soft), var(--surface-indigo-light));
  margin-bottom: 18px;
}
.sa-task__title { font-family: var(--font-display); font-weight: 700; font-size: var(--font-size-lg); color: var(--color-gray-900); margin: 0 0 8px; }
.sa-task__text { font-size: var(--font-size-sm); line-height: 1.6; color: var(--color-gray-600); margin: 0; }

/* ═══════════════════════════════════════════════════════
   SAFETY BAND (dark)
   ═══════════════════════════════════════════════════════ */
.sa-safety {
  position: relative;
  overflow: hidden;
  padding: 84px 0;
  background: linear-gradient(180deg, var(--surface-indigo-dark), var(--surface-indigo-deep));
}
.sa-safety__aura {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(50% 55% at 50% 0%, rgba(var(--color-primary-rgb), 0.40), transparent 70%);
}
.sa-safety__inner { position: relative; z-index: 1; text-align: center; }
.sa-safety__title {
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 3.5vw, 2.25rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--color-white);
  margin: 0 0 12px;
}
.sa-safety__sub {
  font-size: var(--font-size-lg);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.7);
  max-width: 540px;
  margin: 0 auto 48px;
}
.sa-pillars { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.sa-pillar__icon {
  width: 60px;
  height: 60px;
  margin: 0 auto 18px;
  border-radius: var(--radius-xl);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-2xl);
  color: var(--color-white);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
.sa-pillar__title { font-family: var(--font-display); font-weight: 700; font-size: var(--font-size-lg); color: var(--color-white); margin: 0 0 9px; }
.sa-pillar__text { font-size: var(--font-size-sm); line-height: 1.65; color: rgba(255, 255, 255, 0.75); margin: 0 auto; max-width: 300px; }

/* ═══════════════════════════════════════════════════════
   PERMISSION (two-column on desktop)
   ═══════════════════════════════════════════════════════ */
.sa-perm { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: 44px; align-items: start; }
.sa-perm__card {
  background: var(--color-white);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-2xl);
  padding: 32px;
  box-shadow: var(--shadow-md);
}
.sa-perm__lead { margin: 0; font-size: var(--font-size-base); line-height: 1.7; color: var(--color-gray-700); }
.sa-perm__list { list-style: none; margin: 20px 0 0; padding: 0; }
.sa-perm__list li {
  position: relative;
  padding-left: 34px;
  margin-bottom: 16px;
  font-size: var(--font-size-sm);
  line-height: 1.65;
  color: var(--color-gray-700);
}
.sa-perm__list li:last-child { margin-bottom: 0; }
.sa-perm__list li i { position: absolute; left: 0; top: 3px; color: var(--color-success); font-size: 1.05rem; }
.sa-perm__list li strong { color: var(--color-gray-900); }
.sa-perm__foot {
  margin: 20px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--border-subtle);
  font-size: var(--font-size-sm);
  line-height: 1.65;
  color: var(--color-gray-600);
}

/* ═══════════════════════════════════════════════════════
   FINAL CTA (dark bookend)
   ═══════════════════════════════════════════════════════ */
.sa-final {
  position: relative;
  overflow: hidden;
  padding: 84px 0;
  background: linear-gradient(180deg, var(--surface-indigo-dark), var(--surface-indigo-deep));
}
.sa-final__aura {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(55% 60% at 50% 112%, rgba(var(--color-primary-rgb), 0.45), transparent 70%);
}
.sa-final__inner { position: relative; z-index: 1; text-align: center; }
.sa-final__mark { width: 56px; height: 56px; margin-bottom: 22px; }
.sa-final__title {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--color-white);
  margin: 0 0 12px;
}
.sa-final__sub { font-size: var(--font-size-lg); line-height: 1.6; color: rgba(255, 255, 255, 0.72); max-width: 520px; margin: 0 auto 28px; }
.sa-final__phone { font-size: var(--font-size-sm); color: rgba(255, 255, 255, 0.55); }

/* ═══════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════ */
/* ── Screenshot gallery ────────────────────────────────────────────────
   Real captures of the extension. Aspect ratios vary wildly (a 900x49 strip
   next to a 388x818 panel), so the grid aligns to the start rather than
   stretching, and every image scales on width with its height left to follow.
   Each img carries its real width and height so nothing jumps as it loads. */
/* A single stack, not side-by-side columns. Two columns of unequal content
   left a 400px hole at the bottom of the short one no matter which way the
   shots were dealt; stacking removes the problem instead of balancing it.
   The two upright captures pair up on one row, the wide ones run full width. */
.sa-gallery { display: grid; gap: 22px; }
.sa-gallery__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px;
  align-items: start;
}
/* min-width: 0 everywhere a grid child holds a horizontally scrollable image.
   Grid items default to min-width:auto, so the scroll container's content width
   pushes the whole column wider instead of scrolling inside it. */
.sa-gallery > *,
.sa-gallery__col > * { min-width: 0; }
.sa-gallery__col { display: grid; gap: 22px; align-content: start; min-width: 0; }
.sa-shot {
  margin: 0;
  background: var(--color-white);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-2xl);
  padding: 14px;
  transition: transform var(--transition-fast) var(--ease-out),
              box-shadow var(--transition-fast) var(--ease-out);
}
.sa-shot:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.sa-shot img {
  display: block;
  /* width:auto with a max, never width:100%. A 348px panel forced to fill its
     column upscaled to 902px on a phone and rendered as a blurry giant. */
  width: auto;
  max-width: 100%;
  height: auto;
  /* Upright captures are narrower than the wide column they sit in, so centre
     them rather than leaving a lopsided gap on one side. */
  margin-inline: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle);
}
.sa-shot figcaption {
  margin-top: 12px;
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--color-gray-600);
}
/* Wide captures scale down to an unreadable smudge on a phone. Below the
   breakpoint they keep a legible minimum width and scroll INSIDE their own
   card, the same treatment wide tables get. The page itself never scrolls
   sideways, which is the rule that matters. */
.sa-shot__scroll { display: block; }

/* ── Showcase rows ─────────────────────────────────────────────────────
   Replaces the eight-card capability grid AND the separate screenshot
   gallery. Both said the same things in the same shape, one after the other,
   and four consecutive centred-head-plus-card-row sections read as a wall.
   Here each capability we can actually show gets a full-width row with the
   screenshot on one side and the claim on the other, sides alternating down
   the page. The alternation is the whole point: it is the only thing that
   stops the eye settling into a rhythm and skipping.

   NOTE (Superset Rule): .sa-gallery, .sa-shot, .sa-steps and .sa-tasks above
   are no longer referenced by this template now that those sections are gone.
   They are left in place rather than deleted. Flagging, not removing. */
.sa-show { display: grid; gap: 72px; }
/* Image column deliberately wider than the copy column: the wide captures are
   900px natural and every pixel taken off them is legibility lost. */
.sa-show__row {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  gap: 48px;
  align-items: center;
}
/* Alternating sides. Order, not direction or row-reverse, so the DOM order
   stays the reading order for a screen reader and for the mobile stack. */
.sa-show__row--flip .sa-show__media { order: 2; }
.sa-show__row--flip .sa-show__copy { order: 1; }
/* min-width:0 on the media column. A grid item defaults to min-width:auto, so
   without this the scroll container's 700px content width pushes the whole
   column wider instead of scrolling inside it, and the page scrolls sideways. */
.sa-show__media { min-width: 0; }
.sa-show__fig {
  margin: 0;
  background: var(--color-white);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-2xl);
  padding: 14px;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition-fast) var(--ease-out),
              box-shadow var(--transition-fast) var(--ease-out);
}
.sa-show__fig:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
/* Upright captures (348px natural) sit at natural size, centred. width:auto
   with a max, NEVER width:100% — a 348px panel forced to fill its column
   upscaled to 900px of blur on a phone. */
.sa-show__img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle);
}
/* Wide captures are cropped to their content (620px and 660px, down from 900)
   so they fit the column whole on a computer with no scrollbar at all. A
   screenshot the reader can never see the end of is not proof of anything.
   Below the breakpoint they keep a legible width and scroll inside their own
   card, the wide-table pattern, with the affordance rules below. */
.sa-show__scrollwrap { display: block; position: relative; }
.sa-show__scroll { display: block; border-radius: var(--radius-lg); }
.sa-show__scroll img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle);
}
/* Only shown once the image actually scrolls, on a phone. */
.sa-show__swipe { display: none; }
.sa-show__copy { min-width: 0; }
.sa-show__where {
  display: inline-block;
  margin-bottom: 10px;
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-primary);
}
.sa-show__where i { margin-right: 6px; }
.sa-show__title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.25rem, 2.2vw, 1.625rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--color-gray-900);
  margin: 0 0 12px;
}
.sa-show__text { font-size: var(--font-size-base); line-height: 1.7; color: var(--color-gray-600); margin: 0; }

/* ── The rest, compactly ───────────────────────────────────────────────
   The capabilities with no screenshot yet. A list, not a fifth card grid:
   they are real features, they are just not the reason anyone installs it,
   and giving them the same visual weight as the showcase rows is exactly
   what built the wall this redesign removed. */
.sa-more {
  margin-top: 72px;
  padding-top: 48px;
  border-top: 1px solid var(--border-default);
}
.sa-more__lead {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--font-size-lg);
  color: var(--color-gray-900);
  margin: 0 0 28px;
}
.sa-more__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 32px 44px;
}
.sa-more__item { display: flex; gap: 16px; align-items: flex-start; min-width: 0; }
.sa-more__icon {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-base);
  color: var(--color-primary);
  background: linear-gradient(160deg, var(--color-primary-soft), var(--surface-indigo-light));
}
.sa-more__body { min-width: 0; }
.sa-more__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--font-size-base);
  color: var(--color-gray-900);
  margin: 0 0 6px;
}
.sa-more__text { font-size: var(--font-size-sm); line-height: 1.65; color: var(--color-gray-600); margin: 0; }

/* ── The flight ────────────────────────────────────────────────────────
   A short camera flight through the product window, played once when the
   section scrolls into view. Everything here RESTS in its finished state, so
   the section reads as a normal, complete piece of the page with JavaScript
   off or under reduced motion. The .sa-flight--live class (added by
   extension-install-flight.js) is what turns it into an animation. */
.sa-flight {
  position: relative;
  isolation: isolate;
  padding: 0 0 72px;
  background: linear-gradient(180deg, var(--surface-indigo-dark) 0%, var(--surface-indigo-deep) 60%, var(--surface-indigo-dark) 100%);
}
.sa-flight__aura {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(50% 34% at 50% 32%, rgba(var(--color-primary-rgb), 0.34), transparent 72%),
    radial-gradient(38% 30% at 88% 66%, rgba(var(--color-info-rgb), 0.20), transparent 74%);
}
.sa-flight .sa-stage { margin-top: 0; padding-top: 56px; }

/* Narration under the window. Resting state shows the final line only. */
.sa-caps {
  position: relative;
  display: block;
  /* width: 100% matters: inside the flex column pin, the captions are
     absolutely positioned while live, so without it this box collapses to
     nothing and the text stacks one word per line. */
  width: 100%;
  max-width: 640px;
  margin: 30px auto 0;
  /* Same height whether the script runs or not. The captions become absolutely
     positioned once live, so a smaller resting height would shunt the page
     down by 26px the moment the animation arms. */
  min-height: 56px;
  padding: 0 16px;
  text-align: center;
}
.sa-cap {
  display: none;
  font-family: var(--font-display);
  font-size: var(--font-size-base);
  font-weight: 600;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.72);
}
.sa-cap--on { display: block; }

/* ── Live state (motion allowed) ──────────────────────────────────────
   The section keeps its normal height and never pins. The story plays once,
   on its own, when the section scrolls into view. An earlier version pinned
   the section and scrubbed the story from scroll position; that made the
   visitor drag the payoff out of a page whose only job is to earn an install
   click, so it was removed. Nothing here changes page height or scrolling. */
.sa-flight--live .sa-window {
  will-change: transform, opacity;
  transform-origin: 50% 60%;
}
/* The dock panel stays dark the whole time; its contents slide in on --dock-in
   (0 to 1, written by the script). Fading the panel itself would leave a blank
   white gap in the window, which reads as a rendering fault. */
.sa-flight--live .sa-dock > * {
  opacity: var(--dock-in, 1);
  transform: translate3d(calc((1 - var(--dock-in, 1)) * 36px), 0, 0);
  will-change: transform, opacity;
}
/* The Post button carries a standing pulse animation. A CSS animation always
   beats an inline style, so it silently swallowed the final beat's highlight.
   Standing it down while the story plays lets the last moment actually land. */
.sa-flight--live .sa-post { animation: none; transition: box-shadow 220ms ease; }

/* Word-by-word reveal of the shoutout as it is typed in. */
.sa-w { transition: opacity 260ms ease, color 260ms ease; }
.sa-flight--live .sa-w { opacity: 0.14; }
.sa-flight--live .sa-w--on { opacity: 1; }
/* The caret rides the last revealed word instead of sitting at the end. */
.sa-flight--live .sa-caret { display: none; }
.sa-flight--live .sa-w--edge::after {
  content: "";
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 3px;
  vertical-align: -0.15em;
  background: var(--color-primary);
  animation: sa-blink 1s step-end infinite;
}
@keyframes sa-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* Checklist items land with a small pop as each one ticks. */
.sa-flight--live .sa-done--on i { animation: sa-pop 320ms ease-out; }
@keyframes sa-pop {
  0% { transform: scale(0.5); opacity: 0; }
  60% { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Captions cross-fade during the flight rather than hard-swapping. */
.sa-flight--live .sa-cap {
  display: block;
  position: absolute;
  left: 16px;
  right: 16px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 200ms ease, transform 200ms ease;
}
/* The incoming caption waits for the outgoing one to clear. Without the delay
   both sentences sit at the same coordinates mid-fade and render as mush. */
.sa-flight--live .sa-cap--on {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 190ms;
}

/* Anyone who asks for less motion gets the finished state, full stop. */
@media (prefers-reduced-motion: reduce) {
  .sa-w { opacity: 1 !important; }
  .sa-w--edge::after { display: none !important; }
  .sa-cap { transition: none !important; }
  .sa-done--on i { animation: none !important; }
}

@media (max-width: 900px) {
  .sa-perm { grid-template-columns: 1fr; gap: 28px; }
  .sa-head--left { text-align: center; max-width: 600px; margin: 0 auto; }
  .sa-tasks--three { grid-template-columns: repeat(2, 1fr); }
  /* Below the wrap's full width the two columns get too narrow to carry a
     700px capture and a readable measure at the same time, so the rows stack
     while there is still room to read them. */
  .sa-show { gap: 56px; }
  .sa-show__row { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  /* Image first on every row once stacked. The flip is a two-column idea and
     alternating a single column just looks like a mistake. */
  .sa-show__row--flip .sa-show__media { order: 1; }
  .sa-show__row--flip .sa-show__copy { order: 2; }
  /* Once stacked, the figure and the copy get the same centred measure. Without
     this the upright 341px panel floated in an 812px card with 230px of white
     each side while the wide ones sat hard left in the same card, so two
     adjacent rows aligned two different ways. The cap also keeps the body copy
     off a 110-character line, which is well past readable. */
  .sa-show__fig,
  .sa-show__copy { max-width: 640px; margin-inline: auto; width: 100%; }
  .sa-more__list { gap: 28px 36px; }
}
@media (max-width: 767px) {
  .sa-wrap { padding: 0 16px; }
  .sa-hero { padding: 56px 0 48px; }
  .sa-hero__sub { font-size: var(--font-size-base); }
  .sa-stage { margin-top: 40px; }
  /* The story plays on phones too now that nothing pins. */
  .sa-flight { padding: 0 0 56px; }
  .sa-flight .sa-stage { padding-top: 40px; }
  .sa-caps { margin-top: 24px; padding: 0 16px; }
  .sa-cap { font-size: var(--font-size-sm); }
  .sa-window__body { flex-direction: column; }
  .sa-dock { flex-basis: auto; border-left: none; border-top: 1px solid rgba(255, 255, 255, 0.12); }
  .sa-section { padding: 56px 0; }
  .sa-section--alt { padding: 56px 0; }
  .sa-safety,
  .sa-final { padding: 60px 0; }
  .sa-steps { grid-template-columns: 1fr; }
  .sa-tasks { grid-template-columns: 1fr; }
  .sa-tasks--three { grid-template-columns: 1fr; }
  /* One column on a phone: the tall panel stops spanning rows and everything
     reads top to bottom at full width. */
  .sa-gallery { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .sa-shot { padding: 12px; }
  .sa-shot--wide .sa-shot__scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--radius-lg);
  }
  /* A fixed 620px, not the natural 900px: legible on a phone without making
     the reader drag through two thirds of a screenshot to see the end. */
  .sa-shot--wide .sa-shot__scroll img { width: 620px; min-width: 620px; max-width: none; }
  /* On a phone the wide captures scroll rather than shrink: 620px keeps the
     numbers readable, where scaling to fit a 343px card would not. */
  .sa-show__scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .sa-show__scroll img { width: 620px; min-width: 620px; max-width: none; margin-inline: 0; }
  /* A clipped screenshot with no cue reads as a broken image, so say it scrolls
     and show the edge softening. The fade must never eat the swipe itself. */
  .sa-show__scrollwrap::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 40px;
    pointer-events: none;
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--color-white));
  }
  .sa-show__swipe {
    display: block;
    margin-top: 10px;
    font-size: var(--font-size-xs);
    color: var(--color-gray-500);
  }
  .sa-show { gap: 44px; }
  .sa-show__fig { padding: 12px; }
  .sa-show__text { font-size: var(--font-size-sm); }
  .sa-more { margin-top: 48px; padding-top: 36px; }
  .sa-more__list { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .sa-pillars { grid-template-columns: 1fr; gap: 32px; }
  .sa-sub { font-size: var(--font-size-base); }
  .sa-perm__card { padding: 24px; }
  .sa-strip__inner { gap: 12px 28px; padding: 18px 16px; }
}

/* ═══════════════════════════════════════════════════════
   MID-PAGE INSTALL
   Sits between the light showcase rows and the dark safety band, so it stays
   light: two dark bands back to back would read as one long block and lose the
   rhythm the page is built on. Only rendered once webstoreUrl exists.
   ═══════════════════════════════════════════════════════ */
/* The first draft used --surface-secondary (#f8f9fb) against a #f8fafc page:
   a one-value difference, so the "pause" delivered no contrast at all and the
   badge read as another showcase paragraph. A flat indigo tint ties the moment
   to the CTA colour and actually separates. Flat, not a gradient. */
.sa-midcta {
  padding: 64px 0;
  background: #eef1fe;
  border-top: 1px solid #dcdffb;
  border-bottom: 1px solid #dcdffb;
}
.sa-midcta__inner { text-align: center; }
.sa-midcta__title {
  margin: 0 0 10px;
  font-family: var(--font-display);
  /* Matches the display spec every other heading on this page uses. It was
     rendering smaller and looser than the heading above it, which made the
     stop-and-act moment the weakest heading on screen. */
  font-size: clamp(1.375rem, 2.6vw, 1.75rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-weight: 800;
  color: var(--color-gray-900);
}
.sa-midcta__sub {
  margin: 0 auto 28px;
  max-width: 560px;
  width: 100%;
  font-size: var(--font-size-base);
  color: var(--color-gray-600);
  overflow-wrap: break-word;
}
/* The shared .sa-badge-img shadow is tuned for the dark hero. On this light
   band that weight reads as a smudge, so soften it here only. */
.sa-midcta .sa-badge-img { box-shadow: 0 10px 26px -14px rgba(15, 23, 42, 0.55); }
/* No trust line here on purpose. The first draft repeated the hero's sentence
   verbatim, and the section immediately below is "Our promise", which says the
   same thing a third time. Worse, its green shield icon was the only saturated
   colour in the band, so the eye landed under the badge instead of on it. */

@media (max-width: 767px) {
  .sa-midcta { padding: 44px 0; }
  .sa-midcta__sub { margin-bottom: 22px; font-size: var(--font-size-sm); }
}
