/* Gaffer IQ — layout.css
   App shell: sticky nav, module sections, horizon switcher.
   No component-specific styles here — those belong in components.css.
   All values reference var(--…) from base.css. */

/* ─── App shell ──────────────────────────────────────────────────────────── */

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

/* ─── Top nav ────────────────────────────────────────────────────────────── */

.app-nav {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: 0 var(--space-6);
  height: var(--app-header-height);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: 100;
  flex-shrink: 0;
}

.app-nav__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  color: var(--color-text);
  flex-shrink: 0;
}

.app-nav__logo {
  font-size: var(--font-size-lg);
  line-height: 1;
}

.app-nav__title {
  font-size: var(--font-size-md);
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

/* ─── Module navigation ──────────────────────────────────────────────────── */

.module-nav {
  display: flex;
  gap: 0;
  flex: 1;
}

.module-nav__item {
  display: flex;
  align-items: center;
  padding: 0 var(--space-4);
  height: var(--app-header-height);
  font-size: var(--font-size-sm);
  font-weight: 500;
  color: var(--color-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  white-space: nowrap;
}

.module-nav__item:hover {
  color: var(--color-text);
}

.module-nav__item.is-active {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}

.module-nav__item--inactive {
  opacity: 0.35;
  pointer-events: none;
}

/* ─── Main content ───────────────────────────────────────────────────────── */

.app-main {
  flex: 1;
  padding: var(--space-6);
  max-width: 1400px;
  width: 100%;
  margin: 0 auto;
}

/* ─── Module sections ────────────────────────────────────────────────────── */

.module-view {
  display: none;
}

.module-view.is-active {
  display: block;
}

/* ─── Landing route ──────────────────────────────────────────────────────── */

/* The landing page is a module view like any other (data-module="landing", see
   CONVENTIONS.md §6) so hash routing, deep links and the render-when-visible
   contract all keep working untouched. It just needs the app chrome out of the
   way: it carries no nav of its own by design, and it is a full-bleed,
   viewport-height composition rather than a padded document inside .app-main.

   KEYED OFF :has(), NOT A JS-APPLIED BODY CLASS. js/main.js is a module with a
   large import graph, so the browser paints long before the router runs — a
   class added in JS meant the fully-styled nav rendered and then vanished, a
   visible flash on every load. index.html already ships with .is-active on the
   landing section, so this resolves during the first style pass with no script
   involved, and it re-derives itself for free every time routeToHash() moves
   the class. Nothing here depends on load order.

   :has() is baseline across the evergreen browsers this project targets
   (CONVENTIONS.md §1). Where it is unsupported the app chrome simply stays
   visible on the landing route — degraded, not broken. */

/* NOT `display: none` on .app-nav. assets/js/back-to-jayjaybee.js injects the
   shared "‹ jayjaybee.com" link as the first child of this header, so hiding
   the header outright would take that link with it and strand the landing page
   with no route back to the parent site. Instead the bar is emptied of app
   chrome and left in place, transparent, carrying only the injected link.

   position: fixed rather than sticky so the bar leaves the flex flow entirely
   and the landing keeps the full viewport height it centres against. */
body:has(.landing.is-active) .app-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  background: transparent;
  border-bottom: none;
}

body:has(.landing.is-active) .app-nav__brand,
body:has(.landing.is-active) .module-nav {
  display: none;
}

/* Drop .app-main's centred 1400px column and its padding so the landing can
   own the full viewport. The landing section re-establishes its own 1280px
   max-width internally. */
body:has(.landing.is-active) .app-main {
  max-width: none;
  padding: 0;
}

/* The FPL error banner is app chrome too. Data still loads behind the landing
   and the banner still populates — it is only visually suppressed here, and
   reappears intact the moment the visitor enters a module. */
body:has(.landing.is-active) .app-error-banner {
  display: none;
}

/* ─── Error banner ───────────────────────────────────────────────────────── */

.app-error-banner {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--band-red-bg);
  border: 1px solid var(--band-red);
  border-radius: var(--radius-md);
  color: var(--band-red);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}

/* The HTML `hidden` attribute applies `display: none` via the user-agent
   stylesheet, but the author rule above (`display: flex`) overrides it.
   Restore the expected behaviour so the banner stays hidden until an error
   actually fires. */
.app-error-banner[hidden] {
  display: none;
}

.app-error-banner__retry {
  background: none;
  border: 1px solid var(--band-red);
  border-radius: var(--radius-sm);
  color: var(--band-red);
  cursor: pointer;
  font-size: var(--font-size-sm);
  font-family: var(--font-sans);
  padding: 2px var(--space-2);
  flex-shrink: 0;
  transition: background 0.15s;
}

.app-error-banner__retry:hover {
  background: var(--band-red-bg);
}

/* ─── Module loading / placeholder ──────────────────────────────────────── */

.app-status {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 180px;
  color: var(--color-muted);
  font-size: var(--font-size-md);
}

.coming-soon {
  color: var(--color-muted);
  font-size: var(--font-size-md);
  padding: var(--space-8) 0;
  text-align: center;
}

/* ─── Responsive fallback ────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .app-nav {
    flex-wrap: wrap;
    height: auto;
    padding: var(--space-2) var(--space-4);
    gap: var(--space-2);
  }

  .module-nav {
    order: 3;
    width: 100%;
    border-top: 1px solid var(--color-border);
  }

  .module-nav__item {
    height: 40px;
    padding: 0 var(--space-3);
    font-size: var(--font-size-xs);
  }



  .app-main {
    padding: var(--space-4);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE LAYOUT  ≤ 768px — Phase 4-5
   All desktop rules above are completely untouched; this block is purely
   additive. Overrides the 900px breakpoint where needed.
   Test breakpoints: 375px (iPhone SE), 390px (iPhone 14), 768px (tablet).
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {

  /* ─── App shell ────────────────────────────────────────────────────────── */

  /* Reserve space for the fixed bottom tab bar (56px) plus system safe-area
     (home indicator on iPhone 14 etc.) so the last content row is never
     hidden behind the tab bar. */
  .app-main {
    padding: var(--space-3);
    padding-bottom: calc(56px + var(--space-4) + env(safe-area-inset-bottom, 0px));
  }

  /* ─── Top nav — slimmed to brand + horizon switcher only ──────────────── */

  /* The module nav is fixed to the bottom (see below), so it no longer takes
     up space here. The app-nav becomes a single-row brand + switcher bar. */
  .app-nav {
    flex-wrap: wrap;
    height: auto;
    padding: var(--space-2) var(--space-3);
    gap: var(--space-2);
    align-items: center;
  }

  .app-nav__title {
    font-size: var(--font-size-sm);
  }

  /* ─── Bottom tab bar — replaces the inline module nav ─────────────────── */

  /* position:fixed removes the element from the app-nav flex flow, making the
     app-nav naturally show only brand + horizon switcher. The tab bar sits
     above the system home indicator via env(safe-area-inset-bottom). */
  .module-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 200;
    display: flex;
    flex-direction: row;
    order: unset;
    width: 100%;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    border-bottom: none;
    /* Push tabs above the iOS home indicator */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  .module-nav__item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* 56px total: 44px tap target + breathing room. */
    height: 56px;
    min-height: 44px;
    padding: var(--space-1) var(--space-2);
    font-size: var(--font-size-xs);
    font-weight: 600;
    /* Active indicator moves from bottom underline to top accent bar. */
    border-bottom: none;
    border-top: 2px solid transparent;
    transition: color 0.15s, border-color 0.15s;
  }

  .module-nav__item.is-active {
    color: var(--color-accent);
    border-bottom-color: transparent;
    border-top-color: var(--color-accent);
  }

  /* ─── Horizon switcher — full width below brand ────────────────────────── */


}
