1896b707f8
Twelve narrated walkthroughs, one per Suite tool, in Marty's cloned voice. No screen recording involved: Playwright drives and records the real UI, ElevenLabs narrates, ffmpeg muxes. Pipeline lives outside this repo at ../video-pipeline. Placement (Marty's call): TOP of each tool page but COLLAPSED — a one-line "Watch the walkthrough" bar that auto-opens on a member's first visit to that specific tool and stays shut after. A video in a separate library never gets watched; an embedded player pushes the tool below the fold on mobile for every returning member. First-visit autoplay is muted, so it is never a surprise noise, and every localStorage access is guarded because it throws outright in private windows. Served from the data volume via /tv/<slug>.mp4, NOT from public/. That directory is already 199MB and another 33MB of MP4 would ride along on every deploy forever; this way a video can also be re-cut and dropped in without a rebuild. The route implements HTTP range requests — without them the scrub bar renders but cannot seek, which looks broken in a way people rarely report. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
104 lines
7.9 KiB
HTML
104 lines
7.9 KiB
HTML
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="robots" content="noindex"><meta name="description" content="Traffic Desk — put a team banner on our own ad network, pointed at your invite link. Monthly impressions included with your position."><title>Traffic Desk | The Circle Suite</title><link rel="icon" type="image/png" href="/favicon.png"><link rel="stylesheet" href="/styles.css">
|
|
<style>
|
|
.tw{max-width:940px;margin:0 auto;padding:24px 20px 70px}
|
|
.tw h1{font-size:clamp(26px,4.5vw,36px);margin:6px 0 8px}
|
|
.tw .lede{color:var(--muted);line-height:1.6;margin-bottom:18px}
|
|
#tfGate{display:none;border:2px solid var(--gold);border-radius:12px;padding:16px 20px;margin-bottom:18px;line-height:1.6}
|
|
.tf-bal{display:flex;gap:18px;flex-wrap:wrap;align-items:center;border:2px solid var(--teal);border-radius:14px;padding:14px 18px;margin-bottom:18px}
|
|
.tf-bal .big{font-size:30px;font-weight:900;color:var(--gold);font-variant-numeric:tabular-nums;line-height:1}
|
|
.tf-bal .lab{font-size:12px;font-weight:800;letter-spacing:1.4px;text-transform:uppercase;color:var(--muted);margin-top:3px}
|
|
.tf-bal .note{color:var(--muted);font-size:13px;line-height:1.5;flex:1;min-width:220px}
|
|
.tf-card{background:var(--card,#0d2236);border:1px solid var(--line,#24425d);border-radius:14px;padding:18px 20px;margin-bottom:16px}
|
|
label.tf-lab{display:block;font-weight:700;font-size:14px;margin:14px 0 6px}
|
|
label.tf-lab:first-of-type{margin-top:0}
|
|
.tf-chips{display:flex;flex-wrap:wrap;gap:8px}
|
|
.tf-chip{border:1px solid var(--line);background:transparent;color:var(--muted);border-radius:999px;
|
|
padding:7px 14px;font-size:13.5px;font-weight:700;cursor:pointer}
|
|
.tf-chip.on{border-color:var(--teal);background:rgba(78,214,203,.12);color:var(--teal)}
|
|
.tf-creatives{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px}
|
|
.tf-cre{border:2px solid var(--line);border-radius:10px;padding:6px;cursor:pointer;background:var(--bg,#0b1d2e);line-height:0}
|
|
.tf-cre.on{border-color:var(--gold)}
|
|
.tf-cre img{max-width:230px;max-height:120px;width:auto;height:auto;display:block}
|
|
#tfImp{width:150px;background:var(--bg,#0b1d2e);border:1px solid var(--line);border-radius:10px;color:var(--text);padding:10px 12px;font-size:15px}
|
|
.tf-hint{color:var(--muted);font-size:12.5px;margin-top:6px}
|
|
.tf-row{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:16px}
|
|
#tfErr{display:none;color:#f0a05a;margin-top:12px;font-size:14px;line-height:1.55}
|
|
#tfOk{display:none;border:2px solid var(--teal);border-radius:12px;padding:14px 18px;margin-top:14px;line-height:1.6}
|
|
.tf-live{margin-top:22px}
|
|
.tf-live table{width:100%;border-collapse:collapse;font-size:14px}
|
|
.tf-live th{text-align:left;padding:8px 10px;font-size:11px;letter-spacing:1px;text-transform:uppercase;color:var(--muted);border-bottom:2px solid var(--line)}
|
|
.tf-live td{padding:9px 10px;border-bottom:1px solid var(--line);color:var(--muted);font-variant-numeric:tabular-nums}
|
|
.tf-live td b{color:var(--text)}
|
|
.tf-ads{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:10px;margin-top:14px}
|
|
.tf-ad{border:2px solid var(--line);border-radius:10px;padding:12px 13px;cursor:pointer;
|
|
background:var(--bg,#0b1d2e);transition:border-color .12s}
|
|
.tf-ad:hover{border-color:var(--muted)}
|
|
.tf-ad.on{border-color:var(--gold);background:rgba(212,175,55,.07)}
|
|
.tf-ad .s{font-weight:800;font-size:15px;color:var(--gold);line-height:1.25;margin-bottom:5px;word-break:break-word}
|
|
.tf-ad .l{font-size:13px;line-height:1.5;color:var(--text);word-break:break-word}
|
|
.tf-ad .cnt{margin-top:8px;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
|
|
.tf-note{margin-top:22px;font-size:12.5px;color:var(--muted);line-height:1.6;border-top:1px solid var(--line);padding-top:12px}
|
|
.spin{display:inline-block;width:13px;height:13px;border:2px solid rgba(255,255,255,.25);border-top-color:var(--gold);
|
|
border-radius:50%;animation:sp .8s linear infinite;vertical-align:-2px;margin-right:7px}
|
|
@keyframes sp{to{transform:rotate(360deg)}}
|
|
@media (prefers-reduced-motion:reduce){.spin{animation:none}}
|
|
</style></head>
|
|
<body>
|
|
<header class="wrap nav"><a class="brand" href="/suite"><img class="brand-mark" src="/logo.jpg" alt="The RM Circle" width="42" height="42"><span><span id="brandName">RM Circle</span><small>Traffic Desk</small></span></a><div class="nav-actions"><a class="btn btn-secondary hide-mobile" href="/suite">← The Suite</a><a class="btn btn-primary" href="/my">My Dashboard</a></div></header>
|
|
<main class="tw">
|
|
<div class="eyebrow" style="color:var(--gold)">CIRCLE SUITE · INCLUDED AT EVERY PAID LEVEL</div>
|
|
<h1>Traffic <span class="gold">Desk.</span></h1>
|
|
<p class="lede">Run a team banner or an AI-written text ad on our own advertising network, pointed at your invite link. Impressions are included with your position and scale as you level up — nothing to buy, nothing to configure.</p>
|
|
|
|
<div id="tfGate"></div>
|
|
|
|
<div class="tf-bal" id="tfBal" style="display:none">
|
|
<div><div class="big" id="tfRemain">—</div><div class="lab">impressions left this month</div></div>
|
|
<div><div class="big" id="tfLimit" style="color:var(--teal)">—</div><div class="lab">your monthly allowance</div></div>
|
|
<div class="note" id="tfNote"></div>
|
|
</div>
|
|
|
|
<div class="tf-card" id="tfCard">
|
|
<label class="tf-lab">Ad format</label>
|
|
<div class="tf-chips" id="tfFormat"></div>
|
|
|
|
<div id="tfBannerPane">
|
|
<label class="tf-lab">Banner size</label>
|
|
<div class="tf-chips" id="tfSizes"></div>
|
|
<label class="tf-lab">Pick a design</label>
|
|
<div class="tf-creatives" id="tfCreatives"></div>
|
|
</div>
|
|
|
|
<div id="tfTextPane" style="display:none">
|
|
<label class="tf-lab">What angle should they take?</label>
|
|
<div class="tf-chips" id="tfAngles"></div>
|
|
<div class="tf-row">
|
|
<button id="tfWrite" class="btn btn-secondary">✍️ Write me 5 ads</button>
|
|
<span class="tf-hint" id="tfWriteMeter" style="margin:0"></span>
|
|
</div>
|
|
<div id="tfVariants"></div>
|
|
</div>
|
|
<label class="tf-lab">Where should it send people?</label>
|
|
<div class="tf-chips" id="tfTargets"></div>
|
|
<label class="tf-lab" for="tfImp">How many impressions?</label>
|
|
<input type="number" id="tfImp" min="100" step="100" value="2500">
|
|
<div class="tf-hint">Comes out of this month's allowance. It refills on the 1st.</div>
|
|
<div class="tf-row">
|
|
<button id="tfGo" class="btn btn-primary">🚦 Launch my banner</button>
|
|
</div>
|
|
<div id="tfErr"></div>
|
|
<div id="tfOk"></div>
|
|
</div>
|
|
|
|
<div class="tf-live" id="tfLiveWrap" style="display:none">
|
|
<h2 style="font-size:20px;margin:0 0 8px">Your running banners</h2>
|
|
<div class="table-wrap"><table><thead><tr><th>Size</th><th>Sends to</th><th>Bought</th><th>Served</th><th>Left</th><th>Clicks</th><th>Status</th><th></th></tr></thead><tbody id="tfLive"></tbody></table></div>
|
|
</div>
|
|
|
|
<p class="tf-note"><strong style="color:var(--text)">What this is, honestly:</strong> display advertising is <strong style="color:var(--text)">awareness volume</strong> — it puts your link in front of people browsing the network. It is not a lead list, and click rates on display inventory are low by nature. The conversations you have with people you know are still what actually builds a team; this runs quietly in the background while you do that. <br><br>All banners use approved team creative, so every ad on the network stays on-brand. Independent team resource · No income is guaranteed · Cryptocurrency involves risk.</p>
|
|
</main>
|
|
<script src="/suite-traffic.js"></script>
|
|
<script src="/tool-video.js" data-video="/tv/suite-traffic-desk.mp4" data-title="Watch the Traffic Desk walkthrough" data-key="traffic" defer></script>
|
|
<script src="/chat.js" defer></script>
|
|
<script src="/translate.js" defer></script><script src="/tg-app.js" defer></script><script src="/nav-dash.js" defer></script></body></html>
|