/* The bet slip's motion (founder, Oct 14 2026: "I want the animations on the bet slip to feel premium. Feels too snappy
   and low quality."; the bar: iOS system sheets, Apple Wallet, Linear, Stripe, Robinhood: restrained, physical,
   consistent). Loaded after every other stylesheet on each page with the slip (edgefinder/site.py _head, web/board.html);
   web/parlay.js and web/slip-motion.js set the states. The tokens live here and only here: web/slip-motion-core.js
   TOKENS mirrors them as a fallback and tests/js/slip-motion.test.mjs holds the two equal. Everything moves on
   transform and opacity alone (never width, height, top or left), and under prefers-reduced-motion every motion is a
   short opacity fade: nothing moves. will-change only while a finger drags the sheet (each move then only composites):
   a running transition or animation of transform or opacity gets its own layer from the browser for as long as it runs,
   and taking will-change off as it lands would cost a layout pass mid-motion (tools/slip-motion.mjs --trace). */
:root{--ease-out-soft:cubic-bezier(0.32, 0.72, 0, 1);--ease-in-quick:cubic-bezier(0.3, 0, 0.8, 0.15);--dur-panel-in:380ms;--dur-panel-out:280ms;
  --dur-move:280ms;--dur-content:300ms;--dur-small:200ms;--dur-fade:150ms;--dur-fly:450ms;--stagger:30ms;--rise:6px;--dur-late:250ms;}

/* The slip's states (data-motion on #pslip and its backdrop): none, open and still; "from", the frame before it arrives;
   "enter", arriving; "leave", leaving; "drag", following a finger. A phone's sheet comes up from the foot of the screen,
   a panel or the wide board's rail in from the right edge, and each leaves the way it came, a little faster. A state
   changed mid-way turns the motion around from where it is (a transition starts from the current value): no jump. */
.pslip{translate:0 0}   /* at rest on an identity translate, never none: the end of a slide then changes no containing block (no layout pass) */
.pslip[data-motion="from"],.pslip[data-motion="leave"]{translate:calc(100% + 48px) 0}
.pslip[data-mode="sheet"][data-motion="from"],.pslip[data-mode="sheet"][data-motion="leave"]{translate:0 calc(100% + 40px)}
.pslip[data-motion="from"],.pslip[data-motion="drag"]{transition:none}
.pslip[data-motion="enter"]{transition:translate var(--dur-panel-in) var(--ease-out-soft)}
.pslip[data-motion="leave"]{transition:translate var(--dur-panel-out) var(--ease-in-quick);pointer-events:none}
.pslip[data-motion="drag"]{will-change:translate}
/* the sheet's own colour carries on below its foot, so a sheet pulled up past its top (the rubber band) or settling
   after its content shrinks never shows a gap under it */
.pslip[data-mode="sheet"]::after{content:"";position:absolute;left:0;right:0;top:100%;height:100vh;background:var(--s-bg);pointer-events:none}
/* the sheet's grabber: its head is the handle (drag it down to close it, web/slip-motion.js drag) */
.pslip[data-mode="sheet"] .ps-bar{touch-action:none}
.pslip[data-mode="sheet"] .ps-bar::before{content:"";position:absolute;top:6px;left:50%;width:36px;height:4px;margin-left:-18px;border-radius:2px;background:var(--s-ln2);pointer-events:none}
/* the frames a number or a row fades out from while the new one comes in (web/slip-motion.js morph) */
.ps-bar,.ps-body{position:relative}
.ps-ghost{position:absolute;margin:0;pointer-events:none;z-index:1}
.ps-ghost.n{white-space:nowrap}
.ps-leg[data-leaving]{pointer-events:none}

/* The backdrop behind a phone's sheet or a panel (none beside the rail): a dim that fades in, with a soft blur where the
   browser can (dim alone where it can't, or where the member asks for less transparency). A tap on it closes the slip. */
.ps-scrim{position:fixed;inset:0;z-index:61;background:rgba(13,19,32,.24)}
:root[data-theme="dark"] .ps-scrim{background:rgba(0,0,0,.46)}
.ps-scrim[hidden]{display:none}
.ps-scrim[data-motion="from"],.ps-scrim[data-motion="leave"]{opacity:0}
.ps-scrim[data-motion="from"],.ps-scrim[data-motion="drag"]{transition:none}
.ps-scrim[data-motion="enter"]{transition:opacity var(--dur-panel-in) var(--ease-out-soft)}
.ps-scrim[data-motion="leave"]{transition:opacity var(--dur-panel-out) var(--ease-in-quick);pointer-events:none}
@supports ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){
  .ps-scrim{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background:rgba(13,19,32,.18)}
  :root[data-theme="dark"] .ps-scrim{background:rgba(0,0,0,.38)}
}
@media (prefers-reduced-transparency:reduce){.ps-scrim{-webkit-backdrop-filter:none;backdrop-filter:none}}

/* The tab rides beside the panel or the rail as it opens and closes (a transform, where nav.css moved its right edge);
   on a phone the pill stays where it is, under the sheet. */
.pstab{translate:0 0;transition:translate var(--dur-panel-out) var(--ease-in-quick)}
.pstab.on:not([data-mode="sheet"]){right:0;translate:calc(-16px - var(--s-w)) 0;transition:translate var(--dur-panel-in) var(--ease-out-soft)}
.pstab[data-mode="sheet"].on{right:12px}
.pstab[data-motion="still"]{transition:none}
/* the count: the old number slides out as the new one slides in (web/slip-motion.js roll) */
.pt-n{position:relative}
.pt-n.is-rolling{overflow:hidden}
.pt-d{display:block}
.pt-d.old{position:absolute;left:0;right:0;top:0}
/* the chip that flies from a + or Add to slip to the tab */
.ps-fly{position:fixed;left:0;top:0;z-index:85;width:14px;height:14px;border-radius:50%;background:var(--solid,#0D1320);pointer-events:none;
  box-shadow:0 4px 10px -2px rgba(13,19,32,.35)}
:root[data-theme="dark"] .ps-fly{background:#EEF1F6;box-shadow:0 4px 12px -2px rgba(0,0,0,.6)}

/* Toasts ("Added to your slip"): a short rise and fade in, a quicker fall and fade out; never the layout. */
.toast{transform:translate(-50%,10px);transition:opacity var(--dur-small) var(--ease-in-quick),transform var(--dur-small) var(--ease-in-quick)}
.toast.is-on{transform:translate(-50%,0);transition:opacity var(--dur-small) var(--ease-out-soft),transform var(--dur-small) var(--ease-out-soft)}

/* Reduced motion: every one of these is a short opacity fade; nothing slides, rises, rolls, flies or pulses. The site's
   own rule for reduced motion turns every transition off with !important (board.css, site.css), which would make the
   slip, its backdrop and a toast blink in and out: their fades carry !important too, so they stay short fades. */
@media (prefers-reduced-motion:reduce){
  .pslip[data-motion="from"],.pslip[data-motion="leave"],.pslip[data-mode="sheet"][data-motion="from"],.pslip[data-mode="sheet"][data-motion="leave"]{translate:none;opacity:0}
  .pslip[data-motion="enter"],.pslip[data-motion="leave"]{transition:opacity var(--dur-fade) linear!important}
  .ps-scrim[data-motion="enter"],.ps-scrim[data-motion="leave"]{transition:opacity var(--dur-fade) linear!important}
  .pstab,.pstab.on:not([data-mode="sheet"]){transition:none}
  .toast,.toast.is-on{transform:translate(-50%,0);transition:opacity var(--dur-fade) linear!important}
}
