/* ── motion ──────────────────────────────────────────────────────────────────
   Paste this at the END of the <style> block in web/index.html.
   Nothing here changes layout or colour — every rule targets a class the app
   already renders, so it works with the existing innerHTML re-render model:
   each route rebuilds #view, which replays the entrance animations for free.
   All of it collapses under prefers-reduced-motion. */

@keyframes cc-rise   {from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes cc-slide  {from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
@keyframes cc-pop    {from{opacity:0;transform:scale(.82)}to{opacity:1;transform:scale(1)}}
@keyframes cc-cell   {from{opacity:0;transform:scale(.94) translateY(6px)}to{opacity:1;transform:none}}
@keyframes cc-fade   {from{opacity:0}to{opacity:1}}
@keyframes cc-growx  {from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes cc-growy  {from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes cc-sheen  {0%{transform:translateX(-130%) skewX(-18deg)}60%,100%{transform:translateX(280%) skewX(-18deg)}}
@keyframes cc-sweep  {0%{transform:translateX(-100%)}100%{transform:translateX(400%)}}
@keyframes cc-breathe{0%,100%{box-shadow:0 0 0 0 rgba(56,210,154,0)}50%{box-shadow:0 0 22px -4px rgba(56,210,154,.45)}}
@keyframes cc-halo   {0%,100%{opacity:.12}50%{opacity:.30}}

/* ease used everywhere, so the whole app moves with one hand */
:root{--cc-e:cubic-bezier(.2,.9,.3,1);--cc-eo:cubic-bezier(.2,1.4,.4,1)}

/* ── screen entrance ── */
#view > h2{animation:cc-rise .42s var(--cc-e) both}
#view > .nowcard{animation:cc-rise .55s var(--cc-e) both}
#view > .sum,#view > .cal,#view > .chart,#view > .card,#view > .mapwrap,
#view > .wrap,#view > .mslead,#view > .stat,#view > .legend,#view > .opcard,
#view > .dgrid,#view > .filters,#view > .mnav,#view > .pay{
  animation:cc-rise .5s var(--cc-e) .05s both}

/* summary tiles ripple across */
.sum .s{animation:cc-rise .45s var(--cc-e) both}
.sum .s:nth-child(1){animation-delay:.10s}.sum .s:nth-child(2){animation-delay:.15s}
.sum .s:nth-child(3){animation-delay:.20s}.sum .s:nth-child(4){animation-delay:.25s}
.sum .s:nth-child(5){animation-delay:.30s}.sum .s:nth-child(6){animation-delay:.35s}
.sum .s:nth-child(7){animation-delay:.40s}

/* stat / duty / kv tiles */
.stat .st2,.ops .op,.kv .b,.wg .wc{animation:cc-rise .46s var(--cc-e) both}
.stat .st2:nth-child(2),.ops .op:nth-child(2),.kv .b:nth-child(2),.wg .wc:nth-child(2){animation-delay:.05s}
.stat .st2:nth-child(3),.ops .op:nth-child(3),.kv .b:nth-child(3),.wg .wc:nth-child(3){animation-delay:.10s}
.stat .st2:nth-child(4),.ops .op:nth-child(4),.kv .b:nth-child(4),.wg .wc:nth-child(4){animation-delay:.15s}
.stat .st2:nth-child(5),.ops .op:nth-child(5),.kv .b:nth-child(5){animation-delay:.20s}
.stat .st2:nth-child(6),.ops .op:nth-child(6),.kv .b:nth-child(6){animation-delay:.25s}
.stat .st2:nth-child(7),.ops .op:nth-child(7){animation-delay:.30s}

/* rows arrive from the right, in order */
.fr,.person,.chg,.bid,.dutyrow{animation:cc-slide .42s var(--cc-e) both}
.fr:nth-of-type(2),.person:nth-of-type(2),.chg:nth-of-type(2),.bid:nth-of-type(2),.dutyrow:nth-of-type(2){animation-delay:.055s}
.fr:nth-of-type(3),.person:nth-of-type(3),.chg:nth-of-type(3),.bid:nth-of-type(3),.dutyrow:nth-of-type(3){animation-delay:.11s}
.fr:nth-of-type(4),.person:nth-of-type(4),.chg:nth-of-type(4),.bid:nth-of-type(4),.dutyrow:nth-of-type(4){animation-delay:.165s}
.fr:nth-of-type(5),.person:nth-of-type(5),.chg:nth-of-type(5),.bid:nth-of-type(5),.dutyrow:nth-of-type(5){animation-delay:.22s}
.fr:nth-of-type(n+6),.person:nth-of-type(n+6),.chg:nth-of-type(n+6),.bid:nth-of-type(n+6),.dutyrow:nth-of-type(n+6){animation-delay:.27s}

.trip{animation:cc-rise .48s var(--cc-e) both}
.trip:nth-of-type(2){animation-delay:.06s}.trip:nth-of-type(3){animation-delay:.12s}
.trip:nth-of-type(4){animation-delay:.18s}.trip:nth-of-type(n+5){animation-delay:.24s}
.trip .h{transition:background .18s ease}
.trip.open .legs{animation:cc-rise .34s var(--cc-e) both}
.trip .leg{animation:cc-fade .3s ease-out both}
.trip .leg:nth-of-type(2){animation-delay:.05s}.trip .leg:nth-of-type(3){animation-delay:.1s}
.trip .leg:nth-of-type(n+4){animation-delay:.15s}

/* ── the Now card: a slow sheen, so an airborne card never looks frozen ── */
.nowcard{position:relative;overflow:hidden}
.nowcard::after{
  content:'';position:absolute;top:0;bottom:0;left:0;width:40%;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.07),transparent);
  animation:cc-sheen 5s ease-in-out infinite}
:root[data-theme="light"] .nowcard::after{background:linear-gradient(90deg,transparent,rgba(13,20,33,.05),transparent)}

/* ── calendar: a wave across the columns, chips popping in behind it ── */
.cal .grid .cel{animation:cc-cell .44s var(--cc-e) both}
.cal .grid .cel:nth-child(7n+1){animation-delay:.02s}
.cal .grid .cel:nth-child(7n+2){animation-delay:.05s}
.cal .grid .cel:nth-child(7n+3){animation-delay:.08s}
.cal .grid .cel:nth-child(7n+4){animation-delay:.11s}
.cal .grid .cel:nth-child(7n+5){animation-delay:.14s}
.cal .grid .cel:nth-child(7n+6){animation-delay:.17s}
.cal .grid .cel:nth-child(7n+7){animation-delay:.20s}
.cel .chip{animation:cc-pop .36s var(--cc-eo) .22s both}
.cel .chip:nth-child(3){animation-delay:.28s}
.cel .chip:nth-child(4){animation-delay:.34s}
.cel .chip{transition:filter .15s ease,transform .15s ease}
.cel .chip:hover{filter:brightness(1.2);transform:translateX(1px)}
.legend{animation:cc-rise .5s var(--cc-e) .3s both}

/* ── bars and gauges grow from nothing ── */
.bar i,.rankrow .track2 i,.mslead .bar i,.msrow i,.grow i{
  transform-origin:left;animation:cc-growx .8s var(--cc-e) .12s both}
.rankrow:nth-of-type(2) .track2 i{animation-delay:.19s}
.rankrow:nth-of-type(3) .track2 i{animation-delay:.26s}
.rankrow:nth-of-type(4) .track2 i{animation-delay:.33s}
.rankrow:nth-of-type(n+5) .track2 i{animation-delay:.40s}
.gauge:nth-of-type(2) .bar i{animation-delay:.19s}
.gauge:nth-of-type(3) .bar i{animation-delay:.26s}
.gauge:nth-of-type(n+4) .bar i{animation-delay:.33s}

/* the month bar chart, out of the baseline */
.chart rect.cb{transform-box:fill-box;transform-origin:bottom;
  animation:cc-growy .65s var(--cc-e) both}
.chart rect.cb:nth-of-type(2){animation-delay:.04s}
.chart rect.cb:nth-of-type(3){animation-delay:.08s}
.chart rect.cb:nth-of-type(4){animation-delay:.12s}
.chart rect.cb:nth-of-type(5){animation-delay:.16s}
.chart rect.cb:nth-of-type(6){animation-delay:.20s}
.chart rect.cb:nth-of-type(7){animation-delay:.24s}
.chart rect.cb:nth-of-type(8){animation-delay:.28s}
.chart rect.cb:nth-of-type(n+9){animation-delay:.32s}
.chart text.cv,.chart text.cl2{animation:cc-fade .5s ease-out .35s both}

/* ── map ── */
.arc-flown{animation:cc-fade .9s ease-out .2s both}
.arc-rem{animation:cc-fade .9s ease-out .45s both}
.arc-net{animation:cc-fade 1s ease-out .1s both}
.arc-mine{animation:cc-fade .9s ease-out .25s both}   /* the personal network map */
.plane-halo{animation:cc-halo 2.6s ease-in-out infinite}
#planes > g{transition:transform .9s linear}

/* station photos never sit still */
.dest .ph{transition:transform 6s ease-out}
.dest:hover .ph{transform:scale(1.09)}

/* ── nav: the active tab lifts and its glyph springs ── */
nav a{transition:color .2s ease,background .28s var(--cc-e),transform .28s var(--cc-e)}
nav a .ic{transition:transform .3s var(--cc-eo)}
nav a.on{transform:translateY(-2px)}
nav a.on .ic{transform:scale(1.18)}
nav a:active{transform:scale(.94)}

/* ── press feedback ── */
.badge,.lo,.pill,.seg button,.mnav > button,.pushbtn,.wshare,.gcard button{
  transition:transform .12s ease,filter .15s ease,color .2s ease,border-color .2s ease,background .2s ease}
.badge:active,.lo:active,.pill:active,.seg button:active,
.mnav > button:active,.pushbtn:active,.wshare:active{transform:scale(.95)}
.badge.ok-flash{animation:cc-breathe 1.4s ease-out 1}

/* ── the sync bar (markup + wiring in motion.js) ── */
.syncbar{height:3px;border-radius:2px;background:var(--line2);overflow:hidden;
  margin:0 0 -3px;opacity:0;transition:opacity .35s ease;position:relative}
.syncbar.on{opacity:1}
.syncbar i{display:block;height:100%;width:100%;border-radius:2px;transform:scaleX(0);
  transform-origin:left;background:linear-gradient(90deg,var(--flt),var(--acc))}
/* Real syncs take minutes and the server reports no percentage, so the running
   state is deliberately indeterminate — a sweep, not a lie about progress. */
.syncbar.run i{width:34%;transform:none;animation:cc-sweep 1.15s linear infinite}
.syncbar.done i{width:100%;transform:scaleX(1);background:var(--air);
  transition:transform .45s var(--cc-e),background .3s ease}

/* ── the roster day flip (built by motion.js) ── */
.cel{perspective:700px}
.ccflip{position:relative;height:100%;transform-style:preserve-3d;
  transition:transform .55s cubic-bezier(.2,.85,.3,1)}
.cel.flipped .ccflip{transform:rotateY(180deg)}
.ccfront{backface-visibility:hidden;opacity:1;transition:opacity .01s linear .27s}
.cel.flipped .ccfront{opacity:0}
.ccback{position:absolute;inset:-5px -5px -6px;display:none;flex-direction:column;gap:1px;
  padding:5px 6px;overflow:hidden;background:var(--raise);transform:rotateY(180deg);
  backface-visibility:hidden;box-shadow:inset 0 0 0 1px var(--acc);opacity:0;
  transition:opacity .01s linear .27s}
.cel.flipped .ccback{display:flex;opacity:1}
.ccback .ct{font-family:var(--mono);font-size:8.5px;font-weight:800;letter-spacing:.4px;color:var(--acc)}
.ccback .ch{font-family:var(--mono);font-size:8.5px;font-weight:700;color:var(--txt);line-height:1.3}
.ccback .cs{font-family:var(--mono);font-size:8px;color:var(--dim);line-height:1.3;word-break:break-word}
@media(max-width:620px){
  .ccback{inset:-4px -3px -5px;padding:4px}
  .ccback .ct,.ccback .ch{font-size:8px}
  .ccback .cs{font-size:7.5px}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .ccfront{opacity:1}
  .cel.flipped .ccfront{display:none}
}
