/* Home hero — split layout with a rotating tool showcase.
   Built entirely from the tokens in styles.css, so it retints with
   body[data-product] like everything else. Nothing here overrides an existing
   rule, so the other pages are unaffected.

   IMPORTANT: every tool card is present in the markup and the first one is
   active by default in CSS. JavaScript only *moves* the active state. If the
   script never runs the hero still shows a complete tool — same rule as the
   note in site.js. */

/* The base .hero in styles.css is itself a two-column grid. Left as-is, the
   inner .split-in would become a grid *item* and collapse to one column's
   width, so this hero opts out and does its own layout. */
.hero.split {
  display: block;
  position: relative;
  overflow: hidden;
  padding: 40px 22px 64px;
}
/* styles.css gives any aurora-less hero a static glow; this one brings its own. */
.hero.split::before {
  content: none;
}

/* dotted field + soft corner glow, both decorative */
.hero-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: radial-gradient(currentColor 1px, transparent 1px);
  background-size: 26px 26px;
  color: rgba(19, 19, 19, 0.07);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 82%);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 82%);
}
.hero-bg::after {
  content: "";
  position: absolute;
  top: -22%;
  right: -12%;
  width: 46rem;
  height: 46rem;
  border-radius: 50%;
  background: radial-gradient(
    circle at 30% 30%,
    rgba(var(--accent-rgb), 0.13),
    rgba(var(--accent-2-rgb), 0.07) 45%,
    transparent 68%
  );
}

.split-in {
  position: relative;
  max-width: var(--max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 54px;
  align-items: center;
}

/* ── left column ── */

.brandline {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 18px 0 14px;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.02em;
}
.brandline img {
  border-radius: 9px;
}

.hero.split h1 {
  font-size: clamp(38px, 5.2vw, 62px);
  font-weight: 800;
  letter-spacing: -0.04em;
}
/* the accent phrase, underscored like a marker stroke */
.hero.split .mark {
  position: relative;
  color: var(--accent);
  white-space: nowrap;
}
.hero.split .mark::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.06em;
  height: 0.11em;
  border-radius: 999px;
  background: var(--accent-grad);
}

.hero.split .lede {
  margin: 22px 0 0;
  max-width: 30em;
  font-size: 17.5px;
  color: var(--text-2);
}
.hero.split .lede b {
  color: var(--text);
  font-weight: 650;
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

.hero-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
}
.hero-chips li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 15px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-2);
}
.hero-chips svg {
  width: 15px;
  height: 15px;
  color: var(--accent);
}

/* ── right column: the showcase ── */

.showcase {
  /* Each card sets --tool on itself; the frame reads it so the dots, the bar
     and the skeleton all retint together. */
  position: relative;
}

.showcase-stack {
  position: relative;
  isolation: isolate;
}
/* Cards are stacked; only the active one is visible. Height comes from the
   tallest card because they all occupy the same grid cell. */
.showcase-stack {
  display: grid;
}
.mock {
  grid-area: 1 / 1;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 22px;
  box-shadow: var(--shadow-2);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(0.985);
  transition:
    opacity 0.45s var(--ease),
    transform 0.45s var(--ease),
    visibility 0s linear 0.45s;
}
.mock.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
/* No-JS fallback: without the script nothing ever gets .is-active, so the
   first card must stand on its own. */
.no-js-active {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* ── the slides are the real interfaces ──
   The extension slides reuse the side-panel mockup already defined in
   styles.css. That markup is themed entirely through --accent-rgb / --accent /
   --accent-grad, so setting those on the slide retints the whole panel — which
   is how one set of CSS renders both BatchGPT blue and BatchGemini violet.
   The panel is flattened here: its own 3D tilt and shadow belong to the
   product pages, not inside a card that already has both. */
.showcase .mock {
  padding: 0;
  overflow: hidden;
}
.showcase .hero-shot {
  animation: none;
}
.showcase .panel {
  max-width: none;
  transform: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: var(--surface);
}

/* All three cards share one grid cell, so the row is as tall as the tallest of
   them — the watermark slide, which carries a before/after strip the others do
   not. Left alone the two extension cards ended up with ~80px of dead white
   below their content. Instead of trimming a card down to match, the panel is
   made to fill the row and its call-to-action is pushed to the bottom, so the
   slack turns into breathing room above the button. That also means a fourth
   tool of any height can be added later without reopening this. */
.showcase .mock {
  display: grid;
}
.showcase .hero-shot {
  height: 100%;
}
.showcase .panel {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.showcase .panel-body {
  padding: 16px;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.showcase .panel-body .p-btn {
  margin-top: auto;
}

/* ── the panel has to look like it is mid-run ──
   A frozen screenshot tells you what the tool looks like; a queue that is
   actually moving tells you what it does. Every one of these is driven by
   .is-active, so the run restarts each time the slide comes back round.
   All CSS — nothing here is required for the content to be readable. */

/* the progress bar fills up to whatever width the markup set */
.showcase .p-bar .fill {
  transform-origin: left center;
}
.mock.is-active .p-bar .fill {
  animation: bar-grow 1.7s var(--ease) 0.25s both;
}
@keyframes bar-grow {
  from {
    transform: scaleX(0.06);
  }
  to {
    transform: scaleX(1);
  }
}

/* queue rows drop in, the finished one first */
.mock.is-active .q {
  animation: row-in 0.5s var(--ease) both;
}
.mock.is-active .q.done {
  animation-delay: 0.3s;
}
.mock.is-active .q.live {
  animation-delay: 0.52s;
}
@keyframes row-in {
  from {
    opacity: 0;
    transform: translateY(7px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* the in-flight row keeps blinking, the way a real run does */
.mock.is-active .qs.run {
  animation: blink 1.3s ease-in-out 1s infinite;
}
@keyframes blink {
  50% {
    opacity: 0.4;
  }
}
.mock.is-active .q.live {
  animation:
    row-in 0.5s var(--ease) 0.52s both,
    live-ring 2s ease-in-out 1.2s infinite;
}
@keyframes live-ring {
  50% {
    box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.14);
  }
}

/* the prompt lines arrive one after another */
.mock.is-active .p-editor .tx {
  animation: line-in 0.45s var(--ease) both;
}
.mock.is-active .p-editor .tx:nth-of-type(1) {
  animation-delay: 0.1s;
}
.mock.is-active .p-editor .tx:nth-of-type(2) {
  animation-delay: 0.19s;
}
.mock.is-active .p-editor .tx:nth-of-type(3) {
  animation-delay: 0.28s;
}
@keyframes line-in {
  from {
    opacity: 0;
    transform: translateX(-5px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* the chosen aspect ratio lands last, like a click */
.mock.is-active .p-ratios .r.on {
  animation: pop 0.4s var(--ease) 0.5s both;
}
@keyframes pop {
  0% {
    transform: scale(0.86);
  }
  60% {
    transform: scale(1.05);
  }
  100% {
    transform: none;
  }
}

/* the panel's own status light */
.showcase .panel-dot {
  animation: breathe 2.4s ease-in-out infinite;
}
@keyframes breathe {
  50% {
    opacity: 0.45;
  }
}

/* ── watermark remover slide ── */

.wm-shots {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px;
}
.wm-shot {
  position: relative;
  /* Kept close to 3:2 on purpose: the watermark slide is the tallest of the
     three, and the row is as tall as its tallest card. Every pixel this strip
     gains becomes empty space on the other two. */
  aspect-ratio: 3 / 2;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.wm-shot .sky {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 72% 26%, rgba(255, 214, 150, 0.95), transparent 42%),
    linear-gradient(155deg, #21384f 0%, #7d5a45 52%, #2b3524 100%);
}
.wm-shot .sky::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(105deg, transparent 44%, rgba(255, 255, 255, 0.11) 47%, transparent 51%),
    radial-gradient(ellipse at 22% 82%, rgba(0, 0, 0, 0.42), transparent 55%);
}
.wm-shot .star {
  position: absolute;
  right: 9px;
  bottom: 9px;
  width: 20px;
  height: 20px;
  color: #fff;
  opacity: 0.78;
}
/* The whole point of the tool, shown rather than described: on the "after"
   tile the watermark lifts off once the slide comes into view. */
.mock.is-active .wm-shot .star.lifts {
  animation: wm-lift 1.5s var(--ease) 0.35s both;
}
@keyframes wm-lift {
  from {
    opacity: 0.78;
    transform: none;
  }
  to {
    opacity: 0;
    transform: scale(1.5);
  }
}
.wm-tag {
  position: absolute;
  top: 7px;
  left: 7px;
  padding: 2px 7px;
  border-radius: 5px;
  background: rgba(19, 19, 19, 0.62);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.wm-tag.ok {
  background: rgb(var(--accent-rgb));
}

.wm-drop {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 11px;
  border: 1px dashed var(--line-2);
  border-radius: 9px;
  background: var(--surface);
  font-size: 10.5px;
  color: var(--text-2);
}
.wm-drop b {
  color: var(--text);
  font-weight: 650;
}
.wm-drop .up {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 7px;
  background: rgba(var(--accent-rgb), 0.14);
  color: rgb(var(--accent-rgb));
  font-weight: 800;
  font-size: 11px;
}

.wm-status {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 12px 0 10px;
  padding: 8px 10px;
  border-radius: 9px;
  background: var(--ok-wash);
  color: var(--ok);
  font-size: 10.5px;
  font-weight: 650;
}
.wm-status .tick {
  font-size: 12px;
}
.wm-status span {
  margin-left: auto;
  color: var(--text-2);
  font-weight: 550;
}

.mock-head {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-bottom: 20px;
}
.mock-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 13px;
  background: rgba(var(--tool-rgb), 0.13);
  color: rgb(var(--tool-rgb));
}
.mock-icon svg {
  width: 22px;
  height: 22px;
}
.mock-name {
  font-weight: 700;
  font-size: 16.5px;
  letter-spacing: -0.02em;
}
.mock-sub {
  font-size: 13.5px;
  color: var(--text-2);
}

/* Skeleton rows standing in for the tool's own interface. */
.mock-body {
  display: grid;
  gap: 11px;
}
.sk {
  height: 11px;
  border-radius: 999px;
  background: var(--surface-3);
}
.sk-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.sk-row .sk {
  flex: none;
  width: 74px;
}
.sk-fill {
  flex: 1;
  height: 11px;
  border-radius: 999px;
  background: var(--surface-3);
  overflow: hidden;
}
/* The filled portion is the tool's accent — this is what makes each card read
   as a different product at a glance. */
.sk-fill i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: rgba(var(--tool-rgb), 0.55);
  width: var(--w, 60%);
  transform-origin: left center;
}
.mock.is-active .sk-fill i {
  animation: sk-grow 0.75s var(--ease) both;
}
@keyframes sk-grow {
  from {
    transform: scaleX(0.15);
  }
  to {
    transform: scaleX(1);
  }
}

.mock-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.mock-chip {
  width: 60px;
  height: 26px;
  border-radius: 8px;
  background: var(--surface-3);
}
.mock-chip.wide {
  width: 84px;
}
.mock-chip.go {
  margin-left: auto;
  width: 96px;
  background: rgba(var(--tool-rgb), 0.22);
}

/* ── dots + counter ── */

.showcase-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 20px 4px 16px;
}
.dots {
  display: flex;
  align-items: center;
  gap: 7px;
}
.dot-btn {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--line-2);
  cursor: pointer;
  transition: all 0.3s var(--ease);
}
.dot-btn.is-active {
  width: 30px;
  background: rgb(var(--tool-rgb));
}
.showcase-count {
  margin-left: auto;
  font-size: 13px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* ── the dark "open this tool" bar ── */

.showcase-bars {
  display: grid;
}
.showcase-bar {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 14px 16px;
  border-radius: 16px;
  background: var(--text);
  color: #fff;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition:
    opacity 0.45s var(--ease),
    transform 0.45s var(--ease),
    visibility 0s linear 0.45s;
}
.showcase-bar.is-active,
.showcase-bar.no-js-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
.showcase-bar:hover {
  filter: brightness(1.15);
}
.bar-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.1);
  color: rgb(var(--tool-rgb));
}
.bar-icon svg {
  width: 20px;
  height: 20px;
}
.bar-text {
  min-width: 0;
}
.bar-name {
  display: block;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.01em;
}
.bar-sub {
  display: block;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.62);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bar-go {
  margin-left: auto;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 15px;
  border-radius: 10px;
  background: rgb(var(--tool-rgb));
  color: #fff;
  font-size: 13.5px;
  font-weight: 650;
}

/* ── responsive ── */

@media (max-width: 940px) {
  .split-in {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }
  .hero.split {
    padding-top: 26px;
  }
  .showcase {
    max-width: 520px;
    width: 100%;
  }
}

@media (max-width: 560px) {
  .mock {
    padding: 17px;
    border-radius: 16px;
  }
  .bar-sub {
    display: none;
  }
  .hero-cta .btn {
    flex: 1 1 100%;
  }
}

/* Reduced motion kills every one of the "it's running" animations. They all use
   animation-fill-mode: both, so switching them off must leave the element in its
   normal state, not stuck on the invisible first frame — the exact failure the
   README warns about. Each rule below is checked for that. */
@media (prefers-reduced-motion: reduce) {
  .mock,
  .showcase-bar,
  .dot-btn {
    transition: none;
  }
  .mock.is-active .q,
  .mock.is-active .q.live,
  .mock.is-active .qs.run,
  .mock.is-active .p-editor .tx,
  .mock.is-active .p-ratios .r.on,
  .mock.is-active .p-bar .fill,
  .showcase .panel-dot {
    animation: none;
  }
  /* The "after" tile has to end up watermark-free — that is the whole point of
     the slide — so it is hidden outright rather than animated away. */
  .mock.is-active .wm-shot .star.lifts {
    animation: none;
    opacity: 0;
  }
}
