overhaul operations: system-ui font, interactive needs checkboxes, daily routine & cron schedule from old launch dashboard
This commit is contained in:
+286
-6
@@ -20,8 +20,8 @@
|
||||
--danger-dim: #3b0000;
|
||||
--success: #00ff88;
|
||||
--warning: #ffaa00;
|
||||
--text: #c8f0ff;
|
||||
--text-muted: #2e6a80;
|
||||
--text: #e0f4ff;
|
||||
--text-muted: #3a8aaa;
|
||||
--radius: 8px;
|
||||
--radius-card: 18px;
|
||||
--shadow: 0 0 0 1px rgba(0,245,255,0.25), 0 0 60px rgba(0,245,255,0.12), 0 28px 72px rgba(0,0,0,0.9);
|
||||
@@ -30,11 +30,11 @@
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; }
|
||||
body {
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
line-height: 1.7;
|
||||
overflow-x: hidden;
|
||||
padding: 32px 0;
|
||||
}
|
||||
@@ -57,12 +57,16 @@
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", "Consolas", monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* ── Brief Header ────────────────────────── */
|
||||
.brief-header {
|
||||
text-align: center;
|
||||
margin-bottom: 32px;
|
||||
padding: 32px 24px 28px;
|
||||
padding: 36px 28px 28px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-card);
|
||||
@@ -71,7 +75,7 @@
|
||||
.brief-header .date {
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
@@ -309,6 +313,64 @@
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ── Items Needed (interactive checkboxes) ── */
|
||||
.needs-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-card);
|
||||
padding: 24px;
|
||||
}
|
||||
.needs-card .needs-intro {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.needs-list { list-style: none; }
|
||||
.needs-list li {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid rgba(10,48,96,0.3);
|
||||
}
|
||||
.needs-list li:last-child { border-bottom: none; }
|
||||
.need-checkbox {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
min-width: 20px;
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 5px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.need-checkbox:hover {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
.need-checkbox.checked {
|
||||
background: var(--success);
|
||||
border-color: var(--success);
|
||||
}
|
||||
.need-checkbox.checked::after {
|
||||
content: "✓";
|
||||
color: var(--bg);
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.need-item.done .need-text {
|
||||
color: var(--text-muted);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.need-text {
|
||||
font-size: 14px;
|
||||
color: var(--text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ── Strategy ────────────────────────────── */
|
||||
.strategy-grid {
|
||||
display: grid;
|
||||
@@ -454,11 +516,99 @@
|
||||
.comms-alert .alert-body { color: var(--text); }
|
||||
.comms-alert .alert-detail { color: var(--text-muted); font-size: 11px; margin-top: 2px; }
|
||||
|
||||
/* ── Daily Routine (from old dashboard) ──── */
|
||||
.grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
.info-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-card);
|
||||
padding: 24px;
|
||||
}
|
||||
.info-card h3 {
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--accent);
|
||||
margin-bottom: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.cron-timeline {
|
||||
position: relative;
|
||||
padding-left: 28px;
|
||||
}
|
||||
.cron-timeline::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 4px;
|
||||
bottom: 4px;
|
||||
width: 2px;
|
||||
background: var(--border);
|
||||
}
|
||||
.cron-item {
|
||||
position: relative;
|
||||
padding: 6px 0 16px;
|
||||
}
|
||||
.cron-item::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -24px;
|
||||
top: 10px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 2px solid var(--accent);
|
||||
}
|
||||
.cron-item.daily-hour::before {
|
||||
background: var(--accent);
|
||||
box-shadow: 0 0 12px rgba(0,245,255,0.5);
|
||||
}
|
||||
.cron-time {
|
||||
font-size: 12px;
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
.cron-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.cron-desc {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 2px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ── Progress badge ──────────────────────── */
|
||||
.progress-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.progress-tag.done { background: rgba(0,255,136,0.12); color: var(--success); border: 1px solid rgba(0,255,136,0.25); }
|
||||
.progress-tag.in-progress { background: rgba(0,245,255,0.12); color: var(--accent); border: 1px solid rgba(0,245,255,0.25); }
|
||||
.progress-tag.pending { background: rgba(46,106,128,0.15); color: var(--text-muted); border: 1px solid transparent; }
|
||||
.progress-tag.blocked { background: rgba(255,59,59,0.12); color: var(--danger); border: 1px solid rgba(255,59,59,0.25); }
|
||||
.progress-tag.today { background: rgba(255,170,0,0.15); color: var(--warning); border: 1px solid rgba(255,170,0,0.3); }
|
||||
|
||||
.highlight { color: var(--accent); }
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.campaign-grid { grid-template-columns: 1fr; }
|
||||
.comms-grid { grid-template-columns: 1fr; }
|
||||
.goals-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
.strategy-grid { grid-template-columns: 1fr; }
|
||||
.grid-2 { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (max-width: 500px) {
|
||||
.goals-grid { grid-template-columns: 1fr; }
|
||||
@@ -514,6 +664,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════ ITEMS NEEDED (INTERACTIVE CHECKBOXES) ═══════════════ -->
|
||||
<div class="section">
|
||||
<div class="section-header" onclick="toggleSection('needs-section', this)">
|
||||
<h2><span class="icon">📦</span> Items Needed From You <span class="count">check off as delivered</span></h2>
|
||||
<span class="section-toggle">▼</span>
|
||||
</div>
|
||||
<div class="section-body" id="needs-section">
|
||||
<div class="needs-card">
|
||||
<p class="needs-intro">
|
||||
Click a checkbox to mark it done — saved in your browser.
|
||||
</p>
|
||||
<ul class="needs-list" id="needs-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════ COMMUNICATIONS ═══════════════ -->
|
||||
<div class="section">
|
||||
<div class="section-header" onclick="toggleSection('comms-section', this)">
|
||||
@@ -525,6 +691,69 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════ DAILY ROUTINE ═══════════════ -->
|
||||
<div class="section">
|
||||
<div class="section-header" onclick="toggleSection('routine-section', this)">
|
||||
<h2><span class="icon">⏰</span> Daily Routine & Cron Schedule</h2>
|
||||
<span class="section-toggle">▼</span>
|
||||
</div>
|
||||
<div class="section-body" id="routine-section">
|
||||
<div class="grid-2">
|
||||
<div class="info-card">
|
||||
<h3>⏱ Our Daily 1-Hour Block</h3>
|
||||
<p style="font-size:13px;margin-bottom:12px;">Every day at <strong class="highlight">09:00 PYST</strong> (America/Asuncion) — 60 minutes.</p>
|
||||
<div class="cron-timeline">
|
||||
<div class="cron-item daily-hour">
|
||||
<div class="cron-time">09:00 – 09:05</div>
|
||||
<div class="cron-title">Dashboard review</div>
|
||||
<div class="cron-desc">Read the 03:00 auto-update, review KPIs, see what changed overnight</div>
|
||||
</div>
|
||||
<div class="cron-item daily-hour">
|
||||
<div class="cron-time">09:05 – 09:15</div>
|
||||
<div class="cron-title">Status sync</div>
|
||||
<div class="cron-desc">Reply to dashboard comments, update action statuses, unblock items</div>
|
||||
</div>
|
||||
<div class="cron-item daily-hour">
|
||||
<div class="cron-time">09:15 – 09:45</div>
|
||||
<div class="cron-title">Deep work</div>
|
||||
<div class="cron-desc">Execute today's priority actions (outreach emails, content drafts, influencer DMs)</div>
|
||||
</div>
|
||||
<div class="cron-item daily-hour">
|
||||
<div class="cron-time">09:45 – 10:00</div>
|
||||
<div class="cron-title">Wrap & queue</div>
|
||||
<div class="cron-desc">Set tomorrow's priorities, queue tasks for the cron, log progress</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<h3>🤖 Automated Cron Jobs</h3>
|
||||
<div class="cron-timeline">
|
||||
<div class="cron-item">
|
||||
<div class="cron-time">03:00 PYST</div>
|
||||
<div class="cron-title">📊 Dashboard Update</div>
|
||||
<div class="cron-desc">Auto-generates KPI snapshot: signups, traffic, backlinks, influencer status. Writes to <code>data/operations.json</code> for review at 09:00.</div>
|
||||
</div>
|
||||
<div class="cron-item">
|
||||
<div class="cron-time">03:10 PYST</div>
|
||||
<div class="cron-title">📈 SEO & Rank Tracker</div>
|
||||
<div class="cron-desc">Check Google Search Console for new impressions/clicks. Log keyword positions. Alert on +50% change.</div>
|
||||
</div>
|
||||
<div class="cron-item">
|
||||
<div class="cron-time">03:20 PYST</div>
|
||||
<div class="cron-title">🔗 Backlink Monitor</div>
|
||||
<div class="cron-desc">Check Ahrefs/Moz API for new backlinks. Update backlink count. Flag new domains referring.</div>
|
||||
</div>
|
||||
<div class="cron-item">
|
||||
<div class="cron-time">03:30 PYST</div>
|
||||
<div class="cron-title">💬 Social Monitor</div>
|
||||
<div class="cron-desc">Check X/Twitter for brand mentions, reply to inquiries, log sentiment.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════ STRATEGY & RECOMMENDATIONS ═══════════════ -->
|
||||
<div class="section">
|
||||
<div class="section-header" onclick="toggleSection('strategy-section', this)">
|
||||
@@ -587,6 +816,21 @@
|
||||
{ num: 3, title: 'Send first cold email batch', desc: 'Using friends950 / creator950 coupons. Draft goes to Telegram for confirmation first.', owner: 'Oliver + Mint' },
|
||||
];
|
||||
|
||||
const NEEDS = [
|
||||
{ id: "n1", text: "List of 20–30 friends & family contacts (name + email)", done: false },
|
||||
{ id: "n2", text: "Target influencer list (30 names, handles/emails, niche, follower count)", done: false },
|
||||
{ id: "n3", text: "Influencer partnership budget (free plans? cash? affiliate %?)", done: false },
|
||||
{ id: "n4", text: "OpenRouter coupon codes for referral program (5 needed)", done: false },
|
||||
{ id: "n5", text: "Product demo video (3 min screen recording) or go-ahead to record one", done: false },
|
||||
{ id: "n6", text: "3–5 screenshots of dashboard / agent setup flow", done: false },
|
||||
{ id: "n7", text: "Social media account access (X/Twitter + LinkedIn posting access)", done: false },
|
||||
{ id: "n8", text: "Personal story / 'Why I built Derez.ai' notes for blog post", done: false },
|
||||
{ id: "n9", text: "Competitor list (5–10 names) for backlink gap analysis", done: false },
|
||||
{ id: "n10", text: "Price anchoring: confirm if F&F get special discount or free month", done: false },
|
||||
{ id: "n11", text: "HARO / Qwoted / Connectively account (or credentials to set up)", done: false },
|
||||
{ id: "n12", text: "Google Search Console access for derez.ai", done: true },
|
||||
];
|
||||
|
||||
const strategyCards = [
|
||||
{
|
||||
icon: '📢', title: 'Influencer Outreach',
|
||||
@@ -695,6 +939,40 @@
|
||||
).join('');
|
||||
}
|
||||
|
||||
/* ── Interactive Checkboxes ────────────────── */
|
||||
function getNeeds() {
|
||||
try {
|
||||
const saved = localStorage.getItem("derez-needs");
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved);
|
||||
return NEEDS.map(def => {
|
||||
const s = parsed.find(p => p.id === def.id);
|
||||
return s ? { ...def, done: s.done } : def;
|
||||
});
|
||||
}
|
||||
} catch(e) {}
|
||||
return NEEDS;
|
||||
}
|
||||
|
||||
function toggleNeed(id) {
|
||||
const needs = getNeeds();
|
||||
const idx = needs.findIndex(n => n.id === id);
|
||||
if (idx === -1) return;
|
||||
needs[idx].done = !needs[idx].done;
|
||||
localStorage.setItem("derez-needs", JSON.stringify(needs));
|
||||
renderNeeds(needs);
|
||||
}
|
||||
|
||||
function renderNeeds(needs) {
|
||||
const list = document.getElementById("needs-list");
|
||||
list.innerHTML = needs.map(n => `
|
||||
<li class="need-item${n.done ? ' done' : ''}">
|
||||
<span class="need-checkbox${n.done ? ' checked' : ''}" data-id="${n.id}" onclick="toggleNeed('${n.id}')"></span>
|
||||
<span class="need-text">${n.text}</span>
|
||||
</li>
|
||||
`).join("");
|
||||
}
|
||||
|
||||
function renderStrategy() {
|
||||
document.getElementById('strategy-grid').innerHTML = strategyCards.map(s =>
|
||||
`<div class="strategy-card">
|
||||
@@ -757,10 +1035,12 @@
|
||||
} catch { /* use defaults */ }
|
||||
}
|
||||
|
||||
/* ── Init ──────────────────────────────────── */
|
||||
document.getElementById('brief-date').textContent = fmtDate();
|
||||
renderGoals();
|
||||
renderCampaigns();
|
||||
renderActions();
|
||||
renderNeeds(getNeeds());
|
||||
renderCommunications();
|
||||
renderStrategy();
|
||||
fetchLiveData();
|
||||
|
||||
Reference in New Issue
Block a user