<template>
  <div class="theatre">
    <!-- HEADER + CONTROLS ---------------------------------------- -->
    <section class="head page">
      <div class="head-grid">
        <div class="head-left">
          <span class="eyebrow">PDP Preview Theatre</span>
          <h1 class="head-title">
            See it<br />
            <em>as it ships</em>
          </h1>
          <p class="head-lede">
            The full PDP render for each pilot SKU — every section in elite voice,
            citation-linked, compliance-clean. Switch the render skin to inspect the
            same content through a competitor's typography &amp; colour.
          </p>
        </div>

        <div class="head-right">
          <div class="select-block">
            <span class="meta">Product</span>
            <div class="sku-chips">
              <router-link
                v-for="p in pilots"
                :key="p.sku"
                class="sku-chip"
                :class="{ 'is-active': activeSku === p.sku }"
                :to="`/preview/${p.sku}`"
              >
                <span class="chip-sku">{{ p.sku.replace('JV-', '') }}</span>
                <span class="chip-name">{{ p.name }}</span>
              </router-link>
            </div>
          </div>

          <div class="select-block select-block--skin">
            <span class="meta">Render as</span>
            <div class="skin-row">
              <button
                v-for="skin in SKINS"
                :key="skin.key"
                class="skin-pill"
                :class="{ 'is-active': activeSkin === skin.key }"
                :style="{ '--pill': skin.swatch }"
                @click="activeSkin = skin.key"
              >
                <span class="skin-swatch"></span>
                {{ skin.label }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- PDP STAGE -------------------------------------------- -->
    <section v-if="pilot" class="stage page">
      <div class="stage-frame" :class="`skin-${activeSkin}`">
        <!-- Faux browser chrome to feel "live" -->
        <header class="stage-chrome">
          <div class="chrome-dots">
            <span></span><span></span><span></span>
          </div>
          <div class="chrome-url">
            <span>justvitamins.co.uk/products/{{ pilot.handle || pilot.sku.toLowerCase() }}</span>
          </div>
          <div class="chrome-skin">Rendered as {{ activeSkinLabel }}</div>
        </header>

        <!-- Above-the-fold hero -->
        <section class="atf">
          <div class="atf-image">
            <div class="image-card">
              <span class="image-meta">{{ pilot.sku }}</span>
              <span class="image-title">{{ truth?.title || pilot.name }}</span>
              <span class="image-strength" v-if="truth?.strength">{{ truth.strength }}</span>
            </div>
          </div>
          <div class="atf-text">
            <span class="breadcrumb-meta">Home / {{ catLabel(pilot.category) }} / {{ truth?.title || pilot.name }}</span>
            <h2 class="product-name">{{ truth?.title || pilot.name }}</h2>
            <ul class="atf-bullets">
              <li v-for="b in truthBullets" :key="b">✓ {{ b }}</li>
            </ul>
            <div class="variants" v-if="truth?.variants?.length">
              <span
                v-for="v in truth.variants"
                :key="v.sku"
                class="variant-pill"
              >
                {{ v.option }} · £{{ v.price }}
              </span>
            </div>
            <button class="cta-btn">Add to bag</button>
          </div>
        </section>

        <!-- Section 01 — Scientific Studies -->
        <section class="pdp-section" id="sci">
          <header class="section-header">
            <span class="section-num">01</span>
            <div>
              <span class="section-eyebrow">Scientific Studies</span>
              <h3 class="section-title">{{ pilot.scientificStudy.headline }}</h3>
            </div>
            <div class="section-actions">
              <span class="approve-state" :class="approvedState('scientificStudy')">{{ approveLabel('scientificStudy') }}</span>
              <button class="action-btn" @click="approve('scientificStudy')">Approve ✓</button>
              <button class="action-btn is-quiet" @click="openCite('scientificStudy')">Cite ↗</button>
            </div>
          </header>
          <div class="section-body sci-body">
            <!-- Study framing: actual journal-cited prose, not vague "research suggests" -->
            <p
              v-for="(para, i) in sciBodyParagraphs"
              :key="`sci-p-${i}`"
              class="sci-prose"
            >{{ para }}</p>

            <!-- Authorised health claim — verbatim, set apart visually so it
                 reads as a regulator quote, not marketing copy. -->
            <aside v-if="pilot.scientificStudy.efsaClaim?.verbatim" class="efsa-quote">
              <span class="efsa-eyebrow">Authorised health claim</span>
              <blockquote>"{{ pilot.scientificStudy.efsaClaim.verbatim }}"</blockquote>
              <p v-if="pilot.scientificStudy.efsaClaim.context" class="efsa-context">
                {{ pilot.scientificStudy.efsaClaim.context }}
              </p>
            </aside>

            <!-- Stat tiles — each linked to its real source URL -->
            <div class="stat-strip">
              <component
                v-for="s in pilot.scientificStudy.stats?.slice(0, 3)"
                :key="s.label"
                :is="s.source && /^https?:/.test(s.source) ? 'a' : 'div'"
                :href="s.source && /^https?:/.test(s.source) ? s.source : null"
                :target="s.source && /^https?:/.test(s.source) ? '_blank' : null"
                rel="noopener"
                class="stat"
                :class="{ 'stat-clickable': s.source && /^https?:/.test(s.source) }"
              >
                <div class="stat-num">{{ s.value }}</div>
                <div class="stat-label">{{ s.label }}</div>
                <span v-if="s.source && /^https?:/.test(s.source)" class="stat-cite">view source ↗</span>
              </component>
            </div>

            <!-- References — every citation a real URL, clickable. No file paths. -->
            <div v-if="(pilot.scientificStudy.sourceLinks || []).length" class="references">
              <span class="references-label">References</span>
              <ul class="references-list">
                <li v-for="(c, i) in pilot.scientificStudy.sourceLinks" :key="`sci-ref-${i}`">
                  <a v-if="c.href" :href="c.href" target="_blank" rel="noopener">{{ c.label }}</a>
                  <span v-else>{{ c.label }}</span>
                  <span v-if="c.meta" class="ref-meta">{{ c.meta }}</span>
                </li>
              </ul>
            </div>
          </div>
        </section>

        <!-- Section 02 — Timeline -->
        <section class="pdp-section" id="timeline">
          <header class="section-header">
            <span class="section-num">02</span>
            <div>
              <span class="section-eyebrow">{{ pilot.timelineBlock.subtitle || 'Your results timeline' }}</span>
              <h3 class="section-title">{{ pilot.timelineBlock.headline }}</h3>
            </div>
            <div class="section-actions">
              <span class="approve-state" :class="approvedState('timelineBlock')">{{ approveLabel('timelineBlock') }}</span>
              <button class="action-btn" @click="approve('timelineBlock')">Approve ✓</button>
              <button class="action-btn is-quiet" @click="openCite('timelineBlock')">Cite ↗</button>
            </div>
          </header>
          <div class="section-body">
            <p class="intro-copy">{{ pilot.timelineBlock.intro_copy }}</p>
            <div class="timeline-grid">
              <article
                v-for="(p, i) in pilot.timelineBlock.phases"
                :key="p.handle"
                class="phase"
              >
                <div class="phase-marker">
                  <span class="phase-tick">{{ String(i + 1).padStart(2, '0') }}</span>
                </div>
                <div class="phase-content">
                  <div class="phase-label">{{ p.phase_label }}</div>
                  <p class="phase-body">{{ p.body_copy }}</p>
                </div>
              </article>
            </div>
          </div>
        </section>

        <!-- Section 03 — Comparison -->
        <section class="pdp-section" id="cmp">
          <header class="section-header">
            <span class="section-num">03</span>
            <div>
              <span class="section-eyebrow">How we compare</span>
              <h3 class="section-title">{{ pilot.comparisonTable.section_title }}</h3>
            </div>
            <div class="section-actions">
              <span class="approve-state" :class="approvedState('comparisonTable')">{{ approveLabel('comparisonTable') }}</span>
              <button class="action-btn" @click="approve('comparisonTable')">Approve ✓</button>
              <button class="action-btn is-quiet" @click="openCite('comparisonTable')">Cite ↗</button>
            </div>
          </header>
          <div class="section-body">
            <p v-if="pilot.comparisonTable.subtitle" class="intro-copy">{{ pilot.comparisonTable.subtitle }}</p>
            <div class="cmp-wrap">
              <table class="cmp">
                <thead>
                  <tr>
                    <th class="feature-col">Feature</th>
                    <th v-for="c in pilot.comparisonTable.columns" :key="c.handle" :class="{ 'col-us': c.is_us }">
                      {{ c.name }}
                    </th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="r in pilot.comparisonTable.rows" :key="r.handle">
                    <td class="feature">{{ r.feature_label }}</td>
                    <td
                      v-for="(c, i) in pilot.comparisonTable.columns"
                      :key="c.handle"
                      :class="{ 'cell-us': c.is_us }"
                    >
                      {{ valueAt(r, i) }}
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </section>

        <!-- Section 04 — FAQs -->
        <section class="pdp-section" id="faq">
          <header class="section-header">
            <span class="section-num">04</span>
            <div>
              <span class="section-eyebrow">Get answers</span>
              <h3 class="section-title">{{ pilot.faqBlock.section_title }}</h3>
            </div>
            <div class="section-actions">
              <span class="approve-state" :class="approvedState('faqBlock')">{{ approveLabel('faqBlock') }}</span>
              <button class="action-btn" @click="approve('faqBlock')">Approve ✓</button>
              <button class="action-btn is-quiet" @click="openCite('faqBlock')">Cite ↗</button>
            </div>
          </header>
          <div class="section-body">
            <div class="faq-stack">
              <details v-for="(p, i) in pilot.faqBlock.pairs" :key="p.handle" :open="i < 2">
                <summary>
                  <span class="faq-num">{{ String(i + 1).padStart(2, '0') }}</span>
                  <span class="faq-question">{{ p.question }}</span>
                  <span class="faq-scope" :class="`scope-${p.scope}`">{{ p.scope }}</span>
                </summary>
                <div class="faq-answer">{{ p.answer }}</div>
              </details>
            </div>
            <a class="faq-cta" href="#">{{ pilot.faqBlock.cta_label }} →</a>
          </div>
        </section>
      </div>

      <!-- Approval summary footer ------------------------ -->
      <aside class="approval-summary">
        <div class="approval-summary-inner">
          <div class="approval-stat">
            <span class="approval-num">{{ approvedCount }}/4</span>
            <span class="meta">sections approved on this SKU</span>
          </div>
          <div class="approval-state-list">
            <span v-for="key in SECTION_KEYS" :key="key" class="state-chip" :class="approvedState(key)">
              {{ shortLabel(key) }}
            </span>
          </div>
          <button class="btn is-primary" :disabled="approvedCount < 4">
            <span v-if="approvedCount < 4">Approve all to ship</span>
            <span v-else>Ship to Lewis →</span>
          </button>
        </div>
      </aside>
    </section>

    <!-- CITATION DRAWER -->
    <transition name="slide-up">
      <div v-if="citeOpen" class="cite-drawer">
        <div class="cite-drawer-inner">
          <header class="cite-head">
            <span class="eyebrow">Citation chain</span>
            <h3 class="cite-title">{{ citeTitle }}</h3>
            <button class="cite-close" @click="citeOpen = false">close ×</button>
          </header>
          <ul class="cite-list">
            <li v-for="(c, i) in citeSources" :key="i" class="cite-row">
              <span class="cite-num">{{ String(i + 1).padStart(2, '0') }}</span>
              <div class="cite-body">
                <a v-if="c.href" class="cite-link" :href="c.href" target="_blank" rel="noopener">{{ c.label }}</a>
                <span v-else class="cite-text">{{ c.label }}</span>
                <span v-if="c.meta" class="cite-meta">{{ c.meta }}</span>
                <span v-if="c.type" class="cite-tag" :data-type="c.type">{{ c.type }}</span>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </transition>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useEditorialApi } from '../composables/useEditorialApi.js'

const SKINS = [
  { key: 'jv',       label: 'JV native',      swatch: '#5C6B4A' },
  { key: 'wild',     label: 'Wild Nutrition', swatch: '#A89A82' },
  { key: 'heights',  label: 'Heights',        swatch: '#1F2D4F' },
  { key: 'ritual',   label: 'Ritual',         swatch: '#F2A85B' },
  { key: 'fishy',    label: 'Nothing Fishy',  swatch: '#1A3C2A' }
]

const SECTION_KEYS = ['scientificStudy', 'timelineBlock', 'comparisonTable', 'faqBlock']

const route = useRoute()
const router = useRouter()
const api = useEditorialApi()

const pilots = ref([])
const pilot = ref(null)
const truth = ref(null)
const activeSkin = ref('jv')
const approvals = ref({})   // per-SKU-per-section
const citeOpen = ref(false)
const citeKey = ref(null)

const activeSku = computed(() => route.params.sku || pilots.value[0]?.sku || 'JV-D1000')
const activeSkinLabel = computed(() => SKINS.find(s => s.key === activeSkin.value)?.label || '')

// Split the curated Scientific Studies body into paragraphs on blank lines.
// The generator emits study framing → EFSA verbatim quote → context, separated
// by '\n\n'. We render each as a distinct <p> so the quote sets visually apart.
const sciBodyParagraphs = computed(() => {
  const raw = (pilot.value?.scientificStudy?.body_copy || '').trim()
  if (!raw) return []
  // Strip the verbatim authorised-claim line — it gets its own block.
  return raw
    .split(/\n\s*\n/)
    .map(p => p.trim())
    .filter(p => p && !p.startsWith('Authorised health claim:'))
    .filter(p => !p.startsWith('Authorised European Union nutrient claim'))
})

const truthBullets = computed(() => {
  if (!truth.value) return []
  const out = []
  if (truth.value.format) out.push(`Format: ${truth.value.format}`)
  if (truth.value.strength) out.push(`Strength: ${truth.value.strength}`)
  if (truth.value.tags) {
    const dietary = truth.value.tags.split(',').map(t => t.trim()).filter(t => /vegan|vegetarian|gluten|kosher|halal/i.test(t))
    if (dietary.length) out.push(`Suitable for: ${dietary.join(', ')}`)
  }
  if (truth.value.strapline) out.push(truth.value.strapline)
  return out.slice(0, 4)
})

const approvedCount = computed(() => {
  const sk = approvals.value[activeSku.value] || {}
  return SECTION_KEYS.filter(k => sk[k]).length
})

function approve(key) {
  const cur = approvals.value[activeSku.value] || {}
  approvals.value = { ...approvals.value, [activeSku.value]: { ...cur, [key]: !cur[key] } }
}
function approvedState(key) {
  const sk = approvals.value[activeSku.value] || {}
  return sk[key] ? 'is-approved' : 'is-pending'
}
function approveLabel(key) {
  const sk = approvals.value[activeSku.value] || {}
  return sk[key] ? 'Approved' : 'Draft'
}
function shortLabel(key) {
  const map = { scientificStudy: 'Sci', timelineBlock: 'Time', comparisonTable: 'Cmp', faqBlock: 'FAQ' }
  return map[key]
}

function valueAt(row, i) {
  const v = row.values?.[String(i)]?.value || ''
  return v.length > 80 ? v.slice(0, 80) + '…' : v
}

function catLabel(c) {
  return { vitamin: 'Vitamins', mineral: 'Minerals', botanical: 'Botanicals', collagen: 'Collagen' }[c] || c
}

// Citation drawer
// Prefer the structured sourceLinks array (objects with label/href/meta/type)
// over the legacy sources string array. Show only readable citations, never
// raw file paths.
const citeSources = computed(() => {
  if (!pilot.value || !citeKey.value) return []
  const section = pilot.value[citeKey.value] || {}
  const structured = Array.isArray(section.sourceLinks) ? section.sourceLinks : null
  if (structured && structured.length) return structured
  // Fallback: convert legacy string sources into citation-link shape.
  return (section.sources || [])
    .filter(s => typeof s === 'string')
    .filter(s => !s.startsWith('data/') && !s.startsWith('(no '))   // hide internal paths
    .map(s => {
      // Heuristic: pull out a URL if present in the string.
      const urlMatch = s.match(/https?:\/\/\S+/)
      if (urlMatch) {
        const label = s.replace(urlMatch[0], '').replace(/[—\-:\s]+$/, '').trim() || urlMatch[0]
        return { type: 'other', label, href: urlMatch[0] }
      }
      return { type: 'other', label: s }
    })
})
const citeTitle = computed(() => {
  if (!citeKey.value) return ''
  const map = { scientificStudy: 'Scientific Studies', timelineBlock: 'Results Timeline', comparisonTable: 'Comparison Table', faqBlock: 'FAQs' }
  return map[citeKey.value]
})
function openCite(key) {
  citeKey.value = key
  citeOpen.value = true
}

// Data loading
async function loadPilot(sku) {
  pilot.value = null
  truth.value = null
  pilot.value = await api.loadSku(sku)
  try { truth.value = await api.loadTruth(sku) } catch { truth.value = null }
}

onMounted(async () => {
  pilots.value = await api.loadAllPilots()
  if (!route.params.sku && pilots.value.length) {
    router.replace(`/preview/${pilots.value[0].sku}`)
  } else {
    await loadPilot(activeSku.value)
  }
})

watch(() => route.params.sku, async (sku) => {
  if (sku) await loadPilot(sku)
})
</script>

<style scoped>
.theatre { padding-bottom: var(--s-9); }

/* HEAD -------------------------------------------------------- */
.head { padding-top: var(--s-7); padding-bottom: var(--s-7); }
.head-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: var(--s-8);
  align-items: end;
}
.head-title {
  font-size: var(--t-5xl);
  font-variation-settings: 'opsz' 144, 'SOFT' 80;
  line-height: 0.95;
  letter-spacing: -0.04em;
  margin-top: var(--s-3);
}
.head-title em {
  font-style: italic;
  font-variation-settings: 'opsz' 144, 'SOFT' 100, 'WONK' 1;
  color: var(--accent-sage);
}
.head-lede {
  margin-top: var(--s-5);
  max-width: 56ch;
  font-size: var(--t-lg);
  color: var(--ink-soft);
}

.head-right {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.select-block { display: flex; flex-direction: column; gap: var(--s-3); }

.sku-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}
.sku-chip {
  border: 1px solid var(--rule);
  background: var(--bg-paper);
  padding: var(--s-3) var(--s-4);
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-radius: var(--r-sm);
  text-decoration: none;
  transition: all var(--dur) var(--ease);
  min-width: 140px;
}
.sku-chip:hover {
  border-color: var(--rule-strong);
  background: var(--bg-cream-alt);
}
.sku-chip.is-active {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--bg-paper);
}
.chip-sku {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}
.sku-chip.is-active .chip-sku { color: rgba(244, 239, 230, 0.55); }
.chip-name {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  font-variation-settings: 'opsz' 24, 'SOFT' 20;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.skin-row { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.skin-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--rule);
  font-family: var(--font-sans);
  font-size: var(--t-xs);
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  background: transparent;
  transition: all var(--dur) var(--ease);
}
.skin-pill:hover { border-color: var(--rule-strong); color: var(--ink); }
.skin-pill.is-active {
  background: var(--ink);
  color: var(--bg-paper);
  border-color: var(--ink);
}
.skin-swatch {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pill);
  display: inline-block;
}

/* STAGE ------------------------------------------------------ */
.stage { padding-top: var(--s-5); }

.stage-frame {
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  background: var(--bg-paper);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
  transition: background var(--dur-slow) var(--ease), color var(--dur-slow) var(--ease);
}

.stage-chrome {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-3) var(--s-4);
  background: var(--bg-cream-alt);
  border-bottom: 1px solid var(--rule);
  font-size: var(--t-xs);
  color: var(--ink-muted);
}
.chrome-dots { display: flex; gap: 6px; }
.chrome-dots span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--rule-strong);
}
.chrome-url {
  flex: 1;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: -0.01em;
}
.chrome-skin {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-xs);
  letter-spacing: 0.01em;
  font-variation-settings: 'opsz' 18, 'WONK' 1;
}

/* ABOVE-THE-FOLD --------------------------------------------- */
.atf {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-7);
  padding: var(--s-8) var(--s-7);
  align-items: center;
}
.atf-image {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: var(--s-5);
}
.image-card {
  width: 100%;
  aspect-ratio: 3 / 4;
  max-width: 320px;
  background: var(--bg-cream-alt);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: var(--s-5);
  text-align: center;
}
.image-meta {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  text-transform: uppercase;
}
.image-title {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-variation-settings: 'opsz' 36, 'SOFT' 30;
  line-height: 1.1;
  letter-spacing: -0.012em;
}
.image-strength {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-lg);
  color: var(--ink-soft);
  font-variation-settings: 'opsz' 30, 'WONK' 1;
}

.breadcrumb-meta {
  font-size: var(--t-xs);
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.product-name {
  font-size: var(--t-3xl);
  font-variation-settings: 'opsz' 96, 'SOFT' 40;
  letter-spacing: -0.03em;
  margin-top: var(--s-2);
}
.atf-bullets {
  margin-top: var(--s-5);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.atf-bullets li {
  font-size: var(--t-sm);
  color: var(--ink-soft);
}
.variants {
  margin-top: var(--s-5);
  display: flex;
  gap: var(--s-2);
}
.variant-pill {
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  font-family: var(--font-sans);
}
.cta-btn {
  margin-top: var(--s-5);
  padding: 14px 32px;
  background: var(--ink);
  color: var(--bg-paper);
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: var(--t-sm);
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.cta-btn:hover { background: var(--accent-sage); }

/* PDP SECTION ------------------------------------------------- */
.pdp-section {
  border-top: 1px solid var(--rule);
  padding: var(--s-8) var(--s-7);
}

.section-header {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: end;
  gap: var(--s-5);
  margin-bottom: var(--s-6);
}

.section-num {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: 'opsz' 96, 'WONK' 1, 'SOFT' 80, 'wght' 300;
  font-size: var(--t-4xl);
  line-height: 0.8;
  color: var(--ink);
  letter-spacing: -0.04em;
}
.section-eyebrow {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: 'opsz' 24, 'WONK' 1;
  font-size: var(--t-sm);
  color: var(--ink-muted);
  letter-spacing: 0.01em;
  display: block;
}
.section-title {
  font-size: var(--t-2xl);
  font-variation-settings: 'opsz' 60, 'SOFT' 30;
  letter-spacing: -0.02em;
  margin-top: var(--s-1);
  line-height: 1.15;
}

.section-actions { display: flex; gap: var(--s-2); align-items: center; }
.approve-state {
  font-family: var(--font-sans);
  font-size: 10px;
  padding: 4px 9px;
  border-radius: 999px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
}
.approve-state.is-pending { background: var(--bg-cream-alt); color: var(--ink-muted); }
.approve-state.is-approved { background: var(--accent-sage); color: var(--bg-paper); }

.action-btn {
  font-family: var(--font-sans);
  font-size: var(--t-xs);
  letter-spacing: 0.02em;
  padding: 7px 14px;
  border-radius: var(--r-sm);
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--bg-paper);
  transition: all var(--dur) var(--ease);
}
.action-btn:hover { background: var(--accent-sage); border-color: var(--accent-sage); }
.action-btn.is-quiet {
  background: transparent;
  color: var(--ink);
  border-color: var(--rule-strong);
}
.action-btn.is-quiet:hover {
  background: var(--bg-cream-alt);
  border-color: var(--ink);
  color: var(--ink);
}

/* Section body */
.section-body { max-width: var(--col-wide); }
.sci-prose {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-variation-settings: 'opsz' 36, 'SOFT' 30;
  line-height: var(--lh-snug);
  letter-spacing: -0.012em;
  color: var(--ink);
  max-width: 60ch;
}
.intro-copy {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: 'opsz' 24, 'WONK' 1, 'SOFT' 20;
  font-size: var(--t-lg);
  color: var(--ink-soft);
  max-width: 56ch;
  margin-bottom: var(--s-6);
}

.stat-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-7);
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid var(--rule);
  max-width: var(--col-mid);
}
.stat-num {
  font-family: var(--font-display);
  font-size: var(--t-4xl);
  font-variation-settings: 'opsz' 96, 'SOFT' 60;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--accent-sage);
}
.stat-label {
  font-size: 11px;
  letter-spacing: 0.04em;
  margin-top: var(--s-3);
  color: var(--ink-muted);
  text-transform: uppercase;
  line-height: 1.4;
}
.study-link {
  display: inline-block;
  margin-top: var(--s-6);
  font-family: var(--font-sans);
  font-size: var(--t-sm);
  color: var(--ink-soft);
  text-decoration: underline;
  text-decoration-color: var(--accent-sage);
  text-underline-offset: 4px;
}

/* EFSA verbatim quote — set apart visually so it reads as a regulator quote,
   not marketing copy. Cream block, rule on the left, italic Fraunces. */
.efsa-quote {
  margin: var(--s-6) 0;
  padding: var(--s-5) var(--s-6);
  background: var(--bg-cream-alt);
  border-left: 2px solid var(--accent-sage);
  max-width: var(--col-mid);
}
.efsa-eyebrow {
  display: block;
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-sage);
  margin-bottom: var(--s-2);
  font-weight: 600;
}
.efsa-quote blockquote {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: 'opsz' 36, 'WONK' 1, 'SOFT' 30;
  font-size: var(--t-xl);
  line-height: 1.3;
  color: var(--ink);
  letter-spacing: -0.012em;
}
.efsa-context {
  margin-top: var(--s-3);
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--ink-muted);
}

/* Clickable stat tile — when the source is a real URL, the whole tile links */
.stat-clickable {
  text-decoration: none;
  color: inherit;
  position: relative;
  transition: opacity var(--dur) var(--ease);
}
.stat-clickable:hover { opacity: 0.7; }
.stat-cite {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 0.05em;
  color: var(--accent-sage);
  text-transform: uppercase;
}

/* References footer — real citations as clickable links, not file paths */
.references {
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid var(--rule);
  max-width: var(--col-mid);
}
.references-label {
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  font-weight: 600;
}
.references-list {
  list-style: none;
  margin-top: var(--s-3);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.references-list li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--t-sm);
  line-height: 1.45;
}
.references-list a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent-sage);
  text-underline-offset: 3px;
}
.references-list a:hover { color: var(--accent-sage); }
.ref-meta {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-muted);
  letter-spacing: -0.01em;
}

/* Timeline */
.timeline-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border-top: 1px solid var(--rule);
}
.phase {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: var(--s-5);
  padding: var(--s-5) 0;
  border-bottom: 1px solid var(--rule-faint);
  align-items: start;
}
.phase-marker {
  display: flex;
  justify-content: flex-start;
}
.phase-tick {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--accent-sage);
  padding: 4px 8px;
  border: 1px solid var(--accent-sage);
  border-radius: var(--r-sm);
}
.phase-label {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 36, 'SOFT' 30;
  font-size: var(--t-xl);
  letter-spacing: -0.015em;
  margin-bottom: var(--s-2);
}
.phase-body {
  font-size: var(--t-base);
  line-height: var(--lh-relaxed);
  color: var(--ink-soft);
  max-width: 64ch;
}

/* Comparison */
.cmp-wrap { overflow-x: auto; }
.cmp {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
  margin-top: var(--s-3);
}
.cmp th, .cmp td {
  text-align: left;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}
.cmp thead th {
  font-family: var(--font-sans);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-weight: 600;
  border-bottom: 2px solid var(--ink);
}
.cmp thead th.col-us { color: var(--accent-sage); }
.cmp td.feature {
  font-weight: 500;
  color: var(--ink);
}
.cmp td.cell-us {
  background: var(--bg-sage-soft);
  color: var(--ink);
  font-weight: 500;
}

/* FAQ */
.faq-stack {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--rule);
}
.faq-stack details {
  border-bottom: 1px solid var(--rule);
  padding: var(--s-5) 0;
}
.faq-stack summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s-4);
}
.faq-stack summary::-webkit-details-marker { display: none; }
.faq-num {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}
.faq-question {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-variation-settings: 'opsz' 24, 'SOFT' 20;
  letter-spacing: -0.012em;
  color: var(--ink);
}
.faq-scope {
  font-family: var(--font-sans);
  font-size: 10px;
  padding: 3px 8px;
  border-radius: 999px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--bg-cream-alt);
  color: var(--ink-muted);
}
.faq-scope.scope-product { background: var(--bg-sage-soft); color: var(--accent-sage); }
.faq-answer {
  margin-top: var(--s-3);
  font-size: var(--t-base);
  line-height: var(--lh-relaxed);
  color: var(--ink-soft);
  max-width: 64ch;
  padding-left: 28px;
}
.faq-cta {
  display: inline-block;
  margin-top: var(--s-5);
  font-family: var(--font-sans);
  font-size: var(--t-sm);
  color: var(--accent-sage);
  text-decoration: none;
  letter-spacing: 0.01em;
}
.faq-cta:hover { color: var(--ink); }

/* APPROVAL SUMMARY ---------------------------------------- */
.approval-summary {
  margin-top: var(--s-7);
  border: 1px solid var(--rule-strong);
  background: var(--bg-paper);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-soft);
}
.approval-summary-inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--s-5);
  padding: var(--s-5) var(--s-6);
  align-items: center;
}
.approval-num {
  font-family: var(--font-display);
  font-size: var(--t-3xl);
  font-variation-settings: 'opsz' 96, 'SOFT' 60;
  color: var(--ink);
  display: block;
  line-height: 1;
}
.approval-state-list { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.state-chip {
  font-family: var(--font-sans);
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  background: var(--bg-cream-alt);
  color: var(--ink-muted);
  border: 1px solid var(--rule);
}
.state-chip.is-approved { background: var(--accent-sage); color: var(--bg-paper); border-color: var(--accent-sage); }

/* CITATION DRAWER ----------------------------------------- */
.cite-drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  background: var(--bg-ink);
  color: var(--ink-on-dark);
  border-top: 1px solid var(--rule-strong);
  max-height: 50vh;
  overflow-y: auto;
}
.cite-drawer-inner {
  max-width: var(--col-full);
  margin: 0 auto;
  padding: var(--s-6) var(--s-7);
}
.cite-head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--s-4);
  align-items: center;
  margin-bottom: var(--s-5);
}
.cite-head .eyebrow { color: var(--accent-sage); }
.cite-title {
  font-size: var(--t-2xl);
  color: var(--ink-on-dark);
  font-variation-settings: 'opsz' 60;
}
.cite-close {
  border: 1px solid rgba(244, 239, 230, 0.4);
  color: var(--ink-on-dark);
  padding: 6px 12px;
  border-radius: 999px;
  font-size: var(--t-sm);
}
.cite-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.cite-list li {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: var(--s-3);
  padding: var(--s-3) 0;
  border-bottom: 1px solid rgba(244, 239, 230, 0.1);
}
.cite-num {
  font-family: var(--font-mono);
  color: rgba(244, 239, 230, 0.45);
  font-size: var(--t-xs);
}
.cite-mono {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--ink-on-dark);
  word-break: break-all;
}
.cite-row {
  display: grid !important;
  grid-template-columns: 36px 1fr !important;
}
.cite-body { display: flex; flex-direction: column; gap: 4px; }
.cite-link {
  color: var(--ink-on-dark);
  text-decoration: underline;
  text-decoration-color: var(--accent-sage);
  text-underline-offset: 3px;
  font-family: var(--font-display);
  font-size: var(--t-base);
  font-variation-settings: 'opsz' 24, 'SOFT' 20;
  letter-spacing: -0.005em;
}
.cite-link:hover { color: var(--accent-sage); }
.cite-text {
  font-family: var(--font-display);
  font-size: var(--t-base);
  font-variation-settings: 'opsz' 24;
  color: var(--ink-on-dark);
}
.cite-meta {
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(244, 239, 230, 0.55);
  letter-spacing: -0.01em;
}
.cite-tag {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 2px;
  margin-top: 4px;
  align-self: flex-start;
  background: rgba(244, 239, 230, 0.08);
  color: rgba(244, 239, 230, 0.75);
}
.cite-tag[data-type="pubmed"]      { background: rgba(92, 107, 74, 0.25); color: #B8C2B0; }
.cite-tag[data-type="efsa"],
.cite-tag[data-type="regulation"]  { background: rgba(184, 115, 44, 0.18); color: #D6A47A; }

.slide-up-enter-active, .slide-up-leave-active { transition: transform var(--dur) var(--ease-out), opacity var(--dur) var(--ease); }
.slide-up-enter-from, .slide-up-leave-to { transform: translateY(100%); opacity: 0; }

/* ============================================================
 * COMPETITOR SKIN OVERRIDES
 * Same DOM, different visual language. Re-skin token by token.
 * ============================================================ */

/* Wild Nutrition — warm taupe, more refined, Times-y serif */
.stage-frame.skin-wild {
  --bg-paper: #FBF8F3;
  --bg-cream-alt: #F1E8DB;
  --bg-sage-soft: #E8E2D5;
  --ink: #2A2622;
  --ink-soft: #5A4F44;
  --accent-sage: #948161;
  --font-display: 'Fraunces', Georgia, serif;
  background: #FBF8F3;
}
.stage-frame.skin-wild .stat-num { color: #948161; font-variation-settings: 'opsz' 96, 'wght' 300; }
.stage-frame.skin-wild .section-num { color: #948161; font-variation-settings: 'opsz' 144, 'wght' 200; }
.stage-frame.skin-wild .cta-btn { background: #2A2622; }

/* Heights — navy + cream, sans-heavy */
.stage-frame.skin-heights {
  --bg-paper: #F3EFE4;
  --bg-cream-alt: #E8E1D0;
  --bg-sage-soft: #DBE2EB;
  --ink: #1F2D4F;
  --ink-soft: #4B5878;
  --accent-sage: #1F2D4F;
  --font-display: 'General Sans', sans-serif;
  background: #F3EFE4;
}
.stage-frame.skin-heights .stat-num,
.stage-frame.skin-heights .section-num,
.stage-frame.skin-heights .product-name,
.stage-frame.skin-heights .section-title,
.stage-frame.skin-heights .phase-label,
.stage-frame.skin-heights .image-title,
.stage-frame.skin-heights .faq-question,
.stage-frame.skin-heights .sci-prose,
.stage-frame.skin-heights .head-title {
  font-family: 'General Sans', sans-serif;
  font-style: normal;
  font-weight: 600;
  font-variation-settings: normal;
  letter-spacing: -0.02em;
}
.stage-frame.skin-heights .intro-copy { font-family: 'General Sans', sans-serif; font-style: normal; font-variation-settings: normal; }
.stage-frame.skin-heights .cta-btn { background: #1F2D4F; }

/* Ritual — bright white, single brand-color accent */
.stage-frame.skin-ritual {
  --bg-paper: #FFFFFF;
  --bg-cream-alt: #F5F1EB;
  --bg-sage-soft: #FFEED9;
  --ink: #11243A;
  --ink-soft: #475569;
  --accent-sage: #F2A85B;
  --rule: rgba(17, 36, 58, 0.12);
  --rule-strong: rgba(17, 36, 58, 0.3);
  background: #FFFFFF;
}
.stage-frame.skin-ritual .stat-num { color: #F2A85B; }
.stage-frame.skin-ritual .cta-btn { background: #11243A; }
.stage-frame.skin-ritual .cta-btn:hover { background: #F2A85B; color: #11243A; }

/* Nothing Fishy — deep green, modern */
.stage-frame.skin-fishy {
  --bg-paper: #EFE9DD;
  --bg-cream-alt: #DCD3C3;
  --bg-sage-soft: #C8D3B8;
  --ink: #1A3C2A;
  --ink-soft: #406548;
  --accent-sage: #1A3C2A;
  background: #EFE9DD;
}
.stage-frame.skin-fishy .section-num { color: #1A3C2A; font-variation-settings: 'opsz' 144, 'wght' 500; }
.stage-frame.skin-fishy .stat-num { color: #1A3C2A; }
.stage-frame.skin-fishy .cta-btn { background: #1A3C2A; }

/* Responsive ------------------------------------------------ */
@media (max-width: 1100px) {
  .atf { grid-template-columns: 1fr; }
  .head-grid { grid-template-columns: 1fr; }
  .section-header { grid-template-columns: 1fr; }
  .section-actions { flex-wrap: wrap; }
  .approval-summary-inner { grid-template-columns: 1fr; gap: var(--s-3); }
}
@media (max-width: 900px) {
  .stat-strip { grid-template-columns: 1fr 1fr; gap: var(--s-4); }
  .pdp-section { padding: var(--s-6) var(--s-5); }
  .atf { padding: var(--s-5); }
  .phase { grid-template-columns: 1fr; gap: var(--s-2); }
}
</style>
