<script setup lang="ts">
import { Head, usePage, router } from '@inertiajs/vue3';
import { ref, computed, onMounted, nextTick } from 'vue';
import UserLayout from '../../layouts/user/userlayout.vue';
import { useNotifications } from '@/composables/useNotifications';
import ConfirmModal from '@/components/ui/ConfirmModal.vue';

const page = usePage();
const { notify } = useNotifications();

// Props from controller
const props = defineProps<{
  guild: null | {
    id: number;
    name: string;
    tag: string;
    logo_url?: string | null;
    description?: string | null;
    points: number;
    members_count: number;
    owner: { id: number; username?: string; name?: string; avatar_url?: string | null };
    members: { id: number; username?: string; name?: string; avatar_url?: string | null; role: string; joined_at?: string | null; wagered?: number }[];
  };
  myRole: string | null;
  canManage: boolean;
  invite: string | null;
}>();

const me = computed(() => page.props.auth?.user);
const hasGuild = computed(() => !!props.guild);

// Sort members by wagered amount (descending)
const sortedMembers = computed(() => {
  if (!props.guild?.members) return [];
  return [...props.guild.members].sort((a, b) => (b.wagered || 0) - (a.wagered || 0));
});

// Create form
const cName = ref('');
const cTag = ref('');
const cLogoFile = ref<File | null>(null);
const cLogoPreview = ref<string | null>(null);
const cDesc = ref('');
const cErrors = ref<Record<string,string>>({});
const cBusy = ref(false);

function onCLogoChange(e: Event) {
  const file = (e.target as HTMLInputElement).files?.[0] ?? null;
  cLogoFile.value = file;
  cLogoPreview.value = file ? URL.createObjectURL(file) : null;
}

async function createGuild() {
  cBusy.value = true; cErrors.value = {};
  try {
    const fd = new FormData();
    fd.append('name', cName.value);
    fd.append('tag', cTag.value);
    if (cDesc.value) fd.append('description', cDesc.value);
    if (cLogoFile.value) fd.append('logo', cLogoFile.value);
    const res = await fetch('/guilds', {
      method: 'POST',
      headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement)?.content || '',
      },
      body: fd,
    });
    if (!res.ok) {
      const j = await res.json().catch(() => ({}));
      if (j?.errors) cErrors.value = Object.fromEntries(Object.entries(j.errors).map(([k,v]: any) => [k, (v as string[])[0]]));
      throw new Error(j.message || 'Failed to create guild');
    }
    notify({ type: 'green', title: 'GUILD CREATED', desc: 'Welcome to your new guild!', icon: 'check-circle' });
    router.visit('/guilds', { preserveScroll: true, preserveState: false });
  } catch (e: any) {
      notify({ type: 'magenta', title: 'ERROR', desc: e.message, icon: 'alert-triangle' });
  } finally { cBusy.value = false; }
}

// Join form
const jCode = ref('');
const jBusy = ref(false);
async function joinGuild() {
  jBusy.value = true;
  try {
    const res = await fetch('/guilds/join', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement)?.content || '',
      },
      body: JSON.stringify({ invite_code: jCode.value })
    });
    const j = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(j.message || 'Failed to join guild');

    notify({ type: 'green', title: 'JOINED GUILD', desc: 'You are now a member.', icon: 'users' });
    router.visit('/guilds', { preserveScroll: true, preserveState: false });
  } catch (e: any) {
      notify({ type: 'magenta', title: 'ERROR', desc: e.message, icon: 'alert-triangle' });
  } finally { jBusy.value = false; }
}

// Manage actions
const uLogoFile = ref<File | null>(null);
const uLogoPreview = ref<string | null>(props.guild?.logo_url || null);
const uDesc = ref(props.guild?.description || '');
const mBusy = ref(false);

function onULogoChange(e: Event) {
  const file = (e.target as HTMLInputElement).files?.[0] ?? null;
  uLogoFile.value = file;
  uLogoPreview.value = file ? URL.createObjectURL(file) : (props.guild?.logo_url || null);
}

async function saveGuild() {
  mBusy.value = true;
  try {
    const fd = new FormData();
    fd.append('_method', 'PATCH');
    fd.append('description', uDesc.value || '');
    if (uLogoFile.value) fd.append('logo', uLogoFile.value);
    const res = await fetch('/guilds/update', {
      method: 'POST',
      headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement)?.content || '',
      },
      body: fd,
    });
    const j = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(j.message || 'Failed to update guild');
    notify({ type: 'green', title: 'SAVED', desc: 'Guild settings updated.', icon: 'save' });
  } catch (e: any) {
      notify({ type: 'magenta', title: 'ERROR', desc: e.message, icon: 'alert-triangle' });
  } finally { mBusy.value = false; }
}

// Kick Logic
const kickBusy = ref<number|null>(null);
const showKickModal = ref(false);
const userToKick = ref<number|null>(null);

function confirmKick(id: number) {
    userToKick.value = id;
    showKickModal.value = true;
}

async function kickUser() {
  if (!userToKick.value) return;
  showKickModal.value = false;
  kickBusy.value = userToKick.value;

  try {
    const res = await fetch('/guilds/kick', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement)?.content || '',
      },
      body: JSON.stringify({ user_id: userToKick.value })
    });
    if (!res.ok) {
      const j = await res.json().catch(() => ({}));
      throw new Error(j.message || 'Failed to remove member');
    }
    notify({ type: 'green', title: 'KICKED', desc: 'Member removed.', icon: 'user-minus' });
    router.visit('/guilds', { preserveScroll: true, preserveState: false });
  } catch (e: any) {
      notify({ type: 'magenta', title: 'ERROR', desc: e.message, icon: 'alert-triangle' });
  } finally { kickBusy.value = null; userToKick.value = null; }
}

// Leave Logic
const leaveBusy = ref(false);
const showLeaveModal = ref(false);

async function leaveGuild() {
  showLeaveModal.value = false;
  leaveBusy.value = true;
  try {
    const res = await fetch('/guilds/leave', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement)?.content || '',
      },
      body: JSON.stringify({})
    });
    const j = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(j.message || 'Failed to leave guild');

    notify({ type: 'green', title: 'LEFT GUILD', desc: 'You have left the guild.', icon: 'log-out' });
    router.visit('/guilds', { preserveScroll: true, preserveState: false });
  } catch (e: any) {
      notify({ type: 'magenta', title: 'ERROR', desc: e.message, icon: 'alert-triangle' });
  } finally { leaveBusy.value = false; }
}

const inviteCode = ref(props.invite || '');
const regenBusy = ref(false);
async function regenerateInvite() {
  regenBusy.value = true;
  try {
    const res = await fetch('/guilds/invite/regenerate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement)?.content || '',
      },
      body: JSON.stringify({})
    });
    const j = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(j.message || 'Failed to regenerate invite');
    inviteCode.value = j.invite_code;
    notify({ type: 'green', title: 'REGENERATED', desc: 'New invite code created.', icon: 'refresh-cw' });
  } catch (e: any) {
      notify({ type: 'magenta', title: 'ERROR', desc: e.message, icon: 'alert-triangle' });
  } finally { regenBusy.value = false; }
}

function copyInvite() {
  if (!inviteCode.value) return;
  navigator.clipboard.writeText(inviteCode.value);
  notify({ type: 'green', title: 'COPIED', desc: 'Invite code copied to clipboard.', icon: 'copy' });
}

onMounted(() => nextTick(() => { if ((window as any).lucide) (window as any).lucide.createIcons(); }));
</script>

<template>
  <UserLayout>
    <Head title="Guilds" />

    <!-- Modals -->
    <ConfirmModal
        :isOpen="showKickModal"
        :title="$t('guilds.kick')"
        message="Are you sure you want to remove this member from the guild? They will need a new invite to rejoin."
        confirmText="Kick"
        @close="showKickModal = false"
        @confirm="kickUser"
    />

    <ConfirmModal
        :isOpen="showLeaveModal"
        :title="$t('guilds.leave')"
        message="WARNING: Leaving the guild will reset your guild contribution. You must hold the button to confirm."
        :confirmText="$t('guilds.leave').toUpperCase()"
        :requireHold="true"
        @close="showLeaveModal = false"
        @confirm="leaveGuild"
    />

    <section class="content">
      <div class="wrap">
        <div class="panel main-panel">
          <header class="page-head">
            <div class="head-flex">
                <div class="title-group">
                    <div class="title">{{ $t('guilds.title') }}</div>
                    <p class="subtitle" v-if="!hasGuild">{{ $t('guilds.subtitle_new') }}</p>
                    <p class="subtitle" v-else>{{ $t('guilds.subtitle_member') }}</p>
                </div>
                <div class="security-badge" v-if="hasGuild">
                    <i data-lucide="shield-check"></i>
                    <span>{{ $t('guilds.tab_active') }}</span>
                </div>
            </div>
          </header>

          <!-- No guild: show Create / Join -->
          <div v-if="!hasGuild" class="grid two">
            <div class="glass-card">
              <div class="card-head"><i data-lucide="plus-circle"></i> {{ $t('guilds.create') }}</div>
              <div class="grid-form">
                <label class="field">
                    <span class="lbl">{{ $t('guilds.name') }}</span>
                    <input class="inp" v-model="cName" :placeholder="$t('guilds.name')" />
                </label>
                <label class="field">
                    <span class="lbl">{{ $t('guilds.tag') }}</span>
                    <input class="inp" v-model="cTag" placeholder="TAG (2–6)" />
                </label>
                <label class="field">
                    <span class="lbl">{{ $t('guilds.logo_url') }}</span>
                    <div class="logo-upload-wrap">
                        <div class="logo-preview" :style="cLogoPreview ? { backgroundImage: `url(${cLogoPreview})` } : {}">
                            <span v-if="!cLogoPreview">{{ cTag?.[0]?.toUpperCase() || '?' }}</span>
                        </div>
                        <label class="logo-pick-btn">
                            <i data-lucide="upload"></i> Choose Logo
                            <input type="file" accept="image/*" class="sr-only" @change="onCLogoChange" />
                        </label>
                    </div>
                </label>
                <label class="field col-span-2">
                    <span class="lbl">{{ $t('guilds.description') }}</span>
                    <textarea class="inp" v-model="cDesc" rows="3" placeholder="Short description (max 500)"></textarea>
                </label>
              </div>
              <div class="errors" v-if="Object.keys(cErrors).length">
                <div v-for="(v,k) in cErrors" :key="k" class="err">{{ v }}</div>
              </div>
              <button class="btn-primary mt-4" :disabled="cBusy" @click="createGuild">
                  <span v-if="cBusy" class="spinner"></span>
                  <span>{{ cBusy ? 'Creating…' : 'Create Guild' }}</span>
              </button>
            </div>

            <div class="glass-card">
              <div class="card-head"><i data-lucide="log-in"></i> {{ $t('guilds.join') }}</div>
              <div class="grid-form">
                <label class="field col-span-2">
                    <span class="lbl">{{ $t('guilds.invite_code') }}</span>
                    <input class="inp" v-model="jCode" :placeholder="$t('guilds.invite_code')" />
                </label>
              </div>
              <button class="btn-secondary mt-4" :disabled="jBusy || !jCode.trim()" @click="joinGuild">
                  <span v-if="jBusy" class="spinner"></span>
                  <span>{{ jBusy ? 'Joining…' : 'Join' }}</span>
              </button>
            </div>
          </div>

          <!-- Has guild: dashboard -->
          <div v-else class="guild-dashboard">
            <div class="g-head-card">
              <div class="logo-wrap">
                  <div class="logo" :style="{ backgroundImage: props.guild?.logo_url ? `url(${props.guild.logo_url})` : '' }">
                    <span v-if="!props.guild?.logo_url">{{ props.guild?.tag?.[0] || 'G' }}</span>
                  </div>
              </div>
              <div class="meta">
                <div class="g-name">{{ props.guild?.name }} <span class="tag">[{{ props.guild?.tag }}]</span></div>
                <div class="g-desc">{{ props.guild?.description || 'No description yet.' }}</div>
                <div class="g-stats">
                    <div class="stat-pill"><i data-lucide="trophy"></i> {{ props.guild?.points }} Points</div>
                    <div class="stat-pill"><i data-lucide="users"></i> {{ props.guild?.members_count }} Members</div>
                </div>
              </div>
            </div>

            <div class="controls-grid" v-if="props.canManage">
              <div class="glass-card">
                <div class="card-head"><i data-lucide="link"></i> {{ $t('guilds.invite_code') }}</div>
                <div class="inv-row">
                  <input class="inp" :value="inviteCode" readonly />
                  <button class="btn-icon" @click="copyInvite" :disabled="!inviteCode" title="Copy"><i data-lucide="copy"></i></button>
                  <button class="btn-icon" @click="regenerateInvite" :disabled="regenBusy" title="Regenerate"><i data-lucide="refresh-cw"></i></button>
                </div>
              </div>
              <div class="glass-card">
                <div class="card-head"><i data-lucide="settings"></i> {{ $t('guilds.appearance') }}</div>
                <div class="grid-form">
                  <label class="field">
                      <span class="lbl">{{ $t('guilds.logo_url') }}</span>
                      <div class="logo-upload-wrap">
                          <div class="logo-preview" :style="uLogoPreview ? { backgroundImage: `url(${uLogoPreview})` } : {}">
                              <span v-if="!uLogoPreview">{{ props.guild?.tag?.[0] || 'G' }}</span>
                          </div>
                          <label class="logo-pick-btn">
                              <i data-lucide="upload"></i> Change Logo
                              <input type="file" accept="image/*" class="sr-only" @change="onULogoChange" />
                          </label>
                      </div>
                  </label>
                  <label class="field col-span-2">
                      <span class="lbl">{{ $t('guilds.description') }}</span>
                      <textarea class="inp" v-model="uDesc" rows="2" />
                  </label>
                </div>
                <button class="btn-primary mt-3" :disabled="mBusy" @click="saveGuild">{{ mBusy ? 'Saving…' : 'Save Changes' }}</button>
              </div>
            </div>

            <div class="members-section">
              <div class="section-head">
                  <h3>{{ $t('guilds.members') }}</h3>
                  <span class="sub">{{ $t('guilds.sorted_by_wager') }}</span>
              </div>
              <div class="m-list">
                <div v-for="m in sortedMembers" :key="m.id" class="m-row">
                  <div class="m-avatar"><img v-if="m.avatar_url" :src="m.avatar_url" alt="" /><span v-else>{{ (m.username || m.name || 'U')?.[0]?.toUpperCase?.() }}</span></div>
                  <div class="m-info">
                      <div class="m-name">{{ m.username || m.name || 'User' }} <span v-if="m.id === me?.id" class="you-badge">(You)</span></div>
                      <div class="m-wager">{{ $t('guilds.wagered') }}: {{ m.wagered ? m.wagered.toFixed(2) : '0.00' }}</div>
                  </div>
                  <div class="m-role" :data-role="m.role">{{ m.role }}</div>
                  <div class="m-actions">
                    <button v-if="props.canManage && m.role !== 'owner' && m.id !== me?.id" class="btn-danger-sm" :disabled="kickBusy===m.id" @click="confirmKick(m.id)">
                        <i data-lucide="user-minus"></i>
                    </button>
                  </div>
                </div>
              </div>
            </div>

            <div class="footer-actions">
              <button class="btn-leave" :disabled="leaveBusy" @click="showLeaveModal = true">
                  <i data-lucide="log-out"></i> {{ $t('guilds.leave') }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </section>
  </UserLayout>
</template>

<style scoped>
:global(:root) { --bg-card:#0a0a0a; --border:#151515; --cyan:#00f2ff; --magenta:#ff007a; --green:#00ff9d; }

.content { padding: 30px; animation: fade-in 0.8s cubic-bezier(0.2, 0, 0, 1); }
.wrap { max-width: 1100px; margin: 0 auto; }
.main-panel { background: var(--bg-card); border: 1px solid var(--border); border-radius: 20px; overflow: hidden; box-shadow: 0 20px 50px rgba(0,0,0,0.6); }

/* Header */
.page-head { padding: 25px 30px; border-bottom: 1px solid var(--border); background: linear-gradient(to right, rgba(0,242,255,0.03), transparent); }
.head-flex { display: flex; justify-content: space-between; align-items: center; }
.title { font-size: 14px; font-weight: 900; color: #fff; letter-spacing: 3px; text-transform: uppercase; }
.subtitle { color: #555; font-size: 12px; margin-top: 4px; font-weight: 600; }
.security-badge { display:flex; align-items:center; gap:8px; color: var(--green); background: rgba(0,255,157,0.05); padding:6px 14px; border-radius:50px; border:1px solid rgba(0,255,157,0.1); font-size:10px; font-weight:900; text-transform:uppercase; letter-spacing:1px; }

/* Cards */
.grid.two { padding: 30px; display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.glass-card { background: #050505; border: 1px solid var(--border); border-radius: 16px; padding: 20px; transition: 0.3s; }
.glass-card:hover { border-color: #222; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
.card-head { font-size: 11px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px; color: #fff; margin-bottom: 15px; display: flex; align-items: center; gap: 8px; }
.card-head i { width: 14px; color: var(--cyan); }

/* Forms */
.grid-form { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.lbl { font-size: 10px; font-weight: 900; color: #555; text-transform: uppercase; letter-spacing: 1px; }
.inp { background: #000; border: 1px solid var(--border); color: #fff; border-radius: 10px; padding: 12px 14px; font-size: 13px; transition: 0.3s; width: 100%; }
.inp:focus { border-color: var(--cyan); outline: none; box-shadow: 0 0 15px rgba(0,242,255,0.1); }
.col-span-2 { grid-column: span 2; }

/* Buttons */
.btn-primary { background: var(--cyan); color: #000; border: none; border-radius: 10px; padding: 12px 20px; font-size: 12px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px; cursor: pointer; transition: 0.3s; display: flex; align-items: center; justify-content: center; gap: 10px; }
.btn-primary:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(0,242,255,0.3); }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }

.btn-secondary { background: transparent; border: 1px solid #333; color: #fff; border-radius: 10px; padding: 12px 20px; font-size: 12px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px; cursor: pointer; transition: 0.3s; display: flex; align-items: center; justify-content: center; gap: 10px; }
.btn-secondary:hover:not(:disabled) { border-color: #fff; background: #111; }

.btn-icon { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; background: #111; border: 1px solid var(--border); color: #888; border-radius: 8px; cursor: pointer; transition: 0.2s; }
.btn-icon:hover { color: #fff; border-color: #444; }

.btn-danger-sm { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; background: rgba(255,62,62,0.1); border: 1px solid rgba(255,62,62,0.2); color: #ff3e3e; border-radius: 8px; cursor: pointer; transition: 0.2s; }
.btn-danger-sm:hover { background: rgba(255,62,62,0.2); transform: scale(1.1); }

.btn-leave { background: transparent; border: 1px solid #333; color: #666; border-radius: 10px; padding: 10px 16px; font-size: 11px; font-weight: 800; text-transform: uppercase; cursor: pointer; transition: 0.3s; display: flex; align-items: center; gap: 8px; margin-left: auto; }
.btn-leave:hover { color: #ff3e3e; border-color: #ff3e3e; background: rgba(255,62,62,0.05); }

/* Guild Dashboard */
.guild-dashboard { padding: 30px; display: flex; flex-direction: column; gap: 30px; }

.g-head-card { display: flex; gap: 24px; align-items: center; background: #050505; border: 1px solid var(--border); padding: 24px; border-radius: 16px; position: relative; overflow: hidden; }
.g-head-card::after { content: ''; position: absolute; top: 0; right: 0; width: 200px; height: 100%; background: linear-gradient(90deg, transparent, rgba(0,242,255,0.03)); pointer-events: none; }

.logo { width: 80px; height: 80px; border-radius: 20px; border: 1px solid var(--border); background: #000 center/cover no-repeat; display: grid; place-items: center; font-size: 24px; font-weight: 900; color: #333; box-shadow: 0 10px 30px rgba(0,0,0,0.5); }
.meta { display: flex; flex-direction: column; gap: 8px; }
.g-name { color: #fff; font-size: 20px; font-weight: 900; letter-spacing: 1px; }
.tag { color: var(--cyan); font-size: 12px; margin-left: 8px; background: rgba(0,242,255,0.1); padding: 2px 6px; border-radius: 4px; }
.g-desc { color: #888; font-size: 13px; max-width: 600px; line-height: 1.5; }
.g-stats { display: flex; gap: 12px; margin-top: 5px; }
.stat-pill { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 800; color: #bbb; background: #111; padding: 4px 10px; border-radius: 50px; border: 1px solid #222; }
.stat-pill i { width: 12px; color: var(--gold); }

.controls-grid { display: grid; grid-template-columns: 1fr 1.5fr; gap: 24px; }
.inv-row { display: flex; gap: 10px; }

/* Members */
.members-section { background: #050505; border: 1px solid var(--border); border-radius: 16px; padding: 24px; }
.section-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 1px solid #151515; padding-bottom: 15px; }
.section-head h3 { font-size: 12px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px; color: #fff; margin: 0; }
.section-head .sub { font-size: 10px; color: #666; font-weight: 700; text-transform: uppercase; }

.m-list { display: flex; flex-direction: column; gap: 10px; }
.m-row { display: grid; grid-template-columns: 40px 1fr auto auto; gap: 15px; align-items: center; background: #0a0a0a; border: 1px solid #151515; border-radius: 12px; padding: 12px 16px; transition: 0.2s; }
.m-row:hover { border-color: #333; background: #0e0e0e; }

.m-avatar { width: 40px; height: 40px; border: 1px solid #222; background: #000; color: #444; display: grid; place-items: center; border-radius: 10px; overflow: hidden; font-weight: 800; }
.m-avatar img { width: 100%; height: 100%; object-fit: cover; }

.m-info { display: flex; flex-direction: column; gap: 2px; }
.m-name { color: #fff; font-weight: 800; font-size: 13px; }
.you-badge { font-size: 9px; color: var(--cyan); margin-left: 5px; }
.m-wager { font-size: 10px; color: #666; font-weight: 700; }

.m-role { font-size: 10px; font-weight: 900; text-transform: uppercase; padding: 4px 10px; border-radius: 6px; background: #111; color: #888; border: 1px solid #222; }
.m-role[data-role="owner"] { color: var(--gold); border-color: rgba(247,147,26,0.3); background: rgba(247,147,26,0.05); }

/* Logo upload */
.logo-upload-wrap { display: flex; align-items: center; gap: 12px; }
.logo-preview { width: 52px; height: 52px; border-radius: 12px; border: 1px solid var(--border); background: #000 center/cover no-repeat; display: grid; place-items: center; font-size: 18px; font-weight: 900; color: #444; flex-shrink: 0; }
.logo-pick-btn { display: flex; align-items: center; gap: 6px; background: #111; border: 1px solid #333; color: #aaa; border-radius: 8px; padding: 8px 14px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; cursor: pointer; transition: 0.2s; }
.logo-pick-btn:hover { border-color: var(--cyan); color: var(--cyan); }
.logo-pick-btn i { width: 13px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }

.spinner { width: 16px; height: 16px; border: 2px solid rgba(0,0,0,0.1); border-top-color: currentColor; border-radius: 50%; animation: spin 0.8s linear infinite; }
.err { color: #ff3e3e; font-size: 11px; font-weight: 700; }

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes fade-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

@media (max-width: 900px) {
  .grid.two { grid-template-columns: 1fr; }
  .controls-grid { grid-template-columns: 1fr; }
  .g-head-card { flex-direction: column; text-align: center; }
  .g-stats { justify-content: center; }
}
</style>
