/* ============================================================
   AI PLANNER — single-input generator (Platzi-style)
   ============================================================ */
.aip--generator { padding: var(--space-24) 0; position: relative; overflow: hidden; }
.aip-video-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
  filter: saturate(1.2);
}
.aip-video-burn {
  /* color-burn dark blue — experimental; tint + scrim hidden in markup for now */
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--darkblue) 90%, transparent);
  mix-blend-mode: color-burn;
  z-index: 1;
  pointer-events: none;
}
.aip--generator > .wrap { position: relative; z-index: 3; }

.aip-gen {
  max-width: 1100px;
  margin: 0 auto;
  text-align: center;
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-5, 20px);
  min-height: 560px;
  /* Vertically centers the idle/submitted content via padding-top. When
     the journey result reveals (`is-result`), the padding animates to 0
     so the heading and lede move up to make room for the cards. */
  padding-top: 96px;
}
/* Override AOS's body-scoped transition rules (transform+opacity only)
   so padding-top also transitions when `.is-result` is added. Selector
   matches AOS's (0,2,1) specificity by adding the .aos-init class. */
.aip-gen.aos-init[data-aos] {
  transition-property: transform, opacity, padding-top;
  transition-duration: 1s, 1s, 900ms;
  transition-timing-function:
    cubic-bezier(0.25, 0.46, 0.45, 0.94),
    cubic-bezier(0.25, 0.46, 0.45, 0.94),
    cubic-bezier(0.22, 1, 0.36, 1);
}
.aip-gen.is-result { padding-top: 0; }
/* Form content stays at 720px max regardless of state — the constraint
   is on the content, not the state, so the input doesn't lateral-stretch
   when the section transitions to the submitted state. The journey
   cards below get the wider 1100px because they live outside this
   constrained group. The status row stays at its natural inline-flex
   width so its "pulse + text" stays grouped at the center. */
.aip-gen .aip-gen-h,
.aip-gen .aip-gen-sub,
.aip-gen .aip-gen-input-wrap,
.aip-gen .aip-gen-chips-hint,
.aip-gen .aip-gen-chips,
.aip-gen .aip-gen-echo {
  max-width: 720px;
  width: 100%;
}
.aip-gen-h {
  color: var(--white);
  text-wrap: balance;
}
.aip-gen-em {
  color: var(--aqua-500);
  font-weight: var(--font-bold);
}
.aip-gen-sub {
  font-size: var(--text-md);
  line-height: var(--leading-base);
  color: var(--white);
  max-width: 56ch;
}

.aip-gen-input-wrap {
  position: relative;
  width: 100%;
  margin-top: var(--space-4);
}
/* The form and progress live in the same slot. The visible one is in
   natural flow and drives the stack's height; the hidden one is
   absolutely positioned (top/left/width only — NOT inset:0, so it
   doesn't get force-stretched to the parent's height and visually
   squish during the fade). */
.aip-gen-stack {
  position: relative;
  width: 100%;
  margin-top: var(--space-4);
}
.aip-gen-form,
.aip-gen-progress {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  transition: opacity 420ms var(--ease-out);
}
.aip-gen-form { gap: var(--space-3); }
.aip-gen-progress { gap: var(--space-4); }
/* More breathing room before the primary CTA */
.aip-gen-form > .aip-gen-cta { margin-top: var(--space-6); }

/* Idle: form in flow, progress sits invisible at top-left (no inset:0
   so it keeps its natural height). */
.aip-gen-progress {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
}
/* Submitted: progress moves into flow, form becomes the hidden overlay
   (kept at its natural width via the 720px content constraint above, and
   its natural height because we're not setting inset:0). */
.aip-gen.is-submitted .aip-gen-form {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
}
.aip-gen.is-submitted .aip-gen-progress {
  position: relative;
  opacity: 1;
  pointer-events: auto;
}
/* Echo and status fade in (staggered) after the form has cleared, so
   they don't pop into place along with the parent container swap. */
.aip-gen-progress .aip-gen-echo,
.aip-gen-progress .aip-gen-status {
  opacity: 0;
}
.aip-gen.is-submitted .aip-gen-progress .aip-gen-echo {
  animation: aip-fade-in 600ms ease-out 360ms forwards;
}
.aip-gen.is-submitted .aip-gen-progress .aip-gen-status {
  animation: aip-fade-in 600ms ease-out 540ms forwards;
  /* Stagger so progress fades in after form fades out */
  transition: opacity 420ms var(--ease-out) 220ms;
}

.aip-gen-echo {
  margin: 0;
  font-size: var(--text-xl);
  line-height: var(--leading-xl);
  font-weight: var(--font-medium);
  color: var(--white);
  letter-spacing: -0.015em;
  max-width: 56ch;
  text-wrap: balance;
}
.aip-gen-echo::before { content: '“'; color: var(--aqua-500); margin-right: 2px; }
.aip-gen-echo::after  { content: '”'; color: var(--aqua-500); margin-left:  2px; }
.aip-gen-input {
  position: relative;
  width: 100%;
  background: var(--alpha-darkblue-20);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--aqua-500);
  border-radius: 16px;
  box-shadow: 0 0 16px var(--alpha-aqua-18);
  color: var(--white);
  padding: var(--space-5, 20px) var(--space-5, 20px);
  font-family: inherit;
  font-size: var(--text-base);
  line-height: var(--leading-base);
  resize: vertical;
  outline: none;
  transition:
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out),
    background var(--duration-base) var(--ease-out);
}
.aip-gen-input::placeholder { color: var(--alpha-white-70); }
.aip-gen-input:focus {
  border-color: var(--aqua-400);
  background: var(--alpha-darkblue-25);
  box-shadow: 0 0 32px var(--alpha-aqua-45);
}
.aip-gen-chips-hint {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--white);
  text-align: center;
}
.aip-gen-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: center;
}
.aip-gen-chip {
  height: 36px;
  padding: 0 var(--space-4);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--aqua-500);
  background: transparent;
  border: 1px solid var(--aqua-500);
  border-radius: var(--radius-full);
  cursor: pointer;
  transition:
    color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    background var(--duration-fast) var(--ease-out);
}
.aip-gen-chip:hover {
  color: var(--darkblue);
  border-color: var(--aqua-400);
  background: var(--aqua-400);
}
.aip-gen-chip.is-active {
  color: var(--darkblue);
  border-color: var(--aqua-500);
  background: var(--aqua-500);
}

.aip-gen-cta {
  background: var(--aqua-500);
  color: var(--darkblue);
  border-color: var(--aqua-500);
  font-weight: var(--font-bold);
  padding: 0 var(--space-6);
  transition:
    background var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out);
}
/* Hover: keep the fill, add an aqua outer glow that echoes the input's
   vocabulary. No color shift — depth, not lightening. */
.aip-gen-cta:hover {
  box-shadow: 0 0 16px var(--alpha-aqua-30);
}
/* Disabled (the CTA is disabled until the input has content): visible
   ghost outline with a faded aqua border, so the button reads as
   "AI is here, waiting for you to type" rather than disappearing
   entirely. Transition to enabled = transparent fill swooshes to solid
   aqua. Selector matches the aos reveal rule's specificity so it wins
   after the section animates in. */
.aip-gen-cta:disabled,
.aip-gen.aos-animate .aip-gen-form > .aip-gen-cta:disabled {
  background: transparent;
  border-color: var(--alpha-aqua-45);
  color: var(--alpha-aqua-45);
  box-shadow: none;
  cursor: not-allowed;
}
.aip-gen-cta .ms { color: inherit; }

.aip-gen-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  /* Fixed width matched to the longest cycling message so the pulse
     dot stays anchored as the text swaps in/out — only the text
     content changes, not the row's position. */
  width: 30ch;
  justify-content: flex-start;
  color: var(--aqua-500);
  font-size: var(--text-base);
  font-weight: var(--font-book);
  letter-spacing: 0.04em;
}
.aip-gen-status-text {
  white-space: nowrap;
  transition: opacity var(--duration-base) var(--ease-out);
}
.aip-gen-pulse {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--aqua-500);
  box-shadow: 0 0 12px var(--alpha-aqua-60);
  animation: aip-pulse-dot 1s ease-in-out infinite;
}
@keyframes aip-pulse-dot {
  0%, 100% { transform: scale(0.85); opacity: 0.5; }
  50%      { transform: scale(1.25); opacity: 1;   }
}

/* ---------- Journey preview ---------- */
/* The journey stays in DOM at zero height by default so the section
   grows smoothly when it reveals (max-height transition) rather than
   appearing as an instant jump. */
.aip-journey {
  width: 100%;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-height: 0;
  margin-top: 0;
  overflow: hidden;
  opacity: 0;
  transition:
    max-height 900ms cubic-bezier(0.22, 1, 0.36, 1),
    margin-top 900ms cubic-bezier(0.22, 1, 0.36, 1),
    opacity 600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.aip-journey.is-revealed {
  max-height: 1000px;
  margin-top: var(--space-4);
  opacity: 1;
}
/* Staggered reveal — triggered by .is-revealed on .aip-journey
   Sequence (post-loading):
     eyebrow      0 ms
     title      250 ms
     P1 card    500 ms   → badge pop 700 ms → border draw 900 ms
     P2 card    900 ms   → badge pop 1100 ms → border draw 1300 ms
     P3 card   1300 ms   → badge pop 1500 ms → border draw 1700 ms
     Save CTA  1700 ms
     Refine CTA 1900 ms
*/
/* Journey reveal — opacity-only fade, no transform (per the calm-motion
   principle). Exit is snappy (350 ms), entry is the slower 1 s cinematic
   fade. !important overrides AOS's body-scoped 1 s opacity+transform
   transition that gets stamped on the cards via [data-aos="fade"]. */
.aip-journey-phases .course-card,
.aip-journey .aip-gen-cta,
.aip-journey .aip-gen-refine {
  opacity: 0;
  transition: opacity 350ms var(--ease-out) !important;
}
.aip-journey.is-revealed .course-card,
.aip-journey.is-revealed .aip-gen-cta,
.aip-journey.is-revealed .aip-gen-refine {
  opacity: 1;
  transition: opacity 1000ms cubic-bezier(0.22, 1, 0.36, 1) !important;
}
.aip-journey.is-revealed .course-card:nth-child(1) { transition-delay: 200ms; }
.aip-journey.is-revealed .course-card:nth-child(2) { transition-delay: 400ms; }
.aip-journey.is-revealed .course-card:nth-child(3) { transition-delay: 600ms; }
.aip-journey.is-revealed .aip-gen-cta    { transition-delay: 1000ms; }
.aip-journey.is-revealed .aip-gen-refine { transition-delay: 1200ms; }

.aip-journey-phases {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
}

.aip-journey-cta {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
/* Visual order: Refine first (left), Save second (right).
   All visual styling now comes from .btn--secondary.on-dark in
   components.css — only the layout-order quirk lives here. */
.aip-gen-refine { order: -1; }

/* Ensure [hidden] wins over display overrides on flex/inline-flex */
.aip-gen-input-wrap[hidden],
.aip-gen-chips[hidden],
.aip-gen-cta[hidden],
.aip-gen-status[hidden],
.aip-journey[hidden] {
  display: none;
}

/* RESPONSIVE — journey result phases stack on smaller screens. */
@media (max-width: 1023px) {
  .aip-journey-phases { grid-template-columns: 1fr; }
}
