/*
 * Every animated property here is transform or opacity. The blur is a static
 * class-level declaration, never a transition — animating backdrop-filter
 * per frame stutters badly in Telegram's WebView.
 */

/*
 * Two pieces of chrome float in the nav gutter: the tab bar and, detached
 * beside it, the account bubble. `.bottom-nav` is the row they sit in and is
 * itself invisible — no background, and clicks fall through it to the list
 * beneath everywhere the bar and the bubble are not (pointer-events: none is
 * inherited from .app__nav). It carries the retract, so the two travel as one
 * and each child's own transform is left to its press.
 */
.bottom-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--nav-gap);
  transform: translateY(0) scale(1);
  transition:
    transform var(--spring-duration) var(--spring),
    opacity var(--duration) var(--easing);
}

/* --- Floating chrome, shared by the bar and the bubble -------------------- */

.bottom-nav__bar,
.bottom-nav__account {
  background: var(--tg-surface);
  border: 1px solid var(--tg-border);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-floating);
  /* Re-enable hits the .app__nav gutter opts out of. */
  pointer-events: auto;
}

/*
 * Frosted chrome. Translucency is only applied where the blur can back it up —
 * without it, semi-transparent chrome just looks like a bug.
 *
 * The blur is a separate class because compositing a live backdrop against a
 * *moving* element is the thing that stutters in Telegram's WebView. The row
 * drops --blurred for the duration of the retract, then takes it back once it
 * has settled; the background stays translucent throughout, so nothing flashes.
 */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .bottom-nav__bar,
  .bottom-nav__account {
    background: rgb(var(--tg-surface-rgb) / 0.72);
  }

  .bottom-nav--blurred .bottom-nav__bar,
  .bottom-nav--blurred .bottom-nav__account {
    -webkit-backdrop-filter: blur(18px) saturate(180%);
    backdrop-filter: blur(18px) saturate(180%);
  }
}

/* Scroll-away state: transform + opacity only, so layout never reflows. */
.bottom-nav[data-retracted="true"] {
  transform: translateY(calc(100% + var(--space-6))) scale(0.94);
  opacity: 0;
}

/* The children re-enable hits above, so the row's own none does not reach them. */
.bottom-nav[data-retracted="true"] > * {
  pointer-events: none;
}

/* --- Tab bar ------------------------------------------------------------- */

.bottom-nav__bar {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  /*
   * Every column carries the same floor (set from the widest label by
   * BottomNav.js), so the columns stay equal at any width instead of one
   * label winning extra space. Below the floor the bar itself grows, via
   * min-width: min-content.
   */
  grid-auto-columns: minmax(var(--nav-column-min, 0px), 1fr);
  width: var(--nav-width);
  /* Expand past the target rather than clip labels on very narrow screens. */
  min-width: min-content;
  /* Keeps the end labels clear of the pill's curve. */
  padding-inline: var(--space-2);
  min-height: var(--nav-height);
}

/* --- Account bubble ------------------------------------------------------ */

/*
 * A circle the bar's height, so the two read as one family at one scale. The
 * whole bubble is the button: the press scale from [data-pressable] in
 * interactions.css lands on this element, which is why the retract's
 * transform had to live on the row and not here.
 */
.bottom-nav__account {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--nav-height);
  height: var(--nav-height);
}

/*
 * The no-photo fallback in the accent tint the active pill uses, rather than
 * the sunken grey a crest gets — a grey disc in a frosted circle reads as a
 * missing image, while the tint reads as the same language as the bar.
 */
.bottom-nav__account .logo--monogram {
  background: rgb(var(--tg-accent-rgb) / 0.12);
  color: var(--tg-accent);
  font-size: 12px;
}

/* --- Active indicator ---------------------------------------------------- */

/*
 * Spans the full column — icon and label both sit on it. Height comes from
 * top/bottom so it tracks --nav-height on its own; BottomNav.js sets only the
 * width, once per layout, leaving the per-switch animation pure translateX.
 */
.bottom-nav__indicator {
  position: absolute;
  top: var(--nav-indicator-inset);
  bottom: var(--nav-indicator-inset);
  left: 0;
  border-radius: var(--nav-indicator-radius);
  background: rgb(var(--tg-accent-rgb) / 0.12);
  opacity: 0;
  pointer-events: none;
}

/* Added one frame after mount so the first placement does not fly in from 0. */
.bottom-nav--ready .bottom-nav__indicator {
  opacity: 1;
  transition:
    transform var(--spring-duration) var(--spring),
    opacity var(--duration) var(--easing);
}

/* --- Items --------------------------------------------------------------- */

.nav-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: var(--space-1) 2px;
  border-radius: var(--radius-full);
  color: var(--tg-hint);
  /* Press scale comes from [data-pressable] in interactions.css. */
  transition:
    color var(--duration) var(--easing),
    transform var(--spring-duration) var(--spring);
}

/* Active = the accent, filled icon, and bold label — the label's own box
   stays fixed-width regardless (see the ::before ghost below), so this never
   resizes the column. */
.nav-item[aria-current="page"] {
  color: var(--tg-accent);
}

.nav-item__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  transition: transform var(--spring-duration) var(--spring);
}

.nav-item__glow {
  position: absolute;
  inset: -12px;
  border-radius: var(--radius-full);
  background: radial-gradient(
    circle,
    rgb(var(--tg-accent-rgb) / 0.38) 0%,
    rgb(var(--tg-accent-rgb) / 0) 70%
  );
  opacity: 0;
  transform: scale(0.5);
  pointer-events: none;
  transition:
    opacity var(--duration) var(--easing),
    transform var(--duration) var(--easing);
}

.nav-item[data-pressed="true"] .nav-item__glow {
  opacity: 1;
  transform: scale(1);
}

/* --- Outline / filled cross-fade ----------------------------------------- */

.nav-item__layer {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  transition: opacity var(--duration) var(--easing);
}

.nav-item__layer--filled {
  opacity: 0;
}

.nav-item[aria-current="page"] .nav-item__layer--outline {
  opacity: 0;
}

.nav-item[aria-current="page"] .nav-item__layer--filled {
  opacity: 1;
}

/* Runs whenever the item starts matching aria-current, i.e. on every select. */
.nav-item[aria-current="page"] .nav-item__icon {
  animation: nav-pop var(--spring-duration) var(--spring);
}

@keyframes nav-pop {
  0% {
    transform: scale(1);
  }
  45% {
    transform: scale(1.15);
  }
  100% {
    transform: scale(1);
  }
}

/* --- Label ---------------------------------------------------------------- */

/*
 * Always visible, regular weight by default — the active item goes semibold
 * below. The label's rendered width still only ever reflects this weight:
 * the ::before ghost carries the semibold width instead, so sizeIndicator()'s
 * one-time measurement already accounts for it and switching active items
 * never resizes the column or drags the indicator with it.
 *
 * 10px, the size a platform tab label is. It was 11 with three tabs; the
 * fourth beside the account bubble left no row for that on a 360px screen —
 * see COLUMN_AIR in BottomNav.js for what gives way after this has.
 */
.nav-item__label {
  position: relative;
  font-size: 10px;
  font-weight: var(--weight-medium);
  line-height: 1;
  white-space: nowrap;
}

/* Invisible semibold twin, zero height, reserving the wider width up front. */
.nav-item__label::before {
  content: attr(data-label);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: var(--weight-semibold);
}

.nav-item[aria-current="page"] .nav-item__label {
  font-weight: var(--weight-semibold);
}

/* --- Notification badge ---------------------------------------------------- */

.nav-item__badge {
  position: absolute;
  top: -8px;
  left: 12px;
  display: grid;
  place-items: center;
  min-width: 16px;
  height: 16px;
  padding-inline: 4px;
  border-radius: var(--radius-full);
  background: var(--tg-accent);
  color: var(--tg-accent-text);
  font-size: 9px;
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  animation: nav-badge-in var(--spring-duration) var(--spring) backwards;
}

@keyframes nav-badge-in {
  0% {
    transform: scale(0);
  }
  60% {
    transform: scale(1.25);
  }
  100% {
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav-item__badge,
  .nav-item[aria-current="page"] .nav-item__icon {
    animation: none;
  }
}
