<script lang="ts">
  import { API_URL, WS_URL } from '$lib/api.js';
  import { apiFetch } from '$lib/api.js';
  import { goto } from '$app/navigation';
  import { onMount } from 'svelte';

  let profile: any = $state(null);
  let loading = $state(true);
  let wishlistText = $state('');
  let wishlistSaving = $state(false);
  let wishlistSaved = $state(false);
  let wishlistError = $state('');

  let friends: any[] = $state([]);
  let proposals: any[] = $state([]);
  let challenges: any[] = $state([]);

  let confirmingRemove: Set<string> = $state(new Set());
  let confirmingWithdraw: Set<string> = $state(new Set());

  // Increments every second — passed to formatChallengeExpiry to force re-evaluation
  let tick = $state(0);

  const token = () => localStorage.getItem('token');

  onMount(async () => {
    if (!token()) { goto('/auth'); return; }
    const res = await apiFetch(`${API_URL}/profile`);
    if (res.status === 401) { goto('/auth'); return; }
    profile = await res.json();
    wishlistText = profile.trade_wishlist || '';

    const friendsRes = await apiFetch(`${API_URL}/friends`);
    if (friendsRes.ok) friends = await friendsRes.json();

    const proposalsRes = await apiFetch(`${API_URL}/trade-proposals`);
    if (proposalsRes.ok) proposals = await proposalsRes.json();

    const challengesRes = await apiFetch(`${API_URL}/challenges`);
    if (challengesRes.ok) challenges = await challengesRes.json();

    loading = false;

    const tickInterval = setInterval(() => { tick++; }, 1000);
    const pollInterval = setInterval(async () => {
      const [pRes, cRes] = await Promise.all([
        apiFetch(`${API_URL}/trade-proposals`),
        apiFetch(`${API_URL}/challenges`),
      ]);
      if (pRes.ok) proposals = await pRes.json();
      if (cRes.ok) challenges = await cRes.json();
    }, 30_000);

    return () => {
      clearInterval(tickInterval);
      clearInterval(pollInterval);
    };
  });


  function formatExpiry(isoString: string) {
    const d = new Date(isoString);
    const diff = d.getTime() - Date.now();
    if (diff < 0) return 'expired';
    const hrs = Math.floor(diff / 3600000);
    if (hrs < 1) return 'in < 1h';
    if (hrs < 24) return `in ${hrs}h`;
    return `in ${Math.floor(hrs / 24)}d`;
  }

  async function saveWishlist() {
    wishlistSaving = true;
    wishlistError = '';
    wishlistSaved = false;
    const res = await apiFetch(`${API_URL}/profile`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ trade_wishlist: wishlistText }),
    });
    wishlistSaving = false;
    if (res.ok) {
      wishlistSaved = true;
      setTimeout(() => { wishlistSaved = false; }, 2500);
    } else {
      wishlistError = 'Failed to save.';
    }
  }

  function formatChallengeExpiry(isoString: string, _tick?: number) {
    const secs = Math.max(0, Math.floor((new Date(isoString).getTime() - Date.now()) / 1000));
    if (secs <= 0) return 'expired';
    if (secs < 60) return `${secs}s remaining`;
    return `${Math.floor(secs / 60)}m ${secs % 60}s remaining`;
  }

  async function withdrawChallenge(challengeId: string) {
    const res = await apiFetch(`${API_URL}/challenges/${challengeId}/decline`, { method: 'POST' });
    if (res.ok) challenges = challenges.filter((c: any) => c.id !== challengeId);
  }

  async function removeFriend(friendshipId: string) {
    await apiFetch(`${API_URL}/friendships/${friendshipId}`, { method: 'DELETE' });
    friends = friends.filter((f: any) => f.friendship_id !== friendshipId);
  }

  function logout() {
    localStorage.removeItem('token');
    localStorage.removeItem('refresh_token');
    goto('/auth');
  }

  let resendStatus = $state('');

  async function resendVerification() {
    resendStatus = 'sending';
    await apiFetch(`${API_URL}/auth/resend-verification`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email: profile.email }),
    });
    resendStatus = 'sent';
  }
</script>

<main>
  {#if loading}
    <p class="status">Loading...</p>
  {:else if profile}
    <div class="profile">

      <div class="profile-header">
        <div class="avatar">{profile.username[0].toUpperCase()}</div>
        <div class="profile-info">
          <h1 class="username">{profile.username}</h1>
          <p class="email">
            {profile.email}
            {#if !profile.email_verified}
              <span class="unverified-badge">unverified</span>
            {/if}
          </p>
          {#if !profile.email_verified}
            <button class="resend-btn" onclick={resendVerification} disabled={resendStatus === 'sending' || resendStatus === 'sent'}>
              {resendStatus === 'sent' ? 'Email sent' : resendStatus === 'sending' ? 'Sending...' : 'Resend verification email'}
            </button>
          {/if}
          <p class="joined">Member since {new Date(profile.created_at).toLocaleDateString('en-GB', { year: 'numeric', month: 'long', day: 'numeric' })}</p>
        </div>
        <button class="logout-btn" onclick={logout}>Log Out</button>
        <a href="/reset-password" class="reset-link">Change password</a>
      </div>

      <div class="section-divider"></div>

      <div class="shards-row">
        <span class="shards-icon">◈</span>
        <span class="shards-value">{profile.shards}</span>
        <span class="shards-label">Shards</span>
        <a href="/shatter" class="shards-link">shatter cards</a>
      </div>

      <div class="section-divider"></div>

      <h2 class="section-title">Stats</h2>
      <div class="stats-grid">
        <div class="stat-card">
          <span class="stat-label">Wins</span>
          <span class="stat-value wins">{profile.wins}</span>
        </div>
        <div class="stat-card">
          <span class="stat-label">Losses</span>
          <span class="stat-value losses">{profile.losses}</span>
        </div>
        <div class="stat-card">
          <span class="stat-label">Games Played</span>
          <span class="stat-value">{profile.wins + profile.losses}</span>
        </div>
        <div class="stat-card">
          <span class="stat-label">Win Rate</span>
          <span class="stat-value" class:good-wr={profile.win_rate >= 50} class:bad-wr={profile.win_rate !== null && profile.win_rate < 50}>
            {profile.win_rate !== null ? `${profile.win_rate}%` : '-'}
          </span>
        </div>
      </div>

      <div class="section-divider"></div>

      <div class="wishlist-group">
      <h2 class="section-title">Trade Wishlist</h2>
      <div class="wishlist-section">
        <p class="wishlist-hint">Cards or types you're looking to trade for. Visible on your public profile.</p>
        <textarea
          class="wishlist-textarea"
          bind:value={wishlistText}
          placeholder="e.g. Looking for legendary locations, rare scientists..."
          rows="3"
        ></textarea>
        <div class="wishlist-actions">
          <button class="save-btn" onclick={saveWishlist} disabled={wishlistSaving}>
            {wishlistSaving ? 'Saving...' : 'Save'}
          </button>
          {#if wishlistSaved}<span class="wishlist-ok">Saved ✓</span>{/if}
          <p class="wishlist-error" style="min-height: 1.2em">{wishlistError}</p>
        </div>
      </div>
      </div>

      <div class="section-divider"></div>

      <h2 class="section-title">Highlights</h2>
      <div class="highlights">
        <div class="highlight-card">
          <span class="highlight-label">Most Played Deck</span>
          {#if profile.most_played_deck}
            <span class="highlight-value">{profile.most_played_deck.name}</span>
            <span class="highlight-sub">{profile.most_played_deck.times_played} games</span>
          {:else}
            <span class="no-data">No games played yet</span>
          {/if}
        </div>

        <div class="highlight-card">
          <span class="highlight-label">Most Played Card</span>
          {#if profile.most_played_card}
            <div class="card-preview">
              {#if profile.most_played_card.image_link}
                <img src={profile.most_played_card.image_link} alt={profile.most_played_card.name} class="card-thumb" />
              {/if}
              <div class="card-preview-info">
                <span class="highlight-value">{profile.most_played_card.name}</span>
                <span class="highlight-sub">{profile.most_played_card.times_played} times played</span>
                <span class="highlight-sub">{profile.most_played_card.card_type} · {profile.most_played_card.card_rarity}</span>
              </div>
            </div>
          {:else}
            <span class="no-data">No cards played yet</span>
          {/if}
        </div>
      </div>

      <div class="section-divider"></div>

      <h2 class="section-title">Friends</h2>
      {#if friends.length === 0}
        <p class="no-friends">No friends yet.</p>
      {:else}
        <ul class="friends-list">
          {#each friends as f (f.friendship_id)}
            <li class="friend-item">
              <a href="/profile/{f.username}" class="friend-name">{f.username}</a>
              {#if confirmingRemove.has(f.friendship_id)}
                <span class="confirm-label">Remove friend?</span>
                <button class="confirm-yes-btn" onclick={() => removeFriend(f.friendship_id)}>Confirm</button>
                <button class="confirm-no-btn" onclick={() => { confirmingRemove.delete(f.friendship_id); confirmingRemove = confirmingRemove; }}>Cancel</button>
              {:else}
                <button class="unfriend-btn" onclick={() => { confirmingRemove.add(f.friendship_id); confirmingRemove = confirmingRemove; }}>Remove</button>
              {/if}
            </li>
          {/each}
        </ul>
      {/if}

      <div class="section-divider"></div>

      <h2 class="section-title">Trade Proposals</h2>

      {#if proposals.length === 0}
        <p class="no-friends">No trade proposals.</p>
      {:else}
        {@const incoming = proposals.filter((p: any) => p.direction === 'incoming' && p.status === 'pending')}
        {@const outgoing = proposals.filter((p: any) => p.direction === 'outgoing' && p.status === 'pending')}
        {@const resolved = proposals.filter((p: any) => p.status !== 'pending')}

        {#if incoming.length > 0}
          <p class="proposal-subhead">Incoming</p>
          {#each incoming as p (p.id)}
            <div class="proposal-card">
              <div class="proposal-meta">
                <a href="/profile/{p.proposer_username}" target="_blank" class="friend-name">{p.proposer_username}</a>
                <span class="proposal-status pending">Pending</span>
                <span class="proposal-expires">{formatExpiry(p.expires_at)}</span>
              </div>
              <p class="proposal-desc">
                {#if p.requested_cards.length > 0}Wants: <strong>{p.requested_cards.map((c: any) => c.name).join(', ')}</strong><br/>{/if}
                {#if p.offered_cards.length > 0}Offering: {p.offered_cards.map((c: any) => c.name).join(', ')}{/if}
              </p>
              <a href="/trade/proposal/{p.id}" class="see-proposal-btn">See Proposal</a>
            </div>
          {/each}
        {/if}

        {#if outgoing.length > 0}
          <p class="proposal-subhead">Outgoing</p>
          {#each outgoing as p (p.id)}
            <div class="proposal-card">
              <div class="proposal-meta">
                <span class="proposal-to">To: <a href="/profile/{p.recipient_username}" target="_blank" class="friend-name">{p.recipient_username}</a></span>
                <span class="proposal-status pending">Pending</span>
                <span class="proposal-expires">{formatExpiry(p.expires_at)}</span>
              </div>
              <p class="proposal-desc">
                {#if p.requested_cards.length > 0}Requesting: <strong>{p.requested_cards.map((c: any) => c.name).join(', ')}</strong><br/>{/if}
                {#if p.offered_cards.length > 0}Offering: {p.offered_cards.map((c: any) => c.name).join(', ')}{/if}
              </p>
              <a href="/trade/proposal/{p.id}" class="see-proposal-btn">See Proposal</a>
            </div>
          {/each}
        {/if}

        {#if resolved.length > 0}
          <p class="proposal-subhead">History</p>
          {#each resolved as p (p.id)}
            <div class="proposal-card resolved">
              <div class="proposal-meta">
                <span class="proposal-to">{p.direction === 'incoming' ? `From: ${p.proposer_username}` : `To: ${p.recipient_username}`}</span>
                <span class="proposal-status {p.status}">{p.status}</span>
              </div>
              <p class="proposal-desc">{p.requested_cards.length} requested · {p.offered_cards.length} offered</p>
              <a href="/trade/proposal/{p.id}" class="see-proposal-btn">See Proposal</a>
            </div>
          {/each}
        {/if}


      {/if}

      {#if challenges.length > 0}
        <div class="section-divider"></div>

        <h2 class="section-title">Game Challenges</h2>

        {@const pendingOut = challenges.filter((c: any) => c.direction === 'outgoing' && c.status === 'pending')}
        {@const pendingIn = challenges.filter((c: any) => c.direction === 'incoming' && c.status === 'pending')}
        {@const resolvedC = challenges.filter((c: any) => c.status !== 'pending')}

        {#if pendingOut.length > 0}
          <p class="proposal-subhead">Sent</p>
          {#each pendingOut as c (c.id)}
            <div class="proposal-card">
              <div class="proposal-meta">
                <span class="proposal-to">To: <a href="/profile/{c.challenged_username}" target="_blank" class="friend-name">{c.challenged_username}</a></span>
                <span class="proposal-status pending">Awaiting response</span>
                <span class="proposal-expires">{formatChallengeExpiry(c.expires_at, tick)}</span>
              </div>
              <p class="proposal-desc">Deck: <strong>{c.deck_name}</strong></p>
              {#if confirmingWithdraw.has(c.id)}
                <span class="confirm-label">Withdraw challenge?</span>
                <button class="confirm-yes-btn" onclick={() => withdrawChallenge(c.id)}>Confirm</button>
                <button class="confirm-no-btn" onclick={() => { confirmingWithdraw.delete(c.id); confirmingWithdraw = confirmingWithdraw; }}>Cancel</button>
              {:else}
                <button class="withdraw-btn" onclick={() => { confirmingWithdraw.add(c.id); confirmingWithdraw = confirmingWithdraw; }}>Withdraw</button>
              {/if}
            </div>
          {/each}
        {/if}

        {#if pendingIn.length > 0}
          <p class="proposal-subhead">Incoming</p>
          {#each pendingIn as c (c.id)}
            <div class="proposal-card">
              <div class="proposal-meta">
                <a href="/profile/{c.challenger_username}" target="_blank" class="friend-name">{c.challenger_username}</a>
                <span class="proposal-status pending">Pending</span>
                <span class="proposal-expires">{formatChallengeExpiry(c.expires_at, tick)}</span>
              </div>
              <p class="proposal-desc">Their deck: <strong>{c.deck_name}</strong></p>
              <p class="proposal-desc">Check your notification bell to accept.</p>
            </div>
          {/each}
        {/if}

        {#if resolvedC.length > 0}
          <p class="proposal-subhead">History</p>
          {#each resolvedC as c (c.id)}
            <div class="proposal-card resolved">
              <div class="proposal-meta">
                <span class="proposal-to">
                  {c.direction === 'outgoing' ? `To: ${c.challenged_username}` : `From: ${c.challenger_username}`}
                </span>
                <span class="proposal-status {c.status}">{c.status}</span>
              </div>
            </div>
          {/each}
        {/if}
      {/if}

    </div>
  {/if}
</main>

<style>
  main {
    height: 100vh;
    overflow-y: auto;
    background: var(--color-bg);
    padding: 2rem;
  }

  .profile {
    max-width: 700px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding-bottom: 5rem;
  }

  .profile-header {
    display: flex;
    align-items: center;
    gap: 1.5rem;
  }

  .avatar {
    width: 64px;
    height: 64px;
    border-radius: var(--radius-full);
    background: var(--color-surface-raised);
    border: 2px solid var(--color-bronze);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--color-gold);
    flex-shrink: 0;
  }

  .profile-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
  }

  .username {
    font-family: 'Cinzel', serif;
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--color-gold);
    margin: 0;
  }

  .email {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-md);
    color: rgba(240, 180, 80, 0.5);
    margin: 0;
  }

  .unverified-badge {
    font-family: 'Cinzel', serif;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #c87830;
    border: 1px solid rgba(200, 120, 48, 0.4);
    border-radius: 3px;
    padding: 1px 5px;
    vertical-align: middle;
    margin-left: 6px;
  }

  .resend-btn {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(240, 180, 80, 0.5);
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    text-decoration: underline;
    transition: color 0.15s;
    text-align: left;
  }

  .resend-btn:hover:not(:disabled) { color: rgba(240, 180, 80, 0.8); }
  .resend-btn:disabled { cursor: default; opacity: 0.6; }

  .joined {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(240, 180, 80, 0.35);
    margin: 0;
  }

  .logout-btn {
    font-family: 'Cinzel', serif;
    font-size: var(--btn-font-md);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: none;
    border: 1px solid rgba(180, 60, 60, 0.4);
    border-radius: var(--radius-sm);
    color: rgba(200, 80, 80, 0.7);
    padding: var(--btn-padding-md);
    cursor: pointer;
    transition: all 0.15s;
    align-self: flex-start;
  }

  .logout-btn:hover {
    border-color: var(--color-error);
    color: #e05050;
    background: rgba(180, 40, 40, 0.1);
  }

  .reset-link {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(240, 180, 80, 0.4);
    text-decoration: underline;
    align-self: flex-start;
    transition: color 0.15s;
  }

  .reset-link:hover { color: rgba(240, 180, 80, 0.7); }

  .shards-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  .shards-link {
    font-family: 'Cinzel', serif;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(126, 207, 207, 0.6);
    border: 1px solid rgba(126, 207, 207, 0.3);
    border-radius: var(--radius-sm);
    padding: 3px 8px;
    text-decoration: none;
    margin-top: 4px;
    margin-left: 0.5rem;
    transition: color 0.15s, border-color 0.15s;
  }
  .shards-link:hover { color: var(--color-cyan); border-color: rgba(126, 207, 207, 0.7); }

  .shards-icon {
    font-size: var(--text-xl);
    color: var(--color-cyan);
    position: relative;
    top: -0.1em;
    animation: shard-pulse 3s ease-in-out infinite;
  }

  .shards-value {
    font-family: 'Cinzel', serif;
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--color-cyan);
  }

  .shards-label {
    font-family: 'Cinzel', serif;
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(126, 207, 207, 0.5);
    margin-top: 4px;
  }

  .section-divider {
    height: 1px;
    background: var(--color-border-dim);
  }

  .section-title {
    font-family: 'Cinzel', serif;
    font-size: var(--text-base);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-gold-faint);
    margin: 0;
  }

  .stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
  }

  .stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border-dim);
    border-radius: var(--radius-lg);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }

  .stat-label {
    font-family: 'Cinzel', serif;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-gold-faint);
  }

  .stat-value {
    font-family: 'Cinzel', serif;
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--color-gold);
  }

  .wins   { color: var(--color-success); }
  .losses { color: var(--color-error); }
  .good-wr { color: var(--color-success); }
  .bad-wr  { color: var(--color-error); }

  .highlights {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }

  .highlight-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border-dim);
    border-radius: var(--radius-lg);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }

  .highlight-label {
    font-family: 'Cinzel', serif;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-gold-faint);
  }

  .highlight-value {
    font-family: 'Cinzel', serif;
    font-size: var(--text-md);
    font-weight: 700;
    color: var(--color-gold);
  }

  .highlight-sub {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(240, 180, 80, 0.45);
  }

  .card-preview {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    margin-top: 0.25rem;
  }

  .card-thumb {
    width: 48px;
    height: 48px;
    object-fit: cover;
    object-position: top;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border-subtle);
    flex-shrink: 0;
  }

  .card-preview-info {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
  }

  .wishlist-group {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
  }

  .wishlist-section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
  }

  .wishlist-hint {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(240, 180, 80, 0.35);
    margin: 0;
  }

  .wishlist-textarea {
    width: 100%;
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    color: var(--color-gold);
    font-family: 'Crimson Text', serif;
    font-size: var(--text-md);
    padding: 0.6rem 0.75rem;
    resize: vertical;
    box-sizing: border-box;
    transition: border-color 0.15s;
    outline: none;
  }

  .wishlist-textarea:focus { border-color: var(--color-bronze); }
  .wishlist-textarea::placeholder { color: rgba(240, 180, 80, 0.25); }

  .wishlist-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
  }

  .save-btn {
    font-family: 'Cinzel', serif;
    font-size: var(--btn-font-md);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-bronze);
    border-radius: var(--radius-sm);
    color: var(--color-btn-text);
    padding: var(--btn-padding-md);
    cursor: pointer;
    transition: all 0.15s;
  }

  .save-btn:hover:not(:disabled) { background: #4d3010; }
  .save-btn:disabled { opacity: 0.5; cursor: default; }

  .wishlist-ok {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    color: var(--color-success);
  }

  .wishlist-error {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    color: var(--color-error);
    margin: 0;
  }

  .no-friends {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(240, 180, 80, 0.25);
    margin: 0;
  }

  .friends-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }

  .friend-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.5rem 0.75rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border-dim);
    border-radius: var(--radius-md);
  }

  .friend-name {
    font-family: 'Cinzel', serif;
    font-size: var(--text-base);
    font-weight: 700;
    color: var(--color-gold);
    text-decoration: none;
    flex: 1;
    transition: color 0.15s;
  }

  .friend-name:hover { color: var(--color-bronze); }

  .unfriend-btn {
    font-family: 'Cinzel', serif;
    font-size: var(--btn-font-md);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: rgba(180, 40, 40, 0.8);
    border: none;
    border-radius: var(--radius-md);
    color: #fff;
    padding: var(--btn-padding-md);
    cursor: pointer;
    transition: background 0.15s;
  }

  .unfriend-btn:hover { background: rgba(210, 50, 50, 0.9); }

  .no-data {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(240, 180, 80, 0.25);
  }

  /* ── Trade Proposals ── */
  .proposal-subhead {
    font-family: 'Cinzel', serif;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(240, 180, 80, 0.3);
    margin: 0.5rem 0 0;
  }

  .proposal-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border-dim);
    border-radius: var(--radius-lg);
    padding: 0.85rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
  }

  .proposal-card.resolved { opacity: 0.5; }

  .proposal-meta {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
  }

  .proposal-to {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    color: rgba(240, 180, 80, 0.5);
  }

  .proposal-status {
    font-family: 'Cinzel', serif;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-radius: 3px;
    padding: 1px 5px;
    border: 1px solid;
  }

  .proposal-status.pending  { color: var(--color-bronze); border-color: rgba(200, 134, 26, 0.4); }
  .proposal-status.accepted { color: var(--color-success); border-color: rgba(106, 170, 106, 0.4); }
  .proposal-status.declined { color: var(--color-error); border-color: rgba(200, 64, 64, 0.4); }
  .proposal-status.expired   { color: rgba(240, 180, 80, 0.3); border-color: var(--color-border-dim); }
  .proposal-status.withdrawn { color: rgba(240, 180, 80, 0.3); border-color: var(--color-border-dim); }

  .proposal-expires {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-sm);
    font-style: italic;
    color: rgba(240, 180, 80, 0.3);
    margin-left: auto;
  }

  .proposal-desc {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    color: rgba(240, 180, 80, 0.65);
    margin: 0;
    line-height: 1.5;
  }

  .proposal-desc strong { color: var(--color-gold); font-style: normal; font-weight: 600; }

  .see-proposal-btn {
    font-family: 'Cinzel', serif;
    font-size: var(--btn-font-md);
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    color: var(--color-gold);
    padding: var(--btn-padding-md);
    text-decoration: none;
    display: inline-block;
    transition: all 0.15s;
    margin-top: 0.25rem;
    align-self: flex-start;
  }
  .see-proposal-btn:hover { border-color: var(--color-bronze); background: #4d3010; }

  .withdraw-btn {
    font-family: 'Cinzel', serif;
    font-size: var(--btn-font-sm);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: none;
    border: 1px solid rgba(180, 60, 60, 0.4);
    border-radius: var(--radius-sm);
    color: rgba(200, 80, 80, 0.6);
    padding: var(--btn-padding-sm);
    cursor: pointer;
    transition: all 0.15s;
    align-self: flex-start;
  }

  .withdraw-btn:hover { border-color: var(--color-error); color: #e05050; }

  .status {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-md);
    font-style: italic;
    color: rgba(240, 180, 80, 0.5);
    text-align: center;
    margin-top: 4rem;
  }

  .confirm-label {
    font-family: 'Crimson Text', serif;
    font-size: var(--text-base);
    font-style: italic;
    color: rgba(200, 80, 80, 0.8);
  }

  .confirm-yes-btn {
    font-family: 'Cinzel', serif;
    font-size: var(--btn-font-sm);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: rgba(180, 40, 40, 0.8);
    border: none;
    border-radius: var(--radius-sm);
    color: #fff;
    padding: var(--btn-padding-sm);
    cursor: pointer;
    transition: background 0.15s;
  }

  .confirm-yes-btn:hover { background: rgba(210, 50, 50, 0.9); }

  .confirm-no-btn {
    font-family: 'Cinzel', serif;
    font-size: var(--btn-font-sm);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: none;
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
    color: var(--color-gold-faint);
    padding: var(--btn-padding-sm);
    cursor: pointer;
    transition: all 0.15s;
  }

  .confirm-no-btn:hover { border-color: rgba(107, 76, 30, 0.7); color: rgba(240, 180, 80, 0.7); }

  @media (max-width: 640px) {
    .stats-grid { grid-template-columns: repeat(2, 1fr); }
    .highlights { grid-template-columns: 1fr; }
    .profile-header { flex-wrap: wrap; }
  }
</style>