Sessions 5-7a: 955 tests, deployment ready

This commit is contained in:
Kev
2026-06-08 18:35:13 -04:00
parent 06b82624a2
commit 1fa04dc776
371 changed files with 49366 additions and 955 deletions
+4
View File
@@ -0,0 +1,4 @@
Contact: mailto:security@vyndr.xyz
Expires: 2027-05-28T00:00:00.000Z
Preferred-Languages: en
Canonical: https://vyndr.xyz/.well-known/security.txt
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

+22
View File
@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="VYNDR">
<defs>
<linearGradient id="vy" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#00FFB8"/>
<stop offset="100%" stop-color="#00D4A0"/>
</linearGradient>
<filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur stdDeviation="1.6"/>
</filter>
</defs>
<rect width="64" height="64" rx="12" fill="#06060B"/>
<g stroke="url(#vy)" stroke-linecap="round" fill="none">
<g filter="url(#glow)" opacity="0.55">
<line x1="14" y1="14" x2="32" y2="34" stroke-width="6"/>
<line x1="32" y1="34" x2="32" y2="52" stroke-width="6"/>
<line x1="6" y1="58" x2="58" y2="6" stroke-width="6"/>
</g>
<line x1="14" y1="14" x2="32" y2="34" stroke-width="6"/>
<line x1="32" y1="34" x2="32" y2="52" stroke-width="6"/>
<line x1="6" y1="58" x2="58" y2="6" stroke-width="5.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

+17
View File
@@ -0,0 +1,17 @@
{
"name": "VYNDR",
"short_name": "VYNDR",
"description": "Grade your props with intelligence the books don't want you to have.",
"start_url": "/dashboard",
"scope": "/",
"display": "standalone",
"background_color": "#06060B",
"theme_color": "#06060B",
"orientation": "portrait-primary",
"icons": [
{ "src": "/favicon.svg", "sizes": "any", "type": "image/svg+xml" },
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icons/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

+44
View File
@@ -0,0 +1,44 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0E0E16"/>
<stop offset="100%" stop-color="#06060B"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="40%" r="60%">
<stop offset="0%" stop-color="rgba(0,212,160,0.16)"/>
<stop offset="100%" stop-color="rgba(0,212,160,0)"/>
</radialGradient>
<pattern id="scan" width="4" height="4" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="1200" y2="0" stroke="rgba(255,255,255,0.04)" stroke-width="1"/>
</pattern>
</defs>
<rect width="1200" height="630" fill="url(#bg)"/>
<rect width="1200" height="630" fill="url(#glow)"/>
<rect width="1200" height="630" fill="url(#scan)"/>
<!-- Wordmark -->
<g font-family="'IBM Plex Mono','JetBrains Mono',monospace" font-weight="800" letter-spacing="8">
<text x="600" y="280" text-anchor="middle" font-size="140" fill="#E8E8F0">VYND</text>
<text x="780" y="280" text-anchor="middle" font-size="140" fill="#00D4A0" style="filter:drop-shadow(0 0 24px rgba(0,212,160,0.6))">R</text>
</g>
<!-- Tagline -->
<text x="600" y="360" text-anchor="middle" font-family="'Instrument Sans',system-ui,sans-serif" font-size="28" font-weight="600" fill="#E8E8F0">
The books have every advantage.
</text>
<text x="600" y="400" text-anchor="middle" font-family="'Instrument Sans',system-ui,sans-serif" font-size="28" font-weight="600" fill="#00D4A0">
We built this to give it back.
</text>
<!-- Example A- grade card -->
<g transform="translate(490 460)">
<rect width="220" height="110" rx="12" fill="#0E0E16" stroke="#1E1E2E"/>
<text x="20" y="35" font-family="'IBM Plex Mono',monospace" font-size="11" letter-spacing="2" fill="#7A7A8E">NBA · JOKIC · PTS</text>
<text x="200" y="90" text-anchor="end" font-family="'IBM Plex Mono',monospace" font-weight="800" font-size="64" fill="#00D4A0" style="filter:drop-shadow(0 0 16px rgba(0,212,160,0.7))">A-</text>
</g>
<!-- Built in Detroit stamp -->
<text x="600" y="600" text-anchor="middle" font-family="'IBM Plex Mono',monospace" font-size="14" letter-spacing="6" fill="#4A4A5E">
BUILT IN DETROIT · VYNDR.XYZ
</text>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+2
View File
File diff suppressed because one or more lines are too long
+158
View File
@@ -0,0 +1,158 @@
/* VYNDR embeddable widget — single self-contained file, ~3.5 KB minified.
*
* <script src="https://vyndr.app/widget.js" data-sport="nba" data-theme="dark"></script>
*
* Mounts a 300px card at the script tag's location, refreshes every 30
* minutes, links each grade to https://vyndr.app (new tab). Two themes:
* dark (default), light.
*/
(function () {
'use strict';
var SCRIPT = document.currentScript;
if (!SCRIPT) {
var all = document.getElementsByTagName('script');
for (var i = all.length - 1; i >= 0; i--) {
if (/widget\.js(\?|$)/.test(all[i].src)) { SCRIPT = all[i]; break; }
}
}
if (!SCRIPT) return;
var SPORT = (SCRIPT.getAttribute('data-sport') || 'nba').toLowerCase();
var THEME = (SCRIPT.getAttribute('data-theme') || 'dark').toLowerCase();
if (['nba', 'wnba', 'mlb'].indexOf(SPORT) < 0) SPORT = 'nba';
if (['dark', 'light'].indexOf(THEME) < 0) THEME = 'dark';
var API = (SCRIPT.getAttribute('data-api') || 'https://api.vyndr.app') + '/api/widget';
var REFRESH_MS = 30 * 60 * 1000;
// ── styles ─────────────────────────────────────────────────────────────
var PALETTE = THEME === 'light' ? {
bg: '#FFFFFF', border: '#E5E5EC', text: '#0E0E16',
textDim: '#4A4A5E', accent: '#0F3D2E',
} : {
bg: '#06060B', border: '#1E1E2E', text: '#E8E8F0',
textDim: '#7A7A8E', accent: '#00D4A0',
};
var GRADE_COLORS = {
'A+': '#00FFB8', 'A': '#00D4A0', 'A-': '#00D4A0',
'B+': '#4A9EFF', 'B': '#4A9EFF', 'B-': '#4A9EFF',
'C+': '#FFB347', 'C': '#FFB347', 'C-': '#FFB347',
'D': '#FF5252', 'F': '#FF5252',
};
function el(tag, css, text) {
var n = document.createElement(tag);
if (css) n.style.cssText = css;
if (text != null) n.textContent = text;
return n;
}
function gradeColor(g) { return GRADE_COLORS[g] || PALETTE.textDim; }
// ── mount ─────────────────────────────────────────────────────────────
var host = el('div', [
'box-sizing:border-box',
'width:300px',
'background:' + PALETTE.bg,
'color:' + PALETTE.text,
'border:1px solid ' + PALETTE.border,
'border-radius:14px',
'padding:16px',
'font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",sans-serif',
'font-size:14px',
'line-height:1.4',
].join(';') + ';');
host.setAttribute('data-vyndr-widget', SPORT);
var header = el('div', 'display:flex;justify-content:space-between;align-items:baseline;margin-bottom:10px;');
var brand = el('span', 'font-family:"IBM Plex Mono","JetBrains Mono","SF Mono",ui-monospace,monospace;font-weight:800;letter-spacing:2px;color:' + PALETTE.text + ';');
brand.appendChild(document.createTextNode('VYND'));
var r = el('span', 'color:' + PALETTE.accent + ';text-shadow:0 0 6px rgba(0,212,160,.45);', 'R');
brand.appendChild(r);
header.appendChild(brand);
header.appendChild(el('span', 'font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:2px;color:' + PALETTE.textDim + ';', 'TOP ' + SPORT.toUpperCase()));
host.appendChild(header);
var list = el('div', '');
host.appendChild(list);
var footer = el('div', 'margin-top:12px;font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:2px;color:' + PALETTE.textDim + ';text-align:center;');
var foot = el('a', 'color:inherit;text-decoration:none;');
foot.href = 'https://vyndr.app';
foot.target = '_blank';
foot.rel = 'noopener noreferrer';
foot.textContent = 'Powered by VYNDR · vyndr.app';
footer.appendChild(foot);
host.appendChild(footer);
if (SCRIPT.parentNode) SCRIPT.parentNode.insertBefore(host, SCRIPT);
// ── render ────────────────────────────────────────────────────────────
function row(g) {
var a = el('a', [
'display:flex',
'justify-content:space-between',
'align-items:center',
'padding:10px 12px',
'margin-bottom:6px',
'border-radius:8px',
'text-decoration:none',
'color:' + PALETTE.text,
'border:1px solid ' + PALETTE.border,
'background:' + (THEME === 'light' ? '#F8F8FC' : '#0E0E16'),
].join(';') + ';');
a.href = 'https://vyndr.app';
a.target = '_blank';
a.rel = 'noopener noreferrer';
var left = el('div', 'min-width:0;');
var name = el('div', 'font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;', String(g.player || ''));
var sub = el('div', 'font-family:"IBM Plex Mono",monospace;font-size:11px;color:' + PALETTE.textDim + ';',
[g.stat || '', String(g.direction || '').toUpperCase(), g.line ?? ''].join(' '));
left.appendChild(name);
left.appendChild(sub);
var grade = el('div', [
'font-family:"IBM Plex Mono",monospace',
'font-weight:800',
'font-size:22px',
'margin-left:8px',
'color:' + gradeColor(g.grade),
'text-shadow:0 0 6px ' + gradeColor(g.grade) + '55',
].join(';') + ';', String(g.grade || ''));
a.appendChild(left);
a.appendChild(grade);
return a;
}
function setError(msg) {
list.innerHTML = '';
var p = el('div', 'padding:10px 0;color:' + PALETTE.textDim + ';font-size:12px;', msg);
list.appendChild(p);
}
function fetchAndRender() {
var url = API + '?sport=' + encodeURIComponent(SPORT) + '&_=' + Date.now();
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.timeout = 8000;
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return;
if (xhr.status < 200 || xhr.status >= 300) return setError('Signal unavailable. Try later.');
try {
var data = JSON.parse(xhr.responseText);
list.innerHTML = '';
var props = (data && data.props) || [];
if (!props.length) return setError('No grades on the slate yet.');
for (var i = 0; i < props.length; i++) list.appendChild(row(props[i]));
} catch (e) { setError('Could not parse response.'); }
};
xhr.ontimeout = function () { setError('Signal timed out.'); };
xhr.send();
}
fetchAndRender();
setInterval(fetchAndRender, REFRESH_MS);
})();