/* =============================================================
   Artsopolis Octave Theme — Submission Form Progress Meter

   The playful "how far along am I?" strip that sits above the
   /dashboard/submit-event/ form: a horizontal rail with one dot
   per required section, and above each dot a graphic that gets
   progressively larger from left to right. Each graphic lights up
   as its section is completed; when the last one lights up it
   plays a celebration (the gift box pops open with a small
   firework burst).

   Markup is built at runtime by assets/js/dashboard-form-progress.js
   from the tab rail's own state — see that file for why the two
   cannot drift apart. Everything here is styling only.

   Built on the theme's existing custom properties (--color-*,
   --space-*, --radius-*, --shadow-*) so it follows the Customizer
   Brand Kit like the rest of the front end. The five --ao-gift-*
   properties below are deliberately separate hooks: a site that
   wants a non-brand gift box can override just those in Additional
   CSS without touching anything else.
   ============================================================= */

.ao-form-progress {
  /* Smallest / largest rendered size of the step graphic. The per-step
     size is interpolated between these two by CSS (see __art below) from
     a plain 0-1 ratio the script sets on each step, which is what lets the
     responsive rules further down rescale the whole strip by changing two
     values instead of asking the script to re-measure anything. */
  --ao-art-min: 18px;
  --ao-art-max: 56px;

  /* Set by the script: number of steps, and completed/total as a 0-1
     ratio. Declared here so the rail still has sane values to calc()
     against for the one frame before the script runs. */
  --ao-step-count: 1;
  --ao-progress: 0;

  --ao-dot-size: 13px;

  /* Gift box palette — brand-following by default. */
  --ao-gift-box:    var(--color-accent);
  --ao-gift-lid:    var(--color-primary);
  --ao-gift-ribbon: var(--color-paper);
  --ao-gift-spark:  var(--color-primary);
  --ao-gift-shadow: rgba(0, 0, 0, 0.38);

  margin: 0 0 var(--space-6);
  padding: var(--space-5) var(--space-6);
  /* Horizontal only, and `clip` rather than `hidden` so the vertical axis
     stays visible: the celebration's sparks are meant to fly up out of the
     card, but on a narrow screen the last step sits close enough to the
     right edge that letting them fly sideways too would widen the page.
     A browser without `clip` ignores this and simply keeps the old
     behaviour. */
  overflow-x: clip;
  background: var(--color-bg-card);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.ao-form-progress__heading {
  margin: 0 0 var(--space-5);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
}

/* -----------------------------------------------------------------------
   Meter — rail + steps

   aria-hidden in the markup: the tab rail already tells assistive tech
   which sections are complete (role="tab" plus the .is-complete
   checkmark), and the __status line below states the count in words. A
   second, purely decorative copy of the same information would only add
   noise, and the steps are deliberately not interactive for the same
   reason — the tab rail is the navigation.
   ----------------------------------------------------------------------- */
.ao-form-progress__meter {
  position: relative;
}

/* The horizontal line. Inset by half a step at each end so it starts and
   finishes at the centre of the first and last dot rather than running off
   past them — each step is an equal-width flex child, so half a step is
   50% / (number of steps). */
.ao-form-progress__rail {
  position: absolute;
  left: calc(50% / var(--ao-step-count));
  right: calc(50% / var(--ao-step-count));
  bottom: calc(var(--ao-dot-size) / 2 - 1px);
  height: 2px;
  border-radius: 2px;
  background: var(--color-rule);
  overflow: hidden;
}

.ao-form-progress__rail-fill {
  display: block;
  height: 100%;
  width: calc(var(--ao-progress) * 100%);
  border-radius: 2px;
  background: var(--color-accent);
  transition: width 420ms cubic-bezier(0.25, 0.8, 0.35, 1);
}

.ao-form-progress__steps {
  position: relative;
  display: flex;
  align-items: stretch; /* every step as tall as the biggest graphic … */
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ao-form-progress__step {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Column flex: align-items is the HORIZONTAL axis here and
     justify-content the vertical one. Bottom-justifying is what lines
     every dot up on the rail no matter how tall its graphic is. */
  align-items: center;
  justify-content: flex-end;
  gap: 7px;
  list-style: none;
}

/* Sized explicitly in both dimensions. The theme's global
   `img, video, svg { height: auto }` responsive-media reset collapses any
   inline SVG that is only given a width, so the box gets a real height and
   the SVG inside is pinned to 100% of it. */
.ao-form-progress__art {
  display: block;
  width: calc(var(--ao-art-min) + (var(--ao-art-max) - var(--ao-art-min)) * var(--ao-art-t, 0));
  height: calc(var(--ao-art-min) + (var(--ao-art-max) - var(--ao-art-min)) * var(--ao-art-t, 0));
  /* Sparks fly outside the graphic's own box during the celebration. */
  overflow: visible;
  transition: filter 260ms ease, opacity 260ms ease;
  filter: grayscale(1);
  opacity: 0.32;
}

.ao-form-progress__art svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.ao-form-progress__step.is-complete .ao-form-progress__art {
  filter: none;
  opacity: 1;
  animation: ao-progress-pop 460ms cubic-bezier(0.34, 1.42, 0.5, 1) both;
}

.ao-form-progress__dot {
  flex-shrink: 0;
  width: var(--ao-dot-size);
  height: var(--ao-dot-size);
  border-radius: 50%;
  background: var(--color-bg-card);
  border: 2px solid var(--color-rule);
  box-sizing: border-box;
  transition: background-color 260ms ease, border-color 260ms ease, transform 260ms ease;
}

.ao-form-progress__step.is-complete .ao-form-progress__dot {
  background: var(--color-accent);
  border-color: var(--color-accent);
  transform: scale(1.12);
}

/* -----------------------------------------------------------------------
   Status line — the accessible half of the meter.
   ----------------------------------------------------------------------- */
.ao-form-progress__status {
  margin: var(--space-4) 0 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-ink-muted);
  text-align: center;
}

.ao-form-progress.is-finished .ao-form-progress__status {
  color: var(--color-success);
}

/* -----------------------------------------------------------------------
   Gift box graphic
   ----------------------------------------------------------------------- */
.ao-gift__inside   { fill: var(--ao-gift-shadow); }
.ao-gift__body     { fill: var(--ao-gift-box); }
.ao-gift__ribbon   { fill: var(--ao-gift-ribbon); }
.ao-gift__lid-base { fill: var(--ao-gift-lid); }

/* The bow is the one piece of ribbon that does NOT sit on top of the box —
   it rises above the lid onto the page behind. --ao-gift-ribbon defaults to
   the paper colour, which would make it invisible there, so it carries the
   lid colour as an outline. That keeps the ribbon reading as one continuous
   colour across the whole graphic while still having an edge against the
   card, whatever the Brand Kit sets those two colours to. */
.ao-gift__bow {
  fill: var(--ao-gift-ribbon);
  stroke: var(--ao-gift-lid);
  stroke-width: 2;
  stroke-linejoin: round;
}

.ao-gift__lid {
  /* view-box units, so the origin is stated in the same coordinates as the
     shape data rather than in the element's own bounding box. */
  transform-box: view-box;
  transform-origin: 32px 26px;
}

/* Both celebration layers rest at scale(0), not merely at opacity 0.
   The sparks are authored outside the 64-unit viewBox and the SVG is
   overflow:visible, so at their authored size they widen the page's scroll
   box — invisibly, but enough to put a horizontal scrollbar on a phone.
   Collapsing them to a point takes them out of the overflow calculation
   until the animation actually scales them up. */
.ao-gift__ring {
  fill: none;
  stroke: var(--ao-gift-spark);
  stroke-width: 3.5;
  opacity: 0;
  transform: scale(0);
  transform-box: view-box;
  transform-origin: 32px 22px;
}

.ao-gift__sparks {
  fill: var(--ao-gift-spark);
  opacity: 0;
  transform: scale(0);
  transform-box: view-box;
  transform-origin: 32px 22px;
}

/* Celebration — fired once by the script when the final step completes.
   .is-burst plays it; .is-open is the resting state it leaves behind (and
   the state the strip loads straight into when a form is already complete
   on arrival, e.g. reopening a finished draft). */
.ao-form-progress__step.is-burst .ao-gift__lid {
  animation: ao-progress-lid 1000ms cubic-bezier(0.3, 1.5, 0.45, 1) forwards;
}

.ao-form-progress__step.is-burst .ao-gift__sparks {
  animation: ao-progress-sparks 950ms cubic-bezier(0.2, 0.75, 0.3, 1) forwards;
}

.ao-form-progress__step.is-burst .ao-gift__ring {
  animation: ao-progress-ring 700ms cubic-bezier(0.2, 0.8, 0.3, 1) forwards;
}

.ao-form-progress__step.is-open .ao-gift__lid {
  transform: translateY(-13px) rotate(-12deg);
}

@keyframes ao-progress-pop {
  0%   { transform: scale(0.72); }
  62%  { transform: scale(1.16); }
  100% { transform: scale(1); }
}

@keyframes ao-progress-lid {
  0%   { transform: translateY(0) rotate(0deg); }
  38%  { transform: translateY(-19px) rotate(-16deg); }
  100% { transform: translateY(-13px) rotate(-12deg); }
}

/* The sparks stay at full opacity through most of their travel and only
   fade at the very end. Fading them across the whole run — which is the
   more obvious way to write this — spends the entire visible half of the
   animation at both low opacity AND small scale, which at this size is
   indistinguishable from nothing happening. */
@keyframes ao-progress-sparks {
  0%   { transform: scale(0.25); opacity: 0; }
  14%  { opacity: 1; }
  66%  { opacity: 0.95; }
  100% { transform: scale(1.5); opacity: 0; }
}

@keyframes ao-progress-ring {
  0%   { transform: scale(0.2); opacity: 0.9; }
  100% { transform: scale(1.35); opacity: 0; }
}

/* -----------------------------------------------------------------------
   Responsive — the strip keeps every step and shrinks the graphics to
   fit. Two custom properties do the whole job; the per-step 0-1 ratio the
   script set stays valid at every size.
   ----------------------------------------------------------------------- */
@media (max-width: 900px) {
  .ao-form-progress {
    --ao-art-min: 13px;
    --ao-art-max: 40px;
    padding: var(--space-4) var(--space-5);
  }
}

@media (max-width: 600px) {
  .ao-form-progress {
    --ao-art-min: 9px;
    --ao-art-max: 26px;
    --ao-dot-size: 10px;
  }

  .ao-form-progress__step {
    gap: 5px;
  }

  .ao-form-progress__status {
    font-size: var(--text-xs);
  }
}

/* -----------------------------------------------------------------------
   Reduced motion — the meter still reports progress and the box still
   ends up open, it just gets there without any movement.
   ----------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ao-form-progress__rail-fill,
  .ao-form-progress__art,
  .ao-form-progress__dot {
    transition: none;
  }

  .ao-form-progress__step.is-complete .ao-form-progress__art,
  .ao-form-progress__step.is-burst .ao-gift__lid,
  .ao-form-progress__step.is-burst .ao-gift__sparks,
  .ao-form-progress__step.is-burst .ao-gift__ring {
    animation: none;
  }

  .ao-form-progress__step.is-burst .ao-gift__lid {
    transform: translateY(-13px) rotate(-12deg);
  }
}
