056c47581f
Ships the second dashboard surface — a Pattern Library + Preview Theatre — that presents the 4-section PDP pilot batch back to Umar, compliance, and the board in an editorial format. Adds the full data layer that drives it: 5 source-backed per-SKU drafts at QA 100/100, 15 competitor PDP semantic extracts, PubMed evidence packs, EFSA claims library extension, JV brand voice guide, hand-curated product FAQs, and the Matrixify-ready CSV exports for Lewis. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
227 lines
4.8 KiB
Vue
227 lines
4.8 KiB
Vue
<template>
|
|
<div class="shell">
|
|
<header class="masthead">
|
|
<div class="masthead-inner">
|
|
<div class="brand">
|
|
<span class="brand-eyebrow">Just Vitamins</span>
|
|
<span class="brand-title">Editorial Review</span>
|
|
</div>
|
|
|
|
<nav class="modes" aria-label="View mode">
|
|
<router-link
|
|
class="mode"
|
|
:class="{ 'is-active': isPatterns }"
|
|
to="/patterns"
|
|
>
|
|
<span class="mode-num">01</span>
|
|
<span class="mode-label">Pattern Library</span>
|
|
</router-link>
|
|
<router-link
|
|
class="mode"
|
|
:class="{ 'is-active': isPreview }"
|
|
to="/preview"
|
|
>
|
|
<span class="mode-num">02</span>
|
|
<span class="mode-label">Preview Theatre</span>
|
|
</router-link>
|
|
</nav>
|
|
|
|
<div class="masthead-meta">
|
|
<span class="meta">Pilot batch · 2 Jun 2026</span>
|
|
</div>
|
|
</div>
|
|
<div class="masthead-rule"></div>
|
|
</header>
|
|
|
|
<main class="content">
|
|
<router-view v-slot="{ Component }">
|
|
<transition name="fade" mode="out-in">
|
|
<component :is="Component" />
|
|
</transition>
|
|
</router-view>
|
|
</main>
|
|
|
|
<footer class="footer">
|
|
<div class="footer-inner">
|
|
<span class="meta">5 pilots · 15 references · 100/100 QA</span>
|
|
<span class="meta">Hand-set in Fraunces & General Sans</span>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
|
|
const route = useRoute()
|
|
const isPatterns = computed(() => route.path.startsWith('/patterns'))
|
|
const isPreview = computed(() => route.path.startsWith('/preview'))
|
|
</script>
|
|
|
|
<style scoped>
|
|
.shell {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* MASTHEAD ------------------------------------------------------------ */
|
|
|
|
.masthead {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 50;
|
|
background: var(--bg-paper);
|
|
}
|
|
|
|
.masthead-inner {
|
|
display: grid;
|
|
grid-template-columns: 1fr auto 1fr;
|
|
align-items: end;
|
|
gap: var(--s-7);
|
|
padding: var(--s-6) var(--s-7) var(--s-4);
|
|
max-width: var(--col-full);
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.brand {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-1);
|
|
justify-self: start;
|
|
}
|
|
|
|
.brand-eyebrow {
|
|
font-family: var(--font-display);
|
|
font-style: italic;
|
|
font-variation-settings: 'opsz' 24, 'WONK' 1;
|
|
font-size: var(--t-sm);
|
|
color: var(--ink-soft);
|
|
letter-spacing: 0.01em;
|
|
}
|
|
|
|
.brand-title {
|
|
font-family: var(--font-display);
|
|
font-size: var(--t-2xl);
|
|
font-variation-settings: 'opsz' 60, 'SOFT' 30, 'WONK' 0;
|
|
letter-spacing: -0.025em;
|
|
line-height: 1;
|
|
color: var(--ink);
|
|
}
|
|
|
|
/* Mode toggle — large editorial-style nav, not chips */
|
|
.modes {
|
|
display: flex;
|
|
gap: var(--s-7);
|
|
align-items: baseline;
|
|
justify-self: center;
|
|
}
|
|
|
|
.mode {
|
|
position: relative;
|
|
text-decoration: none;
|
|
display: inline-flex;
|
|
align-items: baseline;
|
|
gap: var(--s-2);
|
|
padding-bottom: var(--s-2);
|
|
transition: color var(--dur) var(--ease);
|
|
color: var(--ink-muted);
|
|
}
|
|
|
|
.mode-num {
|
|
font-family: var(--font-mono);
|
|
font-size: 10px;
|
|
letter-spacing: 0.1em;
|
|
color: inherit;
|
|
align-self: center;
|
|
margin-top: -2px;
|
|
}
|
|
|
|
.mode-label {
|
|
font-family: var(--font-display);
|
|
font-style: italic;
|
|
font-variation-settings: 'opsz' 36, 'WONK' 1, 'SOFT' 20;
|
|
font-size: var(--t-xl);
|
|
font-weight: 400;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
.mode::after {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: -2px;
|
|
height: 2px;
|
|
background: var(--ink);
|
|
transform: scaleX(0);
|
|
transform-origin: left;
|
|
transition: transform var(--dur-slow) var(--ease-out);
|
|
}
|
|
|
|
.mode.is-active {
|
|
color: var(--ink);
|
|
}
|
|
.mode.is-active::after {
|
|
transform: scaleX(1);
|
|
}
|
|
.mode:hover {
|
|
color: var(--ink-soft);
|
|
}
|
|
|
|
.masthead-meta {
|
|
justify-self: end;
|
|
align-self: end;
|
|
}
|
|
|
|
.masthead-rule {
|
|
height: 1px;
|
|
background: var(--rule);
|
|
max-width: var(--col-full);
|
|
margin: 0 auto;
|
|
}
|
|
|
|
/* CONTENT ------------------------------------------------------------ */
|
|
|
|
.content {
|
|
flex: 1;
|
|
padding: var(--s-8) 0 var(--s-9);
|
|
min-height: 60vh;
|
|
}
|
|
|
|
/* FOOTER ------------------------------------------------------------ */
|
|
|
|
.footer {
|
|
padding: var(--s-6) 0;
|
|
border-top: 1px solid var(--rule);
|
|
margin-top: var(--s-7);
|
|
}
|
|
|
|
.footer-inner {
|
|
max-width: var(--col-full);
|
|
margin: 0 auto;
|
|
padding: 0 var(--s-7);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: var(--s-4);
|
|
}
|
|
|
|
/* Responsive ------------------------------------------------------ */
|
|
|
|
@media (max-width: 900px) {
|
|
.masthead-inner {
|
|
grid-template-columns: 1fr;
|
|
gap: var(--s-4);
|
|
padding: var(--s-5) var(--s-5) var(--s-3);
|
|
}
|
|
.modes {
|
|
justify-self: start;
|
|
gap: var(--s-5);
|
|
}
|
|
.mode-label { font-size: var(--t-lg); }
|
|
.masthead-meta { display: none; }
|
|
.footer-inner { padding: 0 var(--s-5); flex-wrap: wrap; }
|
|
}
|
|
</style>
|