/* ══════════════════════════════════════════════════════════════════════════
   canon-sched-instant.css — instant status (feature_dispatch_instant_status,
   js/scheduler/jobmodal.js _setJobStatusInstant). The board shows a picked
   status before the server agrees; these mark the job while the save is out
   (a small pulsing dot), when it lands (a tick that fades) and when it fails
   and is put back (a short red wash). The classes only exist while the flag is
   on. Canon tokens only.
   ══════════════════════════════════════════════════════════════════════════ */
@layer components {
  .sched-app .is-saving[data-job-id], .sched-app .is-saved[data-job-id] { position: relative; }
  .sched-app .is-saving[data-job-id]::after,
  .sched-app .is-saved[data-job-id]::after {
    content: ''; position: absolute; top: var(--sp-1); right: var(--sp-1); z-index: 2; pointer-events: none;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--c-accent); box-shadow: 0 0 0 2px var(--c-card);
    animation: sched-instant-pulse .9s ease-in-out infinite;
  }
  .sched-app .is-saved[data-job-id]::after {
    background: var(--c-ok); animation: sched-instant-fade 1.4s linear forwards;
  }
  .sched-app .is-rollback[data-job-id] {
    box-shadow: inset 3px 0 0 var(--c-danger);
    animation: sched-instant-back 1.8s cubic-bezier(0, 0, .2, 1), sched-instant-shake .36s cubic-bezier(.2, .8, .2, 1);
  }
  @keyframes sched-instant-pulse { 50% { opacity: .3; } }
  @keyframes sched-instant-fade { 0%, 55% { opacity: 1; } 100% { opacity: 0; } }
  @keyframes sched-instant-back {
    0%, 30% { background-color: color-mix(in srgb, var(--c-danger) 16%, var(--c-card)); }
  }
  @keyframes sched-instant-shake {
    20% { translate: -3px 0; } 45% { translate: 3px 0; } 70% { translate: -1px 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .sched-app .is-saving[data-job-id]::after { animation: none; }
    .sched-app .is-rollback[data-job-id] { animation: sched-instant-back 1.8s linear; }
  }
}
