/*
 * Native shell styles must load from the document head. StX component styles
 * are emitted as body links, which bundled WebViews can paint before loading.
 */

/*
 * Two quick taps zoomed the whole page in the app: WebKit's double-tap to
 * zoom, which no native app does, and which also makes every single tap wait
 * to see whether a second one is coming. `manipulation` keeps panning and
 * pinch-zoom, so zoom stays available to anyone who needs it, and drops only
 * the double-tap gesture and its delay. Maps declare their own touch-action
 * and keep it: the browser applies the stricter of an element's and its
 * ancestors'.
 */
.native-app-shell { touch-action: manipulation; }

.native-app-shell {
  --native-safe-area-top: env(safe-area-inset-top, 0px);
  --native-safe-area-right: env(safe-area-inset-right, 0px);
  --native-safe-area-bottom: env(safe-area-inset-bottom, 0px);
  --native-safe-area-left: env(safe-area-inset-left, 0px);

  /* The tab row itself, without the home-indicator inset underneath it.
   * 3.25rem sits just above Apple's own 49pt tab bar, which is what the eye
   * is calibrated against — the previous 4rem, with the inset folded into the
   * row rather than left below it, made the bar 98pt tall on an iPhone 17 Pro
   * and floated the icons in the middle of it. */
  --native-tab-height: 3.25rem;

  /* Clearance under the row, for the home indicator.
   *
   * Apple reserves the full 34pt inset and leaves it blank, which on this bar
   * reads as a band of nothing beneath the labels — the gap that keeps getting
   * flagged. 0.75rem is enough to keep the indicator off the touch targets
   * without handing a third of the bar's height to empty space, and it
   * collapses to 0 on a device that has no inset. */
  --native-tab-inset: min(var(--native-safe-area-bottom), 0.75rem);

  min-height: 100dvh;
  color: inherit;
  background: inherit;
  padding-top: var(--native-safe-area-top);
  padding-right: var(--native-safe-area-right);
  padding-left: var(--native-safe-area-left);
}

.native-app-shell::before {
  content: '';
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 35;
  height: var(--native-safe-area-top);
  pointer-events: none;
  background: var(--native-safe-area-background, Canvas);
}

.native-app-content {
  min-height: calc(100dvh - var(--native-safe-area-top));
  padding-bottom: var(--native-safe-area-bottom);
}

/* Native WebViews can be wide and use either coarse or fine pointer media
 * characteristics. Do not make clearance for a fixed native tab bar depend
 * on those browser heuristics, or login and form actions can end up behind it. */
.native-app-shell.native-mobile:has(.native-app-tab-slot) .native-app-content {
  padding-bottom: calc(var(--native-tab-height) + var(--native-tab-inset));
}

/* Clearance wherever the bar is on screen. It used to stop at 768px, but the
 * bar stays up to the desktop breakpoint below, so a tablet had the last
 * row of every page sitting underneath it. The desktop rule further down
 * takes the clearance away again exactly where it hides the bar. */
.native-app-shell:has(.native-app-tab-slot) .native-app-content {
  padding-bottom: calc(var(--native-tab-height) + var(--native-tab-inset));
}

.native-app-sticky-top { top: var(--native-safe-area-top); }

/* The app has no site header.
 *
 * A wordmark with Log in and Sign up beside it is a website's furniture, and
 * inside a WebView it is the loudest tell that this is one. Every screen here
 * already carries its own title, and the tab bar is the navigation. The bar
 * stays on the mobile *web*, where it is the only navigation there is. */
.native-app-shell.native-mobile .native-app-sticky-top:not(.native-app-header) { display: none; }

/* Except as the app's own top bar on the Feed and the Menu: the brand, search
 * and notifications, as Instagram and Strava carry theirs. It marks itself
 * with .native-app-header on those screens (mobile-header.stx). Its website
 * furniture - Log in, Sign up, the settings gear - is marked .web-only. */
.native-app-shell.native-mobile .web-only { display: none !important; }

/* Shown only inside the native shell — for the handful of controls that lived
 * in that header and still need somewhere to be. */
.native-only { display: none !important; }
.native-app-shell.native-mobile .native-only { display: inline-flex !important; }

.native-app-tab-slot {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 30;
  display: grid;
  grid-template-rows: minmax(0, 1fr);
  height: calc(var(--native-tab-height) + var(--native-tab-inset));
  /* The clearance is padding, not part of the row: the controls centre across
   * the row alone, and the indicator passes over the bar's own background
   * rather than over a label. */
  padding-bottom: var(--native-tab-inset);
  padding-right: var(--native-safe-area-right);
  padding-left: var(--native-safe-area-left);
  background: rgb(255 255 255 / 0.9);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
}

/* STX wraps the slotted tab-bar component in an unclassed scope div. Left
 * block-level it is content-sized, so it collapsed to ~33px and the nav's
 * `height: 100%` resolved against that instead of the 4rem slot -- the
 * controls filled half the footer with dead space beneath. Stretch every
 * wrapper between the slot and the nav. */
.native-tab-visibility,
.native-tab-visibility > * {
  height: 100%;
}

/* A sheet or modal inside the page cannot rise above the tab bar: the router
 * gives <main> a view-transition-name, which makes it a stacking context of
 * its own, so no z-index inside it clears the bar. An overlay marks itself
 * with data-covers-tab-bar instead, and the bar steps aside while it is open. */
.native-app-shell:has([data-covers-tab-bar]) .native-app-tab-slot { display: none; }

.native-tab-bar {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  /* A grid's implicit row is content-sized by default. That left the labels
   * pinned to the top of the native bar and made the unused lower half look
   * like a large spacing error, especially in landscape. Make its sole row
   * fill the fixed touch target instead. */
  grid-auto-rows: minmax(0, 1fr);
  /* 100% of the slot's content box, which now excludes the safe-area padding,
   * so the controls centre across the tab row alone. */
  height: 100%;
  border-top: 1px solid rgb(148 163 184 / 0.22);
  background: rgb(255 255 255 / 0.9);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
}

/* STX places each slotted tab component inside a scope wrapper. Stretch both
 * that wrapper and its link so flex centering applies to the full tab height,
 * rather than to a content-sized link at the top of the bar. */
.native-tab-bar > [data-stx-scope] {
  display: flex;
  min-width: 0;
}

.native-tab-item {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.3rem;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  color: rgb(100 116 139);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.1;
  text-decoration: none;
  transition: color 150ms ease, transform 150ms ease;
  -webkit-tap-highlight-color: transparent;
  /* Chrome, not content: no text selection, callout or link drag on a press
   * that the WebView received late (see followLongPress in NativeTabItem). */
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
  user-select: none;
}

.native-tab-item:active { transform: scale(0.96); }
.native-tab-item.is-active { color: rgb(5 150 105); }
/* Iconify's `i-lucide-*` classes set `width: 1em; height: 1em` at the same
 * specificity and load after this file, so a bare `.native-tab-icon` rule lost
 * and the glyphs silently tracked font-size. Qualify it to win. */
.native-tab-item .native-tab-icon { width: 1.5rem; height: 1.5rem; }

/* A native WebView can report a desktop-sized CSS viewport on a high-density
 * phone. Width alone therefore cannot decide whether this touch navigation
 * belongs on screen. Fine-pointer desktops retain the full navigation and
 * hide the tab bar, while touch-first native shells keep it at every width. */
@media (min-width: 1024px) and (pointer: fine) {
  .native-tab-visibility { display: none; }
  /* The slot, not only its contents. Hiding the bar inside left the fixed
   * slot itself on screen: 52px of translucent white pinned over the bottom
   * of every desktop page, covering the footer's last line. */
  .native-app-shell:not(.native-mobile) .native-app-tab-slot { display: none; }
  .native-app-shell:has(.native-app-tab-slot) .native-app-content { padding-bottom: 0; }

  .native-app-shell.native-mobile .native-tab-visibility { display: block; }
  .native-app-shell.native-mobile .native-app-content {
    padding-bottom: calc(var(--native-tab-height) + var(--native-tab-inset));
  }
}

.dark .native-tab-bar {
  border-color: rgb(71 85 105 / 0.55);
  background: rgb(15 23 42 / 0.9);
}

.dark .native-app-tab-slot { background: rgb(15 23 42 / 0.9); }

.dark .native-tab-item { color: rgb(148 163 184); }
.dark .native-tab-item.is-active { color: rgb(52 211 153); }

@media (prefers-reduced-transparency: reduce) {
  .native-tab-bar {
    background: rgb(255 255 255);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .dark .native-tab-bar { background: rgb(15 23 42); }
  .dark .native-app-tab-slot { background: rgb(15 23 42); }
}

/* In the app the tab bar floats: a pill inset from the edges and sitting
 * above the home indicator, as iOS 26 apps draw theirs, with the page
 * scrolling on underneath it. The website keeps the full-width bar above. */
.native-app-shell.native-mobile {
  --native-tab-float-bottom: max(calc(var(--native-safe-area-bottom) - 0.5rem), 0.75rem);
}

.native-app-shell.native-mobile .native-app-tab-slot {
  right: calc(var(--native-safe-area-right) + 1rem);
  bottom: var(--native-tab-float-bottom);
  left: calc(var(--native-safe-area-left) + 1rem);
  height: calc(var(--native-tab-height) + 0.5rem);
  padding: 0;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.native-app-shell.native-mobile .native-tab-bar {
  overflow: hidden;
  border: 1px solid rgb(148 163 184 / 0.25);
  border-radius: 9999px;
  box-shadow: 0 12px 32px -12px rgb(15 23 42 / 0.45);
}

.native-app-shell.native-mobile:has(.native-app-tab-slot) .native-app-content {
  padding-bottom: calc(var(--native-tab-height) + 0.5rem + var(--native-tab-float-bottom) + 0.75rem);
}

.dark .native-app-shell.native-mobile .native-app-tab-slot { background: transparent; }
.dark .native-app-shell.native-mobile .native-tab-bar { border-color: rgb(71 85 105 / 0.6); }
