/* ══ JEP OS — motion layer ═══════════════════════════════════════════════════
   One place that defines how the system MOVES: modals, menus, views, buttons.
   Rules:
     • animate transform/opacity only — compositor work, no layout thrash, so it
       stays smooth on the shop tablets and inside the Tauri / WKWebView shells;
     • every duration and curve comes from the four tokens below — tune the whole
       feel in one spot, never hard-code a timing further down;
     • motion is decoration. Delete this block and the app behaves identically.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{
  --jm-fast: 130ms;          /* micro-feedback: presses, hovers            */
  --jm-base: 200ms;          /* the default: menus, popovers, view swaps   */
  --jm-slow: 300ms;          /* entrances that deserve a beat: modals      */
  --jm-out:  cubic-bezier(.16,1,.3,1);      /* expo-out — fast off the line, soft landing */
  --jm-in:   cubic-bezier(.6,0,.9,.2);      /* exits leave quicker than they arrived      */
  --jm-pop:  cubic-bezier(.34,1.32,.64,1);  /* a hair of overshoot, for things that "snap" */
}

@keyframes jmFade   { from{opacity:0} to{opacity:1} }
@keyframes jmFadeOut{ from{opacity:1} to{opacity:0} }
@keyframes jmRise   { from{opacity:0;transform:translate3d(0,10px,0)} to{opacity:1;transform:none} }
@keyframes jmModalIn { from{opacity:0;transform:translate3d(0,20px,0) scale(.975)} to{opacity:1;transform:none} }
@keyframes jmModalOut{ from{opacity:1;transform:none} to{opacity:0;transform:translate3d(0,8px,0) scale(.99)} }
@keyframes jmSheetIn { from{transform:translate3d(0,100%,0)} to{transform:none} }
@keyframes jmSheetOut{ from{transform:none} to{transform:translate3d(0,100%,0)} }
@keyframes jmPop    { from{opacity:0;transform:translate3d(0,-6px,0) scale(.97)} to{opacity:1;transform:none} }
@keyframes jmGrow   { from{transform:scaleY(0)} to{transform:scaleY(1)} }
@keyframes jmPill   { from{opacity:0;transform:scale(.88)} to{opacity:1;transform:none} }
@keyframes jmSweep  { from{transform:translateX(-100%)} to{transform:translateX(400%)} }

/* ── Pop-up windows ────────────────────────────────────────────────────────
   The scrim dims AND defocuses what's behind it, so the dialog reads as the only
   live surface on screen. .jm-closing is added by the motion script when `open`
   comes off, purely to give the exit somewhere to play — see the observer. */
.overlay{ background:rgba(10,24,35,.52); backdrop-filter:blur(7px) saturate(115%); -webkit-backdrop-filter:blur(7px) saturate(115%); }
.overlay.open{ animation:jmFade var(--jm-base) var(--jm-out) both; }
.overlay.open > .modal{ animation:jmModalIn var(--jm-slow) var(--jm-out) both; }
/* Drop the blur while closing: WebKit ignores pointer-events:none on an element
   that has a backdrop-filter, so a fading scrim would eat clicks in the desktop
   webview for the length of the exit. */
.overlay.jm-closing{ display:flex !important; animation:jmFadeOut var(--jm-fast) var(--jm-in) both; pointer-events:none;
  backdrop-filter:none; -webkit-backdrop-filter:none; }
.overlay.jm-closing > .modal{ animation:jmModalOut var(--jm-fast) var(--jm-in) both; }
.modal{ will-change:transform,opacity; }
/* Close button: a quarter turn is the cheapest "this is a modern app" signal there is. */
.modal-close{ transition:background var(--jm-fast) var(--jm-out), color var(--jm-fast) var(--jm-out), transform var(--jm-base) var(--jm-pop); }
.modal-close:hover{ transform:rotate(90deg); }

/* ── Views ────────────────────────────────────────────────────────────────
   Switching a tab re-adds .active, which replays this — the section lifts in
   instead of blinking into place. Container-level only: never per row, or a
   500-line job table would animate 500 elements. */
.tab-content.active{ animation:jmRise var(--jm-base) var(--jm-out) both; }

/* ── Menus that JS toggles with display ───────────────────────────────────
   none → block restarts a CSS animation, so these need no JS at all. */
.sub-tabs, .parts-results, .sr-job-dd, .fhelp-pop{ animation:jmPop var(--jm-fast) var(--jm-out) both; }

/* ── Nav rail ─────────────────────────────────────────────────────────────
   The active marker grows out of the rail rather than teleporting, and the whole
   button takes a press. */
.qnb{ transition:background var(--jm-fast) var(--jm-out), transform var(--jm-fast) var(--jm-out); }
.qnb:hover{ transform:translateY(-1px); }
.qnb:active{ transform:scale(.94); }
.qnb.active::before{ animation:jmGrow var(--jm-base) var(--jm-pop) both; box-shadow:0 0 10px var(--nav-color); }
.qnb svg{ transition:transform var(--jm-base) var(--jm-pop); }
.qnb.active svg{ transform:scale(1.12); }

/* ── Tabs / sub-tabs ──────────────────────────────────────────────────────── */
.nav-group, .sub-tab{ transition:color var(--jm-fast) var(--jm-out), background var(--jm-fast) var(--jm-out), transform var(--jm-fast) var(--jm-out); }
.nav-group:active, .sub-tab:active{ transform:scale(.97); }
.sub-tab.active, .nav-group.active{ animation:jmPill var(--jm-base) var(--jm-pop) both; }

/* ── Buttons ──────────────────────────────────────────────────────────────
   Every button answers the finger: down = press, up = release. */
.btn{ transition:background var(--jm-fast) var(--jm-out), box-shadow var(--jm-fast) var(--jm-out), transform var(--jm-fast) var(--jm-out), opacity var(--jm-fast) linear; }
.btn:hover:not(:disabled){ transform:translateY(-1px); }
.btn:active:not(:disabled){ transform:translateY(0) scale(.975); transition-duration:60ms; }
.btn:disabled{ transform:none !important; }
a:focus-visible, button:focus-visible, .btn:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible{
  outline:none; box-shadow:0 0 0 3px rgba(0,137,123,.35); }

/* ── Cards & rows ─────────────────────────────────────────────────────────── */
.home-widget, .order-card{ transition:box-shadow var(--jm-base) var(--jm-out), transform var(--jm-base) var(--jm-out); }
.home-widget:hover, .order-card:hover{ transform:translateY(-2px); box-shadow:0 10px 26px rgba(15,32,45,.10); }
.order-card.open .order-card-body{ animation:jmRise var(--jm-base) var(--jm-out) both; }
.order-chevron{ transition:transform var(--jm-base) var(--jm-pop); }
tr.clickable td, .data-table tbody tr td{ transition:background var(--jm-fast) linear; }

/* ── Toasts ───────────────────────────────────────────────────────────────── */
.toast-item{ transition:opacity var(--jm-base) var(--jm-out), transform var(--jm-base) var(--jm-out) !important; transform:translate3d(12px,8px,0); }
.toast-item.show{ transform:none; }

/* ── Global activity bar ──────────────────────────────────────────────────
   A 2px line under the header that says "the system is working" without a
   spinner parking itself in the middle of the screen. Driven by the fetch
   wrapper in the motion script; only appears if a call outlives 180ms. */
#jm-progress{ position:fixed; top:52px; left:0; right:0; height:2px; z-index:150000; pointer-events:none; opacity:0; transition:opacity var(--jm-base) var(--jm-out); overflow:hidden; }
#jm-progress.on{ opacity:1; }
#jm-progress::after{ content:''; position:absolute; inset:0; width:25%;
  background:linear-gradient(90deg,transparent,#00897b 35%,#4dd0c4 65%,transparent);
  animation:jmSweep 1.1s var(--jm-out) infinite; }

/* ── Mobile: dialogs are bottom sheets, so they arrive from the bottom ────── */
@media (max-width: 768px){
  .overlay.open > .modal{ animation:jmSheetIn var(--jm-base) var(--jm-out) both; }
  .overlay.jm-closing > .modal{ animation:jmSheetOut var(--jm-fast) var(--jm-in) both; }
  #qnb-more-sheet.open .qms-scrim{ animation:jmFade var(--jm-fast) var(--jm-out) both; }
  #qnb-more-sheet.open .qms-panel{ animation:jmSheetIn var(--jm-base) var(--jm-out) both; }
  #jm-progress{ top:52px; }
  .home-widget:hover, .order-card:hover, .qnb:hover, .btn:hover:not(:disabled){ transform:none; }  /* no hover state on a touchscreen */
}

/* ── Opt out ──────────────────────────────────────────────────────────────
   System setting wins over anything above: vestibular disorders are real and a
   shop tablet on a cart is a bad place to be made queasy. */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{ animation-duration:1ms !important; animation-iteration-count:1 !important; transition-duration:1ms !important; }
  .overlay{ backdrop-filter:none; -webkit-backdrop-filter:none; }
  .modal-close:hover, .qnb:hover, .btn:hover:not(:disabled), .home-widget:hover, .order-card:hover{ transform:none; }
}
