/* ===========================================================================
   pwa.css — Collectality installed as an app (manifest.webmanifest, sw.js,
   js/pwa.js): room for the status bar, and the offer to install.

   Loaded last. Installed on an iPhone or iPad, the status bar is opaque
   (index.html: default) and the page starts below it, so
   env(safe-area-inset-top) is 0. A copy added to the Home Screen while the
   page asked for black-translucent still runs up under a see-through bar,
   and there the inset is that bar's height: everything below keeps such a
   copy right too. Everything about it is scoped to an installed app's
   display modes. In a browser tab — and in an
   installed app on Android or a desktop, which keep their own bar above the
   page — the inset is 0 and none of this moves a pixel. The left and right
   insets (a phone on its side) and the bottom one are already looked after
   where they matter: bottomnav.css (safe areas), and the whole-screen sheets
   in search.css and kit-form.css, which pad all four sides.
   =========================================================================== */

:root { --safe-top: 0px; }

@media screen and (display-mode: standalone), screen and (display-mode: fullscreen) {
  :root { --safe-top: env(safe-area-inset-top, 0px); }

  /* black-translucent draws the page under the status bar, and a height of
     100% (or 100dvh) is then the screen minus that inset, which leaves an
     empty band the same size under the app. 100vh is the screen itself. */
  html {
    height: 100vh;
    min-height: -webkit-fill-available;
  }
  body:not(.is-landing) {
    height: 100vh;
    min-height: -webkit-fill-available;
  }
  /* …but where the page starts below an opaque status bar, 100vh is still the whole screen
     and runs that bar's height off the bottom: the window's own height (pwa.js --app-h). */
  html.has-app-h, html.has-app-h body:not(.is-landing) { height: var(--app-h); min-height: 0; }

  /* The top bar grows by the inset and keeps its 52px row beneath it. Every
     view is sized as the screen less 52px (app.css, shell.css, shelves.css…);
     rather than teach each one about the inset, the page becomes a column and
     each view takes what the bar leaves (a flex-basis of 0 outranks its
     height). The landing page scrolls as a page, and has its own header. */
  body:not(.is-landing) { display: flex; flex-direction: column; }
  body:not(.is-landing) > .topbar {
    flex: none;
    height: calc(52px + var(--safe-top));
    padding-top: var(--safe-top);
  }
  body:not(.is-landing) > main { flex: 1 1 0; min-height: 0; }

  /* The landing page's sticky header, the same way: its glass runs up under the bar. */
  .landing .lp-head { height: calc(var(--lp-head-h) + var(--safe-top)); padding-top: var(--safe-top); }

  /* Dialogs keep below the status bar, and the ones that take the whole
     screen pad their top (the picker and the kit form already do). */
  .modal-root { padding-top: max(20px, var(--safe-top)); }
  @media (max-width: 640px) {
    .modal.modal-settings { padding-top: var(--safe-top); }
  }
  @media (max-width: 480px) {
    .modal.cab-dlg { padding-top: var(--safe-top); }
  }

  /* The search filters' drawer hangs from under the top bar. */
  @media (max-width: 980px) {
    .filter-dock { top: calc(52px + var(--safe-top)); }
  }

  /* Only for a copy still under a see-through status bar (the inset is 0
     otherwise, and so is this band). Since iOS 26 an installed web app gets
     the Liquid Glass "scroll edge effect" — a blur — over that strip; iOS is
     meant to skip it when a fixed or sticky box with a background covers the
     top edge, and this band is that box, in the top bar's own colour. (On a
     phone it did not always do so: an opaque status bar, index.html, is the
     fix that holds.) black-translucent draws the time and battery in white,
     whatever the theme: on the light theme they would vanish, so there the
     band is dark. */
  body::before {
    content: ""; position: fixed; top: 0; left: 0; right: 0; z-index: 100;
    height: var(--safe-top);
    background: color-mix(in srgb, var(--bg-2) 72%, var(--bg));
  }
  :root[data-theme="light"] body::before { background: #141820; }
}

/* ============================================================ install card
   Home on a phone or tablet, until it is dismissed (pwa.js paintCard): a
   small glass card just above the bottom bar, under any dialog and toast. */
.install-card {
  position: fixed; z-index: 50;
  left: max(12px, env(safe-area-inset-left, 0px));
  right: max(12px, env(safe-area-inset-right, 0px));
  bottom: calc(var(--bottomnav-h, env(safe-area-inset-bottom, 0px)) + 12px);
  width: auto; max-width: 460px; margin-inline: auto;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 8px 10px 10px;
  background: var(--glass);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.2);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--glass-edge), var(--shadow-2);
  animation: install-card-in var(--t-3) var(--ease-out);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .install-card { background: var(--bg-2); }
}
@keyframes install-card-in { from { opacity: 0; transform: translateY(12px); } }
:root[data-motion="reduced"] .install-card { animation-name: mo-view-in; }

.install-card-icon { flex: none; width: 40px; height: 40px; border-radius: 10px; box-shadow: var(--shadow-1); }
.install-card-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; font-size: 12.5px; line-height: 1.4; color: var(--ink-2); }
.install-card-text strong { font-size: 13.5px; font-weight: 650; color: var(--ink); letter-spacing: -0.01em; }
.install-card-go { flex: none; }
.install-card-x {
  flex: none; display: grid; place-items: center;
  width: 36px; height: 36px; padding: 0;
  background: none; border: none; border-radius: var(--radius-sm);
  color: var(--ink-3); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.install-card-x:hover { color: var(--ink); background: var(--bg-3); }

/* Toasts come up above the card rather than over it (pwa.js measures it). As
   specific as bottomnav.css's rule for the toasts, and later, so it wins. */
body.has-install-card:not(.is-signin, .is-landing, .is-shared) .toast-stack {
  bottom: calc(var(--bottomnav-h, env(safe-area-inset-bottom, 0px)) + 12px + var(--install-card-h, 0px));
}
/* And the end of every page that scrolls can be scrolled out from under it. */
body.has-install-card:not(.is-signin, .is-landing, .is-shared) > :is(.view-home, .view-library, .view-sets, .view-shelves, .view-insights, .view-collection, .view-admin) {
  padding-bottom: calc(var(--bottomnav-h, 0px) + var(--install-card-h, 0px));
  scroll-padding-bottom: calc(var(--bottomnav-h, 0px) + var(--install-card-h, 0px));
}

/* Safari's Share icon, inline with the words that say to tap it. */
.pwa-share-wrap { display: inline-flex; vertical-align: -3px; margin: 0 2px; color: var(--accent-text); }
.pwa-share { display: block; }
.pwa-steps b, .pwa-how b { color: var(--ink); font-weight: 650; }
.pwa-how { margin: 0; font-size: 13.5px; color: var(--ink-2); }

@media print {
  .install-card { display: none !important; }
}

/* ---- no connection (offline.js): a quiet pill in the top bar */
.offline-pill {
  display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px;
  border-radius: 999px; font-size: 12px; font-weight: 700; white-space: nowrap;
  color: var(--gold-text); background: color-mix(in srgb, var(--gold) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gold) 40%, transparent);
}
.offline-pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.offline-pill[hidden] { display: none; }
