/* ═══════════════════════════════════════════
   APP-NATIVE UI
   Everything here is scoped under body.is-native-app
   so the website itself is never affected — this
   only activates inside the Capacitor app.
═══════════════════════════════════════════ */

/* ═══════════════════════════════════════════
   APP WELCOME / LAUNCH SCREEN
   Pure CSS entrance animation — plays the
   instant this element paints, no JS wait,
   so there's no flash between native splash
   and this taking over.
═══════════════════════════════════════════ */
.app-welcome { display: none; }

html.is-native-app-early .app-welcome,
body.is-native-app .app-welcome {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: radial-gradient(ellipse 90% 70% at 50% 30%, #0D1A0F 0%, #0A0A09 70%);
  padding: 32px 28px calc(28px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)));
  text-align: center;
}

body.app-welcome-dismissed .app-welcome {
  display: none !important;
}

.app-welcome-logo-wrap {
  position: relative;
  opacity: 0;
  transform: scale(0.7);
  animation: appWelcomeLogoIn 0.7s cubic-bezier(0.2, 0.9, 0.3, 1.2) forwards;
}

/* Spinning gradient ring — reads as "actively loading" around the logo */
.app-welcome-logo-wrap::before {
  content: '';
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0%, var(--gold, #D4A039) 15%, transparent 35%);
  animation: appWelcomeRingSpin 1.6s linear infinite, appWelcomeRingFade 0.4s ease-out 1.4s forwards;
}

/* Soft pulsing glow breathing behind the logo */
.app-welcome-logo-wrap::after {
  content: '';
  position: absolute;
  inset: -18px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(212,160,57,0.35) 0%, transparent 70%);
  animation: appWelcomeGlowPulse 1.8s ease-in-out infinite;
}

.app-welcome-logo {
  position: relative;
  z-index: 1;
  width: 96px; height: 96px;
  border-radius: 22px;
  box-shadow: 0 8px 32px rgba(212, 160, 57, 0.25);
}

.app-welcome-loading-text {
  font-size: 13px;
  color: var(--text-muted, #8A8A82);
  margin: 20px 0 0;
  opacity: 0;
  animation: appWelcomeFadeUp 0.5s ease-out 0.55s forwards, appWelcomeLoadingFade 0.4s ease-out 1.35s forwards;
}
.app-welcome-loading-text::after {
  content: '';
  animation: appWelcomeDots 1.2s steps(4) infinite;
}

.app-welcome-title {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 900;
  color: var(--text-primary, #F0EEE8);
  margin: 20px 0 6px;
  opacity: 0;
  animation: appWelcomeFadeUp 0.6s ease-out 1.55s forwards;
}

.app-welcome-tagline {
  font-size: 14px;
  color: var(--gold, #D4A039);
  font-style: italic;
  margin: 0 0 44px;
  opacity: 0;
  animation: appWelcomeFadeUp 0.6s ease-out 1.7s forwards;
}

@keyframes appWelcomeLogoIn {
  0%   { opacity: 0; transform: scale(0.7); }
  60%  { opacity: 1; transform: scale(1.06); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes appWelcomeFadeUp {
  0%   { opacity: 0; transform: translateY(14px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes appWelcomeRingSpin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
@keyframes appWelcomeRingFade {
  to { opacity: 0; }
}
@keyframes appWelcomeGlowPulse {
  0%, 100% { opacity: 0.5; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.12); }
}
@keyframes appWelcomeLoadingFade {
  to { opacity: 0; }
}
@keyframes appWelcomeDots {
  0%   { content: ''; }
  25%  { content: '.'; }
  50%  { content: '..'; }
  75%  { content: '...'; }
  100% { content: ''; }
}

/* ---- Floating particles on the welcome screen ---- */
.app-welcome-particles {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.app-welcome-particle {
  position: absolute;
  bottom: -10px;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--gold, #D4A039);
  opacity: 0;
  animation-name: appWelcomeFloat;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
@keyframes appWelcomeFloat {
  0%   { opacity: 0; transform: translateY(0) scale(0.6); }
  15%  { opacity: 0.7; }
  85%  { opacity: 0.4; }
  100% { opacity: 0; transform: translateY(-70vh) scale(1); }
}

/* ---- Glassmorphism refinements ---- */
body.is-native-app .recipe-card-badges .badge {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* ---- 3D tilt cards (trending, key moment only) ---- */
.app-tilt-card {
  transition: transform 0.15s ease-out;
  transform-style: preserve-3d;
  will-change: transform;
}

/* ---- Micro-interactions: press feedback across the app ---- */
body.is-native-app .app-tab:active,
body.is-native-app .app-header-btn:active,
body.is-native-app .app-category-tile:active,
body.is-native-app .app-action-tile:active {
  transform: scale(0.94);
  transition: transform 0.1s ease-out;
}
body.is-native-app .recipe-card:active {
  transform: scale(0.98);
  transition: transform 0.12s ease-out;
}

/* ---- Home quick-bar: parallax-ready background sizing ---- */
body.is-native-app .app-quick-bar {
  background-size: 100% 140%;
  background-repeat: no-repeat;
}

/* The full 5-column desktop footer (Blog, Careers, Press Kit, Premium
   Plan CTAs, etc.) is exactly the kind of chrome that makes an app feel
   like a website wrapped in a shell — the bottom tab bar already covers
   all real navigation, so this is just noise in the app. */
body.is-native-app .footer {
  display: none !important;
}

/* Desktop hover effects (card lift, image zoom) don't make sense on a
   touchscreen — :hover can visually "stick" after a tap until the next
   tap elsewhere, since there's no mouse to actually leave the element.
   Our own :active press-feedback (below) already covers this role, so
   these are neutralized specifically in app mode without touching the
   original website CSS at all. */
body.is-native-app .recipe-card:hover,
body.is-native-app .cuisine-card:hover,
body.is-native-app .chef-card:hover {
  transform: none !important;
  box-shadow: none !important;
}
body.is-native-app .recipe-card:hover .recipe-card-img img,
body.is-native-app .cuisine-card:hover .cuisine-card-bg {
  transform: none !important;
}

/* ---- App header (replaces the full desktop nav) ---- */
.app-header { display: none; }

body.is-native-app .app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 600;
  padding: calc(10px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px))) 16px 10px;
  background: rgba(10, 10, 9, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255,255,255,0.06);
  transition: background 0.25s ease, backdrop-filter 0.25s ease, border-color 0.25s ease;
}

/* On Home, at the very top, the header floats transparently over the
   hero image instead of sitting as a separate flat dark block above
   it — that hard-edged, disconnected look is exactly what made it feel
   like "an end" rather than part of one continuous screen. It becomes
   solid again the moment you scroll past the hero, via JS toggling
   this class based on scroll position. */
body.app-header-transparent .app-header {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}
/* Icon buttons need their own stronger contrast while floating over a
   photo, since the header's own background isn't providing it anymore. */
body.app-header-transparent .app-header-btn {
  background: rgba(10, 10, 9, 0.45);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

body.is-native-app .nav { display: none; }

.app-header-brand { display: flex; align-items: center; gap: 8px; }
/* Transparent logo (assets/logo-mark.png), shown at its own proportions
   with no rounded tile behind it. */
.app-header-mark {
  height: 24px;
  width: auto;
  display: block;
  filter: drop-shadow(0 0 1px rgba(255,255,255,0.3));
}
.app-header-name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 17px;
  color: var(--text-primary, #F0EEE8);
  letter-spacing: 0.2px;
}

.app-header-actions { display: flex; gap: 6px; }
.app-header-btn {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.06);
  border: none;
  color: var(--text-primary, #F0EEE8);
  font-size: 17px;
  cursor: pointer;
}
.app-header-btn:active { background: rgba(255,255,255,0.12); }

/* ---- App quick-bar (replaces the cinematic hero as the app's first screen) ---- */
.app-quick-bar { display: none; }

body.is-native-app .app-quick-bar {
  display: block;
  padding: 22px 18px 6px;
  background: radial-gradient(ellipse 120% 60% at 50% 0%, #0D1A0F 0%, #0A0A09 65%);
}

.app-quick-greeting {
  font-size: 13px;
  font-weight: 600;
  color: var(--gold, #D4A039);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin: 0 0 4px;
}

.app-quick-chip-row {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: none;
}
.app-quick-chip-row::-webkit-scrollbar { display: none; }

/* ---- Compact the cinematic hero + hide the standalone search strip ----
   The app quick-bar above already covers greeting/search-entry duty, so
   the full-viewport marketing hero would be redundant/oversized in-app. */
body.is-native-app .hero {
  min-height: 0 !important;
  height: auto !important;
  padding: 4px 0 0 !important;
}
body.is-native-app .hero-content,
body.is-native-app .hero-scroll-hint,
body.is-native-app .hero-sound-toggle,
body.is-native-app #heroCanvas,
body.is-native-app .hero-video-root {
  display: none !important;
}

body.is-native-app .search-strip { display: none; }

/* ---- Softer, more native-feeling recipe cards in-app ---- */
body.is-native-app .recipe-card-img {
  border-radius: 16px 16px 0 0;
}
body.is-native-app .recipe-card {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 4px 16px rgba(0,0,0,0.35);
}

/* ---- Denser section headers for app screens (less "editorial") ---- */
body.is-native-app .section-title {
  font-size: clamp(1.3rem, 4vw, 1.7rem) !important;
}
body.is-native-app .section-eyebrow {
  font-size: 11px !important;
}

/* ---- Quick Actions — 2-column icon + title/subtitle tiles ---- */
.app-action-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin: 18px 0 4px;
}
.app-action-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border-radius: 14px;
  background: rgba(255,255,255,0.05);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.08);
  color: var(--text-primary, #F0EEE8);
  cursor: pointer;
  text-align: left;
}
.app-action-tile i {
  font-size: 20px;
  color: var(--gold, #D4A039);
  flex-shrink: 0;
}
.app-action-tile div { display: flex; flex-direction: column; min-width: 0; }
.app-action-tile span {
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-action-tile small {
  font-size: 11px;
  color: var(--text-muted, #8A8A82);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- 2. Smart search bar ---- */
.app-smart-search {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 16px;
  border-radius: 999px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.08);
  color: var(--text-muted, #8A8A82);
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  margin-bottom: 18px;
}
.app-smart-search span { flex: 1; text-align: left; }
.app-smart-search i:first-child { font-size: 18px; }
.app-smart-search i:last-child { font-size: 16px; }

/* ---- 3. Hero banner ---- */
.app-hero-banner {
  position: relative;
  border-radius: 20px;
  overflow: hidden;
  height: 240px;
  margin-bottom: 26px;
  background: var(--bg-elevated, #242422);
}
.app-hero-banner-img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.app-hero-banner-img.loaded { opacity: 1; }
.app-hero-banner-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 20px;
  background: linear-gradient(0deg, rgba(10,10,9,0.92) 0%, rgba(10,10,9,0.35) 55%, rgba(10,10,9,0.1) 100%);
}
.app-hero-banner .app-quick-greeting {
  font-size: 12px;
  font-weight: 700;
  color: var(--gold, #D4A039);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin: 0 0 4px;
}
.app-hero-banner-title {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 800;
  color: #fff;
  margin: 0 0 12px;
  line-height: 1.25;
}
.app-hero-banner-title em {
  color: var(--gold, #D4A039);
  font-style: italic;
}
.app-hero-banner-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  padding: 9px 18px;
  border-radius: 999px;
  background: rgba(255,255,255,0.14);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,0.2);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.app-hero-banner-dots {
  position: absolute;
  top: 14px; right: 16px;
  display: flex;
  gap: 5px;
}
.app-hero-banner-dots span {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: rgba(255,255,255,0.4);
}
.app-hero-banner-dots span.active { background: #fff; }

/* ---- 4. Top categories ---- */
.app-section-label {
  font-size: 15px;
  font-weight: 800;
  color: var(--text-primary, #F0EEE8);
  margin: 0 0 10px;
}
.app-category-tile {
  display: flex !important;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 14px 16px !important;
  min-width: 76px;
  flex-shrink: 0;
  white-space: nowrap;
}
.app-category-tile i { font-size: 20px; }
.app-category-tile span { font-size: 10.5px; white-space: nowrap; }

/* ---- Shared "section with View all" row (trending, cuisines) ---- */
.app-section-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 24px 0 10px;
}
.app-section-row .app-section-label { margin: 0; }
.app-section-viewall {
  background: none;
  border: none;
  color: var(--gold, #D4A039);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
}

/* ---- 7. Popular cuisines (circular thumbnails) ---- */
.app-cuisine-strip {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin: 0 -18px;
  padding-left: 18px;
  padding-right: 18px;
  scrollbar-width: none;
}
.app-cuisine-strip::-webkit-scrollbar { display: none; }
.app-cuisine-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  cursor: pointer;
}
.app-cuisine-thumb {
  width: 64px; height: 64px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid rgba(212,160,57,0.4);
}
.app-cuisine-item span {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary, #B8B6AE);
}

/* ---- Featured Chefs (horizontal strip) ---- */
.app-chef-strip {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin: 0 -18px;
  padding-left: 18px;
  padding-right: 18px;
  scrollbar-width: none;
}
.app-chef-strip::-webkit-scrollbar { display: none; }
.app-chef-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  width: 84px;
  cursor: pointer;
  text-align: center;
}
.app-chef-avatar {
  width: 64px; height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  background: var(--bg-elevated, #242422);
  border: 2px solid rgba(212,160,57,0.4);
}
.app-chef-item span {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-primary, #F0EEE8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 84px;
}
.app-chef-item small {
  font-size: 9.5px;
  color: var(--text-muted, #8A8A82);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 84px;
}

/* ---- Loading skeletons — shown until real data replaces them via
   innerHTML, so the dashboard never sits on visibly empty space while
   RECIPES/CHEFS load asynchronously. ---- */
@keyframes appSkeletonShimmer {
  0%   { background-position: -200px 0; }
  100% { background-position: 200px 0; }
}
.app-skeleton-card {
  flex: 0 0 190px;
  width: 190px;
  height: 220px;
  border-radius: 16px;
  background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.09) 37%, rgba(255,255,255,0.04) 63%);
  background-size: 400px 100%;
  animation: appSkeletonShimmer 1.4s ease-in-out infinite;
}
.app-skeleton-circle {
  flex-shrink: 0;
  width: 64px; height: 64px;
  border-radius: 50%;
  background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.09) 37%, rgba(255,255,255,0.04) 63%);
  background-size: 200px 100%;
  animation: appSkeletonShimmer 1.4s ease-in-out infinite;
}
.app-skeleton-circle-sm { width: 64px; height: 64px; }

.app-load-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 24px 20px;
  width: 100%;
  color: var(--text-muted, #8A8A82);
  font-size: 13px;
}
.app-load-error i { font-size: 24px; }
.app-load-retry {
  margin-top: 4px;
  padding: 7px 18px;
  border-radius: 999px;
  background: var(--gold, #D4A039);
  color: #0A0A09;
  border: none;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
}

/* ---- Pull-to-refresh indicator ---- */
.app-pull-refresh {
  display: none;
}
body.is-native-app .app-pull-refresh {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  top: calc(4px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px)));
  left: 50%;
  transform: translateX(-50%) translateY(0);
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--bg-elevated, #242422);
  border: 1px solid rgba(212,160,57,0.3);
  color: var(--gold, #D4A039);
  font-size: 16px;
  opacity: 0;
  z-index: 2100;
  transition: opacity 0.15s ease-out;
  pointer-events: none;
}
body.is-native-app .app-pull-refresh.ready {
  border-color: var(--gold, #D4A039);
  background: rgba(212,160,57,0.15);
}
body.is-native-app .app-pull-refresh.spinning i {
  animation: appPullSpin 0.6s linear infinite;
}
@keyframes appPullSpin {
  to { transform: rotate(360deg); }
}

/* ---- 8. Community preview banner ---- */
.app-community-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin-top: 26px;
  padding: 16px;
  border-radius: 16px;
  background: rgba(212,160,57,0.08);
  border: 1px solid rgba(212,160,57,0.25);
  cursor: pointer;
  text-align: left;
}
.app-community-banner > i:first-child {
  font-size: 24px;
  color: var(--gold, #D4A039);
  flex-shrink: 0;
}
.app-community-banner div { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.app-community-banner span { font-size: 14px; font-weight: 700; color: var(--text-primary, #F0EEE8); }
.app-community-banner small { font-size: 12px; color: var(--text-muted, #8A8A82); }
.app-community-banner > i:last-child { color: var(--text-muted, #8A8A82); }

/* ---- Notifications panel (honest empty state) ---- */
.app-notif-panel {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1600;
  background: var(--bg-void, #0A0A09);
  flex-direction: column;
}
.app-notif-panel.open { display: flex; }
.app-notif-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(16px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px))) 18px 16px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  font-size: 16px;
  font-weight: 800;
  color: var(--text-primary, #F0EEE8);
}
.app-notif-header button {
  background: none; border: none;
  color: var(--text-primary, #F0EEE8);
  font-size: 20px; cursor: pointer;
}
.app-notif-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
  padding: 0 40px;
}
.app-notif-empty i { font-size: 40px; color: var(--text-muted, #8A8A82); }
.app-notif-empty p { font-size: 15px; font-weight: 700; color: var(--text-primary, #F0EEE8); margin: 4px 0 0; }
.app-notif-empty span { font-size: 13px; color: var(--text-muted, #8A8A82); }

.app-continue-strip {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding-bottom: 8px;
  margin: 0 -18px;
  padding-left: 18px;
  padding-right: 18px;
  scrollbar-width: none;
}
.app-continue-strip::-webkit-scrollbar { display: none; }
.app-continue-strip .recipe-card {
  flex: 0 0 190px;
  width: 190px;
}
.app-continue-strip .recipe-card-img {
  height: 130px;
}
.app-continue-strip .recipe-card-meta {
  flex-wrap: wrap;
  row-gap: 4px;
}

/* ---- Hide legacy website sections that are now superseded by the
   dedicated tabs/dashboard above — keeps Home a landing screen, not
   a full content dump. Cuisines/Chefs/AI Chef stay reachable via the
   Quick Actions tiles scrolling to them further down the page. ---- */
body.is-native-app #trending,
body.is-native-app #community,
body.is-native-app #seasonal,
body.is-native-app #chefs {
  display: none !important;
}

/* ---- App search overlay ---- */
.app-search-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1500;
  background: var(--bg-void, #0A0A09);
  flex-direction: column;
}
.app-search-overlay.open { display: flex; }

.app-search-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(14px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px))) 16px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  color: var(--text-muted, #8A8A82);
}
.app-search-bar input {
  flex: 1;
  background: rgba(255,255,255,0.06);
  border: none;
  border-radius: 999px;
  padding: 11px 16px;
  color: var(--text-primary, #F0EEE8);
  font-size: 15px;
  font-family: inherit;
}
.app-search-bar input:focus { outline: none; }
.app-search-bar button {
  background: none;
  border: none;
  color: var(--text-primary, #F0EEE8);
  font-size: 20px;
  cursor: pointer;
}

.app-search-results {
  flex: 1;
  overflow-y: auto;
  padding: 8px 16px 24px;
}
.app-search-result-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 4px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  cursor: pointer;
}
.app-search-result-thumb {
  width: 48px; height: 48px;
  border-radius: 10px;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg-elevated, #242422);
}
.app-search-result-info { flex: 1; min-width: 0; }
.app-search-result-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary, #F0EEE8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-search-result-meta {
  font-size: 12px;
  color: var(--text-muted, #8A8A82);
  margin-top: 2px;
}
.app-search-empty {
  text-align: center;
  color: var(--text-muted, #8A8A82);
  font-size: 14px;
  padding: 40px 20px;
}

/* Cookie consent is a web/browser concept — irrelevant and confusing inside
   the native app, so it's hidden entirely there. */
body.is-native-app #cookieBanner,
body.is-native-app #cookiePrefsModal {
  display: none !important;
}

/* ---- Recipe detail: full-screen native sheet instead of a centered popup ---- */
body.is-native-app #recipeModal.modal-backdrop {
  padding: 0;
  background: var(--bg-void, #0A0A09);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.is-native-app #recipeModal .modal-panel {
  max-width: 100%;
  width: 100%;
  height: 100%;
  max-height: 100%;
  border-radius: 0;
  border: none;
  transform: translateY(100%);
  transition: transform 0.28s var(--ease-smooth, ease-out);
}
body.is-native-app #recipeModal.open .modal-panel {
  transform: translateY(0);
}
body.is-native-app #recipeModal .modal-recipe-hero-photo,
body.is-native-app #recipeModal .modal-recipe-hero-placeholder {
  height: 260px;
  padding-top: var(--safe-area-inset-top, env(safe-area-inset-top, 0px));
}
body.is-native-app #recipeModal .modal-close {
  top: calc(16px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px)));
  background: rgba(10,10,9,0.6);
  backdrop-filter: blur(6px);
}

/* ---- Login/signup: full-screen mandatory gate in the app, not a
   floating card. Structure follows the reference layout (title, fields,
   primary button, divider, social buttons stacked below) — colors stay
   exactly the site's existing palette, nothing new introduced here. ---- */
body.is-native-app #authModal.modal-backdrop {
  padding: 0;
  z-index: 2200 !important; /* must beat .app-header (600) and .app-tab-bar (500) */
  background: #0A0A09 !important; /* fully solid — the base .modal-backdrop's
    rgba(0,0,0,0.85) was letting Home's content visibly bleed through */
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  align-items: stretch;
}
/* Opacity/visibility must stay scoped to .open — forcing opacity:1
   unconditionally (as an earlier version of this rule did) breaks
   closeAuthModal() entirely, since the modal would stay visible forever
   regardless of whether the .open class gets removed. */
body.is-native-app #authModal.modal-backdrop:not(.open) {
  opacity: 0 !important;
  pointer-events: none !important;
}
body.is-native-app #authModal.modal-backdrop.open {
  opacity: 1 !important;
}
body.is-native-app #authModal .modal-panel {
  max-width: 100%;
  width: 100%;
  height: 100%;
  max-height: 100%;
  border-radius: 0;
  border: none;
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow-y: auto;
  padding: calc(24px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px))) 24px calc(24px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)));
}
body.is-native-app #authModal .auth-content { width: 100%; }
body.is-native-app #authModal .auth-inner { width: 100%; max-width: 420px; margin: 0 auto; }

/* Login is mandatory in the app — there is no skip/dismiss option;
   reaching Home requires actually signing in or creating an account. */
body.is-native-app #authModal .modal-close {
  display: none;
}

/* Explicit, JS-driven backup (toggled by app-shell.js) that hides the
   header and tab bar entirely while the login gate is active — this
   guarantees they can never show through again regardless of any
   future z-index/opacity change, rather than relying on stacking order
   alone. */
body.auth-gate-active .app-header,
body.auth-gate-active .app-tab-bar {
  display: none !important;
}
/* Third bypass path for the mandatory login gate, found during the
   Recipes-section audit: the modal's own explicit X button had no gate
   check at all, on top of the hardware-back and backdrop-tap paths
   already fixed. */
body.auth-gate-active #authClose {
  display: none !important;
}

/* ---- App header is shorter than the desktop nav — every page that pads
   itself against --nav-h (community, dashboard, about, chef profiles)
   automatically corrects itself once this one variable is adjusted. ---- */
body.is-native-app {
  --nav-h: 54px;
}

/* The Recipes page header has its OWN extra 2rem top padding on top of
   the --nav-h offset above (desktop breathing room) — combined, this
   was the large empty gap flagged in design review. Tightened for app
   screens, where every pixel of vertical space matters more. */
/* Both of these pages have TWO separate top-padding sources that stack:
   their own outer padding-top:var(--nav-h) (meant for the desktop nav,
   which doesn't exist in-app), PLUS an inner wrapper with its own
   padding I already reduced. The outer one was never actually removed,
   so it was still adding var(--nav-h) worth of redundant space on top
   of the inner fix — confirmed via DevTools computed-style inspection. */
body.is-native-app #page-recipes {
  padding-top: 0 !important;
}
body.is-native-app #page-dashboard {
  padding-top: 0 !important;
}
body.is-native-app #page-discover {
  padding-top: 0 !important;
}
body.is-native-app #page-recipes > div:first-child {
  padding-top: 12px !important;
}
body.is-native-app .dash-hero {
  padding-top: 12px !important;
}

/* On Android, the system back gesture is the primary, expected way to
   navigate backward — our hardware back button handler already returns
   correctly to Home from any of these pages. An explicit in-page
   "← Back" pill button is redundant with that, and its website-style
   presentation (a standalone button rather than a compact nav-bar icon)
   reads as web UI rather than a native app. Left alone: the "Back to
   Community" button on a chef's profile page, since that returns to a
   specific parent page rather than Home — something our simple
   hardware-back logic doesn't yet replicate. */
body.is-native-app .app-hide-back {
  display: none !important;
}
body.is-native-app #page-ai-chef {
  padding-top: 12px;
}
/* This panel was designed to sit as one section among several on a
   scrolling home page (480px was a reasonable height there) — but now
   that it's a dedicated, full-screen destination, that height leaves a
   large, unfinished-looking gap below it on most phones. */
body.is-native-app .ai-chat-panel {
  height: calc(100vh - 340px);
  min-height: 360px;
}
/* The marketing pitch (headline, description) made sense on a landing
   page section someone scrolls past once — on a repeatedly-visited app
   screen the user already chose to open, it's just eating space the
   actual chat could use. Compacted, not removed, since the suggestion
   chips are still genuinely useful. */
body.is-native-app .ai-left .section-eyebrow,
body.is-native-app .ai-left .section-title,
body.is-native-app .ai-desc {
  display: none;
}
body.is-native-app .ai-suggestions {
  margin-top: 0;
}

/* Smooth transition on every page switch (Home/Recipes/Community/Account/
   AI Chef) — an instant, un-animated display swap is exactly the kind of
   abrupt transition that reads as "website" rather than "native app". */
@keyframes appPageFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
body.is-native-app .app-page-transition-in {
  animation: appPageFadeIn 0.22s ease-out;
}

/* ---- Paywall ---- */
.app-paywall-overlay {
  display: none;
}
body.is-native-app .app-paywall-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 2300;
  background: rgba(0,0,0,0.7);
  align-items: center;
  justify-content: center;
  padding: 24px;
}
body.is-native-app .app-paywall-overlay.open { display: flex; }
.app-paywall-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  background: var(--bg-elevated, #1A1A18);
  border: 1px solid rgba(212,160,57,0.25);
  border-radius: 20px;
  padding: 24px;
  max-width: 340px;
  width: 100%;
}

/* ---- Generic searchable option picker (replaces native <select> in-app) ---- */
.app-option-picker {
  display: none;
}
body.is-native-app .app-option-picker {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 2400;
  background: var(--bg-void, #0A0A09);
  flex-direction: column;
}
body.is-native-app .app-option-picker.open { display: flex; }
.app-option-picker-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(10px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px))) 16px 10px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.app-option-picker-header span {
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary, #F0EEE8);
}
.app-option-picker-search {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 16px;
  padding: 12px 16px;
  border-radius: 999px;
  background: rgba(255,255,255,0.06);
  color: var(--text-muted, #8A8A82);
}
.app-option-picker-search input {
  flex: 1;
  background: none;
  border: none;
  outline: none;
  color: var(--text-primary, #F0EEE8);
  font-size: 15px;
  font-family: inherit;
}
.app-option-picker-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 8px 24px;
}
.app-option-picker-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 14px 12px;
  background: none;
  border: none;
  color: var(--text-primary, #F0EEE8);
  font-size: 15px;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}
.app-option-picker-item:active { background: rgba(255,255,255,0.06); }
.app-option-picker-item.selected { color: var(--gold, #D4A039); font-weight: 700; }
.app-option-picker-item i { font-size: 18px; }
.app-option-picker-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--text-muted, #8A8A82);
  font-size: 14px;
}

/* The fake-select button that replaces a hidden native <select> in-app —
   styled to look identical to the site's own .form-select so the swap
   is visually seamless. */
body.is-native-app .app-fake-select {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
}
body.is-native-app .app-fake-select .placeholder { color: var(--text-muted, #8A8A82); }

/* Country filter chips: the base site wraps them into several rows,
   which eats a lot of vertical space and pushes recipes further down.
   A horizontally-scrollable single row feels much more like a native
   app filter bar. */
body.is-native-app #countryTabs {
  flex-wrap: nowrap !important;
  overflow-x: auto !important;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px !important;
  scrollbar-width: none;
}
body.is-native-app #countryTabs::-webkit-scrollbar { display: none; }
body.is-native-app #countryTabs .filter-chip {
  flex-shrink: 0;
  white-space: nowrap;
}

/* Recipe card images were a fixed 200px regardless of the 2-column
   mobile layout, making cards feel photo-heavy — a touch shorter keeps
   more of each card's actual info (title, time, rating) on screen at
   once without needing to scroll past the image first. */
body.is-native-app .recipe-card-img {
  height: 150px;
}

/* "View all" link next to each country's recipe count — makes clear
   the two visible cards aren't the entire collection. */
body.is-native-app .country-section-viewall {
  display: inline-flex !important;
  margin-left: auto;
  align-self: center;
  color: var(--gold, #D4A039);
  font-size: 12.5px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

/* ---- Community page: compact hero, sticky segmented-control-style tabs ---- */
body.is-native-app .community-page-hero {
  padding: 20px 0 16px !important;
}
body.is-native-app .community-hero-title {
  font-size: 1.6rem !important;
  margin-bottom: 8px !important;
}
body.is-native-app .community-hero-sub {
  font-size: 13px !important;
  margin: 0 auto 14px !important;
}
body.is-native-app .community-hero-stats {
  margin-top: 14px !important;
  gap: 1.2rem !important;
}
body.is-native-app .community-hero-stat-num {
  font-size: 1.2rem !important;
}
body.is-native-app .community-tabs-bar {
  top: var(--nav-h);
}
body.is-native-app .community-tab {
  padding: 12px 16px !important;
  font-size: 12px !important;
}
/* ---- Notifications: real feed ---- */
.app-notif-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #F08060;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
.app-notif-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0 calc(16px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)));
}
.app-notif-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-subtle);
}
.app-notif-item > i { font-size: 18px; margin-top: 2px; flex-shrink: 0; }
.app-notif-text { flex: 1; min-width: 0; }
.app-notif-text p,
.app-notif-line {
  font-size: 13.5px;
  color: var(--text-secondary);
  margin: 0 0 2px;
  line-height: 1.4;
}
.app-notif-text strong { color: var(--text-primary); font-weight: 700; }
.app-notif-text em { color: var(--text-primary); font-style: normal; }
.app-notif-body {
  display: block;
  font-size: 12.5px;
  color: var(--text-muted);
  font-style: italic;
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-notif-time { font-size: 11px; color: var(--text-muted); }

/* Discover is an edge-to-edge feed — the page wrappers that give other
   pages their gutters would letterbox the video instead. */
body.is-native-app #page-discover {
  padding: 0 !important;
  margin: 0 !important;
}
/* Notifications are tappable (open that person's profile); new ones
   since your last visit get a subtle highlight. */
button.app-notif-item {
  width: 100%;
  border: none;
  border-bottom: 1px solid var(--border-subtle);
  background: none;
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
button.app-notif-item:active { background: rgba(255,255,255,0.04); }
.app-notif-item.is-unread { background: rgba(212,160,57,0.07); }
.app-notif-text > span { display: block; }

/* ── Dialogs have to clear the app's own chrome ────────────────────
   The app header (z-index 600) and the bottom tab bar (500) are both
   fixed, and every full-screen dialog was stacked BELOW them:
   .modal-backdrop at 200, .upload-modal-overlay and .planner-picker
   at 300. On the website that is harmless, because the web nav is
   only 100 — but in the app the chrome painted straight over each
   dialog at BOTH ends. On "Share a Recipe" that hid the modal's own
   title and its X button behind the header, and put Share Recipe and
   Cancel underneath the tab bar: a form you could neither submit nor
   close without guessing where to tap.
   1700 clears the header, the tab bar, the search overlay (1500) and
   the notification panel (1600), and stays under the fullscreen
   video stack (3000+). */
body.is-native-app .modal-backdrop,
body.is-native-app .upload-modal-overlay,
body.is-native-app .planner-picker {
  z-index: 1700;
  /* Keep out of the notch and the home gesture bar too, so the first
     and last rows of a dialog are always reachable. */
  padding-top: calc(1rem + env(safe-area-inset-top, 0px));
  padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
}
/* The panels cap themselves at 90vh, which is measured against the
   whole screen and so ignored the padding above — tall dialogs still
   ran off the bottom. Against the padded overlay, 100% is exactly the
   room that is actually free. */
body.is-native-app .upload-modal,
body.is-native-app .modal-panel,
body.is-native-app .planner-picker > * {
  max-height: 100%;
}

/* An open dialog is modal, so the tab bar behind it should not still
   be tappable — you could navigate away and leave the form open. */
body.is-native-app:has(.upload-modal-overlay.open) .app-tab-bar,
body.is-native-app:has(.modal-backdrop.open) .app-tab-bar,
body.is-native-app:has(.planner-picker.open) .app-tab-bar {
  display: none;
}

/* ── The post a notification pointed at ───────────────────────────
   Tapping "bob commented on your Mandazi" now scrolls to that post
   rather than opening bob's profile. Without a moment of highlight you
   land mid-feed with no idea which card you were sent to. */
.community-post.is-notif-target {
  animation: gkNotifTarget 2.2s ease-out;
}
@keyframes gkNotifTarget {
  0%, 12% { box-shadow: 0 0 0 2px var(--gold, #D4A039), 0 0 22px rgba(212,160,57,0.35); }
  100%    { box-shadow: 0 0 0 0 rgba(212,160,57,0); }
}
/* Respect a reduced-motion preference: still mark the card, just don't
   animate it. */
@media (prefers-reduced-motion: reduce) {
  .community-post.is-notif-target {
    animation: none;
    box-shadow: 0 0 0 2px var(--gold, #D4A039);
  }
}
