/* How the panel moves (Docs/Systems/ControlPanel.md, rule 6). Motion says what changed: a page arrives, a drawer
   comes from its edge, a control gives under the pointer. Everything arrives on one curve and nothing loops: each
   movement ends in under a second. The curve and the times are app.css's tokens (--ease, --t-press, --t-fast,
   --t-move). There is one set of moves, and a page added beside the built-in ones uses it and adds none: a page
   enters by rising 10 px, a drawer opens from the right edge, a tab's content settles in 4 px (arrive('page' |
   'drawer' | 'tab', el) in core.js), and a control eases its colours under the pointer (the press rule below). Only
   opacity, translate and scale move, so nothing is laid out or painted again while it runs, and the rail and the
   sidebar keep their widths. The page's code starts what a click moves, with glide(), enter() and arrive(), never on a poll's
   redraw: a rule here animates only what a click or a new state puts on the page, and an element a poll draws
   again gets none. This file alone declares @keyframes and animations, and core.js alone calls .animate(): a sheet
   beside it holds only a hover's transition, timed by a token. Under Reduce Motion nothing moves (this file's last
   rule, and enter() in core.js). `python Panel/e2e.py page --stub` keeps both (motion_strays and STILL in
   e2e_page.py). */

/* --- A change of the frame (glide and enter, core.js) -------------------------------------------------------------
   The change is made at once, as the click expects. Another page then rises into its place; a drawer comes from its
   own edge, the left sidebar from the left and a session's details from the right; and the work, a session's
   conversation and the page's name slide from where they stood to where they stand. The page's code runs these
   moves, so only what they need is ruled here. */
@media (min-width: 1181px) { .insp { position: relative; } }  /* the details lie over the conversation that slides out from under them */
.scroll { scroll-behavior: smooth; }  /* a row picked in the left sidebar is brought into view by a scroll the eye can follow */
@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; translate: 0 10px; } }
@keyframes drop { from { opacity: 0; translate: 0 -8px; } }
@keyframes from-right { from { opacity: 0; translate: 28px 0; } }
@keyframes arrive { from { opacity: 0; translate: 0 5px; } }

/* --- The rail's selection: one mark that slides to the open section (railMark in frame.js gives its place) ---------
   Until the page's code has placed it, the open section keeps its own ground, as app.css draws it. */
.rail { position: relative; }
.rail::before { content: ""; position: absolute; top: 0; left: 50%; width: 56px; height: var(--tall, 0); margin-left: -28px; border-radius: 10px; background: var(--sel); translate: 0 var(--at, 0); opacity: 0; }
.rail.placed::before { opacity: 1; transition: translate var(--t-move) var(--ease); }
.rail.placed a[aria-current] { background: none; }

/* --- A press: the control gives under the pointer and comes back on the curve -----------------------------------
   One rule holds what every control eases: its colours for --t-fast, its size for --t-press. */
.primary, .btn, .icon, .tool, .plus, .stop, .send, .pick, .starts button, .seg button, .login-card .google, .rail a, .phone-tabs a, .branch, .me, .row-more, .issue .mk, .box .bar2 .clip {
  transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast), scale var(--t-press) var(--ease);
}
:is(.primary, .btn, .plus, .stop, .send, .starts button, .login-card .google, .issue .mk):active:not(:disabled) { scale: .96; }
:is(.icon, .row-more, .box .bar2 .clip):active { scale: .88; }
:is(.rail a, .tool, .phone-tabs a, .seg button):active { scale: .95; }
/* a row lights at once under the pointer and fades as the pointer leaves it; pressed, it takes the selection's ground */
.item, .proj-head, .sub, .now a, .now h2 button, .pop button, .tool > summary, .entry summary, .w-pick a { transition: background-color var(--t-fast), color var(--t-fast); }
:is(.item, .proj-head, .sub, .now a, .now h2 button, .pop button, .tool > summary, .entry summary, .w-pick a):hover { transition-duration: 0s; }
:is(.item, .proj-head, .now a, .pop button, .branch, .me):active { background: var(--sel); }
/* a field in use: its border turns blue inside a soft ring */
.box, .search { transition: border-color var(--t-fast), box-shadow var(--t-fast); }
.search:focus-within { box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue) 16%, transparent); }
.box:focus-within { box-shadow: var(--shadow), 0 0 0 3px color-mix(in srgb, var(--blue) 16%, transparent); }

/* --- What a click or a new state puts on the page ----------------------------------------------------------------
   Each of these elements stays on the page and is shown or hidden, or is added once: a poll never draws it again. */
/* a notice's whole life (toast in core.js keeps it 4 s): it drops out of the top bar, stays, and lifts away */
.toast { animation: notice 4s both; }
@keyframes notice { 0% { opacity: 0; translate: 0 -12px; animation-timing-function: var(--ease); } 7%, 94% { opacity: 1; translate: 0 0; animation-timing-function: ease-in; } 100% { opacity: 0; translate: 0 -8px; } }
.lost, .wpub { animation: drop var(--t-move) var(--ease); }
.latest { animation: rise var(--t-move) var(--ease); }
.row .pop { transform-origin: top right; }  /* a session's menu opens out of its ⋯ (enter in frame.js) */
/* in a conversation each step of the agent's work arrives as it is made, and a folded run opens the same way */
.chat .col > :not(.working), .tools li { animation: arrive var(--t-move) var(--ease); }
.task[open] > p, .tool[open] > pre, .entry[open] > dl, .was[open] > :not(summary) { animation: drop var(--t-move) var(--ease); }
/* a website: its history comes from the right edge, and a view picked in the top bar fades in */
.wdraw { animation: from-right var(--t-move) var(--ease); }
.wchat, .wpane, .wgo { animation: fade var(--t-fast) ease-out; }
/* a client's and a shop's drawer: its layer fades in and its box comes from the right edge; a menu of choices and a
   dialog fade in */
.ro-scrim, .rv-scrim, .ro-modal, .ro-opts { animation: fade var(--t-fast) ease-out; }
.ro-drawer, .rv-drawer { animation: from-right var(--t-move) var(--ease); }

/* --- Two named moves of one page each --------------------------------------------------------------------------
   The Browser view's click mark: a ring closes on where the agent's click landed, stays, and fades (browserMark in
   browser.js hides it after 1.4 s). The Sales podium: its steps rise once, on the page's first draw. */
.bmark.passing { animation: bmark 1.4s var(--ease) forwards; }
@keyframes bmark { from { opacity: 0; scale: 2.2; } 18% { opacity: 1; scale: 1; } 70% { opacity: 1; } to { opacity: 0; } }
.sa-podium.rise .sa-step { animation: sa-rise 560ms var(--ease) both; }
.sa-podium.rise .p1 { animation-delay: 80ms; } .sa-podium.rise .p3 { animation-delay: 200ms; }
@keyframes sa-rise { from { opacity: 0; translate: 0 18px; } }

/* --- The one authored moment: the mark arrives as its gear turns into place and its cursor clicks ------------------
   On the start page the question and its box follow it; on the sign-in card, the card. Nothing waits for it: the
   box takes the keyboard at once. */
.home .col::before, .login-card img { animation: clutch 720ms var(--ease) both; }
.home .col > *, .home .now, .login-card { animation: rise 420ms var(--ease) both; }
.home .col > :nth-child(2) { animation-delay: 45ms; } .home .col > :nth-child(3) { animation-delay: 90ms; }
.home .col > :nth-child(n+4) { animation-delay: 135ms; } .home .now { animation-delay: 180ms; }
@keyframes clutch { 0% { opacity: 0; rotate: -28deg; scale: .9; } 62% { rotate: 0deg; scale: 1; } 80% { scale: .96; } }

/* Reduce Motion: the one rule that ends every animation and transition at once, the drawn parts included. This
   sheet loads last, so no sheet answers it. */
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; } }
