/* Motion layer on top of glass.css: aurora backdrop, frost grain, pointer light,
   entrances and micro-interactions. Only transform/opacity loop, so the blurred
   surfaces above never force a layout. Pointer data comes from js/motion.js. */
@property --lit { syntax: "<number>"; inherits: false; initial-value: 0; }

:root {
    --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
    --ease-out: cubic-bezier(.16, 1, .3, 1);
    --spot-strength: .34;
    --grain-opacity: .05;
    --aurora-a: var(--glass-glow-a);
    --aurora-b: var(--glass-glow-b);
    --aurora-c: color-mix(in srgb, var(--accent) 34%, transparent);
    --button-fill: var(--accent);
    --glass-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* White button text needs a fill darker than the theme's on-glass accent. */
:root[data-theme="minimal"] { --button-fill: #2864d9; }
:root[data-theme="dark"] { --spot-strength: .13; --grain-opacity: .07; --aurora-c: color-mix(in srgb, var(--accent) 26%, transparent); }
@media (prefers-color-scheme: dark) {
    :root[data-theme="minimal"] {
        --spot-strength: .13;
        --grain-opacity: .07;
        --aurora-a: rgba(64, 124, 228, .46);
        --aurora-b: rgba(40, 176, 190, .3);
        --aurora-c: rgba(126, 92, 236, .3);
    }
}

/* ── Aurora: pre-softened gradients on two composited layers, no filter:blur ── */
body::before,
body::after {
    content: "";
    position: fixed;
    inset: -25%;
    z-index: -1;
    pointer-events: none;
    will-change: transform;
    animation: aurora-drift-a 48s var(--aurora-phase, 0s) ease-in-out infinite alternate;
}
body::before {
    background:
        radial-gradient(38% 42% at 24% 22%, var(--aurora-a), transparent 72%),
        radial-gradient(34% 38% at 78% 68%, var(--aurora-b), transparent 72%);
}
body::after {
    background:
        radial-gradient(30% 34% at 70% 20%, var(--aurora-c), transparent 72%),
        radial-gradient(36% 34% at 28% 78%, var(--aurora-b), transparent 72%);
    animation-name: aurora-drift-b;
    animation-duration: 60s;
}
@keyframes aurora-drift-a {
    from { transform: translate3d(-5%, -4%, 0) rotate(-6deg) scale(1); }
    to { transform: translate3d(7%, 6%, 0) rotate(10deg) scale(1.14); }
}
@keyframes aurora-drift-b {
    from { transform: translate3d(6%, 5%, 0) rotate(8deg) scale(1.12); }
    to { transform: translate3d(-7%, -5%, 0) rotate(-12deg) scale(.98); }
}

/* ── Glass surface: grain + pointer light live behind the content ── */
.app-header, .page-heading, .metric-card, .panel, .login-shell,
.packet-header, .packet-page .packet-card, .task-card, .svg-link-card {
    --lit: 0;
    isolation: isolate;
    transition: --lit 320ms ease, transform 320ms var(--ease-out), box-shadow 240ms ease, border-color 240ms ease;
}
.app-header::before, .page-heading::before, .metric-card::before, .panel::before, .login-shell::before,
.packet-header::before, .packet-page .packet-card::before, .task-card::before, .svg-link-card::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(460px circle at var(--mx, 50%) var(--my, 0%), rgb(255 255 255 / calc(var(--lit) * var(--spot-strength))), transparent 68%),
        linear-gradient(160deg, var(--glass-shine), transparent 34%);
}
/* Grain on its own layer so its opacity never dims the pointer light. */
.app-header::after, .page-heading::after, .panel::after, .login-shell::after,
.packet-header::after, .packet-page .packet-card::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    pointer-events: none;
    background: var(--glass-grain);
    opacity: var(--grain-opacity);
}
.page-heading, .panel:not(.client-panel), .login-shell,
.packet-header, .packet-page .packet-card, .svg-link-card { position: relative; }
.is-lit { --lit: 1; }

/* Sticky header gains presence once content scrolls underneath it. */
.app-header { z-index: 20; }
.is-scrolled .app-header { box-shadow: var(--glass-shadow), 0 14px 34px color-mix(in srgb, var(--text) 13%, transparent); }

/* ── Metrics: tinted corner glow and a pointer tilt ── */
.metric-card { --metric-tint: var(--accent); }
.metric-card:nth-child(2) { --metric-tint: var(--positive); }
.metric-card:nth-child(3) { --metric-tint: var(--muted); }
.metric-card:nth-child(4) { --metric-tint: var(--warning); }
.metric-card:nth-child(5) { --metric-tint: var(--danger); }
.metric-card::after {
    inset: auto -30px -46px auto;
    z-index: -1;
    width: 150px;
    height: 150px;
    border: 0;
    background: radial-gradient(circle, var(--metric-tint), transparent 68%);
    opacity: .2;
    transition: opacity 320ms ease, transform 500ms var(--ease-out);
}
.metric-card.is-lit::after { opacity: .36; transform: scale(1.25); }
.metric-value { font-variant-numeric: tabular-nums; }
@media (hover: hover) and (pointer: fine) {
    /* Driven by .is-lit only: motion.js holds it near the edge so tilt can't flicker. */
    .metric-card.is-lit {
        transform: perspective(800px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-4px);
    }
    .task-card:hover, .svg-link-card:hover { transform: translateY(-2px); box-shadow: inset 0 1px 0 var(--glass-shine), 0 12px 28px color-mix(in srgb, var(--accent) 13%, transparent); }
    :root[data-theme] .svg-link-grid.is-list .svg-link-card:hover { transform: none; }
    /* Lifted cards keep the vacated strip hoverable, or the bottom edge flickers. */
    .task-card:hover::after, .svg-link-card:hover::after { content: ""; position: absolute; inset: 0 0 -3px; z-index: -1; }
}

/* ── Headline: slow light passes through the current page title ── */
:root[data-theme] .page-nav a[aria-current="page"],
:root[data-theme] .packet-page .packet-header h1,
:root[data-theme] #login-product-title span {
    color: var(--text);
    background: linear-gradient(100deg, var(--text) 20%, var(--accent) 42%, var(--grad-b, var(--accent)) 56%, var(--text) 78%) 0 0 / 260% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: title-flow 9s linear infinite;
}
:root[data-theme] .page-nav a[aria-current="page"] {
    /* The pill stays while only the text carries the flowing gradient. */
    background:
        linear-gradient(100deg, var(--text) 20%, var(--accent) 42%, var(--grad-b, var(--accent)) 56%, var(--text) 78%) 0 0 / 260% 100% text,
        var(--glass-input) border-box;
}
@keyframes title-flow { from { background-position: 130% 0, 0 0; } to { background-position: -130% 0, 0 0; } }
.page-nav-link { transition: color 200ms ease, transform 300ms var(--ease-spring); }
.page-nav-link:hover { transform: translateY(-2px); }
.page-heading .eyebrow::before { animation: dot-ping 2.6s ease-out infinite; }

/* ── Status: a soft ping means the connection is alive ── */
@keyframes dot-ping {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent); }
    70%, 100% { box-shadow: 0 0 0 9px transparent; }
}
.connection-pill .status-dot { --ping: var(--warning); }
.connection-pill[data-state="connected"] .status-dot { animation: status-ping 2.2s ease-out infinite; }
.connection-pill[data-state="connecting"] .status-dot { animation: status-blink 1s ease-in-out infinite alternate; }
@keyframes status-ping {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--positive) 55%, transparent); }
    70%, 100% { box-shadow: 0 0 0 7px transparent; }
}
@keyframes status-blink { to { opacity: .3; } }

/* ── Buttons: gradient body, sheen on hover, ripple on press ── */
:where(.button, .icon-button, .send-button, .copy-button) { position: relative; overflow: hidden; }
:root[data-theme] :is(.button-primary, .send-button) {
    color: #fff;
    background: linear-gradient(120deg, var(--button-fill), color-mix(in srgb, var(--button-fill) 72%, #7c3aed)) 0 0 / 160% 100%;
    transition: background-position 500ms var(--ease-out), box-shadow 240ms ease, transform 240ms var(--ease-spring);
}
:root[data-theme] :is(.button-primary, .send-button):hover:not(:disabled) { background-position: 100% 0; }
:is(.button-primary, .send-button)::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / .42) 50%, transparent 65%);
    transform: translateX(-120%);
    pointer-events: none;
}
:is(.button-primary, .send-button):hover:not(:disabled)::after { transform: translateX(120%); transition: transform 760ms var(--ease-out); }
.button:hover:not(:disabled), .icon-button:hover:not(:disabled) { transition-timing-function: var(--ease-spring); }
.fx-ripple {
    position: absolute;
    border-radius: 50%;
    background: currentColor;
    opacity: .22;
    pointer-events: none;
}

/* ── Fields: focus blooms outward ── */
.field :is(input, select, textarea), .search-box, .filter-control select, .packet-card :is(input, textarea) {
    transition: border-color 200ms ease, box-shadow 280ms var(--ease-out), background-color 200ms ease;
}
.field :is(input, select, textarea):focus, .search-box:focus-within, .filter-control select:focus, .packet-card :is(input, textarea):focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 16%, transparent), 0 10px 26px color-mix(in srgb, var(--accent) 12%, transparent);
}

/* ── Entrances ── */
@keyframes rise-in {
    from { opacity: 0; transform: translateY(18px) scale(.985); }
    to { opacity: 1; transform: none; }
}
@keyframes bloom-in {
    from { opacity: 0; transform: translateY(24px) scale(.96); }
    to { opacity: 1; transform: none; }
}
@keyframes header-drop {
    from { opacity: 0; transform: translateY(-16px); }
    to { opacity: 1; transform: none; }
}
@keyframes line-reveal {
    from { opacity: 0; transform: translateY(70%); }
    to { opacity: 1; transform: none; }
}
.app-header { animation: header-drop 600ms var(--ease-out) backwards; }
.page-heading, .packet-header { animation: rise-in 640ms var(--ease-out) 40ms backwards; }
.metric-card { animation: rise-in 640ms var(--ease-out) calc(90ms + var(--i, 0) * 55ms) backwards; }
.metric-card:nth-child(2) { --i: 1; }
.metric-card:nth-child(3) { --i: 2; }
.metric-card:nth-child(4) { --i: 3; }
.metric-card:nth-child(5) { --i: 4; }
.panel, .packet-page .notice, .packet-page .packet-card { animation: rise-in 700ms var(--ease-out) 320ms backwards; }
.client-panel, .response-card { animation-delay: 400ms; }

/* Dialog contents settle a beat after the surface springs open. */
.dialog[open]:not(.dialog-closing) .dialog-body > * { animation: rise-in 460ms var(--ease-out) 70ms backwards; }
.dialog::backdrop { -webkit-backdrop-filter: blur(8px) saturate(120%); backdrop-filter: blur(8px) saturate(120%); }
.toast {
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    border-radius: 14px;
    animation: toast-spring 480ms var(--ease-spring);
}
@keyframes toast-spring {
    from { opacity: 0; transform: translateX(26px) scale(.94); }
    to { opacity: 1; transform: none; }
}

/* ── Login: the shell blooms, headline rises line by line, rings orbit ── */
.login-shell { animation: bloom-in 900ms var(--ease-out) backwards; box-shadow: var(--glass-shadow), 0 30px 80px color-mix(in srgb, var(--text) 14%, transparent); }
@media (hover: hover) and (pointer: fine) {
    .login-shell.is-lit { transform: perspective(1600px) rotateX(calc(var(--rx, 0deg) * .3)) rotateY(calc(var(--ry, 0deg) * .3)); }
}
:root[data-theme] #login-product-title span { animation: line-reveal 760ms var(--ease-out) 240ms backwards, title-flow 9s linear 1s infinite; }
:root[data-theme] #login-product-title span:nth-child(2) { animation-delay: 360ms, 1s; }
.login-message .eyebrow, .login-message > p:last-child, .login-brand, .login-footnote,
.login-form-panel > *, .login-form > * { animation: rise-in 700ms var(--ease-out) 320ms backwards; }
.login-form-panel > :nth-child(2) { animation-delay: 380ms; }
.login-form-panel > :nth-child(3) { animation-delay: 440ms; }
.login-form > :nth-child(n+2) { animation-delay: 520ms; }
.login-form-panel > :nth-child(4) { animation-delay: 600ms; }
.glass-orbit { animation: orbit-float 11s ease-in-out infinite alternate; }
.glass-orbit span { animation: orbit-spin 26s linear infinite; }
.glass-orbit span:nth-child(2) { animation-duration: 18s; animation-direction: reverse; }
.glass-orbit span:nth-child(3) { animation-duration: 12s; }
@keyframes orbit-float {
    from { transform: rotate(-25deg) translate3d(0, 0, 0); }
    to { transform: rotate(-15deg) translate3d(-22px, -26px, 0); }
}
@keyframes orbit-spin { to { transform: rotate(360deg); } }
.login-error:not([hidden]) { animation: nudge 460ms var(--ease-out); }
@keyframes nudge {
    20% { transform: translateX(-7px); }
    45% { transform: translateX(6px); }
    70% { transform: translateX(-3px); }
}
[aria-busy="true"] .login-submit { background-size: 300% 100%; animation: busy-flow 1.3s linear infinite; }
@keyframes busy-flow { to { background-position: -300% 0; } }

/* ── View switch (js/view-router.js): one crossfade, no replayed entrances ── */
:root[data-view="tasks"] [data-view-only="svg"],
:root[data-view="svg"] [data-view-only="tasks"] { display: none !important; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 180ms; animation-timing-function: ease; }
.fx-settled :is(.app-header, .page-heading, .metric-card, .panel) { animation: none; }

/* Touch devices keep one aurora layer and lighter frost to save battery. */
@media (pointer: coarse), (max-width: 760px) {
    :root { --glass-blur: 9px; }
    body::after { animation: none; }
    .app-header { z-index: auto; }
}

@media (prefers-reduced-motion: reduce) {
    body::before, body::after,
    .app-header, .page-heading, .packet-header, .metric-card, .panel, .login-shell, .toast,
    .packet-page .notice, .packet-page .packet-card, .glass-orbit, .glass-orbit span,
    .login-message .eyebrow, .login-message > p:last-child, .login-brand, .login-footnote,
    .login-form-panel > *, .login-form > *, .login-error,
    .dialog[open] .dialog-body > *, .connection-pill .status-dot, .page-heading .eyebrow::before,
    :root[data-theme] .page-nav a[aria-current="page"],
    :root[data-theme] .packet-page .packet-header h1,
    :root[data-theme] #login-product-title span { animation: none !important; }
    ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
    .metric-card:hover, .metric-card.is-lit, .login-shell.is-lit, .task-card:hover, .svg-link-card:hover { transform: none; }
}
