/* Site motion: transitions.dev recipes (Jakub Antalik's catalog) at the catalog
   defaults. Three recipes carry every page / tab / section change:
     08 "Page side-by-side"  route changes and in-screen tab panels
     16 "Tabs sliding"       the active pill on nav rails and tab rows
     06 "Modal" / 07 "Panel reveal"  sheets and the nav drawer
   The wizard's step change (wizard.css) reads the same --page-* tokens. */
:root {
  --page-slide-dur: 250ms;
  --page-fade-dur: 250ms;
  --page-slide-distance: 8px;
  --page-blur: 3px;
  --page-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --page-fade-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --tabs-dur: 250ms;
  --tabs-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --modal-open-dur: 250ms;
  --modal-close-dur: 150ms;
  --modal-scale: 0.96;
  --modal-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --panel-open-dur: 400ms;
  --panel-close-dur: 350ms;
  --panel-translate-y: 100px;
  --panel-blur: 2px;
  --panel-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ------------------------------------------------ page side-by-side --
   --t-pg-x is the sign of travel: +1 = the new page comes from the right
   (forward), -1 = from the left (back). The outgoing page moves the other way.

   Route change: the old screen is parked in a fixed .t-pg-out over the outlet,
   at the scroll offset it was seen at (--t-pg-y), and slides away while the
   new screen's body slides in. Its bars hide the moment the new bars paint,
   since they are the same chrome. z-index sits above the new body and under
   the new topbar (40) / bottomnav (50) / rail (60). */
.t-pg-out {
  position: fixed; inset: 0; z-index: 35;
  overflow: hidden; pointer-events: none;
}
.t-pg-out > .t-pg-in {
  position: absolute; left: 0; right: 0; top: var(--t-pg-y, 0px);
  transition:
    opacity   var(--page-fade-dur)  var(--page-fade-ease),
    transform var(--page-slide-dur) var(--page-slide-ease),
    filter    var(--page-slide-dur) var(--page-slide-ease);
  will-change: opacity, transform, filter;
}
.t-pg-out.is-gone > .t-pg-in {
  opacity: 0;
  transform: translateX(calc(var(--page-slide-distance) * var(--t-pg-x, 1) * -1));
  filter: blur(var(--page-blur));
}
.t-pg-out.is-gone .topbar,
.t-pg-out.is-gone .bottomnav { visibility: hidden; }

/* Incoming: .t-pg-enter is the start state (no transition), .t-pg-run tweens
   to the element's own resting values. The resting state has NO transform or
   filter so screens with position:fixed children keep the viewport as their
   containing block once the run is over. */
.t-pg-enter {
  opacity: 0;
  transform: translateX(calc(var(--page-slide-distance) * var(--t-pg-x, 1)));
  filter: blur(var(--page-blur));
  transition: none !important;
}
.t-pg-run {
  transition:
    opacity   var(--page-fade-dur)  var(--page-fade-ease),
    transform var(--page-slide-dur) var(--page-slide-ease),
    filter    var(--page-slide-dur) var(--page-slide-ease);
}
/* screens whose layout is position:fixed (chat, feed, generate, paywall) only
   cross-fade: a transform on their root would re-anchor those children */
.t-pg-fade.t-pg-enter,
.t-pg-out.t-pg-fade.is-gone > .t-pg-in { transform: none; filter: none; }

/* In-screen tab panels: the host keeps the outgoing children in an absolute
   .t-pg-old while the new children run the enter tween. */
.t-pg-host { position: relative; }
.t-pg-host > .t-pg-old {
  position: absolute; left: 0; right: 0; top: 0; pointer-events: none;
  /* the parked children keep the host's own layout (a grid host stays a grid) */
  display: inherit; grid-template-columns: inherit; gap: inherit;
  flex-direction: inherit; flex-wrap: inherit; align-items: inherit; justify-content: inherit;
  transition:
    opacity   var(--page-fade-dur)  var(--page-fade-ease),
    transform var(--page-slide-dur) var(--page-slide-ease),
    filter    var(--page-slide-dur) var(--page-slide-ease);
  will-change: opacity, transform, filter;
}
.t-pg-host > .t-pg-old.is-gone {
  opacity: 0;
  transform: translateX(calc(var(--page-slide-distance) * var(--t-pg-x, 1) * -1));
  filter: blur(var(--page-blur));
}

/* -------------------------------------------------------- tabs sliding --
   One .t-pill per bar, sized and placed by motion.js from the active item's
   box; CSS owns the tween. Items sit on z-index 1, the pill on 0, so labels
   read above it. A bar that carries a pill drops its own active fill. */
.has-pill { position: relative; }
.t-pill {
  position: absolute; left: 0; top: 0; z-index: 0;
  width: 0; height: 0;
  border-radius: var(--t-pill-radius, var(--pc-radius-pill));
  background: var(--t-pill-bg, rgb(var(--pc-surface-tertiary)));
  transform: translate(0, 0);
  transition:
    transform var(--tabs-dur) var(--tabs-ease),
    width     var(--tabs-dur) var(--tabs-ease),
    height    var(--tabs-dur) var(--tabs-ease),
    opacity   var(--tabs-dur) var(--tabs-ease);
  will-change: transform, width;
  pointer-events: none;
}
.t-pill.is-off { opacity: 0; }
.has-pill > .pill, .has-pill > .ex-chip, .has-pill > .gp-seg-btn, .has-pill > .gp-pill,
.has-pill > .pw-seg, .has-pill .sn-item, .has-pill > .bn-item { position: relative; z-index: 1; }
.has-pill > .pill.is-on, .has-pill > .ex-chip.is-on, .has-pill > .gp-seg-btn.is-active,
.has-pill > .gp-pill.is-active, .has-pill > .pw-seg.is-on { background: transparent; }

/* nav rails: the pill is the only active fill; hover keeps its own */
.sn-panel.has-pill { --t-pill-bg: var(--pc-color-overlay-white-faint); --t-pill-radius: var(--pc-radius-md); }
.sn-panel.has-pill .sn-item.is-active { background: transparent; }
.sn-panel.has-pill .sn-item:hover { background: var(--pc-color-overlay-white-faint); }
.bottomnav.has-pill { --t-pill-bg: var(--pc-color-overlay-white-faint); }
.bn-ico { display: flex; align-items: center; justify-content: center; width: 56px; height: 30px; }
.gp-seg.has-pill { --t-pill-bg: rgb(var(--pc-colour-bg-inverse)); }
.pw-toggle.has-pill { --t-pill-bg: rgb(var(--pc-color-white)); }

/* --------------------------------------------- sheets, drawer, modals --
   Bottom sheet = panel reveal (rises with a cross-blur); centred sheet and
   every desktop sheet = modal (scale from .96). Close is quicker than open. */
.sheet {
  transform: translateY(var(--panel-translate-y));
  filter: blur(var(--panel-blur));
  transition:
    transform var(--panel-close-dur) var(--panel-ease),
    filter    var(--panel-close-dur) var(--panel-ease);
}
.is-open .sheet { transform: none; filter: none; transition-duration: var(--panel-open-dur); }
.sheet.sheet-center,
.sheet-scrim.sheet-center .sheet {
  transform: scale(var(--modal-scale));
  filter: none;
  transition: transform var(--modal-close-dur) var(--modal-ease);
}
.is-open .sheet.sheet-center,
.sheet-scrim.sheet-center.is-open .sheet { transform: none; transition-duration: var(--modal-open-dur); }
.sheet-scrim.is-closing { transition-duration: var(--modal-close-dur); }
@media (min-width: 1000px) {
  .sheet { transform: scale(var(--modal-scale)); filter: none; transition: transform var(--modal-close-dur) var(--modal-ease); }
  .is-open .sheet { transform: none; transition-duration: var(--modal-open-dur); }
}
.drawer {
  filter: blur(var(--panel-blur));
  transition:
    transform var(--panel-close-dur) var(--panel-ease),
    filter    var(--panel-close-dur) var(--panel-ease);
}
.drawer-scrim.is-open .drawer { filter: none; transition-duration: var(--panel-open-dur); }

@media (prefers-reduced-motion: reduce) {
  .t-pg-out > .t-pg-in, .t-pg-host > .t-pg-old, .t-pg-run, .t-pill,
  .sheet, .sheet.sheet-center, .drawer { transition: none !important; }
  .t-pg-enter { opacity: 1; transform: none; filter: none; }
}
