/*
 * Xiao Ao Travel — planning-flow motion system
 *
 * This is deliberately opt-in.  Add `.flow-motion` to a planning-flow root,
 * then add one of the `flow-motion--*` stage classes and
 * `data-flow-motion-state="enter"` only when that stage has just arrived.
 *
 * The scene is a visualisation of planning data (people, verified bookings,
 * fixed anchors, a day rhythm, and a departure checklist).  It is not a
 * destination image, a fake boarding pass, or a representation of a real
 * route.  Any meaningful flight, place, ticket, or person remains semantic
 * content outside this decorative layer.
 */

.flow-motion {
  --flow-motion-accent: #ef6d2b;
  --flow-motion-accent-soft: rgba(239, 109, 43, .16);
  --flow-motion-ink: #294860;
  --flow-motion-ink-soft: rgba(41, 72, 96, .14);
  --flow-motion-paper: rgba(255, 252, 248, .92);
  --flow-motion-line: rgba(176, 108, 69, .25);
  --flow-motion-duration: 680ms;
  --flow-motion-ease: cubic-bezier(.2, .8, .2, 1);
  position: relative;
  isolation: isolate;
}

.flow-motion--create { --flow-motion-accent: #ef6d2b; --flow-motion-ink: #294860; }
.flow-motion--companions { --flow-motion-accent: #f17a37; --flow-motion-ink: #2d4d66; }
.flow-motion--bookings { --flow-motion-accent: #d86d3b; --flow-motion-ink: #31536d; }
.flow-motion--anchors { --flow-motion-accent: #b97846; --flow-motion-ink: #64513f; }
.flow-motion--days { --flow-motion-accent: #e16a31; --flow-motion-ink: #315168; }
.flow-motion--prepare { --flow-motion-accent: #43845b; --flow-motion-ink: #355c46; }

/* Stage shell: a single visual field, rather than a small image appended to
 * a form. It can wrap `flow-motion__scene`, or coexist with the existing
 * `.journey-stage-visual` while the host migrates incrementally. */
.flow-motion :is(.flow-motion__scene, .journey-stage-visual) {
  position: relative;
  display: grid;
  min-width: 0;
  min-height: clamp(194px, 24vw, 310px);
  place-items: center;
  overflow: clip;
  border: 1px solid var(--flow-motion-line);
  border-radius: clamp(22px, 3vw, 38px);
  background:
    radial-gradient(ellipse at 16% 20%, var(--flow-motion-accent-soft), transparent 35%),
    radial-gradient(ellipse at 84% 78%, var(--flow-motion-ink-soft), transparent 41%),
    linear-gradient(134deg, rgba(255, 253, 250, .96), var(--flow-motion-paper));
  box-shadow: inset 0 1px rgba(255,255,255,.92), 0 18px 42px rgba(89, 58, 38, .07);
}

.flow-motion :is(.flow-motion__scene, .journey-stage-visual)::before,
.flow-motion :is(.flow-motion__scene, .journey-stage-visual)::after {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  content: "";
}

.flow-motion :is(.flow-motion__scene, .journey-stage-visual)::before {
  width: min(86%, 430px);
  height: min(72%, 224px);
  border: 1px solid var(--flow-motion-line);
  border-radius: 50% 46% 53% 47%;
  background: radial-gradient(ellipse at center, rgba(255,255,255,.78) 0 16%, transparent 56%);
  opacity: .9;
  transform: rotate(-8deg);
}

.flow-motion :is(.flow-motion__scene, .journey-stage-visual)::after {
  right: 7%;
  bottom: 18%;
  left: 7%;
  height: 1px;
  background: repeating-linear-gradient(90deg, var(--flow-motion-line) 0 6px, transparent 6px 15px);
  opacity: .84;
  transform: rotate(-6deg);
}

.flow-motion__scene > * { position: relative; z-index: 1; }

/* A route is intentionally abstract.  It gains no airport code, airline,
 * seat number or destination unless the adjacent semantic content has real
 * confirmed data to show those values. */
.flow-motion__route {
  position: absolute;
  inset: 48% 9% auto;
  height: 2px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--flow-motion-accent), var(--flow-motion-ink));
  transform: rotate(-5deg);
  transform-origin: left;
}
.flow-motion__route::after {
  position: absolute;
  top: -3px;
  right: -1px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--flow-motion-ink);
  box-shadow: 0 0 0 6px rgba(255,255,255,.78), 0 0 0 7px var(--flow-motion-ink-soft);
  content: "";
}

.flow-motion__node {
  position: absolute;
  top: calc(48% - 10px);
  width: 20px;
  height: 20px;
  border: 4px solid #fffdfa;
  border-radius: 50%;
  background: var(--flow-motion-accent);
  box-shadow: 0 0 0 6px var(--flow-motion-accent-soft), 0 10px 20px rgba(65, 42, 27, .11);
}
.flow-motion__node--start { left: 9%; }
.flow-motion__node--middle { left: calc(50% - 10px); background: var(--flow-motion-paper); box-shadow: 0 0 0 6px var(--flow-motion-ink-soft), 0 10px 20px rgba(65,42,27,.08); }
.flow-motion__node--end { right: 9%; background: var(--flow-motion-ink); box-shadow: 0 0 0 6px var(--flow-motion-ink-soft), 0 10px 20px rgba(65,42,27,.08); }

/* People are equal-width, equal-spacing avatar nodes.  Their presence only
 * communicates “companions are part of this step”; names and consent remain
 * in accessible card controls outside the artwork. */
.flow-motion__travellers {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: center;
  width: min(72%, 330px);
  height: 116px;
}
.flow-motion__travellers::before {
  position: absolute;
  right: 10%;
  left: 10%;
  height: 2px;
  background: linear-gradient(90deg, var(--flow-motion-accent), var(--flow-motion-ink));
  content: "";
}
.flow-motion__traveller {
  position: relative;
  justify-self: center;
  width: clamp(40px, 5vw, 58px);
  height: clamp(40px, 5vw, 58px);
  border: clamp(5px, .7vw, 8px) solid #fffdfa;
  border-radius: 50%;
  background: var(--flow-motion-accent);
  box-shadow: 0 12px 24px rgba(65,42,27,.12), 0 0 0 5px var(--flow-motion-accent-soft);
}
.flow-motion__traveller:nth-child(2) { background: var(--flow-motion-ink); box-shadow: 0 12px 24px rgba(65,42,27,.12), 0 0 0 5px var(--flow-motion-ink-soft); }
.flow-motion__traveller::after {
  position: absolute;
  inset: 31%;
  border-radius: inherit;
  background: #fffdfa;
  content: "";
}

/* Verified booking stage. The “ticket plane” remains geometric, with no
 * copied airline trade dress and no fabricated booking details. */
.flow-motion__ticket {
  position: relative;
  display: block;
  width: clamp(136px, 20vw, 178px);
  height: clamp(86px, 12vw, 112px);
  border: 1px solid var(--flow-motion-line);
  border-radius: 20px 38px 19px 34px;
  background: linear-gradient(135deg, rgba(255,255,255,.98), rgba(239,247,251,.84));
  box-shadow: 0 18px 30px rgba(42,68,89,.11);
  transform: perspective(600px) rotateX(54deg) rotateZ(-16deg);
}
.flow-motion__ticket::before,
.flow-motion__ticket::after {
  position: absolute;
  left: 15%;
  height: 1px;
  border-radius: 999px;
  background: var(--flow-motion-ink-soft);
  content: "";
}
.flow-motion__ticket::before { top: 35%; width: 56%; }
.flow-motion__ticket::after { top: 51%; width: 38%; }
.flow-motion__ticket-mark {
  position: absolute;
  top: 42%;
  left: calc(50% - 16px);
  width: 32px;
  height: 14px;
  border-radius: 85% 15% 64% 20%;
  background: var(--flow-motion-ink);
  transform: rotate(-18deg);
  box-shadow: -11px 7px 0 -7px var(--flow-motion-accent), 11px 7px 0 -7px var(--flow-motion-accent);
}

/* Fixed arrangements radiate from one decision point.  This communicates
 * protected constraints without implying a map accuracy or mileage. */
.flow-motion__anchor {
  position: relative;
  width: clamp(34px, 4vw, 44px);
  height: clamp(34px, 4vw, 44px);
  border: 7px solid #fffdfa;
  border-radius: 50% 50% 50% 0;
  background: var(--flow-motion-accent);
  box-shadow: 0 0 0 12px var(--flow-motion-accent-soft), 0 15px 24px rgba(70,48,32,.12);
  transform: rotate(-45deg);
}
.flow-motion__anchor::after { position: absolute; inset: 29%; border-radius: 50%; background: #fffdfa; content: ""; }
.flow-motion__anchor-radius {
  position: absolute;
  width: clamp(94px, 15vw, 136px);
  height: clamp(94px, 15vw, 136px);
  border: 1px solid var(--flow-motion-line);
  border-radius: 50%;
  opacity: .75;
}
.flow-motion__anchor-radius::before,
.flow-motion__anchor-radius::after { position: absolute; inset: 26% -8%; border: inherit; border-radius: inherit; content: ""; transform: rotate(38deg); }
.flow-motion__anchor-radius::after { inset: -8% 29%; transform: none; }

/* Daily planning is a legible rhythm of three slots, not a fake complete
 * itinerary. Real early/lunch/evening labels belong in adjacent data. */
.flow-motion__day-rhythm {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: end;
  width: min(74%, 310px);
  height: 118px;
  gap: clamp(18px, 4vw, 38px);
}
.flow-motion__day-rhythm::before {
  position: absolute;
  right: 0;
  bottom: 27px;
  left: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--flow-motion-accent-soft), var(--flow-motion-ink-soft));
  content: "";
}
.flow-motion__day-slot {
  position: relative;
  z-index: 1;
  display: block;
  height: 42px;
  border-radius: 999px 999px 10px 10px;
  background: linear-gradient(180deg, var(--flow-motion-accent), rgba(239,109,43,.55));
  box-shadow: 0 11px 19px rgba(62,44,31,.1);
}
.flow-motion__day-slot:nth-child(2) { height: 64px; background: linear-gradient(180deg, var(--flow-motion-ink), rgba(41,72,96,.58)); }
.flow-motion__day-slot:nth-child(3) { height: 51px; }

/* Departure readiness is a small stack of verified “carry-with-you” items.
 * It is not a replacement for real ticket / passport content. */
.flow-motion__checklist {
  position: relative;
  width: min(70%, 284px);
  height: 140px;
}
.flow-motion__check {
  position: absolute;
  width: clamp(61px, 9vw, 76px);
  height: clamp(78px, 11vw, 94px);
  border: 1px solid var(--flow-motion-line);
  border-radius: 14px;
  background: rgba(255,255,255,.9);
  box-shadow: 0 14px 23px rgba(65,43,29,.08);
}
.flow-motion__check::before,
.flow-motion__check::after { position: absolute; right: 19%; left: 19%; height: 1px; background: var(--flow-motion-line); content: ""; }
.flow-motion__check::before { top: 31%; }.flow-motion__check::after { top: 46%; width: 47%; }
.flow-motion__check--one { left: 12%; top: 15px; transform: rotate(-11deg); }
.flow-motion__check--two { right: 12%; top: 11px; transform: rotate(11deg); }
.flow-motion__check-beacon {
  position: absolute;
  z-index: 2;
  top: 36px;
  left: calc(50% - 20px);
  width: 40px;
  height: 40px;
  border: 7px solid #fffdfa;
  border-radius: 50%;
  background: var(--flow-motion-accent);
  box-shadow: 0 0 0 11px var(--flow-motion-accent-soft), 0 12px 18px rgba(70,46,30,.12);
}

/* One entrance, coordinated as a scene.  Nothing loops in normal use: a
 * completed planning action should settle, not keep demanding attention. */
@media (prefers-reduced-motion: no-preference) {
  .flow-motion[data-flow-motion-state="enter"] :is(.flow-motion__scene, .journey-stage-visual) {
    animation: flowMotionSceneIn var(--flow-motion-duration) var(--flow-motion-ease) both;
  }
  .flow-motion[data-flow-motion-state="enter"] :is(.flow-motion__scene, .journey-stage-visual)::before {
    animation: flowMotionHaloIn calc(var(--flow-motion-duration) + 90ms) 50ms var(--flow-motion-ease) both;
  }
  .flow-motion[data-flow-motion-state="enter"] :is(.flow-motion__scene, .journey-stage-visual)::after,
  .flow-motion[data-flow-motion-state="enter"] .flow-motion__route {
    animation: flowMotionRouteIn 560ms 120ms var(--flow-motion-ease) both;
    transform-origin: left center;
  }
  .flow-motion--companions[data-flow-motion-state="enter"] .flow-motion__traveller {
    animation: flowMotionNodeIn 440ms var(--flow-motion-ease) both;
  }
  .flow-motion--companions[data-flow-motion-state="enter"] .flow-motion__traveller:nth-child(2) { animation-delay: 90ms; }
  .flow-motion--companions[data-flow-motion-state="enter"] .flow-motion__traveller:nth-child(3) { animation-delay: 180ms; }
  .flow-motion--bookings[data-flow-motion-state="enter"] .flow-motion__ticket {
    animation: flowMotionTicketIn 640ms 150ms cubic-bezier(.17,.82,.25,1) both;
  }
  .flow-motion--bookings[data-flow-motion-state="enter"] .flow-motion__ticket-mark {
    animation: flowMotionMarkIn 430ms 330ms var(--flow-motion-ease) both;
  }
  .flow-motion--anchors[data-flow-motion-state="enter"] .flow-motion__anchor-radius {
    animation: flowMotionRadiusIn 580ms 180ms var(--flow-motion-ease) both;
  }
  .flow-motion--anchors[data-flow-motion-state="enter"] .flow-motion__anchor {
    animation: flowMotionAnchorIn 500ms 250ms var(--flow-motion-ease) both;
  }
  .flow-motion--days[data-flow-motion-state="enter"] .flow-motion__day-slot {
    animation: flowMotionSlotIn 460ms var(--flow-motion-ease) both;
    transform-origin: bottom;
  }
  .flow-motion--days[data-flow-motion-state="enter"] .flow-motion__day-slot:nth-child(2) { animation-delay: 100ms; }
  .flow-motion--days[data-flow-motion-state="enter"] .flow-motion__day-slot:nth-child(3) { animation-delay: 190ms; }
  .flow-motion--prepare[data-flow-motion-state="enter"] .flow-motion__check--one { animation: flowMotionCheckLeft 550ms 130ms var(--flow-motion-ease) both; }
  .flow-motion--prepare[data-flow-motion-state="enter"] .flow-motion__check--two { animation: flowMotionCheckRight 550ms 210ms var(--flow-motion-ease) both; }
  .flow-motion--prepare[data-flow-motion-state="enter"] .flow-motion__check-beacon { animation: flowMotionBeaconIn 470ms 350ms var(--flow-motion-ease) both; }
}

@keyframes flowMotionSceneIn { from { opacity: 0; transform: translateY(12px) scale(.982); } to { opacity: 1; transform: none; } }
@keyframes flowMotionHaloIn { from { opacity: 0; transform: rotate(-18deg) scale(.72); } to { opacity: .9; transform: rotate(-8deg) scale(1); } }
@keyframes flowMotionRouteIn { from { opacity: 0; transform: rotate(-5deg) scaleX(.08); } to { opacity: 1; transform: rotate(-5deg) scaleX(1); } }
@keyframes flowMotionNodeIn { from { opacity: 0; transform: translateY(13px) scale(.68); } to { opacity: 1; transform: none; } }
@keyframes flowMotionTicketIn { from { opacity: 0; transform: perspective(600px) rotateX(70deg) rotateZ(-28deg) translateY(26px); } to { opacity: 1; transform: perspective(600px) rotateX(54deg) rotateZ(-16deg); } }
@keyframes flowMotionMarkIn { from { opacity: 0; transform: translate(-24px, 14px) rotate(-25deg) scale(.7); } to { opacity: 1; transform: rotate(-18deg); } }
@keyframes flowMotionRadiusIn { from { opacity: 0; transform: scale(.32); } to { opacity: .75; transform: scale(1); } }
@keyframes flowMotionAnchorIn { from { opacity: 0; transform: rotate(-45deg) translate(13px,13px) scale(.68); } to { opacity: 1; transform: rotate(-45deg); } }
@keyframes flowMotionSlotIn { from { opacity: 0; transform: scaleY(.18); } to { opacity: 1; transform: scaleY(1); } }
@keyframes flowMotionCheckLeft { from { opacity: 0; transform: translate(28px,14px) rotate(-23deg); } to { opacity: 1; transform: rotate(-11deg); } }
@keyframes flowMotionCheckRight { from { opacity: 0; transform: translate(-28px,14px) rotate(23deg); } to { opacity: 1; transform: rotate(11deg); } }
@keyframes flowMotionBeaconIn { from { opacity: 0; transform: scale(.45); } 74% { opacity: 1; transform: scale(1.11); } to { opacity: 1; transform: scale(1); } }

/* The same responsive scene must remain clear rather than merely shrink. */
@media (max-width: 760px) {
  .flow-motion :is(.flow-motion__scene, .journey-stage-visual) {
    min-height: 196px;
    border-radius: 23px;
  }
  .flow-motion__route { right: 8%; left: 8%; }
  .flow-motion__node--start { left: 8%; }.flow-motion__node--end { right: 8%; }
  .flow-motion__travellers { width: min(82%, 288px); height: 102px; }
  .flow-motion__checklist { width: min(82%, 270px); height: 124px; }
}

@media (prefers-reduced-motion: reduce) {
  .flow-motion *,
  .flow-motion *::before,
  .flow-motion *::after {
    animation: none !important;
    scroll-behavior: auto !important;
    transition: none !important;
  }
}

/* High-contrast mode keeps the current step and its real controls usable.
 * Decorative geometry does not compete with forced system colours. */
@media (forced-colors: active) {
  .flow-motion :is(.flow-motion__scene, .journey-stage-visual) {
    border: 1px solid CanvasText;
    background: Canvas;
    box-shadow: none;
  }
  .flow-motion :is(.flow-motion__scene, .journey-stage-visual)::before,
  .flow-motion :is(.flow-motion__scene, .journey-stage-visual)::after,
  .flow-motion__route,
  .flow-motion__travellers::before,
  .flow-motion__day-rhythm::before,
  .flow-motion__anchor-radius { display: none; }
  .flow-motion__node,
  .flow-motion__traveller,
  .flow-motion__ticket,
  .flow-motion__anchor,
  .flow-motion__day-slot,
  .flow-motion__check,
  .flow-motion__check-beacon {
    forced-color-adjust: auto;
    border-color: CanvasText;
    background: Canvas;
    box-shadow: none;
  }
}
