<script setup lang="ts">
// Strict port of project/platform-screens.jsx `BrandingScreen` (lines 1542-1668)
// with BrandingPreview (1669), UploadAssetModal (1733), EditEmailTemplatePanel
// (1903), PublishBrandingModal (2031) and ResetBrandingModal (2148). Two-column
// layout — controls on the left (420px), live preview on the right.


const toast = useToast()

const color = ref('#D4FF3A')
const name = ref('Acme Workspace')

const uploadAsset = ref<typeof ASSETS[number] | null>(null)
const uploaded = ref(false)
const dragOver = ref(false)

const editTemplate = ref<typeof TEMPLATES[number] | null>(null)
const subject = ref('')
const body = ref('')
const testSent = ref(false)
function sendTest() {
  testSent.value = true
  setTimeout(() => (testSent.value = false), 2500)
}

const publishOpen = ref(false)
const publishState = ref<'confirm' | 'publishing' | 'done'>('confirm')
const resetOpen = ref(false)

const ASSETS = [
  { id: 'full',    l: 'Full logo',   d: 'horizontal · 4:1 · png/svg', ratio: '4:1', formats: 'png · svg', maxKb: 400, current: false, currentName: '',                  currentSize: '' },
  { id: 'mark',    l: 'Square mark', d: '1:1 · transparent · png/svg', ratio: '1:1', formats: 'png · svg', maxKb: 200, current: true,  currentName: 'acme-mark.svg',     currentSize: '12 KB' },
  { id: 'favicon', l: 'Favicon',     d: '32×32 · ico/png',             ratio: '1:1', formats: 'ico · png', maxKb: 50,  current: true,  currentName: 'favicon.ico',       currentSize: '4 KB' },
] as const

const TEMPLATES = [
  { id: 'invitation', name: 'User invitation',    subject: 'You’ve been invited to {{workspace.name}}',  desc: 'sent when an admin invites a new user',          edited: '3 days ago' },
  { id: 'reset',      name: 'Password reset',     subject: 'Reset your {{workspace.name}} password',     desc: 'sent on forgot-password requests',                edited: 'default' },
  { id: 'digest',     name: 'Notification digest', subject: 'Your weekly summary from {{workspace.name}}', desc: 'sent weekly to users opted-in for digests',       edited: '2 weeks ago' },
  { id: 'trial',      name: 'Trial expiring',     subject: 'Your trial ends in {{trial.days_left}} days', desc: 'sent 7 / 3 / 1 days before trial expiry',         edited: 'default' },
] as const

const TEMPLATE_BODIES: Record<string, string> = {
  invitation: `Hi {{user.first_name}},

{{inviter.name}} has invited you to join {{workspace.name}} on dezky.

Click below to set up your account — the link expires in 7 days.

→ {{invite.url}}

If you have any questions, reply to this email and we'll help out.

— The {{workspace.name}} team`,
  reset: `Hi {{user.first_name}},

Someone (hopefully you) asked to reset your {{workspace.name}} password.

Click the link below within the next 60 minutes to choose a new one:

→ {{reset.url}}

If you didn't request this, you can safely ignore this email.

— {{workspace.name}} security`,
  digest: `Hi {{user.first_name}},

Here's what happened in {{workspace.name}} this week:

· {{stats.messages}} new messages across your channels
· {{stats.files}} files shared
· {{stats.meetings}} meetings recorded

→ Open dashboard: {{workspace.url}}

Manage how often you receive these from your profile.`,
  trial: `Hi {{user.first_name}},

Your {{workspace.name}} trial ends in {{trial.days_left}} days.

You've added {{stats.users}} users and uploaded {{stats.gb}} GB of files. To keep everything running smoothly, upgrade to Business or Enterprise.

→ Choose a plan: {{billing.url}}

— {{workspace.name}}`,
}

const TEMPLATE_MERGE_TAGS: Record<string, string[]> = {
  invitation: ['user.first_name', 'user.email', 'inviter.name', 'workspace.name', 'invite.url', 'invite.expires_at'],
  reset:      ['user.first_name', 'workspace.name', 'reset.url', 'reset.expires_at', 'security.ip'],
  digest:     ['user.first_name', 'workspace.name', 'workspace.url', 'stats.messages', 'stats.files', 'stats.meetings'],
  trial:      ['user.first_name', 'workspace.name', 'trial.days_left', 'stats.users', 'stats.gb', 'billing.url'],
}

const colorPalette = ['#D4FF3A', '#3F6BFF', '#FF6B4A', '#5B8C5A', '#9B59B6']

function openTemplate(t: typeof TEMPLATES[number]) {
  editTemplate.value = t
  subject.value = t.subject
  body.value = TEMPLATE_BODIES[t.id] || ''
  testSent.value = false
}

function insertTag(tag: string) {
  body.value += `{{${tag}}}`
}

// Reset the currently-open template's subject + body to the canonical default.
function resetTemplate() {
  if (!editTemplate.value) return
  subject.value = editTemplate.value.subject
  body.value = TEMPLATE_BODIES[editTemplate.value.id] || ''
  toast.info('Template reset to default')
}

// Wrap a merge-tag name in mustaches via JS so the template doesn't have to
// nest `{{ ... }}` inside `{{ ... }}` (which Vue's parser scans positionally
// and breaks on).
function wrapTag(tag: string) {
  return '{' + '{' + tag + '}' + '}'
}

function startPublish() {
  publishState.value = 'publishing'
  setTimeout(() => { publishState.value = 'done' }, 1800)
}

function openPublish() {
  publishOpen.value = true
  publishState.value = 'confirm'
}

const renderedSubject = computed(() =>
  subject.value
    .replace(/\{\{workspace\.name\}\}/g, name.value)
    .replace(/\{\{user\.first_name\}\}/g, 'Anne')
    .replace(/\{\{trial\.days_left\}\}/g, '3'),
)
const renderedBody = computed(() =>
  body.value
    .replace(/\{\{workspace\.name\}\}/g, name.value)
    .replace(/\{\{workspace\.url\}\}/g, 'workspace.acme.dk')
    .replace(/\{\{user\.first_name\}\}/g, 'Anne')
    .replace(/\{\{user\.email\}\}/g, 'anne@acme.dk')
    .replace(/\{\{inviter\.name\}\}/g, 'Mikkel Nørgaard')
    .replace(/\{\{invite\.url\}\}/g, 'workspace.acme.dk/accept/x9k2a')
    .replace(/\{\{reset\.url\}\}/g, 'workspace.acme.dk/reset/p2b7c')
    .replace(/\{\{billing\.url\}\}/g, 'workspace.acme.dk/billing')
    .replace(/\{\{trial\.days_left\}\}/g, '3')
    .replace(/\{\{stats\.messages\}\}/g, '1.840')
    .replace(/\{\{stats\.files\}\}/g, '24')
    .replace(/\{\{stats\.meetings\}\}/g, '6')
    .replace(/\{\{stats\.users\}\}/g, '8')
    .replace(/\{\{stats\.gb\}\}/g, '14'),
)
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Whitelabel"
      title="Branding"
      subtitle="Replace the dezky shell with your own logo, color, and product name. Changes propagate everywhere."
    >
      <template #actions>
        <UiButton variant="ghost" @click="resetOpen = true">Reset</UiButton>
        <UiButton variant="primary" @click="openPublish">Publish</UiButton>
      </template>
    </PageHeader>

    <div class="content">
      <!-- Controls -->
      <div class="controls">
        <Card>
          <div class="card-head"><Eyebrow>Identity</Eyebrow><div class="card-title">Product identity</div></div>
          <label class="field"><Eyebrow>Product name (shown to users)</Eyebrow><input class="input" v-model="name" /></label>
          <label class="field"><Eyebrow>Custom domain</Eyebrow>
            <div class="input-row">
              <input value="workspace.acme.dk" readonly />
              <UiIcon name="check" :size="12" stroke="var(--ok)" :stroke-width="2.5" />
            </div>
          </label>
        </Card>

        <Card>
          <div class="card-head">
            <Eyebrow>Color</Eyebrow>
            <div class="card-title">Primary accent</div>
            <div class="card-sub">Propagates to buttons, links, focus rings, and active states.</div>
          </div>
          <div class="swatches">
            <button v-for="c in colorPalette" :key="c" :style="{ background: c, borderColor: color === c ? 'var(--text)' : 'var(--border)', borderWidth: color === c ? '2px' : '1px' }" @click="color = c" />
          </div>
          <div class="input-row">
            <input v-model="color" />
            <div class="color-preview" :style="{ background: color }" />
          </div>
        </Card>

        <Card>
          <div class="card-head"><Eyebrow>Assets</Eyebrow><div class="card-title">Logo upload</div></div>
          <div class="assets">
            <div v-for="a in ASSETS" :key="a.id" class="asset" :class="{ has: a.current }">
              <div class="asset-icon" :style="{ color: a.current ? 'var(--ok)' : 'var(--text-mute)' }">
                <UiIcon :name="a.current ? 'check' : 'upload'" :size="16" :stroke-width="a.current ? 2.5 : 2" />
              </div>
              <div class="asset-meta">
                <div class="asset-l">{{ a.l }}</div>
                <Mono dim>{{ a.current ? `${a.currentName} · ${a.currentSize}` : a.d }}</Mono>
              </div>
              <UiButton size="sm" :variant="a.current ? 'ghost' : 'secondary'" @click="uploadAsset = a as any; uploaded = false">
                {{ a.current ? 'Replace' : 'Upload' }}
              </UiButton>
            </div>
          </div>
        </Card>

        <Card>
          <div class="card-head"><Eyebrow>Templates</Eyebrow><div class="card-title">Email templates</div></div>
          <div class="templates">
            <button v-for="t in TEMPLATES" :key="t.id" class="tmpl-row" @click="openTemplate(t as any)">
              <div class="tmpl-meta">
                <div class="tmpl-name-row">
                  <span class="tmpl-name">{{ t.name }}</span>
                  <Badge :tone="t.edited === 'default' ? 'neutral' : 'info'">{{ t.edited === 'default' ? 'default' : 'edited' }}</Badge>
                </div>
                <Mono dim>edited {{ t.edited }}</Mono>
              </div>
              <UiIcon name="chevRight" :size="14" stroke="var(--text-mute)" />
            </button>
          </div>
        </Card>
      </div>

      <!-- Preview -->
      <div class="preview-col">
        <div class="preview-head">
          <Eyebrow>Live preview</Eyebrow>
          <Mono dim>workspace.acme.dk</Mono>
        </div>
        <div class="preview-frame">
          <div class="frame-topbar">
            <div class="frame-mark" :style="{ background: color }">{{ name[0]?.toLowerCase() || 'a' }}</div>
            <div class="frame-brand">{{ name.toLowerCase() }}</div>
            <div class="frame-spacer" />
            <div class="frame-user">anne@acme.dk</div>
          </div>
          <div class="frame-hero">
            <div class="frame-eyebrow">Dashboard</div>
            <div class="frame-title">Good morning, Anne.</div>
            <div class="frame-tiles">
              <div v-for="n in ['Mail', 'Drev', 'Møder', 'Chat']" :key="n" class="frame-tile">
                <div class="frame-tile-icon">{{ n[0] }}</div>
                <div class="frame-tile-name">{{ n }}</div>
              </div>
            </div>
            <div class="frame-cta" :style="{ background: color }">
              <div>
                <div class="frame-cta-title">Welcome to {{ name }}.</div>
                <div class="frame-cta-sub">Your team's workspace is ready.</div>
              </div>
              <button class="frame-cta-btn">Get started</button>
            </div>
          </div>
          <div class="frame-foot">
            <span>powered by dezky</span>
            <span>v1.0 · light</span>
          </div>
        </div>
      </div>
    </div>

    <!-- Upload asset modal -->
    <Modal :open="!!uploadAsset" :eyebrow="uploadAsset ? `Branding · ${uploadAsset.l.toLowerCase()}` : ''" :title="uploadAsset ? `Upload ${uploadAsset.l.toLowerCase()}` : ''" size="md" @close="uploadAsset = null">
      <div v-if="uploadAsset" class="upload">
        <button v-if="!uploaded" class="dropzone" :class="{ over: dragOver }"
          @dragover.prevent="dragOver = true"
          @dragleave="dragOver = false"
          @drop.prevent="dragOver = false; uploaded = true"
          @click="uploaded = true">
          <UiIcon name="upload" :size="28" stroke="var(--text-mute)" />
          <div class="drop-text">
            <div class="drop-title">Drop {{ uploadAsset.l.toLowerCase() }} here, or click to browse</div>
            <Mono dim>{{ uploadAsset.formats }} · {{ uploadAsset.ratio }} ratio · up to {{ uploadAsset.maxKb }} KB</Mono>
          </div>
        </button>

        <template v-if="uploaded">
          <div class="upload-preview">
            <div class="upload-mark" :style="{ width: uploadAsset.id === 'full' ? '96px' : '56px' }">
              {{ uploadAsset.id === 'full' ? 'acme' : 'a' }}
            </div>
            <div class="upload-meta">
              <div class="upload-name">{{ uploadAsset.id === 'favicon' ? 'favicon-new.png' : uploadAsset.id === 'mark' ? 'acme-mark-v2.svg' : 'acme-logo.svg' }}</div>
              <Mono dim>{{ uploadAsset.id === 'favicon' ? '6 KB' : uploadAsset.id === 'mark' ? '14 KB' : '38 KB' }} · {{ uploadAsset.id === 'favicon' ? '32×32' : uploadAsset.id === 'mark' ? '512×512' : '1200×300' }} · clean alpha</Mono>
            </div>
            <UiButton size="sm" variant="ghost" @click="uploaded = false">Replace</UiButton>
          </div>
          <Eyebrow>Looks good</Eyebrow>
          <div class="check-list">
            <div class="check-row">
              <UiIcon name="check" :size="12" stroke="var(--ok)" :stroke-width="2.5" />
              <Mono dim>Format</Mono>
              <span>{{ uploadAsset.formats.split(' · ')[0] }} ✓</span>
            </div>
            <div class="check-row">
              <UiIcon name="check" :size="12" stroke="var(--ok)" :stroke-width="2.5" />
              <Mono dim>Dimensions</Mono>
              <span>{{ uploadAsset.id === 'favicon' ? '32×32 ✓' : uploadAsset.ratio + ' ✓' }}</span>
            </div>
            <div class="check-row">
              <UiIcon name="check" :size="12" stroke="var(--ok)" :stroke-width="2.5" />
              <Mono dim>Size</Mono>
              <span>{{ uploadAsset.id === 'favicon' ? '6 KB' : uploadAsset.id === 'mark' ? '14 KB' : '38 KB' }} (under {{ uploadAsset.maxKb }} KB)</span>
            </div>
            <div class="check-row">
              <UiIcon name="check" :size="12" stroke="var(--ok)" :stroke-width="2.5" />
              <Mono dim>Transparency</Mono>
              <span>{{ uploadAsset.id === 'favicon' ? 'opaque background OK' : 'transparent background ✓' }}</span>
            </div>
          </div>
          <div class="ld-preview">
            <Eyebrow>Preview · on light + dark</Eyebrow>
            <div class="ld-grid">
              <div class="ld-light">
                <div class="ld-mark dark" :style="{ width: uploadAsset.id === 'full' ? '80px' : '32px' }">{{ uploadAsset.id === 'full' ? 'acme' : 'a' }}</div>
              </div>
              <div class="ld-dark">
                <div class="ld-mark light" :style="{ width: uploadAsset.id === 'full' ? '80px' : '32px' }">{{ uploadAsset.id === 'full' ? 'acme' : 'a' }}</div>
              </div>
            </div>
          </div>
        </template>

        <div class="req-box">
          <Mono dim>// requirements</Mono>
          <div class="req-body">
            <template v-if="uploadAsset.id === 'full'">Used in the top navigation bar, login screen, and email headers. Roughly 200×50 displayed — supply at 2× minimum.</template>
            <template v-else-if="uploadAsset.id === 'mark'">Used as the app icon, favicon fallback, and any compact context (PWA install, notifications). Must read at 24×24.</template>
            <template v-else>Browser tab icon and bookmark badge. 32×32 is the standard size — modern browsers use the same file at 16×16.</template>
          </div>
        </div>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="uploadAsset = null">Cancel</UiButton>
        <UiButton variant="primary" :disabled="!uploaded" @click="uploadAsset = null">
          <template #leading><UiIcon name="check" :size="13" /></template>
          {{ uploaded ? 'Use this asset' : 'Select a file to continue' }}
        </UiButton>
      </template>
    </Modal>

    <!-- Edit email template side panel -->
    <SidePanel :open="!!editTemplate" :eyebrow="'Email template'" :title="editTemplate?.name || ''" width="lg" @close="editTemplate = null">
      <div v-if="editTemplate" class="tmpl-edit">
        <div class="tmpl-col">
          <label class="field"><Eyebrow>Subject</Eyebrow><input class="input" v-model="subject" /></label>
          <div>
            <Eyebrow>Body</Eyebrow>
            <textarea v-model="body" class="body-area" />
          </div>
          <div>
            <Eyebrow>Merge tags · click to insert</Eyebrow>
            <div class="merge-tags">
              <button v-for="tag in (TEMPLATE_MERGE_TAGS[editTemplate.id] || [])" :key="tag" @click="insertTag(tag)">{{ wrapTag(tag) }}</button>
            </div>
          </div>
        </div>
        <div class="tmpl-prev">
          <Eyebrow>Preview</Eyebrow>
          <div class="email-frame">
            <div class="email-head">
              <div class="from-row">
                <div class="from-mark" :style="{ background: '#0A0A0A', color }">{{ name[0]?.toLowerCase() || 'a' }}</div>
                <Mono dim>From: {{ name.toLowerCase().replace(/\s+/g, '-') }}@dezky.com</Mono>
              </div>
              <div class="email-subj">{{ renderedSubject }}</div>
            </div>
            <div class="email-body">{{ renderedBody }}</div>
            <div class="email-foot" :style="{ background: color }">{{ name }} · workspace.acme.dk</div>
          </div>
          <Mono dim style="text-align: center; display: block;">preview substitutes sample data · real send uses recipient's data</Mono>
        </div>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="resetTemplate">
          <template #leading><UiIcon name="refresh" :size="13" /></template>
          Reset to default
        </UiButton>
        <div style="flex: 1" />
        <UiButton variant="secondary" @click="sendTest">
          <template #leading><UiIcon name="mail" :size="13" /></template>
          {{ testSent ? 'Sent to anne@dezky.com ✓' : 'Send test to me' }}
        </UiButton>
        <UiButton variant="primary" @click="editTemplate = null">
          <template #leading><UiIcon name="check" :size="13" /></template>
          Save template
        </UiButton>
      </template>
    </SidePanel>

    <!-- Publish modal -->
    <Modal :open="publishOpen" eyebrow="Branding · publish" :title="publishState === 'done' ? 'Branding published' : 'Publish branding changes?'" size="md" @close="publishState !== 'publishing' ? (publishOpen = false) : null">
      <template v-if="publishState === 'confirm'">
        <div class="publish-intro">These changes will replace dezky's branding for everyone in your workspace within ~30 seconds.</div>
        <Eyebrow>Will go live</Eyebrow>
        <div class="publish-summary">
          <div class="ps-row"><Mono dim>Product name</Mono><span>{{ name }}</span></div>
          <div class="ps-row">
            <Mono dim>Primary color</Mono>
            <span class="color-line">
              <span class="color-chip" :style="{ background: color }" />
              <Mono>{{ color }}</Mono>
            </span>
          </div>
          <div class="ps-row">
            <Mono dim>Custom domain</Mono>
            <Mono>workspace.acme.dk</Mono>
            <Badge tone="ok" dot>verified</Badge>
          </div>
        </div>
        <Eyebrow>Propagates to</Eyebrow>
        <div class="prop-grid">
          <div v-for="[k, t] in [
            ['Web app · workspace shell', '~10s'],
            ['Login + auth pages', '~10s'],
            ['Outbound email templates', '~30s'],
            ['Mobile app · next session', 'on next launch'],
            ['Status page', '~30s'],
            ['PDF invoices', 'next billing cycle'],
          ]" :key="k" class="prop-cell">
            <UiIcon name="check" :size="11" stroke="var(--ok)" :stroke-width="2.5" />
            <span>{{ k }}</span>
            <Mono dim>{{ t }}</Mono>
          </div>
        </div>
        <div class="publish-warn">
          <UiIcon name="shield" :size="14" stroke="var(--warn)" />
          <div>Users may need to hard-refresh to see the new branding immediately. You can revert with one click for the next 7 days.</div>
        </div>
      </template>
      <template v-else-if="publishState === 'publishing'">
        <div class="publishing">
          <div class="spinner" />
          <div class="publish-title">Publishing across services…</div>
          <Mono dim>web shell · auth · mail templates · CDN</Mono>
        </div>
      </template>
      <template v-else>
        <div class="done-head">
          <div class="done-badge" :style="{ background: color }">
            <UiIcon name="check" :size="20" :stroke-width="2.5" />
          </div>
          <div>
            <div class="publish-title">{{ name }} branding is live</div>
            <Mono dim>5 services updated · 1 queued for next cycle</Mono>
          </div>
        </div>
        <div class="done-list">
          <dl class="def">
            <div><dt>Web app + auth</dt><dd>live · 8 seconds</dd></div>
            <div><dt>Email templates</dt><dd>live · 18 seconds</dd></div>
            <div><dt>Mobile · status · CDN</dt><dd>queued · ~30s</dd></div>
            <div><dt>PDF invoices</dt><dd>starts 01 Jun 2026</dd></div>
          </dl>
        </div>
      </template>
      <template #footer>
        <template v-if="publishState === 'confirm'">
          <UiButton variant="ghost" @click="publishOpen = false">Cancel</UiButton>
          <UiButton variant="primary" @click="startPublish">
            <template #leading><UiIcon name="external" :size="13" /></template>
            Publish now
          </UiButton>
        </template>
        <template v-else-if="publishState === 'publishing'">
          <UiButton variant="ghost" disabled>Publishing…</UiButton>
        </template>
        <template v-else>
          <UiButton variant="primary" @click="publishOpen = false">Done</UiButton>
        </template>
      </template>
    </Modal>

    <!-- Reset branding modal -->
    <Modal :open="resetOpen" eyebrow="Destructive · reverts to defaults" title="Reset branding to dezky defaults?" size="sm" @close="resetOpen = false">
      <div class="reset-box bad">
        <UiIcon name="shield" :size="16" stroke="var(--bad)" />
        <div>Reverts product name, colors, logos, and email templates to dezky defaults. Your custom domain stays connected. Edits made today are kept for 7 days and can be restored from your audit log.</div>
      </div>
      <div class="reset-list">
        <dl class="def">
          <div><dt>Product name</dt><dd>Acme Workspace → dezky</dd></div>
          <div><dt>Primary color</dt><dd>#D4FF3A → #D4FF3A (default)</dd></div>
          <div><dt>Full logo</dt><dd>will be removed</dd></div>
          <div><dt>Square mark</dt><dd>will be removed</dd></div>
          <div><dt>Favicon</dt><dd>will be removed</dd></div>
          <div><dt>Email templates</dt><dd>2 edited templates → defaults</dd></div>
          <div><dt>Custom domain</dt><dd>workspace.acme.dk · kept</dd></div>
        </dl>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="resetOpen = false">Cancel</UiButton>
        <UiButton variant="danger" @click="resetOpen = false">
          <template #leading><UiIcon name="refresh" :size="13" /></template>
          Reset everything
        </UiButton>
      </template>
    </Modal>
  </div>
</template>

<style scoped>
.content { padding: 24px 40px 64px 40px; display: grid; grid-template-columns: 420px 1fr; gap: 24px; }
.controls { display: flex; flex-direction: column; gap: 16px; }

.card-head { margin-bottom: 14px; }
.card-title { font-family: var(--font-display); font-weight: 600; font-size: 18px; letter-spacing: -0.01em; margin-top: 4px; }
.card-sub { font-size: 13px; color: var(--text-mute); margin-top: 4px; }

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field:last-child { margin-bottom: 0; }
.input { height: 36px; padding: 0 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; font-family: inherit; font-size: 13px; color: var(--text); outline: none; }
.input:focus { border-color: var(--text); }
.input-row {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.input-row input { flex: 1; border: none; outline: none; background: transparent; font-family: inherit; font-size: 13px; color: var(--text); }
.color-preview { width: 36px; height: 36px; border-radius: 6px; border: 1px solid var(--border); flex-shrink: 0; }

.swatches { display: flex; gap: 10px; margin-bottom: 14px; }
.swatches button { width: 38px; height: 38px; border-radius: 6px; cursor: pointer; }

.assets { display: flex; flex-direction: column; gap: 10px; }
.asset {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px dashed var(--border);
  border-radius: 6px;
}
.asset.has { background: var(--surface); border-style: solid; }
.asset-icon { width: 40px; height: 40px; border-radius: 6px; background: var(--bg); display: inline-flex; align-items: center; justify-content: center; }
.asset-meta { flex: 1; min-width: 0; }
.asset-l { font-size: 13px; font-weight: 500; }

.templates { display: flex; flex-direction: column; }
.tmpl-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); background: transparent; border-left: none; border-right: none; border-top: none; text-align: left; color: var(--text); font-family: inherit; font-size: 13px; cursor: pointer; }
.tmpl-row:last-child { border-bottom: none; }
.tmpl-meta { flex: 1; min-width: 0; }
.tmpl-name-row { display: flex; align-items: center; gap: 8px; }
.tmpl-name { font-weight: 500; }

.preview-col { min-width: 0; }
.preview-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.preview-frame {
  background: #FAFAF7;
  color: #0A0A0A;
  border-radius: 10px;
  border: 1px solid var(--border);
  overflow: hidden;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.08);
  font-family: 'Inter', sans-serif;
}
.frame-topbar {
  height: 52px;
  background: #0A0A0A;
  color: #F4F3EE;
  display: flex;
  align-items: center;
  padding: 0 20px;
  gap: 16px;
}
.frame-mark {
  width: 24px;
  height: 24px;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 13px;
  color: #0A0A0A;
}
.frame-brand { font-family: var(--font-mono); font-size: 13px; font-weight: 600; }
.frame-spacer { flex: 1; }
.frame-user { font-size: 11px; font-family: var(--font-mono); opacity: 0.6; }
.frame-hero { padding: 36px 32px 24px 32px; }
.frame-eyebrow { font-family: var(--font-mono); font-size: 10px; color: #5A5A55; letter-spacing: 0.12em; text-transform: uppercase; }
.frame-title { font-family: var(--font-display); font-size: 28px; font-weight: 600; letter-spacing: -0.02em; margin-top: 8px; }
.frame-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 20px; }
.frame-tile { background: #fff; border: 1px solid #E6E4DC; border-radius: 6px; padding: 14px; }
.frame-tile-icon {
  width: 24px;
  height: 24px;
  border-radius: 5px;
  background: #0A0A0A;
  color: #F4F3EE;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 11px;
}
.frame-tile-name { font-family: var(--font-display); font-weight: 600; font-size: 14px; margin-top: 12px; }
.frame-cta { margin-top: 24px; padding: 18px 20px; border-radius: 6px; display: flex; align-items: center; justify-content: space-between; }
.frame-cta-title { font-family: var(--font-display); font-weight: 600; font-size: 15px; color: #0A0A0A; }
.frame-cta-sub { font-size: 12px; color: rgba(10, 10, 10, 0.7); margin-top: 4px; }
.frame-cta-btn { height: 32px; padding: 0 14px; border-radius: 5px; border: none; background: #0A0A0A; color: #F4F3EE; font-weight: 600; font-size: 12px; cursor: pointer; }
.frame-foot { padding: 12px 32px; border-top: 1px solid #E6E4DC; background: #F4F3EE; font-size: 11px; color: #5A5A55; font-family: var(--font-mono); display: flex; justify-content: space-between; }

/* Upload modal */
.upload { display: flex; flex-direction: column; gap: 14px; }
.dropzone {
  padding: 48px 24px;
  background: var(--bg);
  border: 2px dashed var(--border);
  border-radius: 10px;
  cursor: pointer;
  font-family: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.dropzone.over { background: var(--surface); border-color: var(--text); }
.drop-text { text-align: center; }
.drop-title { font-size: 14px; font-weight: 500; color: var(--text); }
.upload-preview {
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 14px;
}
.upload-mark {
  height: 56px;
  background: var(--text);
  color: var(--bg);
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 18px;
  flex-shrink: 0;
}
.upload-meta { flex: 1; min-width: 0; }
.upload-name { font-size: 13px; font-weight: 500; }
.check-list { display: flex; flex-direction: column; gap: 6px; }
.check-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--bg); border-radius: 6px; border: 1px solid var(--border); font-size: 12px; }
.check-row > :first-of-type { flex-shrink: 0; }
.ld-preview { padding: 12px; background: var(--bg); border-radius: 6px; border: 1px solid var(--border); }
.ld-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.ld-light, .ld-dark { border-radius: 6px; padding: 18px; display: flex; align-items: center; justify-content: center; }
.ld-light { background: #FAFAF7; }
.ld-dark { background: #0A0A0A; }
.ld-mark {
  height: 32px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 12px;
}
.ld-mark.dark { background: #0A0A0A; color: #F4F3EE; }
.ld-mark.light { background: #F4F3EE; color: #0A0A0A; }
.req-box { padding: 12px; background: var(--bg); border-radius: 6px; border: 1px solid var(--border); font-size: 12px; color: var(--text-mute); line-height: 1.55; }
.req-body { margin-top: 6px; }

/* Email template editor */
.tmpl-edit { display: grid; grid-template-columns: 1fr 1fr; min-height: 0; height: 100%; }
.tmpl-col { padding: 24px; border-right: 1px solid var(--border); display: flex; flex-direction: column; gap: 14px; }
.tmpl-prev { padding: 24px; background: var(--bg); display: flex; flex-direction: column; gap: 12px; }
.body-area {
  width: 100%;
  min-height: 320px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  color: var(--text);
  font-family: var(--font-mono);
  line-height: 1.6;
  resize: vertical;
  outline: none;
  box-sizing: border-box;
}
.merge-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.merge-tags button {
  padding: 4px 8px;
  border-radius: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text);
  cursor: pointer;
}
.email-frame {
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #E6E4DC;
  color: #0A0A0A;
  font-family: 'Inter', sans-serif;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
  flex: 1;
  display: flex;
  flex-direction: column;
}
.email-head { padding: 16px 20px; border-bottom: 1px solid #E6E4DC; background: #FAFAF7; }
.from-row { display: flex; align-items: center; gap: 8px; }
.from-mark {
  width: 22px;
  height: 22px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
}
.email-subj { font-family: var(--font-display); font-weight: 600; font-size: 16px; margin-top: 10px; color: #0A0A0A; }
.email-body { padding: 20px; font-size: 13px; line-height: 1.65; color: #3A3A35; white-space: pre-wrap; flex: 1; overflow-y: auto; }
.email-foot { padding: 14px 20px; border-top: 1px solid #E6E4DC; color: #0A0A0A; font-size: 11px; font-family: var(--font-mono); text-align: center; }

/* Publish modal */
.publish-intro { font-size: 13px; color: var(--text-dim); line-height: 1.55; margin-bottom: 14px; }
.publish-summary { padding: 14px; background: var(--bg); border-radius: 6px; border: 1px solid var(--border); display: flex; flex-direction: column; gap: 10px; margin-top: 8px; margin-bottom: 14px; }
.ps-row { display: flex; align-items: center; gap: 12px; }
.ps-row > :first-child { width: 100px; }
.color-line { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
.color-chip { width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--border); }
.prop-grid { padding: 14px; background: var(--bg); border-radius: 6px; border: 1px solid var(--border); display: grid; grid-template-columns: 1fr 1fr; gap: 10px; font-size: 12px; margin-top: 8px; margin-bottom: 14px; }
.prop-cell { display: flex; align-items: center; gap: 8px; }
.prop-cell span:first-of-type { flex: 1; }
.publish-warn { padding: 12px; background: rgba(232, 154, 31, 0.06); border-radius: 6px; border: 1px solid rgba(232, 154, 31, 0.2); font-size: 12px; color: var(--text-dim); line-height: 1.55; display: flex; gap: 10px; }
.publishing { padding: 32px 0; text-align: center; }
.spinner {
  width: 56px;
  height: 56px;
  margin: 0 auto 18px auto;
  border-radius: 999px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg) } }
.publish-title { font-family: var(--font-display); font-size: 20px; font-weight: 600; }
.done-head { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.done-badge {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  color: #0A0A0A;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.done-list { padding: 14px; background: var(--bg); border-radius: 6px; border: 1px solid var(--border); }
.def { margin: 0; display: grid; grid-template-columns: 140px 1fr; row-gap: 12px; column-gap: 16px; }
.def > div { display: contents; }
.def dt { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-mute); }
.def dd { margin: 0; font-size: 13px; color: var(--text); }

/* Reset modal */
.reset-box { padding: 14px; border-radius: 6px; display: flex; gap: 10px; align-items: flex-start; margin-bottom: 14px; }
.reset-box.bad { background: rgba(226, 48, 48, 0.06); border: 1px solid rgba(226, 48, 48, 0.2); }
.reset-box > div { font-size: 13px; color: var(--text-dim); line-height: 1.5; }
.reset-list { padding: 12px; background: var(--bg); border-radius: 6px; border: 1px solid var(--border); }
</style>
