<script setup lang="ts">
import {
  ArrowLeft,
  Bookmark,
  Camera,
  ChevronLeft,
  ChevronRight,
  Compass,
  Heart,
  ImagePlus,
  Images,
  MapPin,
  Plus,
  Search,
  Send,
  Store,
  Trash2,
  UserRound,
  X,
} from 'lucide-vue-next'
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'

import CityMarktSelect from '@/components/citymarkt/CityMarktSelect.vue'
import CityMarktGallery from '@/components/citymarkt/CityMarktGallery.vue'
import { useAccountStore } from '@/stores/account'
import { useMediaStore } from '@/stores/media'
import { usePagesStore } from '@/stores/pages'
import { usePhoneStore } from '@/stores/phone'
import type { PagesCategory, PagesPost } from '@/types/pages'

type Screen = 'main' | 'detail' | 'compose'
type Tab = 'feed' | 'create' | 'profile'

const phone = usePhoneStore()
const account = useAccountStore()
const media = useMediaStore()
const pages = usePagesStore()
const router = useRouter()
const screen = ref<Screen>('main')
const tab = ref<Tab>('feed')
const profileMode = ref<'own' | 'saved'>('own')
const selected = ref<PagesPost | null>(null)
const galleryIndex = ref(0)
const search = ref('')
const category = ref<string>('all')
const feedback = ref('')
const reactionPending = ref(false)
const photoSource = ref<'camera' | 'gallery' | null>(null)
const cameraFlash = ref(false)
const draft = ref({
  body: '',
  category: 'recommendation' as Exclude<PagesCategory, 'citymarkt'>,
  district: 'los_santos',
  images: [] as string[],
  title: '',
})

const categoryIds: PagesCategory[] = [
  'recommendation', 'wanted', 'service', 'event', 'place', 'community', 'citymarkt',
]
const composeCategoryIds = categoryIds.filter((item) => item !== 'citymarkt')
const districts = ['los_santos', 'vinewood', 'vespucci', 'south_los_santos', 'sandy_shores', 'paleto_bay', 'blaine_county']
const categoryOptions = computed(() => [
  { label: phone.t('Apps.localPages.allCategories'), value: 'all' },
  ...categoryIds.map((value) => ({ label: label('categories', value), value })),
])
const composeCategoryOptions = computed(() => composeCategoryIds.map((value) => ({
  label: label('categories', value), value,
})))
const districtOptions = computed(() => districts.map((value) => ({
  label: phone.t(`Apps.citymarkt.districts.${value}`), value,
})))
const displayedPosts = computed(() => tab.value === 'profile'
  ? (profileMode.value === 'own' ? pages.ownItems : pages.savedItems)
  : pages.items)
const isAuthenticated = computed(() => Boolean(account.email))
const selectedPhotos = computed(() => draft.value.images
  .map((id) => media.photos.find((photo) => photo.id === id))
  .filter((photo) => photo !== undefined))
const selectedImages = computed(() => selectedPhotos.value.map((photo, index) => ({
  gradient: photo.gradient,
  media_id: photo.id,
  sort_order: index + 1,
})))
const canPublish = computed(() => {
  const title = draft.value.title.trim().length
  const body = draft.value.body.trim().length
  return title >= 5 && title <= 80 && body >= 10 && body <= 1500
})

function label(group: string, value: string): string {
  return phone.t(`Apps.localPages.${group}.${value}`)
}

function relativeDate(value: number): string {
  const elapsed = Math.max(0, Date.now() - value)
  const hours = Math.max(1, Math.floor(elapsed / 3_600_000))
  return hours < 24
    ? phone.t('Apps.localPages.hoursAgo', { count: String(hours) })
    : phone.t('Apps.localPages.daysAgo', { count: String(Math.floor(hours / 24)) })
}

function showFeedback(key: string): void {
  feedback.value = phone.t(key)
  window.setTimeout(() => { feedback.value = '' }, 2600)
}

async function loadFeed(): Promise<void> {
  await pages.load({ category: category.value, search: search.value })
}

async function selectTab(next: Tab): Promise<void> {
  if (next === 'create') {
    if (!isAuthenticated.value) {
      tab.value = 'profile'
      return
    }
    screen.value = 'compose'
    return
  }
  tab.value = next
  screen.value = 'main'
  if (next === 'profile' && isAuthenticated.value) await pages.loadProfile()
}

async function openPost(post: PagesPost): Promise<void> {
  const response = await pages.get(post.id)
  if (!response.success || !response.data) return
  selected.value = response.data
  galleryIndex.value = 0
  screen.value = 'detail'
}

function togglePhoto(id: string): void {
  const index = draft.value.images.indexOf(id)
  if (index >= 0) draft.value.images.splice(index, 1)
  else if (draft.value.images.length < 6) draft.value.images.push(id)
  else showFeedback('Apps.localPages.photoLimit')
}

function capturePhoto(): void {
  if (draft.value.images.length >= 6) {
    showFeedback('Apps.localPages.photoLimit')
    return
  }
  cameraFlash.value = true
  draft.value.images.push(media.capture().id)
  window.setTimeout(() => (cameraFlash.value = false), 120)
}

async function publish(): Promise<void> {
  if (!canPublish.value) {
    showFeedback('Apps.localPages.errors.invalid_post')
    return
  }
  const response = await pages.create({
    body: draft.value.body.trim(),
    category: draft.value.category,
    district: draft.value.district,
    images: draft.value.images.map((id) => ({ id })),
    title: draft.value.title.trim(),
  })
  if (!response.success) {
    showFeedback(`Apps.localPages.errors.${response.error ?? 'default'}`)
    return
  }
  draft.value = { body: '', category: 'recommendation', district: 'los_santos', images: [], title: '' }
  photoSource.value = null
  tab.value = 'feed'
  screen.value = 'main'
  showFeedback('Apps.localPages.published')
}

async function react(kind: 'like' | 'save'): Promise<void> {
  if (!selected.value || !isAuthenticated.value) {
    showFeedback('Apps.localPages.errors.not_authenticated')
    return
  }
  const active = kind === 'like' ? !Boolean(selected.value.is_liked) : !Boolean(selected.value.is_saved)
  if (await pages.react(selected.value.id, kind, active)) {
    if (kind === 'like') {
      selected.value.like_count = Math.max(0, selected.value.like_count + (active ? 1 : -1))
      selected.value.is_liked = active
    } else selected.value.is_saved = active
  }
}

async function reactToPost(post: PagesPost, kind: 'like' | 'save'): Promise<void> {
  if (!isAuthenticated.value) {
    showFeedback('Apps.localPages.errors.not_authenticated')
    return
  }
  if (reactionPending.value) return
  const active = kind === 'like' ? !Boolean(post.is_liked) : !Boolean(post.is_saved)
  reactionPending.value = true
  try {
    await pages.react(post.id, kind, active)
  } finally {
    reactionPending.value = false
  }
}

async function removePost(): Promise<void> {
  if (!selected.value || !(await pages.remove(selected.value.id))) return
  selected.value = null
  screen.value = 'main'
  await pages.loadProfile()
  showFeedback('Apps.localPages.deleted')
}

function moveGallery(direction: number): void {
  if (!selected.value?.images.length) return
  galleryIndex.value = (galleryIndex.value + direction + selected.value.images.length) % selected.value.images.length
}

function openCityMarktListing(): void {
  if (!selected.value?.citymarkt_listing_id) return
  void router.push({
    path: '/apps/citymarkt',
    query: {
      listingId: selected.value.citymarkt_listing_id,
      transition: 'app-switch',
    },
  })
}

onMounted(() => void loadFeed())
</script>

<template>
  <main class="pages" :class="{ 'pages--light': !phone.isDarkMode }">
    <template v-if="screen === 'main'">
      <header class="pages__header">
        <div>
          <span class="pages__brand">
            <MapPin :size="14" />
            {{ phone.t(tab === 'feed' ? 'Apps.localPages.eyebrow' : 'Apps.localPages.name') }}
          </span>
          <h1>{{ phone.t(tab === 'feed' ? 'Apps.localPages.name' : 'Apps.localPages.profile') }}</h1>
        </div>
      </header>

      <section class="pages__content">
        <template v-if="tab === 'feed'">
          <div class="pages__hero"><div><small>{{ phone.t('Apps.localPages.cityPulse') }}</small><strong>{{ phone.t('Apps.localPages.heroTitle') }}</strong><span>{{ phone.t('Apps.localPages.heroBody') }}</span></div><MapPin :size="40" /></div>
          <form class="pages__search" @submit.prevent="loadFeed"><Search :size="17" /><input v-model="search" :placeholder="phone.t('Apps.localPages.searchPlaceholder')" /><button>{{ phone.t('Apps.localPages.search') }}</button></form>
          <CityMarktSelect :model-value="category" :options="categoryOptions" @change="(value) => { category = value; loadFeed() }" />
        </template>

        <template v-else>
          <div v-if="!isAuthenticated" class="pages__empty"><UserRound :size="42" /><strong>{{ phone.t('Apps.localPages.signInTitle') }}</strong><span>{{ phone.t('Apps.localPages.signInBody') }}</span></div>
          <template v-else>
            <div class="pages__profile"><span>{{ account.email.charAt(0).toUpperCase() }}</span><div><small>{{ phone.t('Apps.localPages.localCreator') }}</small><strong>@{{ account.email.split('@')[0] }}</strong><b>{{ pages.ownItems.length }} {{ phone.t('Apps.localPages.posts') }}</b></div></div>
            <div class="pages__segmented"><button :class="{ active: profileMode === 'own' }" @click="profileMode = 'own'">{{ phone.t('Apps.localPages.myPosts') }}</button><button :class="{ active: profileMode === 'saved' }" @click="profileMode = 'saved'">{{ phone.t('Apps.localPages.saved') }}</button></div>
          </template>
        </template>

        <div v-if="pages.isLoading" class="pages__empty">{{ phone.t('Common.loading') }}</div>
        <div v-else-if="isAuthenticated || tab === 'feed'" class="pages__feed">
          <article v-for="post in displayedPosts" :key="post.id" class="pages__post">
            <button class="pages__post-open" type="button" @click="openPost(post)">
              <div class="pages__post-head"><span>{{ post.author_name.charAt(0).toUpperCase() }}</span><div><strong>@{{ post.author_name }}</strong><small><MapPin :size="10" /> {{ post.district ? phone.t(`Apps.citymarkt.districts.${post.district}`) : phone.t('Apps.localPages.allLosSantos') }} · {{ relativeDate(post.created_at) }}</small></div><i>{{ label('categories', post.category) }}</i></div>
              <div v-if="post.image" class="pages__cover" :style="{ background: post.image }"><b v-if="post.images.length > 1">1 / {{ post.images.length }}</b></div>
              <h2>{{ post.title }}</h2><p>{{ post.body }}</p>
            </button>
            <div class="pages__post-foot">
              <button type="button" :class="{ active: post.is_liked }" :disabled="reactionPending" :aria-label="phone.t('Apps.localPages.likes')" @click="reactToPost(post, 'like')"><Heart :size="15" :fill="post.is_liked ? 'currentColor' : 'none'" /> {{ post.like_count }}</button>
              <span v-if="post.source_type === 'citymarkt'"><Store :size="14" /> CityMarkt</span>
              <button type="button" :class="{ active: post.is_saved }" :disabled="reactionPending" :aria-label="phone.t('Apps.localPages.save')" @click="reactToPost(post, 'save')"><Bookmark :size="15" :fill="post.is_saved ? 'currentColor' : 'none'" /> {{ phone.t('Apps.localPages.save') }}</button>
            </div>
          </article>
          <div v-if="!displayedPosts.length" class="pages__empty"><Compass :size="38" /><strong>{{ phone.t('Apps.localPages.noPosts') }}</strong><span>{{ phone.t('Apps.localPages.noPostsBody') }}</span></div>
        </div>
      </section>

      <nav class="pages__tabbar">
        <button :class="{ active: tab === 'feed' }" @click="selectTab('feed')"><span><Compass :size="20" /></span>{{ phone.t('Apps.localPages.discover') }}</button>
        <button class="create" @click="selectTab('create')"><span><Plus :size="23" /></span>{{ phone.t('Apps.localPages.create') }}</button>
        <button :class="{ active: tab === 'profile' }" @click="selectTab('profile')"><span><UserRound :size="20" /></span>{{ phone.t('Apps.localPages.profile') }}</button>
      </nav>
    </template>

    <section v-else-if="screen === 'detail' && selected" class="pages__detail">
      <header><button @click="screen = 'main'"><ArrowLeft :size="20" /></button><strong>{{ phone.t('Apps.localPages.post') }}</strong><button v-if="selected.is_owner" class="danger" @click="removePost"><Trash2 :size="18" /></button><button v-else @click="react('save')"><Bookmark :size="18" :fill="selected.is_saved ? 'currentColor' : 'none'" /></button></header>
      <div class="pages__detail-scroll">
        <div v-if="selected.images.length" class="pages__gallery" :style="{ background: selected.images[galleryIndex]?.gradient }"><button v-if="selected.images.length > 1" @click="moveGallery(-1)"><ChevronLeft /></button><button v-if="selected.images.length > 1" @click="moveGallery(1)"><ChevronRight /></button><span>{{ galleryIndex + 1 }} / {{ selected.images.length }}</span></div>
        <article><div class="pages__author"><span>{{ selected.author_name.charAt(0).toUpperCase() }}</span><div><strong>@{{ selected.author_name }}</strong><small>{{ relativeDate(selected.created_at) }}</small></div><i>{{ label('categories', selected.category) }}</i></div><h1>{{ selected.title }}</h1><p>{{ selected.body }}</p><div class="pages__location"><MapPin :size="17" /><div><small>{{ phone.t('Apps.localPages.location') }}</small><strong>{{ selected.district ? phone.t(`Apps.citymarkt.districts.${selected.district}`) : phone.t('Apps.localPages.allLosSantos') }}</strong></div></div><button v-if="selected.source_type === 'citymarkt'" class="pages__market-link" @click="openCityMarktListing"><Store :size="18" /><span><small>{{ phone.t('Apps.localPages.sharedFrom') }}</small><strong>{{ phone.t('Apps.localPages.openCityMarkt') }}</strong></span><b v-if="selected.citymarkt_price">${{ Number(selected.citymarkt_price).toLocaleString() }}</b></button></article>
      </div>
      <div class="pages__detail-actions"><button :class="{ active: selected.is_liked }" @click="react('like')"><Heart :size="19" :fill="selected.is_liked ? 'currentColor' : 'none'" />{{ selected.like_count }} {{ phone.t('Apps.localPages.likes') }}</button><button @click="react('save')"><Bookmark :size="19" :fill="selected.is_saved ? 'currentColor' : 'none'" />{{ phone.t('Apps.localPages.save') }}</button></div>
    </section>

    <section v-else class="pages__compose">
      <header><button @click="screen = 'main'"><X :size="20" /></button><div><small>{{ phone.t('Apps.localPages.newPost') }}</small><strong>{{ phone.t('Apps.localPages.shareWithCity') }}</strong></div><button :disabled="!canPublish" @click="publish"><Send :size="16" />{{ phone.t('Apps.localPages.publish') }}</button></header>
      <div class="pages__compose-scroll">
        <label>{{ phone.t('Apps.localPages.title') }} <span :class="{ valid: draft.title.trim().length >= 5 }">{{ draft.title.trim().length }}/80 · {{ phone.t('Apps.citymarkt.minimumCharacters', { minimum: '5' }) }}</span><input v-model="draft.title" maxlength="80" :placeholder="phone.t('Apps.localPages.titlePlaceholder')" /></label>
        <label>{{ phone.t('Apps.localPages.body') }} <span :class="{ valid: draft.body.trim().length >= 10 }">{{ draft.body.trim().length }}/1500 · {{ phone.t('Apps.citymarkt.minimumCharacters', { minimum: '10' }) }}</span><textarea v-model="draft.body" maxlength="1500" :placeholder="phone.t('Apps.localPages.bodyPlaceholder')" /></label>
        <div class="pages__form-row"><label>{{ phone.t('Apps.localPages.category') }}<CityMarktSelect :model-value="draft.category" :options="composeCategoryOptions" @change="(value) => draft.category = value as typeof draft.category" /></label><label>{{ phone.t('Apps.localPages.location') }}<CityMarktSelect :model-value="draft.district" :options="districtOptions" @change="(value) => draft.district = value" /></label></div>
        <section class="pages__photos">
          <ImagePlus :size="30" />
          <h2>{{ phone.t('Apps.citymarkt.addPhotos') }}</h2>
          <p>{{ phone.t('Apps.citymarkt.addPhotosBody') }}</p>
          <div class="pages__photo-actions">
            <button type="button" @click="photoSource = 'gallery'">
              <span><Images :size="20" /></span>
              <strong>{{ phone.t('Apps.citymarkt.chooseGallery') }}</strong>
              <small>{{ phone.t('Apps.citymarkt.chooseGalleryBody') }}</small>
            </button>
            <button type="button" @click="photoSource = 'camera'">
              <span><Camera :size="20" /></span>
              <strong>{{ phone.t('Apps.citymarkt.takePhotos') }}</strong>
              <small>{{ phone.t('Apps.citymarkt.takePhotosBody') }}</small>
            </button>
          </div>
          <div class="pages__selected-heading">
            <strong>{{ phone.t('Apps.citymarkt.selectedPhotos') }}</strong>
            <span>{{ draft.images.length }} / 6</span>
          </div>
          <CityMarktGallery
            class="pages__selection-gallery"
            :images="selectedImages"
            :empty-title="phone.t('Apps.citymarkt.noPhoto')"
            :empty-body="phone.t('Apps.citymarkt.noPhotoOptional')"
            :previous-label="phone.t('Apps.citymarkt.previousPhoto')"
            :next-label="phone.t('Apps.citymarkt.nextPhoto')"
            :photo-label="phone.t('Apps.citymarkt.photo')"
          />
          <div v-if="selectedImages.length" class="pages__selected-strip">
            <button v-for="(photo, index) in selectedImages" :key="photo.media_id" type="button" :style="{ background: photo.gradient }" :aria-label="phone.t('Apps.citymarkt.removePhoto', { number: String(index + 1) })" @click="togglePhoto(photo.media_id)"><i>{{ index + 1 }}</i><X :size="12" /></button>
          </div>
        </section>
      </div>
      <div v-if="photoSource" class="pages__photo-source">
        <header>
          <div><small>{{ phone.t('Apps.citymarkt.addPhotos') }}</small><strong>{{ phone.t(photoSource === 'gallery' ? 'Apps.citymarkt.gallery' : 'Apps.citymarkt.camera') }}</strong></div>
          <span>{{ draft.images.length }} / 6</span>
          <button type="button" :aria-label="phone.t('Common.close')" @click="photoSource = null"><X :size="18" /></button>
        </header>
        <div v-if="photoSource === 'gallery'" class="pages__photo-picker">
          <button v-for="photo in media.photos" :key="photo.id" type="button" :class="{ active: draft.images.includes(photo.id) }" :style="{ background: photo.gradient }" @click="togglePhoto(photo.id)"><i v-if="draft.images.includes(photo.id)">{{ draft.images.indexOf(photo.id) + 1 }}</i></button>
        </div>
        <div v-else class="pages__capture">
          <div class="pages__viewfinder" :style="{ background: media.photos[0]?.gradient }">
            <i v-for="corner in ['tl', 'tr', 'bl', 'br']" :key="corner" :class="`corner-${corner}`" />
            <span class="pages__camera-flash" :class="{ active: cameraFlash }" />
          </div>
          <p>{{ phone.t('Apps.citymarkt.cameraHint') }}</p>
          <button class="pages__shutter" type="button" :aria-label="phone.t('Apps.citymarkt.takePhoto')" @click="capturePhoto"><Camera :size="23" /></button>
        </div>
      </div>
    </section>
    <Transition name="toast"><div v-if="feedback" class="pages__toast">{{ feedback }}</div></Transition>
  </main>
</template>

<style scoped>
.pages{--yellow:#ffd63e;--ink:#15191d;--panel:#20262c;--muted:#9ba4aa;position:absolute;inset:0;padding:47px 0 24px;overflow:hidden;background:#12171b;color:#f7f7f2;font-family:Inter,system-ui,sans-serif}.pages--light{--panel:#f0f0eb;--muted:#737a7d;background:#fbfbf6;color:#171b1e}.pages button,.pages input,.pages textarea{font:inherit;color:inherit}.pages button{border:0}.pages__header{height:65px;padding:6px 14px;display:grid;grid-template-columns:36px 1fr 36px;align-items:center}.pages__header>button,.pages__detail>header button{width:34px;height:34px;border-radius:11px;display:grid;place-items:center;background:var(--panel)}.pages__header>div{text-align:center}.pages__header span,.pages__compose header small{display:block;color:var(--yellow);font-size:8px;font-weight:900;letter-spacing:.11em;text-transform:uppercase}.pages__header h1{margin:0;font-size:22px;line-height:1.05}.pages__content{height:calc(100% - 65px - 59px);padding:0 13px 18px;overflow-y:auto;scrollbar-width:none}.pages__hero{height:105px;margin-bottom:10px;padding:15px;border-radius:17px;display:flex;align-items:center;justify-content:space-between;background:linear-gradient(125deg,#514005,#d99a00);color:#fff7d2;box-shadow:0 8px 22px #0003}.pages__hero div{max-width:210px}.pages__hero small,.pages__hero strong,.pages__hero span{display:block}.pages__hero small{font-size:8px;font-weight:900;letter-spacing:.1em;text-transform:uppercase}.pages__hero strong{margin:2px 0;font-size:18px}.pages__hero span{font-size:9px;line-height:1.35}.pages__hero>svg{color:var(--yellow);filter:drop-shadow(0 4px 6px #0005)}.pages__search{height:39px;margin-bottom:7px;padding:0 8px 0 10px;border-radius:11px;display:flex;align-items:center;gap:7px;background:var(--panel);color:var(--muted)}.pages__search input{min-width:0;flex:1;border:0;outline:0;background:none;font-size:11px}.pages__search button{padding:5px 8px;border-radius:7px;background:var(--yellow);color:#17191a;font-size:9px;font-weight:800}.pages__feed{padding-top:10px;display:flex;flex-direction:column;gap:12px}.pages__post{width:100%;padding:11px;border-radius:16px;text-align:left;background:var(--panel);box-shadow:0 5px 18px #0002}.pages__post-head{display:flex;align-items:center;gap:7px}.pages__post-head>span,.pages__profile>span,.pages__author>span{width:32px;height:32px;flex:none;border-radius:50%;display:grid;place-items:center;background:var(--yellow);color:#20231f;font-size:13px;font-weight:900}.pages__post-head>div{min-width:0;flex:1}.pages__post-head strong,.pages__post-head small{display:block}.pages__post-head strong{font-size:11px}.pages__post-head small{display:flex;align-items:center;gap:2px;overflow:hidden;color:var(--muted);font-size:8px;white-space:nowrap}.pages__post-head i,.pages__author i{padding:4px 6px;border-radius:7px;background:#ffd63e22;color:var(--yellow);font-size:7px;font-style:normal;font-weight:800}.pages__cover{height:138px;margin:9px 0;border-radius:12px;background-size:cover!important;position:relative}.pages__cover>b{position:absolute;right:7px;bottom:7px;padding:3px 6px;border-radius:6px;background:#111b;color:white;font-size:8px}.pages__cover--empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;background:linear-gradient(145deg,#262d32,#1a2024)!important;color:var(--muted);font-size:9px}.pages--light .pages__cover--empty{background:#e7e8e2!important}.pages__post h2{margin:0 0 3px;font-size:14px}.pages__post p{margin:0;display:-webkit-box;overflow:hidden;color:var(--muted);font-size:10px;line-height:1.4;-webkit-box-orient:vertical;-webkit-line-clamp:2}.pages__post-foot{margin-top:9px;padding-top:8px;border-top:1px solid #ffffff12;display:flex;align-items:center;gap:13px;color:var(--muted);font-size:9px}.pages__post-foot span{display:flex;align-items:center;gap:4px}.pages__post-foot svg:last-child{margin-left:auto}.pages__empty{min-height:230px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-align:center;color:var(--muted)}.pages__empty strong{font-size:15px}.pages__empty span{max-width:220px;font-size:10px}.pages__profile{margin:3px 0 10px;padding:15px;border-radius:17px;display:flex;align-items:center;gap:10px;background:linear-gradient(125deg,#58450b,#262b2f)}.pages__profile>span{width:48px;height:48px;font-size:19px}.pages__profile small,.pages__profile strong,.pages__profile b{display:block}.pages__profile small{color:var(--yellow);font-size:8px;text-transform:uppercase}.pages__profile strong{font-size:16px}.pages__profile b{color:var(--muted);font-size:9px}.pages__segmented{padding:4px;border-radius:11px;display:flex;background:var(--panel)}.pages__segmented button{flex:1;padding:8px;border-radius:8px;background:none;font-size:10px}.pages__segmented button.active{background:var(--yellow);color:#17191a;font-weight:800}.pages__tabbar{position:absolute;right:0;bottom:22px;left:0;height:59px;padding:5px 35px 0;display:flex;align-items:center;justify-content:space-between;border-top:1px solid #ffffff13;background:#151a1eea;backdrop-filter:blur(15px)}.pages--light .pages__tabbar{background:#fbfbf6ec}.pages__tabbar button{width:55px;padding:0;display:flex;flex-direction:column;align-items:center;gap:2px;background:none;color:var(--muted);font-size:8px}.pages__tabbar button.active{color:var(--yellow)}.pages__tabbar .create span{width:44px;height:36px;margin-top:-17px;border-radius:13px;display:grid;place-items:center;background:var(--yellow);color:#17191a;box-shadow:0 5px 15px #0004}.pages__detail,.pages__compose{position:absolute;inset:0;padding-top:47px;background:#12171b}.pages--light .pages__detail,.pages--light .pages__compose{background:#fbfbf6}.pages__detail>header,.pages__compose>header{height:53px;padding:5px 13px;border-bottom:1px solid #ffffff12;display:flex;align-items:center;gap:8px}.pages__detail>header strong{flex:1;text-align:center;font-size:13px}.pages__detail>header .danger{color:#ff6961}.pages__detail-scroll{height:calc(100% - 105px);padding-bottom:64px;overflow-y:auto}.pages__gallery{height:235px;display:flex;align-items:center;justify-content:space-between;background-size:cover!important;position:relative}.pages__gallery button{width:32px;height:38px;margin:8px;border-radius:10px;display:grid;place-items:center;background:#101820aa;color:#fff}.pages__gallery>span{position:absolute;right:10px;bottom:9px;padding:4px 7px;border-radius:7px;background:#101820bb;color:#fff;font-size:8px}.pages__detail article{padding:13px 15px}.pages__author{display:flex;align-items:center;gap:8px}.pages__author>div{flex:1}.pages__author strong,.pages__author small{display:block}.pages__author strong{font-size:12px}.pages__author small{color:var(--muted);font-size:8px}.pages__detail h1{margin:14px 0 5px;font-size:20px}.pages__detail article>p{margin:0;color:var(--muted);font-size:11px;line-height:1.55;white-space:pre-wrap}.pages__location,.pages__market-link{margin-top:14px;padding:10px;border-radius:12px;display:flex;align-items:center;gap:8px;background:var(--panel)}.pages__location svg{color:var(--yellow)}.pages__location small,.pages__location strong,.pages__market-link small,.pages__market-link strong{display:block}.pages__location small,.pages__market-link small{color:var(--muted);font-size:8px}.pages__location strong,.pages__market-link strong{font-size:10px}.pages__market-link{width:100%;text-align:left}.pages__market-link>svg{color:var(--yellow)}.pages__market-link>span{flex:1}.pages__market-link>b{color:var(--yellow);font-size:11px}.pages__detail-actions{position:absolute;right:12px;bottom:30px;left:12px;height:43px;padding:4px;border-radius:14px;display:flex;gap:5px;background:var(--panel);box-shadow:0 7px 25px #0005}.pages__detail-actions button{flex:1;border-radius:10px;display:flex;align-items:center;justify-content:center;gap:5px;background:none;font-size:10px;font-weight:700}.pages__detail-actions button.active{color:#ff6473}.pages__compose>header>div{min-width:0;flex:1}.pages__compose>header strong{display:block;font-size:12px}.pages__compose>header>button{padding:7px;border-radius:10px;background:var(--panel)}.pages__compose>header>button:last-child{display:flex;align-items:center;gap:4px;background:var(--yellow);color:#17191a;font-size:9px;font-weight:800}.pages__compose>header>button:disabled{opacity:.35}.pages__compose-scroll{height:calc(100% - 53px);padding:15px 14px 35px;overflow-y:auto}.pages__compose-scroll label{display:block;margin-bottom:14px;color:var(--muted);font-size:10px;font-weight:700}.pages__compose-scroll label>span{float:right;color:#ff9c47;font-size:8px}.pages__compose-scroll label>span.valid{color:#59d889}.pages__compose input,.pages__compose textarea{width:100%;margin-top:5px;padding:11px;border:1px solid #ffffff13;border-radius:11px;outline:0;background:var(--panel);font-size:12px}.pages__compose textarea{height:116px;resize:none;line-height:1.45}.pages__form-row{display:grid;grid-template-columns:1fr 1fr;gap:7px}.pages__photo-title{margin:5px 0 8px;display:flex;align-items:center;justify-content:space-between}.pages__photo-title strong,.pages__photo-title small{display:block}.pages__photo-title strong,.pages__gallery-label{font-size:12px}.pages__photo-title small{color:var(--muted);font-size:8px}.pages__photo-title button{padding:7px 9px;border-radius:9px;display:flex;align-items:center;gap:4px;background:var(--yellow);color:#17191a;font-size:9px;font-weight:800}.pages__selected{margin-bottom:12px;display:grid;grid-template-columns:repeat(3,1fr);gap:6px}.pages__selected button,.pages__picker button{aspect-ratio:1;border-radius:10px;background-size:cover!important;position:relative}.pages__selected svg{position:absolute;top:5px;right:5px;padding:3px;box-sizing:content-box;border-radius:50%;background:#12171bcc;color:white}.pages__gallery-label{display:block;margin-bottom:7px}.pages__picker{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}.pages__picker button{border:2px solid transparent}.pages__picker button.active{border-color:var(--yellow)}.pages__picker i{width:19px;height:19px;margin:4px;border-radius:50%;display:grid;place-items:center;background:var(--yellow);color:#17191a;font-size:9px;font-style:normal;font-weight:900}.pages__toast{position:absolute;z-index:20;right:17px;bottom:91px;left:17px;padding:11px;border-radius:11px;background:#fff6cf;color:#1b2023;box-shadow:0 8px 30px #0007;font-size:10px;font-weight:800;text-align:center}.toast-enter-active,.toast-leave-active{transition:.2s}.toast-enter-from,.toast-leave-to{transform:translateY(8px);opacity:0}
.pages__tabbar{height:58px;padding:7px 7px 0;justify-content:space-around;backdrop-filter:blur(18px)}
.pages--light .pages__tabbar{border-color:#00000012}
.pages__tabbar button{width:54px;gap:2px}
.pages__tabbar button>span{position:relative}
.pages__tabbar .create span{width:37px;height:30px;margin-top:-4px;border-radius:10px;box-shadow:none}
.pages__header{height:64px;padding:6px 16px 8px;display:flex;align-items:center;justify-content:space-between}
.pages__header>div{text-align:left}
.pages__header .pages__brand{display:flex;align-items:center;gap:4px;color:var(--yellow);font-size:10px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}
.pages__header h1{margin:1px 0 0;font-size:25px;line-height:1}
.pages__content{height:calc(100% - 64px - 58px)}
.pages__segmented button{min-height:34px;padding:8px 10px;font-size:12px;font-weight:700}
.pages__post-open{width:100%;padding:0;text-align:left;background:none}.pages__post-foot{gap:6px}.pages__post-foot button{min-height:28px;padding:5px 8px;border-radius:9px;display:flex;align-items:center;gap:4px;background:#ffffff08;color:var(--muted);font-size:9px;font-weight:800}.pages__post-foot button:last-child{margin-left:auto}.pages__post-foot button:first-child.active{background:#ff647318;color:#ff6473}.pages__post-foot button:last-child.active{background:#ffd63e1c;color:var(--yellow)}.pages__post-foot button:disabled{opacity:.55}.pages__post-foot button svg:last-child{margin-left:0}.pages--light .pages__post-foot button{background:#00000008}
.pages__photos{margin-top:5px}.pages__photos>svg{color:var(--yellow)}.pages__photos>h2{margin:7px 0 3px;font-size:19px}.pages__photos>p{margin:0 0 11px;color:var(--muted);font-size:9px;line-height:1.4}.pages__photo-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}.pages__photo-actions>button{min-width:0;padding:11px 9px;border:1px solid #ffffff12;border-radius:14px;display:flex;flex-direction:column;align-items:flex-start;text-align:left;background:var(--panel)}.pages__photo-actions>button>span{width:34px;height:34px;margin-bottom:8px;border-radius:11px;display:grid;place-items:center;background:#ffd63e1c;color:var(--yellow)}.pages__photo-actions strong{font-size:11px}.pages__photo-actions small{margin-top:2px;color:var(--muted);font-size:8px;line-height:1.35}.pages__selected-heading{margin:15px 1px 7px;display:flex;align-items:center;justify-content:space-between}.pages__selected-heading strong{font-size:12px}.pages__selected-heading span{padding:3px 6px;border-radius:7px;background:var(--panel);color:var(--yellow);font-size:9px;font-weight:900}.pages__selection-gallery{height:142px;border-radius:14px}.pages__selected-strip{margin-top:7px;display:flex;gap:6px;overflow-x:auto;scrollbar-width:none}.pages__selected-strip button{position:relative;width:46px;height:46px;flex:none;border:1px solid #ffffff1d;border-radius:9px;background-position:center!important;background-size:cover!important}.pages__selected-strip button i{position:absolute;left:3px;bottom:3px;width:15px;height:15px;border-radius:50%;display:grid;place-items:center;background:var(--yellow);color:#17191a;font-size:7px;font-style:normal;font-weight:900}.pages__selected-strip button svg{position:absolute;top:3px;right:3px;padding:2px;box-sizing:content-box;border-radius:50%;background:#11120fc7;color:#fff}
.pages__photo-source{position:absolute;z-index:8;inset:47px 0 0;padding:14px 14px 33px;background:#12171b}.pages--light .pages__photo-source{background:#fbfbf6}.pages__photo-source>header{height:52px;display:flex;align-items:center;gap:8px}.pages__photo-source>header>div{min-width:0;flex:1}.pages__photo-source>header small,.pages__photo-source>header strong{display:block}.pages__photo-source>header small{color:var(--yellow);font-size:8px;font-weight:900;text-transform:uppercase}.pages__photo-source>header strong{font-size:18px}.pages__photo-source>header>span{padding:4px 7px;border-radius:8px;background:var(--panel);color:var(--yellow);font-size:8px;font-weight:900}.pages__photo-source>header>button{width:31px;height:31px;padding:0;border-radius:50%;display:grid;place-items:center;background:var(--panel)}.pages__photo-picker{max-height:calc(100% - 58px);display:grid;grid-template-columns:repeat(3,1fr);gap:7px;overflow-y:auto;scrollbar-width:none}.pages__photo-picker button{position:relative;aspect-ratio:1;border:2px solid transparent;border-radius:11px;background-position:center!important;background-size:cover!important}.pages__photo-picker button.active{border-color:var(--yellow)}.pages__photo-picker i{width:19px;height:19px;margin:5px;border-radius:50%;display:grid;place-items:center;background:var(--yellow);color:#17191a;font-size:9px;font-style:normal;font-weight:900}.pages__capture{height:calc(100% - 52px);display:flex;flex-direction:column;align-items:center}.pages__viewfinder{position:relative;width:100%;min-height:305px;overflow:hidden;border-radius:18px;background-position:center!important;background-size:cover!important;box-shadow:inset 0 0 0 1px #ffffff1c}.pages__viewfinder:after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,#0001,#00000038)}.pages__viewfinder>i{position:absolute;z-index:2;width:25px;height:25px;border-color:#fff;border-style:solid}.pages__viewfinder .corner-tl{top:18px;left:18px;border-width:2px 0 0 2px}.pages__viewfinder .corner-tr{top:18px;right:18px;border-width:2px 2px 0 0}.pages__viewfinder .corner-bl{bottom:18px;left:18px;border-width:0 0 2px 2px}.pages__viewfinder .corner-br{right:18px;bottom:18px;border-width:0 2px 2px 0}.pages__camera-flash{position:absolute;z-index:4;inset:0;background:#fff;opacity:0;pointer-events:none;transition:opacity .12s}.pages__camera-flash.active{opacity:.9}.pages__capture p{max-width:230px;margin:9px 0;color:var(--muted);font-size:8px;text-align:center}.pages__shutter{width:58px;height:58px;padding:0;border:5px solid #f5f5ee;border-radius:50%;display:grid;place-items:center;background:var(--yellow);color:#17191a;box-shadow:0 0 0 2px #ffffff42}.pages--light .pages__photo-actions>button,.pages--light .pages__selected-strip button{border-color:#00000012}
/* Keep community content readable at the physical phone scale. */
.pages__header span,.pages__compose header small,.pages__header .pages__brand{font-size:12px}
.pages__hero{padding:13px 15px;gap:12px}.pages__hero div{min-width:0;max-width:205px}.pages__hero small{font-size:9.5px;line-height:1.1}.pages__hero strong{margin:4px 0 3px;font-size:16px;line-height:1.12}.pages__hero span{font-size:11px;line-height:1.3}.pages__hero>svg{flex:none}
.pages__search input{font-size:13px}.pages__search button{font-size:12px}
.pages__post-head strong{font-size:13px}.pages__post-head small{font-size:11.5px}
.pages__post-head i,.pages__author i{font-size:10.5px}
.pages__cover>b,.pages__gallery>span{font-size:10.5px}
.pages__cover--empty,.pages__empty span{font-size:12px}
.pages__post h2{font-size:16px}.pages__post p{font-size:13px}
.pages__post-foot,.pages__post-foot button{font-size:11.5px}
.pages__profile small,.pages__profile b{font-size:11.5px}
.pages__tabbar button{font-size:10.5px}
.pages__author strong{font-size:14px}
.pages__author small,.pages__location small,.pages__market-link small{font-size:11.5px}
.pages__detail article>p{font-size:13px}
.pages__location strong,.pages__market-link strong{font-size:13px}.pages__market-link>b{font-size:14px}
.pages__detail-actions button{font-size:12.5px}
.pages__compose>header strong{font-size:14px}.pages__compose>header>button:last-child{font-size:12px}
.pages__compose-scroll label{font-size:12px}.pages__compose-scroll label>span{font-size:10.5px}
.pages__compose input,.pages__compose textarea{font-size:13px}
.pages__photo-title strong,.pages__gallery-label,.pages__selected-heading strong{font-size:14px}
.pages__photo-title small,.pages__photos>p,.pages__photo-actions small,.pages__capture p{font-size:11.5px}
.pages__photo-title button{font-size:12px}.pages__photo-actions strong{font-size:13px}
.pages__selected-heading span,.pages__photo-source>header small,.pages__photo-source>header>span{font-size:11px}
.pages__selected-strip button i,.pages__photo-picker i{font-size:10px}
.pages__toast{font-size:12px}
</style>
