/*
 * motion.css — timing tokens, press feedback and the "appear" animations
 * (things that animate when they stop being [hidden]). Leaving, dragging and
 * measuring live in motion.js. Opening animations wait for html.motion-ready
 * so the first paint is still; base.css stops them all under
 * prefers-reduced-motion.
 */

:root {
    --ease-out: cubic-bezier(.22,.61,.36,1);
    --ease-in: cubic-bezier(.4,0,1,1);
    --ease-spring: cubic-bezier(.34,1.4,.64,1);
    --ease-sheet: cubic-bezier(.32,.72,0,1);
    --dur-fast: 140ms;
    --dur: 240ms;
    --dur-sheet: 380ms;
}

/* The old screen is lifted out of the flow while it slides away. */
.app-main { position: relative; }
.app-main.is-switching { overflow-x: clip; }

/* ── Press feedback: controls give a little under the finger ────────────── */
.btn, .context-chip, .plan-tool, .spot-row, .app-toast-close {
    transition: transform var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.btn:active:not(:disabled),
.context-chip:active,
.plan-tool:active:not(:disabled) { transform: scale(0.96); }
.spot-row:active { transform: scale(0.985); }
.seg-opt { transition: background-color var(--dur-fast) var(--ease-out); }

/* ── Tab bar: sliding indicator, filled + popping icon ──────────────────── */
/* Positioned for the indicator (phones: already fixed as the bottom bar). */
@media (min-width: 701px) {
    .screen-nav.seg { position: relative; }
}
.screen-nav .seg-opt[aria-selected="true"] { box-shadow: none; }
.screen-nav .seg-opt { transition: color var(--dur) var(--ease-out), background-color var(--dur-fast) var(--ease-out); }
.screen-nav .seg-opt .ph,
.screen-nav .seg-opt .ph-fill { transition: transform var(--dur-fast) var(--ease-out); }
.screen-nav .seg-opt:active .ph,
.screen-nav .seg-opt:active .ph-fill { transform: scale(0.86); }
html.motion-ready .screen-nav .seg-opt[aria-selected="true"] .ph-fill {
    animation: tab-pop 420ms var(--ease-spring);
}
@keyframes tab-pop {
    0% { transform: scale(0.8); }
    60% { transform: scale(1.15); }
    100% { transform: none; }
}

.tab-indicator {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: var(--w, 0);
    transform: translateX(var(--x, 0));
    pointer-events: none;
}
.tab-indicator.is-live {
    transition: transform 380ms var(--ease-spring), width 380ms var(--ease-spring);
}
.tab-indicator::before {
    content: "";
    position: absolute;
    inset: 0;
    box-shadow: inset 0 0 0 1px var(--color-accent);
}
@media (max-width: 700px) {
    .tab-indicator::before {
        inset: 0 auto auto 50%;
        width: 32px;
        height: 3px;
        transform: translateX(-50%);
        border-radius: 0 0 3px 3px;
        background: var(--color-accent);
        box-shadow: 0 0 12px color-mix(in srgb, var(--color-accent) 60%, transparent);
    }
}

/* ── Things that appear ─────────────────────────────────────────────────── */
@keyframes fade-in { from { opacity: 0; } }
@keyframes rise-in { from { opacity: 0; transform: translateY(6px); } }

html.motion-ready .form-error:not([hidden]),
html.motion-ready .context-feedback:not([hidden]),
html.motion-ready .net-status:not([hidden]),
html.motion-ready .empty-state:not([hidden]) {
    animation: rise-in var(--dur) var(--ease-out);
}
html.motion-ready .dashboard-skeleton:not([hidden]) { animation: fade-in 200ms var(--ease-out); }
html.motion-ready .map-conditions-pill:not([hidden]) { animation: pill-in 320ms var(--ease-spring); }
@keyframes pill-in { from { opacity: 0; transform: scale(0.8); } }

/* Analyze: the sparkle spins while the read is computed. */
.btn.is-busy:disabled { opacity: 0.8; cursor: progress; }
.btn.is-busy .ph { animation: spin 900ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Hour bars grow from the baseline (motion.js). */
.hour-bar { transform-origin: bottom; }

/* ── Dialogs: pop in on desktop, slide up as a sheet on phones ──────────── */
html.motion-ready .dialog-backdrop:not([hidden]) { animation: fade-in var(--dur) var(--ease-out); }
html.motion-ready .dialog-backdrop:not([hidden]) > .dialog {
    animation: dialog-in 300ms var(--ease-spring);
}
@keyframes dialog-in { from { opacity: 0; transform: scale(0.94) translateY(8px); } }
@media (max-width: 700px) {
    html.motion-ready .dialog-backdrop:not([hidden]) > .dialog {
        animation: sheet-up var(--dur-sheet) var(--ease-sheet);
    }
    /* The handle + title row drags the sheet (motion.js). */
    .dialog-head { touch-action: none; }
}
@keyframes sheet-up { from { transform: translateY(100%); } }

/* ── Toast: springs up; swipe it away ───────────────────────────────────── */
.app-toast { touch-action: none; }
html.motion-ready .app-toast:not([hidden]) { animation: toast-in 380ms var(--ease-spring); }
@keyframes toast-in { from { opacity: 0; translate: 0 24px; } }

/* ── Map markers ────────────────────────────────────────────────────────── */
html.motion-ready .spot-dot { animation: dot-in 320ms var(--ease-spring) backwards; }
@keyframes dot-in { from { opacity: 0; transform: scale(0.3); } }

.spot-dot.is-selected { position: relative; }
html.motion-ready .spot-dot.is-selected { animation: marker-drop 560ms var(--ease-spring) backwards; }
@keyframes marker-drop {
    0% { opacity: 0; transform: translateY(-28px) scale(0.6); }
    60% { opacity: 1; transform: translateY(2px) scale(1.08); }
    100% { transform: none; }
}
.spot-dot.is-selected::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid var(--dot);
    opacity: 0;
    animation: marker-pulse 2s var(--ease-out) 600ms infinite;
}
@keyframes marker-pulse {
    0% { opacity: 0.9; transform: scale(1); }
    100% { opacity: 0; transform: scale(3); }
}

/* A tap on the location picker leaves a ripple (map-module.js). */
.leaflet-marker-icon.tap-ripple-wrap { background: none; border: 0; pointer-events: none; }
.tap-ripple {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    border: 2px solid var(--color-accent);
    animation: tap-ripple 600ms var(--ease-out) forwards;
}
@keyframes tap-ripple {
    from { opacity: 0.9; transform: scale(0.2); }
    to { opacity: 0; transform: scale(1); }
}

/* Wind / current arrows fade in after each pan. */
.flow-arrow > span { animation: fade-in 420ms var(--ease-out) backwards; }
