/* Boot and first-paint skeleton styles: the member shell's cold-start and
   repeat-visit experience, before the routed view (Overview/Collection/
   Discover/...) takes over. Owned by the boot work-stream; per-module
   loading skeletons for an already-mounted view live in each view's own
   stylesheet (site/overview.css, site/watches.css, ...) and are untouched
   here. Tokens only, from site/member-tokens.css -- no new colors. */

/* ---- shared shimmer primitive ------------------------------------------- */
.ps-boot-shimmer {
  display: block;
  border-radius: var(--radius-xs);
  background: linear-gradient(105deg, var(--well) 15%, var(--card1-hi) 42%, var(--well) 68%);
  background-size: 220% 100%;
  animation: member-shimmer var(--duration-ambient) ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ps-boot-shimmer { animation: none; background: var(--card1-hi); }
}

/* ---- sidebar / bottom nav skeleton (first-ever visit) ------------------- */
/* Every real nav item, present and legible, rather than missing -- the
   sidebar disappearing entirely was one of the three named defects in the
   boot-screen report. Disabled, not interactive, until site/member.js's
   real GET /bootstrap-driven sidebar replaces this node outright. */
#member-shell .ps-boot-nav-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; min-height: var(--control-height); padding: 0 var(--space-2);
  border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--muted); font: 400 var(--font-size-400)/1.25 var(--font-sans); text-align: left;
  opacity: .55; cursor: default;
}
@media (pointer: fine) { #member-shell .ps-boot-nav-item { min-height: 32px; } }
.ps-boot-nav-item .ps-icon { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; }
@media (max-width: 899px) {
  #shell-sidebar.ps-boot-nav .ps-boot-nav-item span { display: none; }
  #shell-sidebar.ps-boot-nav .ps-boot-nav-item { justify-content: center; padding-inline: 0; }
}
/* #shell-bottomnav lays its five items out as a horizontal row of icon-over-
   label columns (site/shell.css's #shell-bottomnav .ps-tabs__item), not the
   sidebar's icon-beside-label rows -- .ps-boot-nav-item's shared default
   above is the sidebar shape, so the phone bar needs its own layout here or
   every label wraps one character per line in a column that narrow.
   MUST stay gated to the exact breakpoint site/shell.css's own
   `#shell-bottomnav:not([hidden]) { display: flex; }` uses (max-width:
   899px) -- an earlier, ungated version of this rule set `display:flex`
   unconditionally, which (being a class selector, so more specific than the
   base `#shell-bottomnav, ... { display:none }` rule) rendered the phone
   tab bar at every width, desktop included, for as long as .ps-boot-nav
   stayed on the element. Caught 2026-09-24 from a 1280x900 visual-suite
   diff after the real shell had already replaced this file's own skeleton
   nav -- MEASURED: the leftover class outlived this node's skeleton
   content, so an ungated rule here is never safe, regardless of whether
   the class itself is ever cleared afterwards. */
@media (max-width: 899px) {
  #shell-bottomnav.ps-boot-nav {
    display: flex; justify-content: space-around;
  }
  #shell-bottomnav.ps-boot-nav .ps-boot-nav-item {
    flex: 1 1 0; flex-direction: column; justify-content: center; align-items: center; gap: 2px;
    width: auto; min-height: 52px; min-width: 0; padding: var(--space-1);
    border-left: 0; text-align: center;
  }
  #shell-bottomnav.ps-boot-nav .ps-boot-nav-item span {
    max-width: 100%; font-size: var(--font-size-100); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
}

/* ---- header: instant-paint revalidation indicator ------------------------ */
#ps-boot-revalidate {
  margin: 0; padding: var(--space-1) var(--space-4);
  font: 400 var(--font-size-200)/var(--leading-snug) var(--font-sans);
  color: var(--muted); text-align: center;
  border-bottom: var(--border-hairline) solid var(--border-dash);
  background: var(--well);
}
#ps-boot-revalidate[data-state="stale"] { color: var(--status-stale, var(--muted)); }
#ps-boot-revalidate .ps-boot-revalidate-retry {
  margin-left: var(--space-2); border: 0; background: none; padding: 0;
  color: var(--accent); font: inherit; text-decoration: underline; cursor: pointer;
}

/* ---- first-ever-visit skeleton body -------------------------------------- */
#member-boot-skeleton { animation: ps-boot-fade 150ms ease-out; }
@keyframes ps-boot-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #member-boot-skeleton { animation: none; } }

/* Ending-soon row skeleton, mirrors moduleSkeleton('row', n)'s own
   .alert-receipt shape (site/member.js) so the handoff to the real
   #hd-ending-soon-body skeleton (same markup) is an exact-size no-op. */
.ps-boot-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) 0; }
.ps-boot-row-art { width: 40px; height: 56px; border-radius: var(--radius-xs); flex: none; }
.ps-boot-row-lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }

/* Discover / Collection first-visit shapes (spec 2) -- built once here
   rather than duplicated per screen; each screen host adds one extra class
   (ps-boot-tiles--collection / --discover) only where its grid differs. */
.ps-boot-search-card { height: 96px; border-radius: var(--radius-md); margin: 0 0 var(--space-4); }
.ps-boot-set-row { display: flex; gap: var(--space-3); margin: 0 0 var(--space-4); overflow: hidden; }
.ps-boot-set-chip { width: 92px; height: 34px; border-radius: 999px; flex: none; }
.ps-boot-filter-bar { height: 44px; border-radius: var(--radius-sm); margin: 0 0 var(--space-4); }
.ps-boot-stat-card { height: 84px; border-radius: var(--radius-md); margin: 0 0 var(--space-4); }
.ps-boot-chart-block { height: 220px; border-radius: var(--radius-md); margin: 0 0 var(--space-4); }
.ps-boot-tile-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
@media (min-width: 640px) { .ps-boot-tile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .ps-boot-tile-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.ps-boot-slab-tile { aspect-ratio: 5 / 7; border-radius: var(--radius-sm); }

/* A pending read belongs under the route heading, not in a full-screen stage.
   Same owner for first boot and the authenticated Collection fetch. */
.collection-boot-ash {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--space-8);
  padding: var(--space-3) 0;
  border-block-start: var(--border-hairline) solid var(--border);
  color: var(--body);
}
.collection-boot-ash p { margin: 0; color: var(--body); font: 400 var(--font-size-400)/var(--leading-snug) var(--font-sans); }

#member-shell #member-persistent-loader[data-recovery-state="waiting"] .module-pending__orbit { animation: none; }

/* ---- "showing saved data" fallback banner -------------------------------- */
.ps-boot-saved-banner {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-4);
  border: var(--border-hairline) dashed var(--border-dash); border-radius: var(--radius-sm);
  background: var(--well); color: var(--body); font: 400 var(--font-size-300)/var(--leading-snug) var(--font-sans);
}
.ps-boot-saved-banner button { border: 0; background: none; padding: 0; color: var(--accent); font: 700 inherit; cursor: pointer; text-decoration: underline; }

/* ---- calm inline "still loading" line inside the boot skeleton (spec 3) - */
.ps-boot-still-loading {
  grid-column: 1 / -1; flex-basis: 100%; margin: var(--space-2) 0 0; color: var(--muted);
  font: 400 var(--font-size-300)/var(--leading-snug) var(--font-sans);
}
.ps-boot-still-loading button {
  min-width: 44px; min-height: 44px; margin-left: var(--space-2); border: var(--border-hairline) solid var(--border-control);
  border-radius: var(--radius-xs); background: none; padding: var(--space-1) var(--space-2); color: inherit; cursor: pointer;
}
