/*! Board — a Neuraft product. Copyright (c) 2026 Neuraft Studio (Hossein Zandinejad). All rights reserved. */
/* ============================================================
   Motion for every page.

   Three speeds and two curves, used everywhere:
     quick   120–200ms  feedback: presses, hovers, menus closing
     base    300–450ms  things arriving: cards, dialogs, panels
     slow    500–700ms  journeys: page changes, the view gliding
   --ease     decelerates: things arrive and settle
   --spring   overshoots a little: things that pop (new items, ticks, badges)

   Entrances use fill-mode `backwards`, never `both`, so once they finish
   the element's own hover and active transforms take over again.

   Everything here switches off for people who ask for less motion
   (their device setting, or Account → Appearance → Motion).
   ============================================================ */

:root {
  --ease: cubic-bezier(.22, 1, .36, 1);
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-in: cubic-bezier(.4, 0, 1, 1);
}

@keyframes rise { from { opacity: 0; transform: translateY(16px); } }
@keyframes riseSm { from { opacity: 0; transform: translateY(8px); } }
@keyframes fadeIn { from { opacity: 0; } }
@keyframes fadeOut { to { opacity: 0; } }
@keyframes pop { 0% { opacity: 0; transform: scale(.5); } 65% { opacity: 1; transform: scale(1.1); } 100% { transform: scale(1); } }
@keyframes slideRight { from { opacity: 0; transform: translateX(-16px); } }
@keyframes dropIn { from { opacity: 0; transform: translateY(-12px) scale(.98); } }
@keyframes shake { 0%, 100% { transform: translateX(0); } 18% { transform: translateX(-8px); } 36% { transform: translateX(7px); }
  54% { transform: translateX(-5px); } 72% { transform: translateX(3px); } 88% { transform: translateX(-1px); } }
@keyframes cardIn { 0% { opacity: 0; transform: translateY(28px) rotate(-1.2deg) scale(.97); box-shadow: 0 0 0 var(--accent); }
  60% { opacity: 1; box-shadow: 0 0 0 var(--accent); } 100% { box-shadow: 6px 6px 0 var(--accent); } }
@keyframes dialogIn { from { opacity: 0; transform: translateY(22px) scale(.95); } }
@keyframes dialogOut { to { opacity: 0; transform: translateY(12px) scale(.97); } }
@keyframes menuIn { from { opacity: 0; transform: translateY(-6px) scale(.95); } }
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, 24px) scale(.9); } }
@keyframes toastOut { to { opacity: 0; transform: translate(-50%, 10px) scale(.96); } }
@keyframes starPop { 0% { transform: scale(1); } 30% { transform: scale(.6) rotate(-20deg); } 65% { transform: scale(1.45) rotate(14deg); } 100% { transform: scale(1) rotate(0); } }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@keyframes spinIn { from { opacity: 0; transform: rotate(-90deg) scale(.4); } }

/* ---------- the Board mark draws itself ---------- */
@keyframes mPlate { from { opacity: 0; transform: scale(.55) rotate(-14deg); } 70% { transform: scale(1.06) rotate(2deg); } }
@keyframes mDraw { to { stroke-dashoffset: 0; } }
@keyframes mNode { 0% { transform: scale(0); } 70% { transform: scale(1.3); } 100% { transform: scale(1); } }
@keyframes mHop { 0%, 100% { transform: translateY(0) scale(1); } 40% { transform: translateY(-9px) scale(1.15); } 70% { transform: translateY(2px) scale(.95); } }
@keyframes mLoop { 0% { stroke-dashoffset: 1; } 45%, 72% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: -1; } }
@keyframes mBeat { 0%, 100% { transform: scale(1); } 30% { transform: scale(1.35); } 55% { transform: scale(.9); } }
.mark .m-plate, .mark .m-node { transform-box: fill-box; transform-origin: center; }
.mark-draw .m-plate { animation: mPlate .6s var(--spring) backwards; }
.mark-draw .m-stroke { stroke-dasharray: 1; stroke-dashoffset: 1; animation: mDraw .6s var(--ease) forwards; }
.mark-draw .m-s1 { animation-delay: .22s; } .mark-draw .m-s2 { animation-delay: .38s; } .mark-draw .m-s3 { animation-delay: .54s; }
.mark-draw .m-node { animation: mNode .5s var(--spring) backwards; }
.mark-draw .m-n1 { animation-delay: .32s; } .mark-draw .m-n2 { animation-delay: .62s; } .mark-draw .m-n3 { animation-delay: .78s; } .mark-draw .m-hub { animation-delay: .95s; }
.brand:hover .mark .m-node, .lockup:hover .mark .m-node, .brandlink:hover .mark .m-node { animation: mHop .55s var(--spring); }
.brand:hover .mark .m-n2, .lockup:hover .mark .m-n2, .brandlink:hover .mark .m-n2 { animation-delay: .06s; }
.brand:hover .mark .m-n3, .lockup:hover .mark .m-n3, .brandlink:hover .mark .m-n3 { animation-delay: .12s; }
.brand:hover .mark .m-hub, .lockup:hover .mark .m-hub, .brandlink:hover .mark .m-hub { animation-delay: .18s; }
.mark-loop .m-stroke { stroke-dasharray: 1; stroke-dashoffset: 1; animation: mLoop 1.8s var(--ease) infinite; }
.mark-loop .m-s2 { animation-delay: .15s; } .mark-loop .m-s3 { animation-delay: .3s; }
.mark-loop .m-node { animation: mBeat 1.8s var(--spring) infinite; }
.mark-loop .m-n2 { animation-delay: .2s; } .mark-loop .m-n3 { animation-delay: .4s; } .mark-loop .m-hub { animation-delay: .6s; }
.lockup .mark { width: 48px; height: 48px; flex: none; }
.brand .mark { width: 36px; height: 36px; flex: none; }

/* ---------- pages arrive ---------- */
.main > .flash { animation: dropIn .45s var(--ease) backwards; }
.main > .flash-error, .auth .flash-error { animation: dropIn .4s var(--ease) backwards, shake .55s .25s ease-in-out; }
.page-head > * { animation: rise .55s var(--ease) backwards; }
.page-head > :nth-child(2) { animation-delay: .08s; }
.page-head h1 { animation: rise .6s var(--ease) .05s backwards; }
.section-title { animation: rise .5s var(--ease) .12s backwards; }
.grid > *, .strip > *, .stats > *, .tpl-grid > *, .variants > *, .swatch-pick > label { animation: rise .55s var(--ease) backwards; }
.grid > :nth-child(1), .strip > :nth-child(1), .stats > :nth-child(1), .tpl-grid > :nth-child(1) { animation-delay: .10s; }
.grid > :nth-child(2), .strip > :nth-child(2), .stats > :nth-child(2), .tpl-grid > :nth-child(2) { animation-delay: .15s; }
.grid > :nth-child(3), .strip > :nth-child(3), .stats > :nth-child(3), .tpl-grid > :nth-child(3) { animation-delay: .20s; }
.grid > :nth-child(4), .strip > :nth-child(4), .stats > :nth-child(4), .tpl-grid > :nth-child(4) { animation-delay: .25s; }
.grid > :nth-child(5), .strip > :nth-child(5), .stats > :nth-child(5), .tpl-grid > :nth-child(5) { animation-delay: .30s; }
.grid > :nth-child(6), .strip > :nth-child(6), .stats > :nth-child(6), .tpl-grid > :nth-child(6) { animation-delay: .35s; }
.grid > :nth-child(7), .tpl-grid > :nth-child(7) { animation-delay: .40s; }
.grid > :nth-child(8), .tpl-grid > :nth-child(8) { animation-delay: .45s; }
.grid > :nth-child(9), .tpl-grid > :nth-child(9) { animation-delay: .50s; }
.grid > :nth-child(10), .tpl-grid > :nth-child(10) { animation-delay: .54s; }
.grid > :nth-child(11), .tpl-grid > :nth-child(11) { animation-delay: .58s; }
.grid > :nth-child(n+12) { animation-delay: .62s; }
.swatch-pick > label { animation-name: pop; animation-duration: .4s; animation-timing-function: var(--spring); }
.swatch-pick > label:nth-child(2) { animation-delay: .03s; } .swatch-pick > label:nth-child(3) { animation-delay: .06s; } .swatch-pick > label:nth-child(4) { animation-delay: .09s; }
.swatch-pick > label:nth-child(5) { animation-delay: .12s; } .swatch-pick > label:nth-child(6) { animation-delay: .15s; } .swatch-pick > label:nth-child(7) { animation-delay: .18s; }
.swatch-pick > label:nth-child(8) { animation-delay: .21s; } .swatch-pick > label:nth-child(9) { animation-delay: .24s; } .swatch-pick > label:nth-child(10) { animation-delay: .27s; }
.cols > * > .panel, .cols > .panel, .main > .panel, .temp-box { animation: rise .55s var(--ease) backwards; }
.cols > :nth-child(2) > .panel:nth-child(1) { animation-delay: .1s; }
.cols > * > .panel:nth-child(2) { animation-delay: .16s; } .cols > * > .panel:nth-child(3) { animation-delay: .22s; } .cols > * > .panel:nth-child(4) { animation-delay: .28s; }
table.list tbody tr { animation: riseSm .45s var(--ease) backwards; }
table.list tbody tr:nth-child(2) { animation-delay: .04s; } table.list tbody tr:nth-child(3) { animation-delay: .08s; } table.list tbody tr:nth-child(4) { animation-delay: .12s; }
table.list tbody tr:nth-child(5) { animation-delay: .16s; } table.list tbody tr:nth-child(n+6) { animation-delay: .2s; }
.members-row .avatar { animation: pop .45s var(--spring) backwards; }
.members-row .avatar:nth-child(2) { animation-delay: .06s; } .members-row .avatar:nth-child(3) { animation-delay: .12s; } .members-row .avatar:nth-child(n+4) { animation-delay: .18s; }
.empty { animation: rise .6s var(--ease) .1s backwards; }
.error-page .code { display: inline-block; animation: pop .7s var(--spring) backwards, float 3.2s ease-in-out .7s infinite; }
.error-page h1, .error-page p, .error-page .btn { animation: rise .55s var(--ease) .15s backwards; }
.legal > * { animation: riseSm .5s var(--ease) backwards; }

/* sidebar */
.sidebar .brand { animation: fadeIn .4s var(--ease) backwards; }
.side-new { animation: pop .5s var(--spring) .15s backwards; }
.nav a { transition: background .18s, color .18s, transform .25s var(--spring); }
.nav a:hover { transform: translateX(3px); }
.nav a .ico, .nav a .dot { transition: transform .3s var(--spring); }
.nav a:hover .ico, .nav a:hover .dot { transform: scale(1.15) rotate(-6deg); }
.sidebar .nav a { animation: slideRight .45s var(--ease) backwards; }
.sidebar .nav a:nth-child(1) { animation-delay: .12s; } .sidebar .nav a:nth-child(2) { animation-delay: .17s; } .sidebar .nav a:nth-child(3) { animation-delay: .22s; }
.sidebar .nav a:nth-child(4) { animation-delay: .27s; } .sidebar .nav a:nth-child(5) { animation-delay: .32s; } .sidebar .nav a:nth-child(n+6) { animation-delay: .36s; }
.side-foot { animation: fadeIn .5s var(--ease) .3s backwards; }
.who .avatar { transition: transform .3s var(--spring); }
.who:hover .avatar { transform: rotate(-8deg) scale(1.08); }

/* auth */
.auth-card { animation: cardIn .75s var(--ease) backwards; }
.auth-card .lockup span { animation: slideRight .5s var(--ease) .5s backwards; }
.auth-card h1 { animation: rise .55s var(--ease) .18s backwards; }
.auth-card .intro, .auth-card .invite-banner { animation: rise .55s var(--ease) .26s backwards; }
.auth-card form > * { animation: riseSm .5s var(--ease) backwards; }
.auth-card form > :nth-child(1) { animation-delay: .3s; } .auth-card form > :nth-child(2) { animation-delay: .35s; } .auth-card form > :nth-child(3) { animation-delay: .4s; }
.auth-card form > :nth-child(4) { animation-delay: .45s; } .auth-card form > :nth-child(5) { animation-delay: .5s; } .auth-card form > :nth-child(n+6) { animation-delay: .55s; }
.auth-alt, .studio { animation: fadeIn .6s var(--ease) .6s backwards; }

/* ---------- things you touch ---------- */
.btn { transition: transform .16s var(--spring), box-shadow .16s var(--ease), background .16s, border-color .16s, color .16s; }
.btn:active { transform: scale(.96); }
.btn-primary:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--hard); transition-duration: .06s; }
.btn .ico { transition: transform .3s var(--spring); }
.btn:hover .ico { transform: scale(1.12); }
.side-new:hover .ico { transform: rotate(90deg) scale(1.15); }
input, select, textarea { transition: border-color .18s, box-shadow .25s var(--ease), background .18s; }
.pw-toggle, .chip { transition: transform .2s var(--spring); }
.pw-toggle:active { transform: translateY(-50%) scale(.9); }
.swatch-pick span { transition: transform .25s var(--spring), border-color .15s; }
.swatch-pick label:hover span { transform: scale(1.15); }
.swatch-pick input:checked + span { animation: pop .4s var(--spring); }
.radio-cards label, .tpl .tc { transition: border-color .18s, background .2s, transform .25s var(--spring), box-shadow .2s; }
.radio-cards label:active { transform: scale(.985); }
.tpl:hover .tc { transform: translateY(-3px); }
.tpl input:checked + .tc { transform: translateY(-3px); }
.tpl .tt svg { transition: transform .5s var(--ease); }
.tpl:hover .tt svg { transform: scale(1.07); }
.tabs a { transition: color .18s, border-color .25s var(--ease); }

/* board cards */
.bthumb svg { transition: transform .6s var(--ease); }
.bcard:hover .bthumb svg { transform: scale(1.07) translateY(-2px); }
.bmeta b { transition: color .2s; }
.bcard:hover .bmeta b { color: var(--accent-text); }
.bacts { transition: transform .25s var(--spring), box-shadow .2s; }
.bcard:hover .bacts { transform: translateY(-1px); box-shadow: 0 4px 10px -4px rgba(0,0,0,.25); }
.bacts button { transition: transform .2s var(--spring), color .15s, background .15s; }
.bacts button:active { transform: scale(.85); }
.fav.popping svg { animation: starPop .55s var(--spring); }
.new-card .ico { transition: transform .45s var(--spring); }
.new-card:hover .ico { transform: rotate(90deg) scale(1.2); }
.new-card { transition: border-color .2s, color .2s, background .25s, transform .25s var(--spring), box-shadow .2s; }
.new-card:hover { background: var(--accent-bg); }
.mini { transition: border-color .2s, transform .25s var(--spring), box-shadow .2s; }
.mini:hover { transform: translateY(-3px); box-shadow: 0 8px 18px -10px rgba(0,0,0,.35); }
.mini .mt svg { transition: transform .5s var(--ease); }
.mini:hover .mt svg { transform: scale(1.12); }
.lock { animation: pop .4s var(--spring) .5s backwards; }

/* dialogs, menus, toasts */
dialog[open] { animation: dialogIn .42s var(--spring) backwards; }
dialog[open]::backdrop { animation: fadeIn .3s var(--ease) backwards; }
dialog.closing { animation: dialogOut .18s var(--ease-in) forwards; }
dialog.closing::backdrop { animation: fadeOut .18s var(--ease-in) forwards; }
dialog .dlg-head h2 { animation: riseSm .45s var(--ease) .08s backwards; }
dialog .x { transition: transform .3s var(--spring), color .15s; }
dialog .x:hover { transform: rotate(90deg); color: var(--text); }
.menu { animation: menuIn .2s var(--ease) backwards; transform-origin: top right; }
.menu button, .menu a { transition: background .12s, padding-left .2s var(--ease); }
.menu button:hover, .menu a:hover { padding-left: 14px; }
.toast { animation: toastIn .45s var(--spring) backwards; }
.toast.out { animation: toastOut .25s var(--ease-in) forwards; }
.stat b { font-variant-numeric: tabular-nums; }

/* ---------- moving between pages ---------- */
@view-transition { navigation: auto; }
@keyframes vtOut { to { opacity: 0; transform: translateY(-10px) scale(.992); } }
@keyframes vtIn { from { opacity: 0; transform: translateY(14px) scale(.992); } }
::view-transition-old(root) { animation: vtOut .22s var(--ease-in) both; }
::view-transition-new(root) { animation: vtIn .42s var(--ease) both; }
.sidemark, .brandmark { view-transition-name: brand-mark; }
::view-transition-group(brand-mark) { animation-duration: .5s; animation-timing-function: var(--spring); }
::view-transition-group(board-open) { animation-duration: .5s; animation-timing-function: var(--ease); }
::view-transition-old(board-open), ::view-transition-new(board-open) { height: 100%; object-fit: cover; }
/* switching light/dark: a circle grows from where you clicked (app.js drives it) */
html.theme-vt::view-transition-old(root), html.theme-vt::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.theme-vt::view-transition-new(root) { z-index: 2; }

/* ---------- less motion, when asked ---------- */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]) *, :root:not([data-motion="full"]) *::before, :root:not([data-motion="full"]) *::after {
    animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
  :root:not([data-motion="full"])::view-transition-group(*), :root:not([data-motion="full"])::view-transition-old(*),
  :root:not([data-motion="full"])::view-transition-new(*) { animation: none !important; }
}
:root[data-motion="reduced"] *, :root[data-motion="reduced"] *::before, :root[data-motion="reduced"] *::after {
  animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
  transition-duration: .01ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
:root[data-motion="reduced"]::view-transition-group(*), :root[data-motion="reduced"]::view-transition-old(*),
:root[data-motion="reduced"]::view-transition-new(*) { animation: none !important; }
