README / index.html
appvoid's picture
Update index.html
f344053 verified
Raw History Blame Contribute Delete
13.8 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Dot Labs</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
background: #000;
color: #f5f5f7;
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
}
.card {
position: relative;
isolation: isolate;
overflow: hidden;
width: min(100%, 720px);
min-height: 480px;
padding: clamp(32px, 7vw, 64px);
display: flex;
flex-direction: column;
justify-content: space-between;
background: #000; /* PURE BLACK — no gradients, overlays or colored fog */
border: 1px solid #1c1c1e;
border-radius: 28px;
}
canvas.grain {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 0;
pointer-events: none;
display: block;
}
.card > :not(canvas) { position: relative; z-index: 1; }
.logo { font-size: 15px; font-weight: 600; letter-spacing: -0.02em; }
main { max-width: 580px; }
h1 {
margin: 0;
font-size: clamp(16px, 5vw, 32px);
line-height: 0.98;
font-weight: 550;
letter-spacing: -0.06em;
}
p, a {
margin: 28px 0 0;
max-width: 520px;
color: #8e8e93;
font-size: clamp(17px, 2vw, 20px);
line-height: 1.5;
letter-spacing: -0.02em;
}
footer { color: #555; font-size: 11px; letter-spacing: 0.04em; }
/* Partners: each identity is a single, non-wrapping icon + name row. */
.partners {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12px;
margin: 0 0 17px;
padding-top: 17px;
border-top: 1px solid rgba(255,255,255,.105);
}
.partners-label {
margin: 0;
color: #68686b;
font-size: 10px;
font-weight: 600;
letter-spacing: .16em;
text-transform: uppercase;
line-height: 1;
}
.partner-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
width: 100%;
}
.partner-link {
display: inline-flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: nowrap;
gap: 10px;
min-width: 153px;
min-height: 43px;
padding: 6px 10px 6px 7px;
margin: 0;
background: rgba(255,255,255,.026);
border: 1px solid rgba(255,255,255,.105);
border-radius: 9px;
color: #d7d7d9;
text-decoration: none;
font-size: 12px;
font-weight: 550;
letter-spacing: -.015em;
line-height: 1;
transition: border-color .2s ease, background .2s ease, color .2s ease;
}
.partner-link:hover,
.partner-link:focus-visible {
background: rgba(255,255,255,.055);
border-color: rgba(255,255,255,.26);
color: #fff;
outline-offset: 3px;
}
.partner-icon {
position: relative;
display: grid;
place-items: center;
width: 29px;
height: 29px;
min-width: 29px;
flex: 0 0 29px;
overflow: hidden;
background: #1a1a1c;
border: 1px solid #29292d;
border-radius: 6px;
color: #c9c9cc;
font-size: 13px;
font-weight: 700;
line-height: 1;
letter-spacing: 0;
}
.partner-icon img {
position: absolute;
width: 100%;
height: 100%;
inset: 0;
border-radius: inherit;
object-fit: cover;
}
.partner-name { white-space: nowrap; }
.partner-arrow {
display: inline-block;
margin-left: auto;
color: #77777b;
font-size: 14px;
line-height: 1;
transition: transform .2s ease, color .2s ease;
}
.partner-link:hover .partner-arrow { color: #cfcfd2; transform: translate(1px,-1px); }
.disclaimer { color: #555; font-size: 10px; line-height: 1.6; letter-spacing: .018em; }
@media (max-width: 600px) {
body { padding: 14px; }
.card {
min-height: calc(100vh - 28px);
padding: 28px 24px;
border-radius: 22px;
}
}
</style>
</head>
<body>
<section class="card">
<canvas class="grain" aria-hidden="true"></canvas>
<div class="logo">D●t Labs</div>
<main>
<h1>Intelligence<br>from the byte up.</h1>
<p>
Independent AI research exploring multimodal,
byte-level intelligence and simpler foundations
for increasingly general models.
</p>
<br/>
<a style="font-size: 14px" href="https://huggingface.co/spaces/dotlabs/README/discussions/1">Click here to learn on how to join!</a>
</main>
<footer>
<div class="partners" aria-label="Partners">
<div class="partners-label">Partners</div>
<div class="partner-list">
<a class="partner-link" href="https://huggingface.co/SurjoLabs" target="_blank" rel="noopener noreferrer" aria-label="Visit SurjoLabs on Hugging Face">
<span class="partner-icon" aria-hidden="true">
<span>S</span>
<img src="https://huggingface.co/api/organizations/SurjoLabs/avatar?redirect=true" alt="" loading="lazy" referrerpolicy="no-referrer" onerror="this.style.display='none'">
</span>
<span class="partner-name">SurjoLabs</span>
<span class="partner-arrow" aria-hidden="true">↗</span>
</a>
<a class="partner-link" href="https://huggingface.co/AxiomicLabs" target="_blank" rel="noopener noreferrer" aria-label="Visit AxiomicLabs on Hugging Face">
<span class="partner-icon" aria-hidden="true">
<span>B</span>
<img src="https://huggingface.co/api/organizations/AxiomicLabs/avatar?redirect=true" alt="" loading="lazy" referrerpolicy="no-referrer" onerror="this.style.display='none'">
</span>
<span class="partner-name">AxiomicLabs</span>
<span class="partner-arrow" aria-hidden="true">↗</span>
</a>
</div>
</div>
<div class="disclaimer">Dot Labs™ is not related in any way to OpenAI's Dot product nor SpaceXAI web domain.</div>
</footer>
</section>
<script>
(() => {
// Feel free to tune these; everything is native Canvas, no dependencies.
const SETTINGS = {
style: 'drift',
seed: 137,
opacity: 1.0, // Grain visibility
size: 1.0, // Overall dot size
speed: 1.0 // Animation speed; 0 = frozen
};
const card = document.querySelector('.card');
const canvas = document.querySelector('canvas.grain');
const ctx = canvas.getContext('2d', { alpha: true });
if (!ctx) return;
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
const PI2 = Math.PI * 2;
const gaussian = (x) => Math.exp(-x*x * .5);
const clamp = (x, a=0, b=1) => Math.max(a, Math.min(b, x));
const fract = x => x - Math.floor(x);
let particles = [], width=0, height=0, dpr=1, frame=0, then=0, elapsed=0, active=true;
function rng(seed) {
return () => {
let t = seed += 0x6D2B79F5;
t = Math.imul(t ^ t >>> 15, t | 1);
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
return ((t ^ t >>> 14) >>> 0) / 4294967296;
};
}
function concentration(x, y) {
if (SETTINGS.style === 'drift') {
return clamp(.28 + .34*x + .22*gaussian((x-.78)/.28)*gaussian((y-.43)/.47));
}
if (SETTINGS.style === 'nebula') {
const cloud = gaussian((x-.72)/.23)*gaussian((y-.41-.09*Math.sin(x*7))/.21);
const plume = gaussian((x-.53)/.29)*gaussian((y-.72)/.16);
return clamp(.055 + .88*cloud + .34*plume);
}
if (SETTINGS.style === 'eclipse') {
const r = Math.hypot((x-.72)/.43, (y-.48)/.60);
return clamp(.045 + .88*gaussian((r-.77)/.19));
}
const path = .80 - .53*x + .046*Math.sin(9*x);
return clamp(.07 + .89*gaussian((y-path)/.125) * (.35+.65*x));
}
// Larger dots progressively emerge across each pattern, without any
// solid gray gradient. Only individual particles carry color.
function sizeProgress(x, y) {
if (SETTINGS.style === 'eclipse') {
return clamp(.07 + .93*x);
}
if (SETTINGS.style === 'nebula') {
return clamp(.06 + .78*x + .17*y);
}
return clamp(.04 + .96*x);
}
function rebuild() {
const rect = card.getBoundingClientRect();
width = rect.width;
height = rect.height;
if (!width || !height) return;
dpr = Math.min(window.devicePixelRatio || 1, 2);
canvas.width = Math.round(width*dpr);
canvas.height = Math.round(height*dpr);
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
const random = rng(SETTINGS.seed);
const area = width*height;
particles = [];
const count = Math.floor(area / (SETTINGS.style === 'nebula' ? 13 : 15));
for (let i=0; i<count; i++) {
const x=random(), y=random();
const c = concentration(x,y);
if (random()>c) continue;
const growth = sizeProgress(x,y);
const isFine = random() < .76;
let radius;
let alpha;
if (isFine) {
radius=(.13 + .15*random() + .12*growth)*SETTINGS.size;
alpha=(.17 + .34*random()) * (.71+.29*c);
} else {
// A few larger grains emerge gently, but all remain subpixel-to-1px dust.
radius=(.19 + .66*Math.pow(growth,1.9)) * (.47+.53*random())*SETTINGS.size;
alpha=(.18 + .42*random())*(.70+.30*c);
}
// Occasional slightly larger isolated grains in the denser region.
if (random()<.008 && growth>.60) radius*=1.18;
const shade = Math.floor(139 + random()*75);
particles.push({x,y,radius,alpha,shade,phase:random()*PI2,
velocity:.42+random()*1.25,depth:random(),offset:0});
}
// The quiet microdust layer fills dark negative space at tiny sizes.
const fineCount = Math.floor(area / 21);
for (let i=0; i<fineCount; i++) {
const x=random(), y=random();
const density = concentration(x,y);
if (random() > .42+.36*density) continue;
const shade=Math.floor(140+random()*73);
particles.push({x,y,radius:(.12+.16*random())*SETTINGS.size,
alpha:(.16+.19*random())* (.67+.33*density),
shade,phase:random()*PI2,velocity:.24+random()*.75,
depth:random(),offset:0});
}
draw(0);
}
function position(p, t) {
const x=p.x, y=p.y;
if (SETTINGS.style === 'drift') {
// Low, steady breeze; different velocity at every dust depth.
return [fract(x+t*(3.5+4.2*p.velocity)/width),
y + 1.6*Math.sin(t*.49+p.phase)/height];
}
if (SETTINGS.style === 'nebula') {
// A barely rotating, breathing cloud of gray points.
const dx=(x-.68)*width, dy=(y-.48)*height;
const theta=t*(.003+.006*p.velocity);
const cos=Math.cos(theta), sin=Math.sin(theta);
return [.68 + (dx*cos-dy*sin+2.1*Math.sin(t*.31+p.phase))/width,
.48 + (dx*sin+dy*cos+2.0*Math.cos(t*.33+p.phase))/height];
}
if (SETTINGS.style === 'eclipse') {
// Subtle orbital travel around the ring; no fog or glow.
const dx=(x-.72)*width, dy=(y-.48)*height;
const angle=t*(.009+.006*p.velocity);
const rx=Math.cos(angle)*dx-Math.sin(angle)*dy*.78;
const ry=Math.sin(angle)*dx/ .78+Math.cos(angle)*dy;
return [.72+rx/width,.48+ry/height];
}
// Stream moves diagonally upward along a curved path.
const nx=fract(x+t*(4.0+5.5*p.velocity)/width);
const oldPath=.80-.53*x+.046*Math.sin(9*x);
const newPath=.80-.53*nx+.046*Math.sin(9*nx);
return [nx, newPath + (y-oldPath) + 1.8*Math.sin(t*.50+p.phase)/height];
}
function draw(t) {
ctx.clearRect(0,0,width,height);
for (const p of particles) {
const [nx,ny]=position(p,t);
if (nx<0 || nx>1 || ny<0 || ny>1) continue;
const shimmer=.91+.09*Math.sin(t*.67+p.phase);
const a=clamp(p.alpha*shimmer*SETTINGS.opacity);
ctx.fillStyle=`rgba(${p.shade},${p.shade},${p.shade},${a})`;
ctx.beginPath();
ctx.arc(nx*width,ny*height,p.radius,0,PI2);
ctx.fill();
}
}
function stop() {
cancelAnimationFrame(frame);
frame=0;
then=0;
}
function tick(now) {
if (!active || reducedMotion.matches) { stop(); return; }
if (then) elapsed+=Math.min((now-then)/1000,.05)*SETTINGS.speed;
then=now;
// Max ~25fps to keep the denser microdust field lightweight.
if (!tick.drawn || now-tick.drawn>=40) {
draw(elapsed);
tick.drawn=now;
}
frame=requestAnimationFrame(tick);
}
function updateRunning() {
stop();
if (active && !reducedMotion.matches) frame=requestAnimationFrame(tick);
else draw(elapsed);
}
document.addEventListener('visibilitychange',()=> {
active=!document.hidden;
updateRunning();
});
reducedMotion.addEventListener('change', updateRunning);
new ResizeObserver(rebuild).observe(card);
rebuild();
updateRunning();
})();
</script>
</body>
</html>