/* App shell: bottom tab bar on mobile, right-hand sidebar on desktop.
   The 900px breakpoint is where the laptop layout takes over. */

.app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* ============================================================ Page */

.page {
  flex: 1;
  padding-block-end: calc(104px + var(--safe-bottom));   /* addendum §1 */
}

/* A page with no header has to clear the notch itself — see Page() in shell.js.
   The app runs viewport-fit=cover, so without this the first line of content
   genuinely sits under the status bar and the Dynamic Island. */
.page--safe { padding-block-start: var(--safe-top); }

.page__body {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--page-x);
}

/* Full-bleed sections (feed posts, banded lists) opt out of the gutter. */
.page__bleed {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}

/* When the floating dock is visible, give the page extra room. */
.app[data-dock="true"] .page {
  padding-block-end: calc(var(--nav-h) + 68px + var(--safe-bottom));
}

/* Screens whose primary action is pinned to the bottom edge (.actionbar) need
   room for it, or the last row of the list sits underneath. */
.page--actionbar {
  padding-block-end: calc(var(--nav-h) + 84px + var(--safe-bottom));
}

#app[data-activebar] .page--actionbar {
  padding-block-end: calc(var(--nav-h) + 140px + var(--safe-bottom));
}

/* Immersive screens (the active workout log) drop the tab bar entirely and
   let their own dock own the bottom edge. */
.app[data-chrome="immersive"] .nav { display: none; }

.app[data-chrome="immersive"] .page {
  padding-block-end: calc(var(--s6) + var(--safe-bottom));
}

.app[data-chrome="immersive"] .page--actionbar {
  padding-block-end: calc(88px + var(--safe-bottom));
}

.app[data-chrome="immersive"] .dock {
  inset-block-end: 0;
  padding-block-end: calc(var(--s3) + var(--safe-bottom));
}

.app[data-chrome="immersive"][data-dock="true"] .page {
  padding-block-end: calc(76px + var(--safe-bottom));
}

.app[data-chrome="immersive"] .toasts {
  inset-block-end: calc(var(--s6) + var(--safe-bottom));
}

/* ============================================================ Headers */

/* Tab-root header: large bold title at the start, actions at the end. */
.topbar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-nav);
  background: var(--bg);
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: calc(var(--header-h) + var(--safe-top));
  /* Padding rather than a taller box alone: the background must still fill
     the status-bar strip, or the notch area shows the page scrolling behind. */
  padding-block-start: var(--safe-top);
  padding-inline: var(--page-x);
}

.topbar__inner {
  display: flex;
  align-items: center;
  gap: var(--s2);
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}

.topbar__title {
  font-size: var(--fs-display);
  font-weight: var(--fw-bold);
}

/* Inner-page header — spec §1: back arrow at the start (right in RTL),
   title centred, extra actions at the end. */
.subbar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-nav);
  background: var(--surface-bar);
  min-height: calc(var(--header-h) + var(--safe-top));
  padding-block-start: var(--safe-top);
  display: flex;
  align-items: center;
  padding-inline: var(--s2);
}

.subbar__inner {
  display: flex;
  align-items: center;
  gap: var(--s1);
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}

.subbar__title {
  flex: 1;
  text-align: center;
  font-size: var(--fs-h);
  font-weight: var(--fw-bold);
}

/* Keeps the centred title honest when only one side has buttons. */
.subbar__slot {
  min-width: var(--tap);
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

/* ============================================================ Bottom navigation */

/* Solid, with a hairline above it.
 *
   The v2 design fades the bar out of the page with a gradient to black, and it
   looks better on a static canvas than it works on a moving one: the top half
   of the gradient is transparent, so scrolling text passes *through* the bar
   and sits behind the labels — half-visible, unreadable, and easy to mistake
   for a rendering fault. A tab bar is chrome; it is allowed to be opaque, and
   the page is padded to clear it so nothing is hidden by the change. */
.nav {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: var(--z-nav);
  background: var(--bg);
  border-block-start: 1px solid var(--hairline);
  padding-block-end: var(--safe-bottom);
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: var(--content-max);
  margin-inline: auto;
  /* 46px centre button + 26 + 20 = the 92px bar height the addendum specifies.
     Kept as padding rather than a fixed height so a larger OS text size grows
     the bar instead of clipping the labels. */
  padding: 20px var(--page-x) 16px;
}

/* Labels are not decoration: five destinations are not distinguishable by icon
   alone, which is why the addendum brought them back with the fifth tab. */
.nav__item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-block-size: var(--tap);
  color: var(--text-faint);
  transition: color var(--dur) var(--ease);
}

/* White, not accent — the bar never carries the accent, which is reserved for
   the one live thing on the screen itself. */
.nav__item[aria-current="page"] { color: var(--text); }
.nav__item .icon { width: 24px; height: 24px; }

.nav__label {
  font-size: 10px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.01em;
  /* Persian descends below the baseline further than Latin — the bowl of ن in
     تمرین was being clipped by a box sized to a Latin x-height. */
  line-height: 1.6;
  padding-block-end: 1px;
}

/* The centre action. Not a tab — it does something rather than going
   somewhere, so it is a button and reads as one. */
/* Accent-filled with its bloom, always — addendum §1. It is an action, not a
   destination, so it does not follow the tabs' white/grey treatment. */
/* The centre is the training tab, and it is deliberately the biggest, brightest
   thing on the bar. 58px against the 24px glyphs either side, lifted above the
   strip so it reads as one landmark rather than the middle of five icons — this
   is the app's main verb and it should be findable without looking. */
/* The centre is a tab like the others, not a floating button.
 *
 * It was a filled chartreuse disc, permanently glowing — which made "you are
 * here" unsayable, because the loudest thing on the bar was loud whether you
 * were on it or not. Now it is the same shape and rhythm as its neighbours and
 * earns its emphasis the same way: a bigger glyph always, the glow only when
 * it is the current tab. */
.nav__centre {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  flex: none;
  /* Tall enough for a 40px glyph and a line of type. Without it the bar sized
     itself to the tabs and the label was cut off at the baseline. */
  min-block-size: calc(var(--tap) + 14px);
  margin-inline: var(--s2);
  color: var(--text-dim);
  transition: transform var(--dur) var(--ease), color var(--dur) var(--ease);
}

.nav__centre:active { transform: scale(0.92); }

/* Larger than the other tabs at rest, so the bar still has a centre of gravity
   without needing a colour to say so. */
.nav__centre .icon {
  width: 40px;
  height: 40px;
  stroke-width: 2;
  /* flex: none matters. This is a column flex, so the glyph's height is the
     main axis and it was being shrunk below the size set here — which is why
     "make it bigger" appeared to do nothing. */
  flex: none;
  transition: filter var(--dur) var(--ease);
}

.nav__centre[aria-current="page"] {
  color: var(--accent);
}

/* The glow is the selected state, and only that. drop-shadow follows the glyph
   rather than boxing it, which is what makes it read as the icon lighting up
   instead of a plate behind it. */
.nav__centre[aria-current="page"] .icon {
  filter: drop-shadow(0 0 6px rgba(var(--accent-rgb), 0.9))
          drop-shadow(0 0 16px rgba(var(--accent-rgb), 0.5));
}

/* A session is running. The glyph does not change — it is the same destination
   either way — so the difference is carried by a stronger halo and a slow pulse,
   which reads as "something is happening" without moving anything. */
.nav__centre--live { color: var(--accent); }

.nav__centre--live .icon {
  animation: nav-live 2.4s var(--ease) infinite;
}

/* Pulses the glyph's own halo. The old keyframes animated box-shadow on a disc
   that has been removed; on a transparent tab that drew a rectangle of light
   around nothing. */
@keyframes nav-live {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(var(--accent-rgb), 0.55)); }
  50%      { filter: drop-shadow(0 0 12px rgba(var(--accent-rgb), 0.95)); }
}

@media (prefers-reduced-motion: reduce) {
  .nav__centre--live { animation: none; }
}

/* ============================================================ Desktop ≥900px */

@media (min-width: 900px) {
  :root {
    --page-x: 24px;
  }

  /* DOM order is [page, nav]; row-reverse in RTL lands the rail on the right. */
  .app {
    flex-direction: row-reverse;
  }

  /* Bottom bar becomes a vertical rail. In RTL that means the right edge.
     On a laptop there is room for words again, so the labels the phone gave up
     come back — `aria-label` is what the icon carries either way. */
  .nav {
    position: sticky;
    inset-block: 0 auto;
    inset-inline: auto;
    top: 0;
    height: 100dvh;
    width: var(--sidebar-w);
    flex: none;
    background: var(--bg);
    border-inline-start: 1px solid var(--hairline);
    padding-block: var(--s5);
  }

  .nav__inner {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: var(--s2);
    padding: var(--s3);
  }

  .nav__item {
    flex-direction: row;
    justify-content: flex-start;
    gap: var(--s3);
    min-height: 48px;
    padding-inline: var(--s3);
    border-radius: var(--r-md);
    font-size: var(--fs-body);
  }

  /* --accent-text, not --accent: this row paints --accent-soft behind itself,
     and the mid-tone accent on its own pale wash measured 2.9:1 — a label you
     cannot read on the tab you are standing on. The text variant exists for
     exactly this. Desktop-only, and it went unnoticed because the audit had
     been running at phone width where this rule does not apply. */
  .nav__item[aria-current="page"] {
    background: var(--accent-soft);
    color: var(--accent-text);
  }

  /* The centre action stops being centre and becomes the first row. */
  .nav__centre {
    inline-size: 100%;
    block-size: 48px;
    flex-direction: row;
    gap: var(--s2);
    order: -1;
  }

  .page {
    flex: 1;
    min-width: 0;
    padding-block-end: var(--s8);
  }

  .toasts {
    inset-block-end: var(--s6);
    inset-inline: 0 var(--sidebar-w);
  }

  .dock {
    inset-block-end: 0;
    inset-inline: 0 var(--sidebar-w);
  }

  .app[data-dock="true"] .page {
    padding-block-end: 96px;
  }

  .topbar,
  .subbar {
    padding-inline: var(--page-x);
  }

  /* Bottom sheets become centred dialogs on a laptop. */
  .scrim { align-items: center; justify-items: center; padding: var(--s6); }

  .sheet {
    border-radius: var(--r-xl);
    animation: pop var(--dur) var(--ease);
  }

  .sheet__grip { display: none; }
}

/* Two-column content used by profile / stats on wide screens. */
@media (min-width: 900px) {
  .cols-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s4);
    align-items: start;
  }
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s3);
}

/* One tile per row: the profile's social and support groups (owner, 3 Oct 2026). */
.grid-2--wide { grid-template-columns: 1fr; }



/* On the training tab. The fill is already the accent, so "you are here" is
   said by a ring rather than a colour change — there is no brighter red to go
   to, and shrinking or dimming the one landmark on the bar to indicate arrival
   would be backwards. */
.nav__centre[aria-current="page"] {
  outline: 2px solid var(--bg);
  outline-offset: -5px;
}
