/* ============================================================
   app-feel.css — makes the public site FEEL like a native app.

   Loaded LAST on every public page (home, /trainers and everything that
   uses layouts/public.blade.php) together with public/js/app-feel.js.

   1. Cross-document View Transitions  (page -> page, no white flash)
   2. One canonical bottom dock        (same size/look on every page)
   3. Instant press feedback           (dock, cards)
   4. Top navigation progress bar
   5. Skeleton screens                 (shown while the next page loads)
   6. Image shimmer + fade-in

   Everything here is progressive enhancement: browsers that don't know
   a feature simply ignore it and the site behaves exactly as before.
   ============================================================ */

:root {
  --ht-brand: var(--primary, #2563eb);
  --ht-brand-soft: rgba(37, 99, 235, 0.12);
  --ht-sk-base: #e2e8f0;
  --ht-sk-hi: #f1f5f9;
  --ht-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ht-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ------------------------------------------------------------
   1. VIEW TRANSITIONS (Chrome/Edge 126+, Safari 18.2+; others ignore)
   The browser keeps the OLD page on screen until the NEW page is ready
   to paint, then cross-fades. Header + dock are pinned so only the page
   body animates — exactly how a native tab bar behaves.
   Motion follows Material's "fade through": out fast, in a bit slower.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}

.app-header { view-transition-name: ht-header; }
.bottom-app-dock { view-transition-name: ht-dock; }

::view-transition-old(root) {
  animation: ht-vt-out 110ms ease-in both;
  mix-blend-mode: normal;
}
::view-transition-new(root) {
  animation: ht-vt-in 260ms var(--ht-ease-out) 70ms both;
  mix-blend-mode: normal;
}
/* header + dock: no morph, no cross-fade — the new one simply appears in place */
::view-transition-group(ht-header),
::view-transition-group(ht-dock) { animation-duration: 0s; }
::view-transition-old(ht-header),
::view-transition-old(ht-dock) { display: none; }
::view-transition-new(ht-header),
::view-transition-new(ht-dock) { animation: none; mix-blend-mode: normal; }

@keyframes ht-vt-out { to { opacity: 0; } }
@keyframes ht-vt-in { from { opacity: 0; transform: translateY(10px); } }

/* ------------------------------------------------------------
   2 + 3. BOTTOM DOCK — one definition for every page
   (home, /trainers and the shared shell each shipped their own copy with
   slightly different padding, so the bar "jumped" between pages).
   Active tab = filled icon inside a soft pill (Material 3 / iOS style).
   ------------------------------------------------------------ */
body .bottom-app-dock {
  height: calc(56px + env(safe-area-inset-bottom));
  padding: 0 0 env(safe-area-inset-bottom);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
body .dock-container {
  display: flex; align-items: stretch; justify-content: space-around;
  width: 100%; max-width: 600px; height: 56px; margin: 0 auto; padding: 0 6px;
}
body .dock-tab {
  position: relative; flex: 1; min-width: 0; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 0; color: var(--text-subtle, #94a3b8);
  font-size: 0.7rem; font-weight: 700; line-height: 1.2;
  touch-action: manipulation; transition: color 0.2s ease;
}
body .dock-tab i {
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 28px; border-radius: 999px;
  font-size: 1.28rem; line-height: 1;
  transition: background-color 0.25s ease, transform 0.18s var(--ht-ease-out);
}
body .dock-tab span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body .dock-tab.active { color: var(--ht-brand); }
body .dock-tab.active i { background: var(--ht-brand-soft); }
body .dock-tab.active span { font-weight: 800; }
/* finger down = it reacts on the very same frame */
body .dock-tab:active i { transform: scale(0.86); background: var(--ht-brand-soft); }
body .dock-tab:active { color: var(--ht-brand); }
/* set by app-feel.js the moment a tab is tapped */
body .dock-tab i.ht-pop { animation: ht-pop 0.38s var(--ht-ease-spring); }
@keyframes ht-pop { 0% { transform: scale(0.78); } 100% { transform: scale(1); } }

/* cards / big tappable blocks (class added by app-feel.js on pointerdown) */
.ht-press { transform: scale(0.985); opacity: 0.94; transition: transform 0.12s ease-out, opacity 0.12s ease-out; }

/* ------------------------------------------------------------
   4. NAVIGATION PROGRESS BAR (thin brand line at the very top)
   ------------------------------------------------------------ */
#htNav {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 3100;
  pointer-events: none; opacity: 0; transition: opacity 0.25s ease;
}
#htNav i {
  display: block; height: 100%; width: 100%;
  transform-origin: 0 50%; transform: scaleX(0);
  background: linear-gradient(90deg, var(--ht-brand), #7c3aed);
  box-shadow: 0 0 10px rgba(37, 99, 235, 0.55);
  border-radius: 0 3px 3px 0;
  transition: transform 0.3s ease-out;
}
/* the reading-progress bar of article pages shares that strip: step aside while navigating */
html.ht-navigating #topProgressBar { opacity: 0; }

/* same-page reloads (filters, sort, pagination): dim the results instead of a skeleton */
html.ht-busy main { opacity: 0.55; transition: opacity 0.2s ease; pointer-events: none; }

/* ------------------------------------------------------------
   5. SKELETON SCREENS
   Painted between header and dock, on top of the old page, if the next
   page has not arrived after ~110 ms. Fast navigations never see it.
   ------------------------------------------------------------ */
.ht-skel {
  position: fixed; left: 0; right: 0; z-index: 999; overflow: hidden;
  top: var(--ht-sk-top, 0px); bottom: var(--ht-sk-bottom, 0px);
  background: var(--ht-sk-bg, var(--bg-app, #f8fafc));
  opacity: 0; animation: ht-skel-in 0.2s ease-out forwards;
}
@keyframes ht-skel-in { to { opacity: 1; } }

.ht-sk-wrap { max-width: 1200px; margin: 0 auto; padding: 16px; }

.ht-sk-b {
  border-radius: 12px;
  background: var(--ht-sk-base);
  background-image: linear-gradient(90deg, var(--ht-sk-base) 0%, var(--ht-sk-hi) 40%, var(--ht-sk-base) 80%);
  background-size: 300% 100%;
  animation: ht-shimmer 1.35s linear infinite;
}
@keyframes ht-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

.ht-sk-line { height: 12px; border-radius: 6px; margin-top: 10px; }
.ht-sk-line.lg { height: 22px; border-radius: 8px; }
.ht-sk-line.xl { height: 28px; border-radius: 8px; }
.ht-w20 { width: 20%; } .ht-w30 { width: 30%; } .ht-w40 { width: 40%; } .ht-w50 { width: 50%; }
.ht-w60 { width: 60%; } .ht-w70 { width: 70%; } .ht-w80 { width: 80%; } .ht-w90 { width: 90%; } .ht-w100 { width: 100%; }

.ht-sk-hero { height: 190px; border-radius: 20px; }
.ht-sk-search { height: 46px; border-radius: 14px; }
.ht-sk-row { display: flex; gap: 8px; margin: 14px 0; overflow: hidden; }
.ht-sk-chip { flex: 0 0 auto; width: 84px; height: 32px; border-radius: 999px; }
.ht-sk-section { margin-top: 22px; }
.ht-sk-scroller { display: flex; gap: 12px; margin-top: 12px; overflow: hidden; }
.ht-sk-scroller .ht-sk-card { flex: 0 0 72%; max-width: 300px; }

.ht-sk-card { padding: 0; }
.ht-sk-card.boxed { background: #fff; border: 1px solid var(--border, #e2e8f0); border-radius: 16px; padding: 12px; }
.ht-sk-img { width: 100%; aspect-ratio: 16 / 9; border-radius: 14px; }
.ht-sk-img.wide { aspect-ratio: 2 / 1; }
.ht-sk-img.lg { aspect-ratio: 16 / 9; border-radius: 18px; }
.ht-sk-cover { width: 100%; aspect-ratio: 5 / 7; border-radius: 12px; }
.ht-sk-thumb { flex: 0 0 96px; height: 72px; border-radius: 12px; }
.ht-sk-avatar { flex: 0 0 64px; width: 64px; height: 64px; border-radius: 50%; }
.ht-sk-avatar.sm { flex-basis: 36px; width: 36px; height: 36px; }
.ht-sk-h { display: flex; gap: 12px; align-items: flex-start; }
.ht-sk-col { flex: 1; min-width: 0; }
.ht-sk-btn { height: 36px; width: 110px; border-radius: 999px; margin-top: 14px; }

.ht-sk-grid { display: grid; gap: 14px; grid-template-columns: 1fr; margin-top: 14px; }
.ht-sk-grid.books { grid-template-columns: repeat(2, 1fr); }
.ht-sk-list { display: grid; gap: 14px; margin-top: 16px; }

.ht-sk-side, .ht-sk-only-desktop { display: none; }

@media (min-width: 640px) {
  .ht-sk-grid.two, .ht-sk-grid.three { grid-template-columns: repeat(2, 1fr); }
  .ht-sk-grid.books { grid-template-columns: repeat(3, 1fr); }
  .ht-sk-hero { height: 260px; }
}
@media (min-width: 1024px) {
  .ht-sk-wrap { padding: 24px 16px; }
  .ht-sk-grid.three { grid-template-columns: repeat(3, 1fr); }
  .ht-sk-grid.books { grid-template-columns: repeat(5, 1fr); }
  .ht-sk-hero { height: 340px; }
  .ht-sk-scroller .ht-sk-card { flex-basis: 30%; }
  .ht-sk-split { display: grid; grid-template-columns: 280px 1fr; gap: 24px; align-items: start; }
  .ht-sk-side { display: block; background: #fff; border: 1px solid var(--border, #e2e8f0); border-radius: 16px; padding: 16px; }
  .ht-sk-only-desktop { display: block; }
}

/* soft filters (soft-filters.js): parts of the page that update in place while loading */
[data-soft-dim] { opacity: 0.55; transition: opacity 0.15s ease; }
[data-soft-region][aria-busy="true"] { cursor: progress; }

/* ------------------------------------------------------------
   6. IMAGES — soft shimmer while loading, gentle fade when ready
   (classes are added by app-feel.js only to images that are not loaded yet)
   ------------------------------------------------------------ */
img.ht-img {
  background-color: var(--ht-sk-base);
  background-image: linear-gradient(90deg, var(--ht-sk-base) 0%, var(--ht-sk-hi) 40%, var(--ht-sk-base) 80%);
  background-size: 300% 100%;
  animation: ht-shimmer 1.35s linear infinite;
}
img.ht-img-in { animation: ht-img-in 0.35s ease-out both; }
@keyframes ht-img-in { from { opacity: 0.2; } to { opacity: 1; } }

/* ------------------------------------------------------------
   Reduced motion: keep the information (progress, skeleton), drop the movement
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .ht-sk-b, img.ht-img { animation: none; background-image: none; }
  .ht-skel { animation-duration: 0.01ms; }
  body .dock-tab i.ht-pop, img.ht-img-in { animation: none; }
  .ht-press { transform: none; }
  #htNav i { transition: none; }
}

/* ============================================================
   7. ACCESSIBILITY + TOUCH POLISH (added with the UX audit)
   ============================================================ */

/* 7a. Contrast — the old "subtle" grey (#94a3b8) is only 2.5:1 on white/off-white; WCAG AA needs 4.5:1.
       Same colour as --text-muted now (4.76:1 on white, 4.55:1 on the page background). */
:root { --text-subtle: #64748b; }

/* 7b. Visible keyboard focus everywhere. Author styles that set `outline: none` on inputs keep their
       own focus look; the search "pills" get a ring on the whole pill instead. */
:where(a, button, select, summary, [role="button"], [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--ht-brand);
  outline-offset: 2px;
  border-radius: inherit;
}
.search-pill-combo:focus-within,
.app-search-input-box:focus-within,
.hero-search-box:focus-within,
.skills-mini-search:focus-within,
.newsletter-form input:focus-visible {
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.35);
}
.skip-link:focus { z-index: 4000; }

/* 7c. Helpers used by the new markup */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.search-dropdown-item[hidden] { display: none; }
.search-dropdown-item:focus-visible { background: var(--primary-light, #eff6ff); color: var(--ht-brand); outline-offset: -2px; }
.app-search-icon-btn { display: inline-flex; align-items: center; justify-content: center; padding: 0; background: none; border: 0; color: inherit; cursor: pointer; line-height: 1; }
button.video-close-btn { background: none; border: 0; padding: 0; line-height: 1; }
.header-avatar-btn:focus-visible { outline: 2px solid var(--ht-brand); outline-offset: 2px; }

/* 7d. Touch targets — on touch screens every tappable thing is at least 44px (WCAG 2.2 / Apple HIG).
       Measured before: filter rows 16-21px, pagination 38px, sort box 35px, save heart 32px. */
@media (pointer: coarse) {
  .radio-row-item, .checkbox-row-item { min-height: 44px; display: flex; align-items: center; }
  .toggle-row-item { min-height: 44px; }
  .reset-link-btn { min-height: 44px; display: inline-flex; align-items: center; padding: 0 6px; }
  .mobile-filter-trigger-btn, .sort-select-el, .tg-view-profile-btn, .app-tab-btn,
  .skill-pill-btn, .mode-chip { min-height: 44px; }
  .mobile-filter-trigger-btn, .app-tab-btn, .tg-view-profile-btn { display: inline-flex; align-items: center; justify-content: center; }
  .page-num-btn { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .tg-save-heart { width: 44px; height: 44px; }
  .header-icon-btn, .btn-auth-header, .header-avatar-btn, .header-hamburger-btn { min-width: 44px; min-height: 44px; }
  .hero-search-box button[type="submit"] { min-height: 44px; }

  /* 7d-2. Small circular/icon buttons that must keep their current visual
     size (bookmark, video mute, modal/drawer close, social icons, generic
     icon-btn, search "go" pill) get an invisible enlarged hit area instead
     of being resized — so nothing on screen shifts or overlaps, but the
     tappable region still meets the 44px minimum. Standard technique:
     https://web.dev/articles/accessible-tap-targets */
  .udb-video-icon-btn, .btn-circle-action, .social-circle-btn,
  .hp-modal-close, .db-drawer-close, .icon-btn, .search-pill-go-btn,
  .nav-drawer-close,
  .gm-actions button {
    position: relative;
  }
  .gm-actions { gap: 10px; }
  .udb-bookmark-btn::after, .udb-video-icon-btn::after, .btn-circle-action::after,
  .social-circle-btn::after, .hp-modal-close::after, .db-drawer-close::after,
  .icon-btn::after, .search-pill-go-btn::after, .gm-actions button::after,
  .nav-drawer-close::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: max(44px, 100%);
    height: max(44px, 100%);
    transform: translate(-50%, -50%);
  }
}

/* 7e. Legal pages (/terms, /privacy) */
.legal-prose { max-width: 760px; margin: 8px auto 32px; padding: 0 4px; color: var(--text-main, #0f172a); line-height: 1.7; }
.legal-prose h1 { font-size: 1.7rem; font-weight: 800; margin: 12px 0 4px; }
.legal-prose h2 { font-size: 1.1rem; font-weight: 800; margin: 26px 0 6px; }
.legal-prose p, .legal-prose li { font-size: 0.95rem; color: #334155; }
.legal-prose ul { padding-left: 20px; margin: 6px 0; }
.legal-prose a { color: var(--ht-brand); text-decoration: underline; }
.legal-meta { font-size: 0.82rem !important; color: var(--text-muted, #64748b) !important; margin-bottom: 14px; }

/* 7f. Reduced motion, site-wide: no sliding tickers, springs or smooth-scroll for people who ask for less */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto !important; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------
   8. ONE breakpoint for "phone chrome vs desktop chrome"
   Home + /trainers switched at 768px, the shared shell at 860px (nav) / 1024px (dock), so on a
   tablet the dock and the header links appeared and disappeared between pages. Now: from 768px
   up every public page shows the header links and no bottom dock.
   ------------------------------------------------------------ */
@media (min-width: 768px) {
  body .desktop-nav-links { display: flex; }
  body .bottom-app-dock { display: none !important; }
  body { padding-bottom: 0; }
}
