<script setup lang="ts">
// My profile. Faithfully ports project/platform-enduser.jsx `ProfileScreenDeep`
// (lines 972–1400) and its tab sub-components. 5 tabs: Profile / Work info /
// Preferences / Email signature / Notifications, plus a sticky save bar that
// surfaces when any tab is dirty.


const toast = useToast()
const tweaks = usePortalTweaks()

// Honour ?tab=… so the topbar bell's "Preferences" can deep-link to
// the Notifications tab (since /notifications no longer exists).
const route = useRoute()
const validTabs = ['profile', 'work', 'preferences', 'signature', 'notifications'] as const
const initialTab = (typeof route.query.tab === 'string' && (validTabs as readonly string[]).includes(route.query.tab))
  ? route.query.tab as string
  : 'profile'
const tab = ref(initialTab)
const dirty = ref(false)
const markDirty = () => { dirty.value = true }

function discard() {
  dirty.value = false
  toast.warn('Discarded unsaved changes')
}
function save() {
  dirty.value = false
  toast.ok('Profile saved · changes live in ~10 seconds')
}

// Modals
const photoOpen = ref(false)
const quietOpen = ref(false)
const overrideOpen = ref(false)

// Mustache-tag literals — held as JS constants so the template doesn't have
// to nest `{{ ... }}` inside `{{ ... }}` (which trips Vue's parser).
const AVAILABLE_VARS_TEXT =
  '{' + '{full_name}}' + ' · ' +
  '{' + '{first_name}}' + ' · ' +
  '{' + '{job_title}}' + ' · ' +
  '{' + '{phone}}' + ' · ' +
  '{' + '{email}}' + ' · ' +
  '{' + '{company_name}}' + ' · ' +
  '{' + '{pronouns}}'
const MERGE_TAG_LITERAL = '{' + '{merge}}'

// --- Profile tab ---
const profile = reactive({
  firstName: 'Anne',
  lastName: 'Baslund',
  displayName: 'Anne B.',
  pronouns: 'she/her',
  email: 'anne@dezky.com',
  phone: '+45 21 47 88 02',
})

// --- Work info ---
const work = reactive({
  title: 'Founder · CEO',
  department: 'Leadership',
  manager: '(none · top of org)',
  location: 'Copenhagen, DK',
  startDate: '14 Jan 2026',
  officeDays: 'Mon · Wed · Fri',
})

// Match source `WorkInfoTab` connections list (5 items, only Google + MS365 connected).
const connections = ref([
  { id: 'google',    name: 'Google',           initial: 'G', color: '#4285F4', connected: true,  account: 'anne@gmail.com',          scopes: 'calendar · contacts', since: '14 Jan 2026' },
  { id: 'microsoft', name: 'Microsoft 365',    initial: 'M', color: '#00A4EF', connected: true,  account: 'anne.baslund@outlook.com', scopes: 'calendar',            since: '02 Mar 2026' },
  { id: 'apple',     name: 'Apple',            initial: 'A', color: '#000000', connected: false, account: '', scopes: '', since: '' },
  { id: 'github',    name: 'GitHub',           initial: 'g', color: '#181717', connected: false, account: '', scopes: '', since: '' },
  { id: 'slack',     name: 'Slack (legacy DM)', initial: 's', color: '#4A154B', connected: false, account: '', scopes: '', since: '' },
])

const apiTokens = ref([
  { id: 'tk-1', name: 'CLI · macbook',          scope: 'read:files write:files', last: '2 d ago' },
  { id: 'tk-2', name: 'Zapier integration',     scope: 'read:mail',               last: '14 d ago' },
])

// --- Preferences ---
const theme = ref<'system' | 'light' | 'dark'>('system')
const density = ref<'Comfortable' | 'Compact'>('Comfortable')
const reduceMotion = ref(false)

const ooo = reactive({
  enabled: false,
  from: '2026-06-14',
  to: '2026-06-21',
  message: "I’m on holiday until 21 June and will reply when I’m back.\n\nFor urgent matters, contact Mikkel at mikkel@dezky.com.",
  redirect: true,
})

const region = reactive({
  language: 'English (UK)',
  spellcheck: 'Dansk · English',
  timezone: 'Europe/Copenhagen · CEST',
  dateFormat: 'DD MMM YYYY · 14 May 2026',
  timeFormat: '24-hour · 14:32',
  weekStarts: 'Monday',
  currency: 'DKK · 1.940,00',
  workHours: '09:00 – 17:00',
})

function pickTheme(v: 'system' | 'light' | 'dark') {
  theme.value = v
  if (v === 'light' || v === 'dark') tweaks.setTheme(v)
  markDirty()
}

// --- Signature ---
const sig = reactive({
  // Signature body is plain text shown in the contentEditable preview.
  // Source uses 3 lines + a disclosure footer; we keep the same structure.
  body: 'Anne Baslund\nFounder · CEO at baslund\n+45 21 47 88 02 · anne@dezky.com',
})
const sigApply = reactive({ newEmails: true, replies: true, invites: false, ooo: false })

// --- Notifications ---
// Source `NotifPrefsTab` channels and event labels.
const notifChannels = ['In-app', 'Email', 'Push · mobile', 'Slack mirror'] as const
const notifEvents = ref([
  { id: 'mentions',     label: 'Mentions in chat',                vals: [true, true, true, false] },
  { id: 'dms',          label: 'Direct messages',                  vals: [true, true, true, false] },
  { id: 'shared',       label: 'Files shared with me',             vals: [true, true, false, false] },
  { id: 'invites',      label: 'Meeting invites',                  vals: [true, true, true, false] },
  { id: 'reminders',    label: 'Calendar reminders',               vals: [true, false, true, false] },
  { id: 'security',     label: 'Security alerts on my account',    vals: [true, true, true, false] },
  { id: 'announcements',label: 'Workspace announcements (admin)',   vals: [true, true, false, false] },
  { id: 'billing',      label: 'Billing reminders (admin only)',    vals: [true, true, false, false] },
  { id: 'digest',       label: 'Weekly digest',                    vals: [false, true, false, false] },
  { id: 'marketing',    label: 'Marketing from dezky',             vals: [false, false, false, false] },
])

// Quiet hours modal state — mirrors source EditQuietHoursModal.
const quiet = reactive({
  weekFrom: '22:00',
  weekTo: '07:00',
  weekendDifferent: true,
  wkndFrom: '00:00',
  wkndTo: '09:00',
  pauseHolidays: true,
  allowManager: false,
})

// Change photo modal state — mirrors source ChangePhotoModal.
const photo = reactive({ uploaded: false, crop: 50 })
function uploadPhoto() { photo.uploaded = true }
function removePhoto() { photo.uploaded = false }
watch(photoOpen, (v) => { if (v) { photo.uploaded = false; photo.crop = 50 } })

// Signature override modal state.
const override = reactive({ scope: 'domain' as 'domain' | 'recipient' | 'category', domain: 'baslund.dk', name: 'External communications', body: 'Best regards,\nAnne Baslund\nFounder · baslund\nbaslund.dk · +45 21 47 88 02' })
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Account"
      title="My profile"
      subtitle="Update your personal details, preferences, and email signature."
    />

    <div class="tabs-wrap">
      <Tabs
        v-model="tab"
        :items="[
          { value: 'profile',       label: 'Profile' },
          { value: 'work',          label: 'Work info' },
          { value: 'preferences',   label: 'Preferences' },
          { value: 'signature',     label: 'Email signature' },
          { value: 'notifications', label: 'Notifications' },
        ]"
      />
    </div>

    <div class="content">
      <!-- Profile tab -->
      <section v-if="tab === 'profile'" class="profile-grid">
        <Card>
          <div class="photo">
            <Avatar :name="`${profile.firstName} ${profile.lastName}`" :size="88" />
            <UiButton size="sm" variant="secondary" @click="photoOpen = true">
              <template #leading><UiIcon name="upload" :size="13" /></template>
              Change photo
            </UiButton>
            <div class="photo-meta">
              <div class="display">{{ profile.firstName }} {{ profile.lastName }}</div>
              <Mono dim>{{ profile.email }}</Mono>
            </div>
          </div>
        </Card>
        <Card>
          <header class="card-header">
            <Eyebrow>Personal</Eyebrow>
            <h2>Contact details</h2>
          </header>
          <div class="grid-2">
            <EnduserFormField label="First name"><input v-model="profile.firstName" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Last name"><input v-model="profile.lastName" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Display name"><input v-model="profile.displayName" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Pronouns"><input v-model="profile.pronouns" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Email"><input v-model="profile.email" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Phone"><input v-model="profile.phone" @input="markDirty" /></EnduserFormField>
          </div>
        </Card>
      </section>

      <!-- Work info tab -->
      <section v-else-if="tab === 'work'" class="stack">
        <Card>
          <header class="card-header">
            <Eyebrow>Workplace</Eyebrow>
            <h2>What you do at baslund</h2>
          </header>
          <div class="grid-2">
            <EnduserFormField label="Job title"><input v-model="work.title" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Department"><input v-model="work.department" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Manager"><input v-model="work.manager" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Location"><input v-model="work.location" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Start date"><input v-model="work.startDate" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Office days"><input v-model="work.officeDays" @input="markDirty" /></EnduserFormField>
          </div>
        </Card>

        <Card>
          <header class="card-header">
            <Eyebrow>Connected accounts</Eyebrow>
            <h2>Link external services</h2>
            <p>For calendar sync, contact lookup, and single sign-on. dezky never sees your password.</p>
          </header>
          <ul class="conn">
            <li v-for="p in connections" :key="p.id">
              <span class="conn-tile" :style="{ background: p.color }">{{ p.initial }}</span>
              <div class="conn-text">
                <div class="conn-name">
                  {{ p.name }}
                  <Badge v-if="p.connected" tone="ok" dot>connected</Badge>
                </div>
                <Mono v-if="p.connected" dim>{{ p.account }} · {{ p.scopes }} · since {{ p.since }}</Mono>
                <Mono v-else dim>not linked</Mono>
              </div>
              <div class="conn-actions">
                <template v-if="p.connected">
                  <UiButton size="sm" variant="ghost" @click="toast.info(`Managing ${p.name}`)">Manage</UiButton>
                  <UiButton size="sm" variant="ghost" @click="toast.warn(`Disconnecting ${p.name}`); markDirty()">Disconnect</UiButton>
                </template>
                <UiButton v-else size="sm" variant="secondary" @click="toast.info(`Connecting ${p.name}`)">
                  <template #leading><UiIcon name="external" :size="13" /></template>
                  Connect
                </UiButton>
              </div>
            </li>
          </ul>
        </Card>

        <Card>
          <header class="card-header with-actions">
            <div class="head-text">
              <Eyebrow>Developers</Eyebrow>
              <h2>Personal API tokens</h2>
              <p>Use these in scripts and integrations that act on your behalf. Treat like passwords.</p>
            </div>
            <UiButton size="sm" variant="secondary" @click="toast.info('New token wizard')">
              <template #leading><UiIcon name="plus" :size="13" /></template>
              New token
            </UiButton>
          </header>
          <ul class="tokens">
            <li v-for="t in apiTokens" :key="t.id">
              <UiIcon name="key" :size="15" stroke="var(--text-mute)" />
              <div class="conn-text">
                <div class="conn-name">{{ t.name }}</div>
                <Mono dim>{{ t.scope }} · last used {{ t.last }}</Mono>
              </div>
              <UiButton size="sm" variant="ghost" @click="toast.warn(`Token ${t.id} revoked`)">Revoke</UiButton>
            </li>
          </ul>
        </Card>
      </section>

      <!-- Preferences tab -->
      <section v-else-if="tab === 'preferences'" class="stack">
        <Card>
          <header class="card-header with-actions">
            <div class="head-text">
              <Eyebrow>Out of office</Eyebrow>
              <h2>Auto-reply when you're away</h2>
              <p>Active for the dates below. Senders get a one-time reply per thread.</p>
            </div>
            <EnduserToggle v-model="ooo.enabled" @update:model-value="markDirty" />
          </header>
          <div class="ooo" :data-on="ooo.enabled">
            <div class="grid-2">
              <EnduserFormField label="From"><input v-model="ooo.from" @input="markDirty" /></EnduserFormField>
              <EnduserFormField label="Until"><input v-model="ooo.to" @input="markDirty" /></EnduserFormField>
            </div>
            <EnduserFormField label="Auto-reply message">
              <textarea v-model="ooo.message" rows="5" @input="markDirty" />
            </EnduserFormField>
            <div class="redirect-row">
              <div>
                <div class="rr-l">Forward incoming mail to a coworker</div>
                <Mono dim>mikkel@dezky.com · gets a tag so they know it's a forward</Mono>
              </div>
              <EnduserToggle v-model="ooo.redirect" @update:model-value="markDirty" />
            </div>
            <Mono dim>presence will be set to <b style="color: var(--text);">Away</b> automatically · status reverts on the end date</Mono>
          </div>
        </Card>

        <Card>
          <header class="card-header">
            <Eyebrow>Language & region</Eyebrow>
            <h2>Where and how dezky speaks to you</h2>
          </header>
          <div class="grid-2">
            <EnduserFormField label="Display language"><input v-model="region.language" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Spell-check language"><input v-model="region.spellcheck" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Timezone"><input v-model="region.timezone" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Date format"><input v-model="region.dateFormat" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Time format"><input v-model="region.timeFormat" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Week starts on"><input v-model="region.weekStarts" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Currency"><input v-model="region.currency" @input="markDirty" /></EnduserFormField>
            <EnduserFormField label="Working hours"><input v-model="region.workHours" @input="markDirty" /></EnduserFormField>
          </div>
        </Card>

        <Card>
          <header class="card-header">
            <Eyebrow>Appearance</Eyebrow>
            <h2>How dezky looks</h2>
            <p>Affects this device only. Global theme is set per-workspace by admins.</p>
          </header>
          <div class="appearance">
            <EnduserFormField label="Theme">
              <div class="theme-tiles">
                <button
                  v-for="t in [
                    { v: 'system' as const, l: 'Match system', bg: 'linear-gradient(135deg, #F4F3EE 50%, #0A0A0A 50%)' },
                    { v: 'light' as const,  l: 'Light',         bg: '#F4F3EE' },
                    { v: 'dark' as const,   l: 'Dark',          bg: '#0A0A0A' },
                  ]"
                  :key="t.v"
                  class="theme-tile"
                  :class="{ active: theme === t.v }"
                  @click="pickTheme(t.v)"
                >
                  <span class="theme-swatch" :style="{ background: t.bg }" />
                  <span>{{ t.l }}</span>
                </button>
              </div>
            </EnduserFormField>
            <EnduserFormField label="Density">
              <div class="density">
                <button
                  v-for="d in (['Comfortable', 'Compact'] as const)"
                  :key="d"
                  :class="{ active: density === d }"
                  @click="density = d; tweaks.setDensity(d === 'Comfortable' ? 'comfy' : 'compact'); markDirty()"
                >{{ d }}</button>
              </div>
            </EnduserFormField>
            <EnduserFormField label="Reduce motion">
              <div class="row-toggle">
                <EnduserToggle v-model="reduceMotion" @update:model-value="markDirty" />
                <span>Honor system preference</span>
              </div>
            </EnduserFormField>
          </div>
        </Card>
      </section>

      <!-- Signature tab -->
      <section v-else-if="tab === 'signature'" class="sig-grid">
        <Card>
          <header class="card-header">
            <Eyebrow>Email signature</Eyebrow>
            <h2>Your default signature</h2>
            <p>Appended to outgoing email from your dezky address. You can override per-account.</p>
          </header>
          <div class="toolbar">
            <button class="tb b" @click="markDirty">B</button>
            <button class="tb i" @click="markDirty">I</button>
            <button class="tb u" @click="markDirty">U</button>
            <button class="tb" @click="markDirty">⇿</button>
            <button class="tb mono" @click="markDirty">link</button>
            <button class="tb mono" @click="markDirty">image</button>
          </div>
          <div
            class="sig-editor"
            contenteditable="true"
            @input="markDirty"
            spellcheck="false"
          >
            <div class="sig-line bold">Anne Baslund</div>
            <div class="sig-line dim">Founder · CEO at <b>baslund</b></div>
            <div class="sig-line mute">+45 21 47 88 02 · anne@dezky.com</div>
            <div class="sig-foot">We collect personal data — see our <u>privacy policy</u>. Sent via <span class="mono">dezky</span>.</div>
          </div>
          <div class="vars">
            <Mono>// available variables</Mono><br />
            {{ AVAILABLE_VARS_TEXT }}
          </div>
        </Card>

        <div class="sig-side">
          <Card>
            <header class="card-header">
              <Eyebrow>When to use</Eyebrow>
              <h2>Apply to</h2>
            </header>
            <ul class="apply-list">
              <li>
                <label><input type="checkbox" v-model="sigApply.newEmails" @change="markDirty" /><span>New emails</span></label>
              </li>
              <li>
                <label><input type="checkbox" v-model="sigApply.replies" @change="markDirty" /><span>Replies and forwards</span></label>
              </li>
              <li>
                <label><input type="checkbox" v-model="sigApply.invites" @change="markDirty" /><span>Calendar invites</span></label>
              </li>
              <li>
                <label><input type="checkbox" v-model="sigApply.ooo" @change="markDirty" /><span>Out-of-office replies</span></label>
              </li>
            </ul>
          </Card>
          <Card>
            <header class="card-header with-actions">
              <div class="head-text">
                <Eyebrow>Per-account</Eyebrow>
                <h2>Account overrides</h2>
              </div>
              <UiButton size="sm" variant="ghost" @click="overrideOpen = true">
                <template #leading><UiIcon name="plus" :size="13" /></template>
                Add
              </UiButton>
            </header>
            <Mono dim>// no overrides · all accounts use the default signature</Mono>
          </Card>
        </div>
      </section>

      <!-- Notifications tab -->
      <section v-else-if="tab === 'notifications'">
        <Card :pad="0" style="max-width: 920px;">
          <div class="notif-head">
            <Eyebrow>Channels · per event</Eyebrow>
            <div class="notif-title">Notification preferences</div>
          </div>
          <table class="notif">
            <thead>
              <tr>
                <th class="lhs">Event</th>
                <th v-for="c in notifChannels" :key="c">{{ c }}</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="e in notifEvents" :key="e.id">
                <td class="lhs">{{ e.label }}</td>
                <td v-for="(v, j) in e.vals" :key="j">
                  <input type="checkbox" v-model="e.vals[j]" @change="markDirty" />
                </td>
              </tr>
            </tbody>
          </table>
          <div class="notif-foot">
            <Mono dim>// quiet hours · 22:00 – 07:00 · respects your working hours</Mono>
            <UiButton size="sm" variant="ghost" @click="quietOpen = true">Edit quiet hours</UiButton>
          </div>
        </Card>
      </section>
    </div>

    <EnduserSaveBar :dirty="dirty" @discard="discard" @save="save" />

    <!-- Change photo modal -->
    <Modal :open="photoOpen" eyebrow="Account · photo" title="Change profile photo" size="md" @close="photoOpen = false">
      <div class="photo-modal">
        <button v-if="!photo.uploaded" class="photo-upload" @click="uploadPhoto">
          <UiIcon name="upload" :size="28" stroke="var(--text-mute)" />
          <div class="pu-text">
            <div class="pu-l">Drop a photo here, or click to browse</div>
            <Mono dim style="margin-top: 6px; display: block;">jpg · png · webp · up to 5 MB · best at 512×512</Mono>
          </div>
        </button>
        <template v-else>
          <div class="crop-row">
            <div class="crop-main">
              <Eyebrow style="display: block; margin-bottom: 8px;">Crop preview</Eyebrow>
              <div class="crop-stage">
                <div class="crop-mask" />
                <span class="crop-letter" :style="{ transform: `translate(${(photo.crop - 50) * 0.4}px, 0)` }">A</span>
              </div>
              <div style="margin-top: 12px;">
                <Mono dim style="display: block; margin-bottom: 4px;">Horizontal position</Mono>
                <input type="range" min="0" max="100" v-model.number="photo.crop" />
              </div>
            </div>
            <div class="crop-side">
              <Eyebrow style="display: block; margin-bottom: 8px;">Final result</Eyebrow>
              <div class="circle large"><span :style="{ transform: `translate(${(photo.crop - 50) * 0.1}px, 0)` }">A</span></div>
              <Mono dim>large · 88×88</Mono>
              <div class="circle small"><span>A</span></div>
              <Mono dim>chat · 32×32</Mono>
            </div>
          </div>
          <UiButton size="sm" variant="ghost" @click="removePhoto">Replace photo</UiButton>
        </template>
        <div class="def-block">
          <Mono dim>// where it appears</Mono>
          <div class="def-body">Profile pages, Chat avatars, mail headers, meeting tiles, and the partner console. Co-workers in your workspace can see it.</div>
        </div>
      </div>
      <template #footer>
        <UiButton v-if="photo.uploaded" variant="danger" @click="removePhoto">
          <template #leading><UiIcon name="trash" :size="13" /></template>
          Remove
        </UiButton>
        <div style="flex: 1;" />
        <UiButton variant="ghost" @click="photoOpen = false">Cancel</UiButton>
        <UiButton variant="primary" :disabled="!photo.uploaded" @click="photoOpen = false; markDirty(); toast.ok('Photo queued for upload')">
          <template #leading><UiIcon name="check" :size="13" /></template>
          {{ photo.uploaded ? 'Use this photo' : 'Select a photo' }}
        </UiButton>
      </template>
    </Modal>

    <!-- Edit quiet hours modal -->
    <Modal :open="quietOpen" eyebrow="Notifications · quiet hours" title="Edit quiet hours" size="md" @close="quietOpen = false">
      <div class="quiet-stack">
        <div class="callout-info">
          <UiIcon name="bell" :size="14" />
          <span>Push and email notifications are silenced during quiet hours. In-app indicators still update so nothing is missed — just no pings.</span>
        </div>

        <div>
          <Eyebrow style="display: block; margin-bottom: 8px;">Weekdays · Mon–Fri</Eyebrow>
          <div class="grid-2">
            <EnduserFormField label="From"><input v-model="quiet.weekFrom" /></EnduserFormField>
            <EnduserFormField label="Until"><input v-model="quiet.weekTo" /></EnduserFormField>
          </div>
        </div>

        <div>
          <div class="weekend-head">
            <Eyebrow>Weekends · Sat–Sun</Eyebrow>
            <label class="inline-check">
              <input type="checkbox" v-model="quiet.weekendDifferent" />
              different from weekdays
            </label>
          </div>
          <div v-if="quiet.weekendDifferent" class="grid-2">
            <EnduserFormField label="From"><input v-model="quiet.wkndFrom" /></EnduserFormField>
            <EnduserFormField label="Until"><input v-model="quiet.wkndTo" /></EnduserFormField>
          </div>
          <Mono v-else dim>same as weekdays · {{ quiet.weekFrom }} – {{ quiet.weekTo }}</Mono>
        </div>

        <div class="quiet-rules">
          <div class="qr-row">
            <div>
              <div class="qr-l">Pause on public holidays</div>
              <Mono dim>silence all day on Danish public holidays</Mono>
            </div>
            <EnduserToggle v-model="quiet.pauseHolidays" />
          </div>
          <div class="qr-row">
            <div>
              <div class="qr-l">Always allow your manager</div>
              <Mono dim>Mikkel Nørgaard can still reach you during quiet hours</Mono>
            </div>
            <EnduserToggle v-model="quiet.allowManager" />
          </div>
          <div class="qr-row">
            <div>
              <div class="qr-l">Override for P1 incidents</div>
              <Mono dim>always notify for on-call pages and security alerts</Mono>
            </div>
            <EnduserToggle :model-value="true" />
          </div>
        </div>

        <Mono dim style="display: block; text-align: center;">shown on your profile card so teammates know when not to expect you</Mono>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="quietOpen = false">Cancel</UiButton>
        <UiButton variant="primary" @click="quietOpen = false; toast.ok('Quiet hours saved')">
          <template #leading><UiIcon name="check" :size="13" /></template>
          Save quiet hours
        </UiButton>
      </template>
    </Modal>

    <!-- Add signature override modal -->
    <Modal :open="overrideOpen" eyebrow="Email signature · override" title="New signature override" size="md" @close="overrideOpen = false">
      <div class="override-stack">
        <EnduserFormField label="Override name">
          <input v-model="override.name" placeholder="e.g. External communications" />
        </EnduserFormField>

        <div>
          <Eyebrow style="display: block; margin-bottom: 8px;">Applies to</Eyebrow>
          <div class="scope-grid">
            <button
              v-for="o in [
                { v: 'domain' as const,   l: 'Sending domain', d: 'e.g. mail from @baslund.dk' },
                { v: 'recipient' as const, l: 'Recipients',    d: 'mail to specific domains' },
                { v: 'category' as const,  l: 'Category',      d: 'replies / forwards / OOO' },
              ]"
              :key="o.v"
              class="scope-card"
              :class="{ active: override.scope === o.v }"
              @click="override.scope = o.v"
            >
              <div class="sc-l">{{ o.l }}</div>
              <Mono dim>{{ o.d }}</Mono>
            </button>
          </div>
        </div>

        <EnduserFormField v-if="override.scope === 'domain'" label="Send from">
          <div class="domain-input">
            <span>*@</span>
            <input v-model="override.domain" />
          </div>
        </EnduserFormField>
        <EnduserFormField v-else-if="override.scope === 'recipient'" label="When sending to">
          <input value="*.dk, *.no, *.se" placeholder="comma-separated domains" />
        </EnduserFormField>
        <EnduserFormField v-else label="On message type">
          <input value="Replies and forwards" />
        </EnduserFormField>

        <EnduserFormField label="Signature">
          <textarea v-model="override.body" rows="6" />
          <Mono dim style="display: block; margin-top: 6px;">plain text · supports the same {{ MERGE_TAG_LITERAL }} variables as your default signature</Mono>
        </EnduserFormField>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="overrideOpen = false">Cancel</UiButton>
        <UiButton variant="primary" @click="overrideOpen = false; toast.ok('Override saved'); markDirty()">
          <template #leading><UiIcon name="check" :size="13" /></template>
          Save override
        </UiButton>
      </template>
    </Modal>
  </div>
</template>

<style scoped>
.tabs-wrap { padding: 0 40px; margin-top: 16px; }
.content { padding: 20px 40px 96px 40px; max-width: 1100px; }

.stack { display: flex; flex-direction: column; gap: 16px; max-width: 720px; }

/* Card header */
.card-header { margin-bottom: 16px; }
.card-header.with-actions { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.card-header .head-text { min-width: 0; flex: 1; }
.card-header h2 {
  font-family: var(--font-display); font-weight: 600;
  font-size: 17px; letter-spacing: -0.015em;
  margin: 6px 0 0 0;
}
.card-header p { margin: 8px 0 0 0; font-size: 13px; color: var(--text-mute); line-height: 1.5; max-width: 600px; }

/* Profile tab grid */
.profile-grid { display: grid; grid-template-columns: 320px 1fr; gap: 24px; }
.photo { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 8px; }
.photo-meta { text-align: center; margin-top: 6px; }
.display { font-family: var(--font-display); font-weight: 600; font-size: 18px; }
.photo-meta :deep(.mono) { display: block; margin-top: 4px; }

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

/* Connections */
.conn, .tokens { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.conn li, .tokens li {
  display: flex; align-items: center; gap: 14px;
  padding: 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
}
.tokens li { padding: 12px; gap: 12px; }
.conn-tile {
  width: 36px; height: 36px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-family: var(--font-mono); font-weight: 700; font-size: 16px;
  flex-shrink: 0;
}
.conn-text { flex: 1; min-width: 0; }
.conn-name { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 500; }
.conn-text :deep(.mono) { display: block; margin-top: 2px; }
.conn-actions { display: flex; gap: 4px; }

/* OOO */
.ooo { display: flex; flex-direction: column; gap: 14px; transition: opacity 0.2s; }
.ooo[data-on='false'] { opacity: 0.5; pointer-events: none; }
.ooo textarea {
  width: 100%; min-height: 120px; padding: 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
  font-size: 13px; color: var(--text); font-family: inherit; resize: vertical; line-height: 1.55;
  box-sizing: border-box;
}
.redirect-row {
  padding: 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.rr-l { font-size: 13px; font-weight: 500; }

/* Appearance */
.appearance { display: flex; flex-direction: column; gap: 16px; }
.theme-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; max-width: 460px; }
.theme-tile {
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: 8px;
  display: flex; flex-direction: column; gap: 10px; align-items: center;
  cursor: pointer; font-family: inherit; color: var(--text); font-size: 12px; font-weight: 500;
}
.theme-tile.active { border-color: var(--text); }
.theme-swatch { width: 100%; height: 56px; border-radius: 6px; border: 1px solid var(--border); }

.density {
  display: flex; gap: 0;
  border: 1px solid var(--border); border-radius: 6px; padding: 2px;
  width: fit-content;
}
.density button {
  padding: 6px 14px; border: none; border-radius: 4px;
  background: transparent; color: var(--text);
  font-size: 12px; font-weight: 500; cursor: pointer; font-family: inherit;
}
.density button.active { background: var(--text); color: var(--bg); }

.row-toggle { display: inline-flex; align-items: center; gap: 10px; font-size: 12px; color: var(--text-mute); }

/* Signature */
.sig-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; }
.sig-side { display: flex; flex-direction: column; gap: 12px; }
.toolbar { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; flex-wrap: wrap; }
.tb {
  height: 30px; padding: 0 10px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 5px;
  color: var(--text); cursor: pointer; font-family: var(--font-sans); font-size: 13px;
  font-weight: 500;
}
.tb.b { font-weight: 700; }
.tb.i { font-style: italic; }
.tb.u { text-decoration: underline; }
.tb.mono { font-family: var(--font-mono); font-size: 11px; }
.tb:hover { background: var(--row-hover); }

.sig-editor {
  min-height: 220px; padding: 18px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-sans); font-size: 14px; color: var(--text);
  line-height: 1.55; outline: none;
}
.sig-line.bold { font-weight: 600; }
.sig-line.dim { color: var(--text-dim); }
.sig-line.mute { margin-top: 8px; color: var(--text-mute); font-size: 13px; }
.sig-foot {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px dashed var(--border);
  color: var(--text-mute); font-size: 12px;
}
.sig-foot .mono { font-family: var(--font-mono); }

.vars {
  margin-top: 16px; padding: 14px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 6px;
  font-size: 12px; color: var(--text-mute); line-height: 1.6;
}

.apply-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.apply-list label { display: flex; gap: 8px; align-items: center; font-size: 13px; cursor: pointer; }
.apply-list input { accent-color: var(--text); }

/* Notifications matrix */
.notif-head { padding: 16px 20px; border-bottom: 1px solid var(--border); }
.notif-title { font-family: var(--font-display); font-weight: 600; font-size: 17px; margin-top: 4px; }
.notif { width: 100%; border-collapse: collapse; }
.notif thead tr { border-bottom: 1px solid var(--border); }
.notif thead th {
  padding: 10px 14px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 500;
  width: 110px;
}
.notif thead th.lhs, .notif tbody td.lhs { text-align: left; padding-left: 20px; width: auto; letter-spacing: 0.12em; }
.notif tbody tr { border-bottom: 1px solid var(--border); }
.notif tbody tr:last-child { border-bottom: none; }
.notif tbody td { padding: 12px 14px; text-align: center; font-size: 13px; }
.notif tbody td.lhs { padding-left: 20px; padding-right: 14px; font-weight: 500; }
.notif input[type='checkbox'] { width: 16px; height: 16px; accent-color: var(--text); }

.notif-foot {
  padding: 14px 20px;
  background: var(--bg);
  border-top: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
}

/* Modal · photo upload */
.photo-modal { display: flex; flex-direction: column; gap: 16px; }
.photo-upload {
  padding: 48px 24px;
  background: var(--bg); border: 2px dashed var(--border-hi); border-radius: 10px;
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  cursor: pointer; text-align: center;
  font-family: inherit;
  transition: background 0.12s, border-color 0.12s;
}
.photo-upload:hover { background: var(--row-hover); border-color: var(--text); }
.pu-l { font-size: 14px; font-weight: 500; color: var(--text); }
.pu-text { text-align: center; }

.crop-row { display: flex; gap: 20px; align-items: flex-start; }
.crop-main { flex: 1; }
.crop-stage {
  position: relative; width: 100%; aspect-ratio: 1 / 1;
  background: linear-gradient(135deg, #D4FF3A, #5B8C5A);
  border-radius: 8px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.crop-mask {
  position: absolute; inset: 20%;
  border: 2px solid #fff; border-radius: 50%;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45);
}
.crop-letter {
  color: #fff; font-family: var(--font-display); font-weight: 700; font-size: 80px;
}
.crop-side { width: 140px; display: flex; flex-direction: column; gap: 10px; align-items: center; }
.circle {
  background: linear-gradient(135deg, #D4FF3A, #5B8C5A);
  border-radius: 999px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.circle span { color: #fff; font-family: var(--font-display); font-weight: 700; }
.circle.large { width: 88px; height: 88px; }
.circle.large span { font-size: 36px; }
.circle.small { width: 32px; height: 32px; }
.circle.small span { font-size: 14px; }

.def-block { padding: 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; font-size: 12px; color: var(--text-mute); line-height: 1.55; }
.def-body { margin-top: 6px; color: var(--text-dim); }

/* Quiet hours modal */
.quiet-stack { display: flex; flex-direction: column; gap: 16px; }
.callout-info {
  padding: 12px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 6px;
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 12px; color: var(--text-dim); line-height: 1.55;
}
.callout-info :deep(svg) { color: var(--text-mute); margin-top: 2px; flex-shrink: 0; }
.weekend-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.inline-check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 12px; color: var(--text-mute); }
.inline-check input { accent-color: var(--text); }

.quiet-rules { padding: 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; display: flex; flex-direction: column; gap: 12px; }
.qr-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.qr-row + .qr-row { border-top: 1px solid var(--border); padding-top: 12px; }
.qr-l { font-size: 13px; font-weight: 500; }

/* Override modal */
.override-stack { display: flex; flex-direction: column; gap: 14px; }
.scope-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.scope-card {
  padding: 12px; border-radius: 6px;
  background: var(--surface); border: 1px solid var(--border);
  cursor: pointer; font-family: inherit; color: var(--text); text-align: left;
}
.scope-card.active { border-color: var(--text); background: var(--bg); }
.sc-l { font-size: 13px; font-weight: 500; }
.scope-card :deep(.mono) { display: block; margin-top: 4px; }

.domain-input {
  display: flex; align-items: center; gap: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
  padding: 0 12px; height: 36px;
}
.domain-input span { font-family: var(--font-mono); font-size: 12px; color: var(--text-mute); }
.domain-input input {
  flex: 1; border: none; outline: none; background: transparent;
  font-size: 13px; color: var(--text); font-family: var(--font-mono);
}

.override-stack textarea {
  width: 100%; min-height: 140px; padding: 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
  font-size: 13px; color: var(--text); font-family: var(--font-sans); resize: vertical; line-height: 1.55;
  box-sizing: border-box;
}
</style>
