/* Ports of res/anim/*.xml. Transform + opacity only, so the compositor handles it. */

/* content_slide_in_right (400ms) / content_slide_out_left (300ms) */
.screen-enter-active { animation: macSlideInRight 400ms var(--ease-standard) both; }
.screen-leave-active { animation: macSlideOutLeft  300ms var(--ease-accelerate) both;
                       position:absolute; inset:0; }
.screen-back-enter-active { animation: macSlideInLeft  400ms var(--ease-standard) both; }
.screen-back-leave-active { animation: macSlideOutRight 300ms var(--ease-accelerate) both;
                            position:absolute; inset:0; }

@keyframes macSlideInRight {
  from { transform: translateX(100%) scale(.95); opacity: 0; }
  75%  { opacity: 1; }
  to   { transform: translateX(0) scale(1); opacity: 1; }
}
@keyframes macSlideOutLeft {
  from { transform: translateX(0) scale(1); opacity: 1; }
  83%  { opacity: 0; }
  to   { transform: translateX(-100%) scale(.9); opacity: 0; }
}
@keyframes macSlideInLeft {
  from { transform: translateX(-100%) scale(.95); opacity: 0; }
  75%  { opacity: 1; }
  to   { transform: translateX(0) scale(1); opacity: 1; }
}
@keyframes macSlideOutRight {
  from { transform: translateX(0) scale(1); opacity: 1; }
  83%  { opacity: 0; }
  to   { transform: translateX(100%) scale(.9); opacity: 0; }
}

/* row_slide_in_3b — menu rows, 40ms stagger applied inline as --i */
.mac-row-in {
  animation: macRowIn 300ms var(--ease-decelerate) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}
@keyframes macRowIn {
  from { transform: translateX(-12%); opacity: 0; }
  73%  { opacity: 1; }
  to   { transform: translateX(0); opacity: 1; }
}

/* tile_scale_in_3b — most-used tiles, 40ms stagger */
.mac-tile-in {
  animation: macTileIn 340ms var(--ease-decelerate) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}
@keyframes macTileIn {
  from { transform: scale(.93) translateY(14%); opacity: 0; }
  70%  { opacity: 1; }
  to   { transform: scale(1) translateY(0); opacity: 1; }
}

/* fade_scale_in — list items */
.mac-fade-in {
  animation: macFadeIn 300ms var(--ease-decelerate) both;
  animation-delay: calc(var(--i, 0) * 30ms);
}
@keyframes macFadeIn {
  from { transform: scale(1.06); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

/* ---------------------------------------------------------------------------
   Dashboard stat tiles. Ports of HomeDashboardFragment.animateDashboardCards()
   and the two tab_slide_*.xml sets that run on the tile rows.

   NOT a port of res/anim/dashboard_staggered_fade_in.xml, despite the name:
   that file declares no startOffset, setStartOffset appears nowhere in the
   fragment, and all four of its callers use a hardcoded 1100ms. Its stagger is
   aspirational. The real one is the animate() chain below.
   --------------------------------------------------------------------------- */

/* animateDashboardCards(): delay += 100 per tile, then a 400ms
   translateY 30 -> 0, scale .95 -> 1, alpha 0 -> 1 on an
   AccelerateDecelerateInterpolator == cubic-bezier(.42, 0, .58, 1).

   The cap is real, not a nicety: the Java iterates a fixed array of seven
   findViewById calls, so the eighth tile onwards has no delay at all. --i is
   clamped to 6 at the call site to reproduce that. */
.mac-stat-in {
  animation: macStatIn 400ms cubic-bezier(.42, 0, .58, 1) both;
  animation-delay: calc(var(--i, 0) * 100ms);
}
@keyframes macStatIn {
  from { transform: translateY(30px) scale(.95); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}

/* tab_slide_right_to_left / tab_slide_left_to_right — the three tile ROWS,
   450ms, accelerate_decelerate, alternating direction per row. Five children in
   the XML: translateX +/-25%, a scale .85 -> 1.08 over 300ms, a second scale
   1.08 -> 1 with startOffset 300 (the only real startOffset in the dashboard
   set, hence the 66.7% keyframe), alpha .6 -> 1 over 300ms, and rotate +/-3deg.

   Rows animate together with the tiles inside them; the app does the same, and
   the compositor handles both as transforms on separate elements. */
.mac-row-slide {
  animation: macRowSlideR 450ms cubic-bezier(.42, 0, .58, 1) both;
}
.mac-row-slide--ltr { animation-name: macRowSlideL; }

@keyframes macRowSlideR {
  from  { transform: translateX(25%) scale(.85) rotate(3deg); opacity: .6; }
  66.7% { transform: translateX(0) scale(1.08) rotate(0deg); opacity: 1; }
  to    { transform: translateX(0) scale(1) rotate(0deg); opacity: 1; }
}
@keyframes macRowSlideL {
  from  { transform: translateX(-25%) scale(.85) rotate(-3deg); opacity: .6; }
  66.7% { transform: translateX(0) scale(1.08) rotate(0deg); opacity: 1; }
  to    { transform: translateX(0) scale(1) rotate(0deg); opacity: 1; }
}

/* shimmer_animation — skeletons */
.mac-skeleton {
  background: linear-gradient(90deg, var(--gray-bg) 25%,
              rgba(255,255,255,.35) 50%, var(--gray-bg) 75%);
  background-size: 200% 100%;
  animation: macShimmer 1.2s linear infinite;
  border-radius: 6px;
}
@keyframes macShimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* shake_error — wrong password */
.mac-shake { animation: macShake 400ms var(--ease-standard) both; }
@keyframes macShake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-9px); } 40% { transform: translateX(9px); }
  60% { transform: translateX(-5px); } 80% { transform: translateX(5px); }
}

/* login_logo_bounce */
.mac-logo-bounce { animation: macLogoBounce 700ms var(--ease-decelerate) both; }
@keyframes macLogoBounce {
  0%   { transform: scale(.4); opacity: 0; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Material touch ripple */
.mac-ripple { position: relative; overflow: hidden; }
.mac-ripple > .mac-ripple-ink {
  position: absolute; border-radius: 50%; transform: scale(0);
  background: currentColor; opacity: .18; pointer-events: none;
  animation: macInk 550ms var(--ease-decelerate) forwards;
}
@keyframes macInk { to { transform: scale(2.6); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .screen-enter-active, .screen-leave-active,
  .screen-back-enter-active, .screen-back-leave-active,
  .mac-row-in, .mac-tile-in, .mac-fade-in, .mac-shake, .mac-logo-bounce,
  /* The dashboard tiles: mac-stat-in translates and scales, mac-row-slide also
     rotates, and the whole row of them staggers. That is a lot of motion for
     someone who asked for none. */
  .mac-stat-in, .mac-row-slide, .ddue, .psheet, .psheet-bg, .pact,
  /* The ONU popup: a scale-in panel, two meters that grow from zero, seven
     staggered rows and a pulsing dot. All of it is decoration over a reading
     that is equally legible sitting still. */
  .omodal, .omodal-bg, .otile, .omac, .ogrid > div, .omodal__foot {
    animation: macFade 120ms linear both !important;
  }
  /* macFade has no transform, and the modal is half-width-shifted by one. */
  .omodal { transform: translateX(-50%) !important; }
  /* The fills must still SHOW their width — only the growing stops. */
  .otile__f { animation: none !important; }
  .omodal__dot i::before { animation: none !important; opacity: 0 !important; }
  /* The stagger is the point of --i; with everything fading at once there is
     nothing left to stagger, and a delay would just hold the screen empty. */
  .mac-stat-in { animation-delay: 0ms !important; }
  /* macFade has no transform, so the dialog would lose its centring. */
  .ddue { transform: translate(-50%, -50%) !important; }
  .mac-skeleton { animation: none; }
}
@keyframes macFade { from { opacity: 0; } to { opacity: 1; } }

/* The bottom sheet. Lived in billing.css, where every other screen's .psheet
   was quietly depending on it. */
@keyframes macSheetUp {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* Indeterminate spinner. Same story as macSheetUp: it lived in home.css, and
   the ONU sheet — a shared ui/ component — would have depended on the Home
   screen's stylesheet happening to be loaded. */
@keyframes macSpin { to { transform: rotate(360deg); } }

/* Live ONU Status. The pop is a scale-and-rise rather than the sheet's slide:
   it is a panel that arrives in the middle of the screen, not from an edge.
   onuGrow drives the two meter fills from zero, and onuPulse is the halo on
   the header's status dot. */
@keyframes onuPop {
  from { opacity: 0; transform: translateX(-50%) translateY(-10px) scale(.94); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
@keyframes onuGrow { from { width: 0; } }
@keyframes onuPulse {
  0%        { transform: scale(1); opacity: .55; }
  70%, 100% { transform: scale(2.6); opacity: 0; }
}
