/* Sakura motion (1.4.0)
   Motion explains what changed: a page arriving, a figure counting to its value, a route drawing from load point to
   destination, a truck moving on the map. It is quick (120-600 ms), settles softly, never blocks a tap, and switches
   off completely for anyone whose device asks for less motion. Colours come from the brand tokens. */

:root {
  --sk-ease-out: cubic-bezier(.16, 1, .3, 1);   /* arrives fast, settles softly */
  --sk-ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --sk-ease-spring: cubic-bezier(.34, 1.56, .64, 1); /* a small overshoot, for things that pop in */
  --sk-dur-1: 120ms;
  --sk-dur-2: 220ms;
  --sk-dur-3: 360ms;
  --sk-dur-4: 600ms;
}

@keyframes sk-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes sk-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes sk-rise-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes sk-drop-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@keyframes sk-grow-y { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes sk-grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes sk-draw { to { stroke-dashoffset: 0; } }
@keyframes sk-pop { 0% { opacity: 0; transform: scale(.4); } 100% { opacity: 1; transform: scale(1); } }
@keyframes sk-pulse-ring { 0% { transform: scale(.6); opacity: .55; } 100% { transform: scale(2.4); opacity: 0; } }
@keyframes sk-shimmer { from { background-position: 150% 0; } to { background-position: -50% 0; } }
@keyframes sk-sos-glow { 0%, 100% { box-shadow: 0 0 0 0 rgba(215, 38, 61, .55); } 50% { box-shadow: 0 0 0 10px rgba(215, 38, 61, 0); } }
@keyframes sk-nudge { 0%, 100% { transform: rotate(0); } 20% { transform: rotate(-14deg); } 40% { transform: rotate(10deg); } 60% { transform: rotate(-6deg); } 80% { transform: rotate(3deg); } }
@keyframes sk-check { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes sk-live { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* Loading placeholders: a soft sweep while live figures arrive (used by the trip plan, maps and lists) */
.sk-skeleton, .is-loading .sk-skeleton-text {
  color: transparent !important; border-radius: var(--sk-radius-sm);
  background: linear-gradient(90deg, var(--sk-surface-2) 25%, var(--sk-border) 37%, var(--sk-surface-2) 63%);
  background-size: 400% 100%;
}
.is-loading { position: relative; }
.is-loading::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--sk-indigo-100) 55%, transparent) 50%, transparent 100%);
  background-size: 200% 100%; opacity: .6;
}

/* A live dot: something on the screen refreshes by itself */
.live-dot { display: inline-flex; align-items: center; gap: .35rem; font-size: .78rem; color: var(--sk-text-muted); font-weight: 500; }
.live-dot::before { content: ""; width: .5rem; height: .5rem; border-radius: 50%; background: var(--sk-success); }

/* Close button on saved messages (added by motion.js) */
.alert { position: relative; }
.alert-close { margin-left: auto; flex: none; align-self: center; display: inline-grid; place-items: center; width: 28px; height: 28px;
  border: 0; border-radius: 50%; background: transparent; color: inherit; opacity: .7; cursor: pointer; padding: 0; }
.alert-close:hover, .alert-close:focus-visible { opacity: 1; background: color-mix(in srgb, currentColor 12%, transparent); }
.driver .alert-close { width: 40px; height: 40px; }
.check-anim { flex: none; }

/* A load on the road: a light travels along its route line */
.route-live .leg { overflow: visible; }
.route-live .leg > i { position: absolute; top: -2px; left: 0; width: 6px; height: 6px; border-radius: 50%;
  background: var(--sk-indigo-500); box-shadow: 0 0 0 3px color-mix(in srgb, var(--sk-indigo-500) 25%, transparent); }

.d-route-live .line > i { position: absolute; left: 3px; top: .5rem; width: 6px; height: 6px; border-radius: 50%; z-index: 1;
  background: var(--sk-indigo-500); box-shadow: 0 0 0 3px color-mix(in srgb, var(--sk-indigo-500) 25%, transparent); }

/* Sign-in map: the trucks' lights */
.auth-map .truck-light .halo { fill: var(--sk-indigo-300); opacity: .22; }
.auth-map .truck-light .dot { fill: #fff; }

/* Map pins of trucks reporting live */
.map-pin.live { position: relative; }
.map-pin.live::after { content: ""; position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px;
  border-radius: 50%; border: 2px solid var(--sk-indigo-500); pointer-events: none; opacity: 0; }

@media (prefers-reduced-motion: no-preference) {
  /* ---------- page to page: the menu and top bar stay, the page content changes underneath ---------- */
  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: sk-fade-out 90ms linear both; }
  ::view-transition-new(root) { animation: sk-fade-in 160ms var(--sk-ease-out) both; }
  .office > .sidebar { view-transition-name: sk-sidebar; }
  .office .appbar { view-transition-name: sk-appbar; }
  .office .content { view-transition-name: sk-content; }
  .driver .d-header { view-transition-name: sk-dheader; }
  .driver .bottom-nav { view-transition-name: sk-dnav; }
  .driver .d-main { view-transition-name: sk-dmain; }
  ::view-transition-group(sk-sidebar), ::view-transition-group(sk-appbar),
  ::view-transition-group(sk-dheader), ::view-transition-group(sk-dnav) { animation-duration: 0s; }
  ::view-transition-old(sk-content), ::view-transition-old(sk-dmain) { animation: sk-fade-out 100ms linear both; }
  ::view-transition-new(sk-content), ::view-transition-new(sk-dmain) { animation: sk-rise-in 260ms var(--sk-ease-out) both; }

  /* ---------- the first look at a page: panels arrive one after another ---------- */
  .kpis > *, .dash > *, .content > .grid > *, .content > .stack > section, .money-figures > * {
    animation: sk-rise-in var(--sk-dur-3) var(--sk-ease-out) both;
  }
  .kpis > :nth-child(2), .dash > :nth-child(2), .content > .grid > :nth-child(2), .money-figures > :nth-child(2) { animation-delay: 40ms; }
  .kpis > :nth-child(3), .dash > :nth-child(3), .content > .grid > :nth-child(3), .money-figures > :nth-child(3) { animation-delay: 80ms; }
  .kpis > :nth-child(4), .dash > :nth-child(4), .content > .grid > :nth-child(4), .money-figures > :nth-child(4) { animation-delay: 120ms; }
  .kpis > :nth-child(5), .dash > :nth-child(5), .content > .grid > :nth-child(5) { animation-delay: 160ms; }
  .kpis > :nth-child(6), .dash > :nth-child(6), .content > .grid > :nth-child(6) { animation-delay: 200ms; }
  .kpis > :nth-child(n+7), .dash > :nth-child(n+7), .content > .grid > :nth-child(n+7) { animation-delay: 240ms; }
  .content > .alert { animation: sk-drop-in var(--sk-dur-2) var(--sk-ease-out) both; }
  .alert.is-leaving { transition: opacity var(--sk-dur-2), transform var(--sk-dur-2), max-height var(--sk-dur-3) var(--sk-ease-in-out),
    margin var(--sk-dur-3) var(--sk-ease-in-out), padding var(--sk-dur-3) var(--sk-ease-in-out);
    opacity: 0; transform: translateY(-6px); max-height: 0 !important; margin-top: 0 !important; margin-bottom: 0 !important;
    padding-top: 0 !important; padding-bottom: 0 !important; overflow: hidden; }

  /* ---------- charts: bars rise from the axis, trend lines draw left to right, meters fill ---------- */
  .colchart .bar { transform-origin: 50% 100%; animation: sk-grow-y var(--sk-dur-4) var(--sk-ease-out) both; }
  .colchart-col:nth-child(2) .bar { animation-delay: 30ms; } .colchart-col:nth-child(3) .bar { animation-delay: 60ms; }
  .colchart-col:nth-child(4) .bar { animation-delay: 90ms; } .colchart-col:nth-child(5) .bar { animation-delay: 120ms; }
  .colchart-col:nth-child(6) .bar { animation-delay: 150ms; } .colchart-col:nth-child(7) .bar { animation-delay: 180ms; }
  .colchart-col:nth-child(8) .bar { animation-delay: 210ms; } .colchart-col:nth-child(9) .bar { animation-delay: 240ms; }
  .colchart-col:nth-child(10) .bar { animation-delay: 270ms; } .colchart-col:nth-child(11) .bar { animation-delay: 300ms; }
  .colchart-col:nth-child(12) .bar { animation-delay: 330ms; }
  .spark .spark-line { stroke-dasharray: 1; stroke-dashoffset: 1; animation: sk-draw 900ms var(--sk-ease-in-out) 200ms forwards; }
  .spark .spark-area { animation: sk-fade-in var(--sk-dur-4) ease 500ms both; }
  .meter > span, .bar-meter > span { transform-origin: 0 50%; animation: sk-grow-x var(--sk-dur-4) var(--sk-ease-out) 150ms both; }

  /* ---------- things you touch answer straight away ---------- */
  .btn { transition: background-color var(--sk-dur-1), border-color var(--sk-dur-1), color var(--sk-dur-1),
    box-shadow var(--sk-dur-1), transform var(--sk-dur-1) var(--sk-ease-out); }
  .btn:active:not(:disabled) { transform: translateY(1px) scale(.985); }
  .nav-link { transition: background-color var(--sk-dur-1), color var(--sk-dur-1); }
  .table tbody tr { transition: background-color var(--sk-dur-1); }
  .input, select.input, textarea.input { transition: border-color var(--sk-dur-1), box-shadow var(--sk-dur-2); }
  details > summary ~ * { animation: sk-fade-in var(--sk-dur-2) ease both; }
  .usermenu[open] .usermenu-pop { animation: sk-drop-in var(--sk-dur-2) var(--sk-ease-out) both; }
  @media (hover: hover) and (pointer: fine) {
    .kpi-tile { transition: transform var(--sk-dur-2) var(--sk-ease-out), box-shadow var(--sk-dur-2), border-color var(--sk-dur-2); }
    .kpi-tile:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(15, 12, 51, .08); }
    .quick-tile, .insight { transition: transform var(--sk-dur-2) var(--sk-ease-out), border-color var(--sk-dur-2), background-color var(--sk-dur-2); }
    .quick-tile:hover, .insight:hover { transform: translateY(-2px); }
  }

  /* ---------- live things ---------- */
  .live-dot::before { animation: sk-live 2s ease-in-out infinite; }
  .sos-banner:not([hidden]) { animation: sk-drop-in var(--sk-dur-2) var(--sk-ease-out) both, sk-sos-glow 1.6s ease-in-out 220ms infinite; }
  .appbar-bell.ring svg, .topbar-bell.ring svg { animation: sk-nudge 900ms var(--sk-ease-in-out) both; transform-origin: 50% 0; }
  .is-loading::after { animation: sk-shimmer 1.2s linear infinite; }
  .sk-skeleton, .is-loading .sk-skeleton-text { animation: sk-shimmer 1.4s ease infinite; }
  .figure-changed { animation: sk-flash 900ms var(--sk-ease-out); border-radius: 3px; }

  /* ---------- maps: trucks that are moving pulse; route markers pop in along the line ---------- */
  .truck-pulse { position: relative; }
  .truck-pulse::after { content: ""; position: absolute; inset: -4px; border-radius: 50%; border: 2px solid var(--sk-indigo-500);
    animation: sk-pulse-ring 1.8s var(--sk-ease-out) infinite; pointer-events: none; }
  .route-pin { animation: sk-pop var(--sk-dur-3) var(--sk-ease-spring) both; }

  /* ---------- the driver app: cards press like buttons, the progress bar slides, a sent item ticks ---------- */
  .driver .d-card, .driver .route-opt, .driver .toll-row, .driver .d-btn {
    transition: transform var(--sk-dur-1) var(--sk-ease-out), background-color var(--sk-dur-1), border-color var(--sk-dur-1); }
  .driver a.d-card:active, .driver .d-btn:active, .driver .route-opt:active, .driver .toll-row:active { transform: scale(.985); }
  .driver .bottom-nav a.active svg { animation: sk-pop var(--sk-dur-3) var(--sk-ease-spring) both; }
  .driver .d-main > .alert, .driver .d-toast:not([hidden]) { animation: sk-drop-in var(--sk-dur-2) var(--sk-ease-out) both; }
  .driver .progress > span, .driver [data-progress] { transition: width var(--sk-dur-3) var(--sk-ease-out); }
  .driver .step:not([hidden]) { animation: sk-rise-in var(--sk-dur-3) var(--sk-ease-out) both; }
  .check-anim path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: sk-check 420ms var(--sk-ease-out) 120ms forwards; }
  .check-anim circle { transform-box: fill-box; transform-origin: center; animation: sk-pop var(--sk-dur-3) var(--sk-ease-spring) both; }

  /* ---------- figures: a counting figure keeps its width steady ---------- */
  .is-counting { font-variant-numeric: tabular-nums; }

  /* ---------- loads on the road ---------- */
  .route-live .leg > i { animation: sk-travel 2.4s var(--sk-ease-in-out) infinite; }
  .d-route-live .line > i { animation: sk-travel-down 2.6s var(--sk-ease-in-out) infinite; }
  .map-pin.live::after { animation: sk-pulse-ring 2s var(--sk-ease-out) infinite; }

  /* ---------- sign-in: routes draw, towns light up ---------- */
  .auth-map .road.draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: sk-draw 1100ms var(--sk-ease-in-out) forwards; }
  .auth-map .town.pop { transform-box: fill-box; transform-origin: center; animation: sk-pop var(--sk-dur-3) var(--sk-ease-spring) both; }
  .auth-map .town.hub { animation: sk-pop var(--sk-dur-3) var(--sk-ease-spring) both, sk-hub 2.8s ease-in-out 1.4s infinite; }
  .auth-form .card { animation: sk-rise-in var(--sk-dur-4) var(--sk-ease-out) 120ms both; }
  .auth-brand > img, .auth-brand > p { animation: sk-rise-in var(--sk-dur-4) var(--sk-ease-out) both; }

  /* ---------- dashboard calendar: the days fill in from left to right ---------- */
  .cal tbody td { animation: sk-fade-in var(--sk-dur-3) ease both; }
  .cal tbody td:nth-child(-n+8) { animation-delay: 60ms; }
  .cal tbody td:nth-child(n+9):nth-child(-n+15) { animation-delay: 140ms; }
  .cal tbody td:nth-child(n+16):nth-child(-n+22) { animation-delay: 220ms; }
  .cal tbody td:nth-child(n+23) { animation-delay: 300ms; }

  /* ---------- dispatch board: booked trips slide into their days ---------- */
  .dispatch .slot { animation: sk-rise-in var(--sk-dur-3) var(--sk-ease-out) both; }
}
@keyframes sk-travel { 0% { left: -3px; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { left: calc(100% - 3px); opacity: 0; } }
@keyframes sk-travel-down { 0% { top: .45rem; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { top: calc(100% + .2rem); opacity: 0; } }
@keyframes sk-flash { from { background-color: color-mix(in srgb, var(--sk-indigo-300) 45%, transparent); } to { background-color: transparent; } }
@keyframes sk-hub { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* Nothing moves when the device asks for less motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important; }
}
