rebrand: Studio design system — near-black base, Signal Lime + Agent Violet accents, Inter/Space Grotesk/JetBrains Mono fonts
This commit is contained in:
+45
-35
@@ -15,19 +15,26 @@
|
||||
<meta property="og:description" content="Dev logs, behind-the-scenes, and lessons learned from building games, tools, and platform at Tinqs Studio.">
|
||||
<meta property="og:image" content="https://www.tinqs.com/img/og-cover.jpg">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained index styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — index styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -35,9 +42,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -45,12 +53,12 @@
|
||||
/* ── Section label kicker ── */
|
||||
.section-label {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -63,15 +71,16 @@
|
||||
padding: 60px 24px 32px;
|
||||
}
|
||||
|
||||
/* ── Gradient index title ── */
|
||||
/* ── Gradient index title — lime → violet ── */
|
||||
.blog-header__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.4rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
@@ -96,36 +105,37 @@
|
||||
.blog-card {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
background: #0c1119;
|
||||
background: var(--c-bg-raised);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 12px;
|
||||
border-radius: 8px;
|
||||
padding: 20px 24px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.blog-card:hover {
|
||||
border-color: var(--c-accent);
|
||||
border-color: var(--c-lime);
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.blog-card__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.blog-card__title {
|
||||
color: var(--c-text);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.35;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
color: var(--c-fg);
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.3;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
@@ -138,13 +148,13 @@
|
||||
|
||||
/* ── Read link accent ── */
|
||||
.blog-card__read {
|
||||
color: var(--c-blue);
|
||||
font-size: 0.9rem;
|
||||
color: var(--c-lime);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.blog-card:hover .blog-card__read {
|
||||
color: var(--c-purple);
|
||||
color: var(--c-violet);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
Before
After
|
+64
-52
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
Before
After
|
+66
-54
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -294,7 +306,7 @@ LangChain, CrewAI, and AutoGen are built for web apps. They assume text-in, text
|
||||
|
||||
## The toolchain that makes it work
|
||||
|
||||
Our harness runs on <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a>, built on a Gitea fork with game-specific features. The key pieces:
|
||||
Our harness runs on <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>, built on a Gitea fork with game-specific features. The key pieces:
|
||||
|
||||
<strong>The CLI</strong> — a single Go binary. One command (<code>tinqs identity</code>) gives the agent full project context in 100ms. Screenshots, cloud vision, health checks — all subcommands of the same binary.
|
||||
|
||||
@@ -327,7 +339,7 @@ We're betting that specialised harnesses beat generic ones. A harness built for
|
||||
|
||||
—
|
||||
|
||||
<em>Tinqs Studio is an agent harness for game development — git hosting, AI agents, creative pipelines. Open for teams. We're building <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a> with the same tools.</em></p>
|
||||
<em>Tinqs Studio is an agent harness for game development — git hosting, AI agents, creative pipelines. Open for teams. We're building <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a> with the same tools.</em></p>
|
||||
|
||||
<div class="post__body">
|
||||
|
||||
|
||||
|
Before
After
|
+69
-57
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -286,10 +298,10 @@
|
||||
<p>Agents don't just have instructions. They have <strong>skills</strong> — markdown playbooks that teach specific workflows. When someone says "generate concept art for a character," the agent reads <code>skills/image-generation.md</code> and follows the procedure. No prompt engineering per session. No "let me try a different prompt."</p>
|
||||
<p>We've open-sourced several skills:</p>
|
||||
<ul>
|
||||
<li><a href="../skills/image-generation.md" style="color: var(--c-accent-l);">Image Generation with fal.ai</a> — 4-layer prompt pattern that actually produces usable game art</li>
|
||||
<li><a href="../skills/concept-art-pipeline.md" style="color: var(--c-accent-l);">Concept Art Pipeline</a> — full 2D concept → 3D model workflow</li>
|
||||
<li><a href="../skills/tripo-browser-workflow.md" style="color: var(--c-accent-l);">3D Model Generation</a> — Tripo Studio text-to-3D</li>
|
||||
<li><a href="../skills/sora2-video.md" style="color: var(--c-accent-l);">Video Generation</a> — trailer clips with Sora 2</li>
|
||||
<li><a href="../skills/image-generation.md" style="color: var(--c-lime);">Image Generation with fal.ai</a> — 4-layer prompt pattern that actually produces usable game art</li>
|
||||
<li><a href="../skills/concept-art-pipeline.md" style="color: var(--c-lime);">Concept Art Pipeline</a> — full 2D concept → 3D model workflow</li>
|
||||
<li><a href="../skills/tripo-browser-workflow.md" style="color: var(--c-lime);">3D Model Generation</a> — Tripo Studio text-to-3D</li>
|
||||
<li><a href="../skills/sora2-video.md" style="color: var(--c-lime);">Video Generation</a> — trailer clips with Sora 2</li>
|
||||
</ul>
|
||||
<p>Each skill took about 30 minutes to write. After six months, our agents have 15+ skills covering art generation, competitive research, video production, and project management. Skills compound — every playbook you write makes every future session more capable.</p>
|
||||
<h2>What the agents actually do, every day</h2>
|
||||
@@ -317,7 +329,7 @@
|
||||
<p><strong>Skills compound exponentially.</strong> One skill saves 15 minutes per session. Fifteen skills save hours per day across the whole team. The investment curve is absurdly favourable — 30 minutes of writing per skill, compounding returns forever.</p>
|
||||
<p>We're four people. With agents doing the mechanical work, we operate like forty. Not because the AI is magic — because we gave it identity, memory, and the right playbooks, and then got out of its way.</p>
|
||||
<hr>
|
||||
<p><em>We're building <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a>, a survival colony sim, using the same agent workflow described here. Everything runs on <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a> — a game dev platform with built-in AI agents, git hosting, and creative pipelines.</em></p>
|
||||
<p><em>We're building <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a>, a survival colony sim, using the same agent workflow described here. Everything runs on <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a> — a game dev platform with built-in AI agents, git hosting, and creative pipelines.</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
Before
After
|
+65
-53
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -303,7 +315,7 @@ Done.</code></pre>
|
||||
<p><strong>Build systems make CSS changes safe.</strong> Because we never hand-edit <code>.html</code>, every style change is tested by regenerating all pages and grepping for the new selectors. If a rule doesn't ship, you know immediately.</p>
|
||||
<p>Two gaps we'll fill later: blockquote support in <code>build.js</code> (the callout CSS is waiting) and ordered lists (same story). In the meantime, the blog already looks intentional — and it took two template files, one build step, and zero dependencies.</p>
|
||||
<hr>
|
||||
<p><em>The blog is generated by <a href="https://tinqs.com/tinqs/blog" style="color: var(--c-accent-l);">build.js</a> and served by <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a>. All styling is self-contained in the templates.</em></p>
|
||||
<p><em>The blog is generated by <a href="https://tinqs.com/tinqs/blog" style="color: var(--c-lime);">build.js</a> and served by <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>. All styling is self-contained in the templates.</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
Before
After
|
@@ -148,7 +148,7 @@ function inline(s) {
|
||||
s = s.replace(/---/g, "—");
|
||||
s = s.replace(/--/g, "–");
|
||||
// Links
|
||||
s = s.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" style="color: var(--c-accent-l);">$1</a>');
|
||||
s = s.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" style="color: var(--c-lime);">$1</a>');
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
+66
-54
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -335,10 +347,10 @@ No extra fingers, no merged limbs, no floating accessories.</code></pre>
|
||||
<p><strong>The design context block is worth more than the rest of the prompt combined.</strong> Without it, every image is a one-off. With it, every image belongs to the same game.</p>
|
||||
<p><strong>Never iterate on expensive models.</strong> Schnell at $0.003/image is for exploration. Flux 2 Pro at $0.03 is for final output. The cheap model does 90% of the creative work.</p>
|
||||
<p><strong>Aggregation beats loyalty.</strong> No single model is best at everything. Flux for art, Ideogram for text, Recraft for design, Nano Banana for edits, BiRefNet for masks. Use the right tool for each job.</p>
|
||||
<p><strong>Let the agent handle prompting.</strong> We encode the 4-layer pattern, art style guide, and model selection rules in an <a href="../skills/image-generation.md" style="color: var(--c-accent-l);">agent skill file</a>. The AI writes the full prompt, generates images, displays them, and asks for scores. The human's job is creative direction.</p>
|
||||
<p><strong>Let the agent handle prompting.</strong> We encode the 4-layer pattern, art style guide, and model selection rules in an <a href="../skills/image-generation.md" style="color: var(--c-lime);">agent skill file</a>. The AI writes the full prompt, generates images, displays them, and asks for scores. The human's job is creative direction.</p>
|
||||
<p>AI art isn't magic and it isn't free. But at a penny per image, with the right prompt structure and model strategy, it eliminates the most expensive bottleneck in indie game development: the gap between "I know what this should look like" and "I have an asset I can actually use."</p>
|
||||
<hr>
|
||||
<p><em>Image generation is built into <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a>. We've open-sourced the <a href="../skills/image-generation.md" style="color: var(--c-accent-l);">prompt engineering skill</a> and <a href="../skills/concept-art-pipeline.md" style="color: var(--c-accent-l);">concept art pipeline skill</a>. We're building <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a> with these tools.</em></p>
|
||||
<p><em>Image generation is built into <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>. We've open-sourced the <a href="../skills/image-generation.md" style="color: var(--c-lime);">prompt engineering skill</a> and <a href="../skills/concept-art-pipeline.md" style="color: var(--c-lime);">concept art pipeline skill</a>. We're building <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a> with these tools.</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
Before
After
|
+65
-53
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -337,7 +349,7 @@ while (!approved) {
|
||||
<p><strong>What's next.</strong> Richer on-card flow display — a pinned step strip so you can see progress without opening the session. Attachable asset and agent-structure viewers in the flow card. Run replay for finished sessions after a page reload (the session persists, but you can't rewatch the stream yet).</p>
|
||||
<p>But the principle is settled. A flow isn't a pipeline. A pipeline runs blind and reports back later. A flow is a pair-programming session where one of the pair happens to be code.</p>
|
||||
<hr>
|
||||
<p><em><a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a> is our agent-native development platform — git hosting, AI agents, and the flow engine described here. <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a> is the survival colony sim we're building with it.</em></p>
|
||||
<p><em><a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a> is our agent-native development platform — git hosting, AI agents, and the flow engine described here. <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a> is the survival colony sim we're building with it.</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
Before
After
|
+68
-56
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -276,7 +288,7 @@
|
||||
<p>Across three forks, we've never touched more than 0.5% of upstream code. If your fork hits 1%, you're doing too much — either the upstream tool is wrong for the job, or you're not trusting it enough.</p>
|
||||
<h2>Fork 1: Gitea → Tinqs Studio</h2>
|
||||
<p>Gitea is a self-hosted git server. Single Go binary, MIT license, 45k GitHub stars. We used GitHub for two years. It was fine for docs. For the game repo — 12GB in LFS, growing weekly — it was untenable. LFS bandwidth limits, slow clones, $5/50GB pricing. And nobody on the team could <strong>see</strong> what changed. A PR modifying a <code>.glb</code> file showed a binary diff. No preview. The artist pushed, the developer approved blindly, and three days later someone noticed the normals were inverted.</p>
|
||||
<p>We forked Gitea and built <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a>. Our changes:</p>
|
||||
<p>We forked Gitea and built <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>. Our changes:</p>
|
||||
<p><strong>3D asset preview.</strong> Click a <code>.glb</code>, <code>.gltf</code>, or <code>.fbx</code> file in a PR and rotate the model in your browser. 22 formats supported via O3DV. This alone transformed our review process — the artist pushes, the lead inspects, nobody downloads anything.</p>
|
||||
<p><strong>HTML file preview.</strong> Sandboxed iframe rendering. Our internal docs and game design pages look like websites, not raw source.</p>
|
||||
<p><strong>Agent API.</strong> Six REST endpoints that let AI agents submit tasks, push code, check CI status, and open PRs. Agents are first-class users of the git platform, not bolt-on tools.</p>
|
||||
@@ -285,7 +297,7 @@
|
||||
<p>Total lines changed: about 2,000 out of Gitea's 500,000. We modify templates, add Go modules, tweak CSS. We <strong>never</strong> touch the database schema — upstream owns that, and we ride their migrations.</p>
|
||||
<p>The alternative was building a git platform from scratch. Multi-year project, multi-million dollar budget. Or using GitHub/GitLab and accepting their limitations. Neither gives you the ability to embed agents directly into the platform.</p>
|
||||
<h2>Fork 2: Pi → Agent Runtime with Game Tools</h2>
|
||||
<p><a href="https://pi.dev" style="color: var(--c-accent-l);">Pi</a> is an open-source coding agent by Mario Zechner. MIT license, TypeScript, minimal by design — four core tools (read, write, edit, bash) and an extension system. 51k stars.</p>
|
||||
<p><a href="https://pi.dev" style="color: var(--c-lime);">Pi</a> is an open-source coding agent by Mario Zechner. MIT license, TypeScript, minimal by design — four core tools (read, write, edit, bash) and an extension system. 51k stars.</p>
|
||||
<p>We forked it and added four extensions, each a single TypeScript file:</p>
|
||||
<ul>
|
||||
<li><strong>tinqs-provider</strong> — routes inference through our DeepSeek V4 proxy ($0.28/MTok vs Opus at $15/MTok)</li>
|
||||
@@ -296,7 +308,7 @@
|
||||
<p>The core Pi code is untouched — 900 lines of extensions added to a 15,000-line codebase. Agents get Gitea-native tools without a fork of the entire agent ecosystem.</p>
|
||||
<p>The alternative: building our own agent from scratch — tool-calling logic, context management, streaming, retry handling, conversation threading. Months of work to reinvent what Pi already does.</p>
|
||||
<h2>Fork 3: Godot → Agent-Aware Game Engine</h2>
|
||||
<p><a href="https://godotengine.org" style="color: var(--c-accent-l);">Godot</a> is the open-source game engine powering our survival colony sim. We forked 4.6.2 and added nine C++ modules that give agents direct access to the running game:</p>
|
||||
<p><a href="https://godotengine.org" style="color: var(--c-lime);">Godot</a> is the open-source game engine powering our survival colony sim. We forked 4.6.2 and added nine C++ modules that give agents direct access to the running game:</p>
|
||||
<ul>
|
||||
<li><strong>agent_api</strong> — HTTP server inside the engine so agents can query game state</li>
|
||||
<li><strong>agent_vision</strong> — screenshot capture for AI vision pipelines</li>
|
||||
@@ -315,7 +327,7 @@
|
||||
<p>We're building the layer that connects them. The git server that speaks agent. The coding agent that speaks Gitea. The game engine that speaks HTTP. Each fork is a bridge between an existing tool and the agentic future — not a replacement for either.</p>
|
||||
<p>The age of agents doesn't need more agents. It needs better platforms. Platforms that already exist as open-source projects. They just need someone to fork them and add the wiring.</p>
|
||||
<hr>
|
||||
<p><em><a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a> is our Gitea fork, open for game teams. <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a> is the game we're building with every tool described here.</em></p>
|
||||
<p><em><a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a> is our Gitea fork, open for game teams. <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a> is the game we're building with every tool described here.</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
Before
After
|
+65
-53
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -319,7 +331,7 @@
|
||||
<p><strong>Always measure before optimizing.</strong> We added VRAM logging before writing a single line of optimization code. Half the "problems" we expected were non-issues. The other half were worse than expected. Profiling isn't optional.</p>
|
||||
<hr>
|
||||
<p>Godot 4 can handle open worlds at this scale, but it won't do it for you. You need to build streaming, manage your own caches, audit resource loading, and be disciplined about what runs per frame. The engine gives you the primitives — MultiMesh, <code>LoadThreadedRequest</code>, <code>QueueFree</code>. It's up to you to wire them into a system that scales.</p>
|
||||
<p><em>We're building <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a>, a survival colony sim, with these systems. The tools we use — git hosting, AI agents, creative pipelines — are part of <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a>.</em></p>
|
||||
<p><em>We're building <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a>, a survival colony sim, with these systems. The tools we use — git hosting, AI agents, creative pipelines — are part of <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>.</em></p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
Before
After
|
+71
-59
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -276,7 +288,7 @@
|
||||
<p>The alternative — baking animations to vertex textures — works for static crowds but locks you out of per-instance variation. No blending, no phase offsets, no reactive behaviour.</p>
|
||||
<p>What we need is simpler: <strong>share the skeleton, drive per-instance poses from a single animation, batch the draw call.</strong> That's what <code>agent_skinned</code> does.</p>
|
||||
<h2>How it works: two classes, one texture</h2>
|
||||
<p>The module lives in <code>modules/agent_skinned/</code> inside <a href="https://tinqs.com/tinqs/engine" style="color: var(--c-accent-l);">Tinqs Engine</a>. Two classes, one job:</p>
|
||||
<p>The module lives in <code>modules/agent_skinned/</code> inside <a href="https://tinqs.com/tinqs/engine" style="color: var(--c-lime);">Tinqs Engine</a>. Two classes, one job:</p>
|
||||
<h3><code>MultiSkinnedMeshInstance3D</code> — the data plane</h3>
|
||||
<p>Holds the CPU-side bone matrices. Allocates an <code>ImageTexture</code> of size <code>[4 × max_bones, max_instances]</code> in RGBA32F — each texel is one column of a 4×4 bone matrix. For a 130-bone crocodile with 256 instances:</p>
|
||||
<pre><code>Texture: 520 × 256 RGBA32F ≈ 2 MB</code></pre>
|
||||
@@ -309,7 +321,7 @@ data.update() # upload only dirty instances, not the whole texture</code></pre
|
||||
<p><strong>Bug 2: Bone matrices stored transposed.</strong> The data plane wrote basis rows (standard Godot <code>Transform3D.basis</code> is row-major), but the shader unpacked as columns. Every bone matrix was transposed — the mesh crumpled. Not a scale bug, not an orientation bug — a layout mismatch. Fixed by storing column-major, with a doctest to prevent regression.</p>
|
||||
<p>The lesson: doctests catch logic. Rendering catches truth. You need both.</p>
|
||||
<h2>What's driving it</h2>
|
||||
<p>In <a href="https://www.arikigame.com" style="color: var(--c-accent-l);">Ariki</a>, the sim tracks animal migration across a 12km archipelago. <code>AnimalHerdRenderer.cs</code> groups sim <code>ViewerState.animals</code> by type, feeds positions to <code>skinned_herd.gd</code> (a reusable per-type herd backend), which drives the renderer. One <code>AnimationPlayer</code> animates a single driver skeleton; poses propagate to every instance.</p>
|
||||
<p>In <a href="https://www.arikigame.com" style="color: var(--c-lime);">Ariki</a>, the sim tracks animal migration across a 12km archipelago. <code>AnimalHerdRenderer.cs</code> groups sim <code>ViewerState.animals</code> by type, feeds positions to <code>skinned_herd.gd</code> (a reusable per-type herd backend), which drives the renderer. One <code>AnimationPlayer</code> animates a single driver skeleton; poses propagate to every instance.</p>
|
||||
<p>The crocodile herd scene is 25 instances, one draw call. The same pipeline projects to 200–1,000 before the GPU budget even notices.</p>
|
||||
<h2>What's deliberately not here</h2>
|
||||
<ul>
|
||||
@@ -321,12 +333,12 @@ data.update() # upload only dirty instances, not the whole texture</code></pre
|
||||
<p>Pre-built editor binaries with <code>agent_skinned</code> baked in — no engine compile required:</p>
|
||||
<p>| Platform | Binary | Engine commit |</p>
|
||||
<p>|———-|——–|—————|</p>
|
||||
<p>| <strong>macOS ARM64</strong> | <a href="https://tinqs.com/tinqs/builds/media/branch/main/engine/macos-arm64/tinqs.macos.editor.arm64.mono" style="color: var(--c-accent-l);"><code>tinqs.macos.editor.arm64.mono</code></a> | <code>4fe1323</code> (4.6.4, Xcode 26.3) |</p>
|
||||
<p>| <strong>Windows x64</strong> | <a href="https://tinqs.com/tinqs/builds/media/branch/main/engine/windows-x64/tinqs.windows.editor.x86_64.mono.exe" style="color: var(--c-accent-l);"><code>tinqs.windows.editor.x86_64.mono.exe</code></a> | <code>64fb5cc</code> (4.6.4, MSVC 2022) |</p>
|
||||
<p>All builds live in the public <a href="https://tinqs.com/tinqs/builds" style="color: var(--c-accent-l);"><code>tinqs/builds</code></a> repo — engine source is private, but the binaries are yours. See <a href="https://tinqs.com/tinqs/builds/src/branch/main/manifest.json" style="color: var(--c-accent-l);"><code>manifest.json</code></a> for checksums and build details.</p>
|
||||
<p>The engine source lives in <a href="https://tinqs.com/tinqs/engine" style="color: var(--c-accent-l);"><code>tinqs/engine</code></a> (private). Module docs: <code>modules/agent_skinned/README.md</code> and <code>.agents/wiki/agent-skinned-gpu-herd.md</code>.</p>
|
||||
<p>| <strong>macOS ARM64</strong> | <a href="https://tinqs.com/tinqs/builds/media/branch/main/engine/macos-arm64/tinqs.macos.editor.arm64.mono" style="color: var(--c-lime);"><code>tinqs.macos.editor.arm64.mono</code></a> | <code>4fe1323</code> (4.6.4, Xcode 26.3) |</p>
|
||||
<p>| <strong>Windows x64</strong> | <a href="https://tinqs.com/tinqs/builds/media/branch/main/engine/windows-x64/tinqs.windows.editor.x86_64.mono.exe" style="color: var(--c-lime);"><code>tinqs.windows.editor.x86_64.mono.exe</code></a> | <code>64fb5cc</code> (4.6.4, MSVC 2022) |</p>
|
||||
<p>All builds live in the public <a href="https://tinqs.com/tinqs/builds" style="color: var(--c-lime);"><code>tinqs/builds</code></a> repo — engine source is private, but the binaries are yours. See <a href="https://tinqs.com/tinqs/builds/src/branch/main/manifest.json" style="color: var(--c-lime);"><code>manifest.json</code></a> for checksums and build details.</p>
|
||||
<p>The engine source lives in <a href="https://tinqs.com/tinqs/engine" style="color: var(--c-lime);"><code>tinqs/engine</code></a> (private). Module docs: <code>modules/agent_skinned/README.md</code> and <code>.agents/wiki/agent-skinned-gpu-herd.md</code>.</p>
|
||||
<hr>
|
||||
<p><strong>Related:</strong> <a href="fork-dont-build" style="color: var(--c-accent-l);">Fork, Don't Build</a> — why we modify existing platforms instead of building new ones. <a href="godot-optimisation" style="color: var(--c-accent-l);">Streaming a 12km Archipelago in Godot 4</a> — the terrain and vegetation streaming layers that work alongside this.</p>
|
||||
<p><strong>Related:</strong> <a href="fork-dont-build" style="color: var(--c-lime);">Fork, Don't Build</a> — why we modify existing platforms instead of building new ones. <a href="godot-optimisation" style="color: var(--c-lime);">Streaming a 12km Archipelago in Godot 4</a> — the terrain and vegetation streaming layers that work alongside this.</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
Before
After
|
+45
-35
@@ -15,19 +15,26 @@
|
||||
<meta property="og:description" content="Dev logs, behind-the-scenes, and lessons learned from building games, tools, and platform at Tinqs Studio.">
|
||||
<meta property="og:image" content="https://www.tinqs.com/img/og-cover.jpg">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained index styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — index styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -35,9 +42,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -45,12 +53,12 @@
|
||||
/* ── Section label kicker ── */
|
||||
.section-label {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -63,15 +71,16 @@
|
||||
padding: 60px 24px 32px;
|
||||
}
|
||||
|
||||
/* ── Gradient index title ── */
|
||||
/* ── Gradient index title — lime → violet ── */
|
||||
.blog-header__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.4rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
@@ -96,36 +105,37 @@
|
||||
.blog-card {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
background: #0c1119;
|
||||
background: var(--c-bg-raised);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 12px;
|
||||
border-radius: 8px;
|
||||
padding: 20px 24px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.blog-card:hover {
|
||||
border-color: var(--c-accent);
|
||||
border-color: var(--c-lime);
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.blog-card__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.blog-card__title {
|
||||
color: var(--c-text);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.35;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
color: var(--c-fg);
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.3;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
@@ -138,13 +148,13 @@
|
||||
|
||||
/* ── Read link accent ── */
|
||||
.blog-card__read {
|
||||
color: var(--c-blue);
|
||||
font-size: 0.9rem;
|
||||
color: var(--c-lime);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.blog-card:hover .blog-card__read {
|
||||
color: var(--c-purple);
|
||||
color: var(--c-violet);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
Before
After
|
+65
-53
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -264,7 +276,7 @@
|
||||
<h1 class="post__title">Live Ozan Radio: A Personal AI Station in Cursor</h1>
|
||||
<p class="post__lead">I do not want a playlist. I want a station — something that feels like late-night desert dub and Anadolu psych drifting out of a speaker, but every track is composed fresh, never pulled from Spotify or Apple Music. So we built <strong>Live Ozan Radio</strong>: DeepSeek as the on-air DJ, Google Lyria 3 as the music engine, and our own Gitea instance as the host.
|
||||
|
||||
!<a href="https://tinqs.com/tinqs/blog/media/branch/main/img/live-ozan-radio-workspace.png" style="color: var(--c-accent-l);">Live Ozan Radio in Cursor — player dashboard, saved songs, and DJ chat beside the editor</a>
|
||||
!<a href="https://tinqs.com/tinqs/blog/media/branch/main/img/live-ozan-radio-workspace.png" style="color: var(--c-lime);">Live Ozan Radio in Cursor — player dashboard, saved songs, and DJ chat beside the editor</a>
|
||||
|
||||
That screenshot is how I actually use it: Cursor on the left with taste notes and vocal cues, the local player on <code>:8787</code> on the right, saved songs in a scrollable library, and a chat box to steer the next generation. It is dogfooding in the truest sense — we run our game studio on the same Gitea fork we sell as Tinqs Studio, and the radio lives in that repo too.
|
||||
|
||||
|
||||
|
Before
After
|
+154
-146
@@ -20,6 +20,10 @@
|
||||
<meta name="twitter:description" content="Pi flows + oracle-backed gates: agents that compile, test, drive the game, measure feel, fix CI, and ship green PRs.">
|
||||
<meta name="twitter:image" content="https://www.tinqs.com/img/og-cover.jpg">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
@@ -43,17 +47,14 @@
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +62,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +74,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +128,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +151,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +185,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +241,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,41 +258,41 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ── Analogy callout box ── */
|
||||
.post__body .callout {
|
||||
background: linear-gradient(135deg, rgba(56,189,248,0.06), rgba(168,85,247,0.06));
|
||||
border: 1px solid rgba(56,189,248,0.2);
|
||||
border-left: 4px solid #38bdf8;
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: linear-gradient(135deg, rgba(124,92,255,0.06), rgba(182,255,60,0.04));
|
||||
border: 1px solid rgba(124,92,255,0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 18px 20px;
|
||||
margin: 22px 0;
|
||||
}
|
||||
.post__body .callout--amber {
|
||||
background: linear-gradient(135deg, rgba(245,158,11,0.07), rgba(201,147,90,0.05));
|
||||
border-color: rgba(245,158,11,0.25);
|
||||
border-left-color: #f59e0b;
|
||||
background: linear-gradient(135deg, rgba(182,255,60,0.06), rgba(124,92,255,0.04));
|
||||
border-color: rgba(182,255,60,0.15);
|
||||
border-left-color: var(--c-lime);
|
||||
}
|
||||
.post__body .callout--purple {
|
||||
background: linear-gradient(135deg, rgba(168,85,247,0.07), rgba(56,189,248,0.04));
|
||||
border-color: rgba(168,85,247,0.25);
|
||||
border-left-color: #a855f7;
|
||||
background: linear-gradient(135deg, rgba(124,92,255,0.07), rgba(182,255,60,0.04));
|
||||
border-color: rgba(124,92,255,0.2);
|
||||
border-left-color: var(--c-violet);
|
||||
}
|
||||
.post__body .callout__kicker {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: #38bdf8;
|
||||
color: var(--c-violet);
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
.post__body .callout--amber .callout__kicker { color: #f59e0b; }
|
||||
.post__body .callout--purple .callout__kicker { color: #a855f7; }
|
||||
.post__body .callout p { margin: 6px 0 0; color: #cdd7e2; }
|
||||
.post__body .callout--amber .callout__kicker { color: var(--c-lime); }
|
||||
.post__body .callout--purple .callout__kicker { color: var(--c-violet); }
|
||||
.post__body .callout p { margin: 6px 0 0; color: var(--c-fg); }
|
||||
.post__body .callout p + p { margin-top: 10px; }
|
||||
|
||||
/* ── Gate badge pills ── */
|
||||
@@ -297,18 +305,18 @@
|
||||
border-radius: 5px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
.gate--build { background: rgba(56,189,248,0.12); color: #38bdf8; border: 1px solid rgba(56,189,248,0.3); }
|
||||
.gate--test { background: rgba(52,211,153,0.12); color: #34d399; border: 1px solid rgba(52,211,153,0.3); }
|
||||
.gate--behave { background: rgba(168,85,247,0.12); color: #a855f7; border: 1px solid rgba(168,85,247,0.3); }
|
||||
.gate--feel { background: rgba(245,158,11,0.12); color: #f59e0b; border: 1px solid rgba(245,158,11,0.3); }
|
||||
.gate--visual { background: rgba(201,147,90,0.12); color: #c9935a; border: 1px solid rgba(201,147,90,0.3); }
|
||||
.gate--build { background: rgba(124,92,255,0.12); color: #7C5CFF; border: 1px solid rgba(124,92,255,0.3); }
|
||||
.gate--test { background: rgba(182,255,60,0.10); color: #B6FF3C; border: 1px solid rgba(182,255,60,0.25); }
|
||||
.gate--behave { background: rgba(124,92,255,0.12); color: #7C5CFF; border: 1px solid rgba(124,92,255,0.3); }
|
||||
.gate--feel { background: rgba(182,255,60,0.10); color: #B6FF3C; border: 1px solid rgba(182,255,60,0.25); }
|
||||
.gate--visual { background: rgba(124,92,255,0.10); color: #8A95A3; border: 1px solid rgba(124,92,255,0.2); }
|
||||
|
||||
/* ── Section divider accent ── */
|
||||
.post__body hr { border-color: #2a3340; margin: 36px 0; }
|
||||
.post__body hr { border-color: var(--c-border); margin: 36px 0; }
|
||||
.post__body hr.accent {
|
||||
border: none;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent, #38bdf8 20%, #a855f7 50%, #f59e0b 80%, transparent);
|
||||
background: linear-gradient(90deg, transparent, var(--c-lime) 20%, var(--c-violet) 50%, var(--c-lime) 80%, transparent);
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
@@ -321,8 +329,8 @@
|
||||
}
|
||||
@media (max-width: 640px) { .kitchen-grid { grid-template-columns: 1fr; } }
|
||||
.kitchen-col {
|
||||
background: #0c1119;
|
||||
border: 1px solid #2a3340;
|
||||
background: var(--c-bg-raised);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
padding: 16px 18px;
|
||||
}
|
||||
@@ -334,10 +342,10 @@
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
||||
.kitchen-col__title--kitchen { color: #f59e0b; }
|
||||
.kitchen-col__title--reality { color: #38bdf8; }
|
||||
.kitchen-col p { font-size: 0.9rem; color: #9aa7b4; margin: 4px 0; }
|
||||
.kitchen-col p strong { color: #e6edf3; }
|
||||
.kitchen-col__title--kitchen { color: var(--c-lime); }
|
||||
.kitchen-col__title--reality { color: var(--c-violet); }
|
||||
.kitchen-col p { font-size: 0.9rem; color: #8A95A3; margin: 4px 0; }
|
||||
.kitchen-col p strong { color: var(--c-fg); }
|
||||
|
||||
/* ── Table styles ── */
|
||||
.post__body table {
|
||||
@@ -355,7 +363,7 @@
|
||||
}
|
||||
.post__body td {
|
||||
padding: 9px 12px;
|
||||
border-bottom: 1px solid #1c2230;
|
||||
border-bottom: 1px solid var(--c-border);
|
||||
vertical-align: top;
|
||||
}
|
||||
</style>
|
||||
@@ -379,40 +387,40 @@
|
||||
<p>You run <code>tinqs flow run game-feature --task 'add a double-jump with cooldown'</code> or click Run Flow on the dashboard. The ticket hits the kitchen. What follows is not one agent doing everything — it's a brigade running their stations.</p>
|
||||
|
||||
<figure style="margin:28px 0;">
|
||||
<svg viewBox="0 0 920 350" role="img" aria-label="The verify-heavy flow: context, plan, implement, five gates, a Reflexion loop, and one judge" style="width:100%;height:auto;display:block;background:#0a0e14;border:1px solid #2a3340;border-radius:12px;font-family:'IBM Plex Sans',system-ui,sans-serif;">
|
||||
<svg viewBox="0 0 920 350" role="img" aria-label="The verify-heavy flow: context, plan, implement, five gates, a Reflexion loop, and one judge" style="width:100%;height:auto;display:block;background:#0B0C0E;border:1px solid rgba(255,255,255,0.07);border-radius:12px;font-family:'JetBrains Mono',ui-monospace,monospace;">
|
||||
<defs>
|
||||
<marker id="ah" markerWidth="10" markerHeight="10" refX="7" refY="3.2" orient="auto"><path d="M0,0 L7,3.2 L0,6.4 Z" fill="#5b6b7d"/></marker>
|
||||
<marker id="ahA" markerWidth="10" markerHeight="10" refX="7" refY="3.2" orient="auto"><path d="M0,0 L7,3.2 L0,6.4 Z" fill="#f59e0b"/></marker>
|
||||
<marker id="ah" markerWidth="10" markerHeight="10" refX="7" refY="3.2" orient="auto"><path d="M0,0 L7,3.2 L0,6.4 Z" fill="#8A95A3"/></marker>
|
||||
<marker id="ahA" markerWidth="10" markerHeight="10" refX="7" refY="3.2" orient="auto"><path d="M0,0 L7,3.2 L0,6.4 Z" fill="#B6FF3C"/></marker>
|
||||
</defs>
|
||||
<rect x="40" y="40" width="140" height="46" rx="9" fill="#121821" stroke="#2a3340"/>
|
||||
<text x="110" y="68" text-anchor="middle" fill="#cdd7e2" font-size="15">Context</text>
|
||||
<rect x="210" y="40" width="140" height="46" rx="9" fill="#121821" stroke="#2a3340"/>
|
||||
<text x="280" y="68" text-anchor="middle" fill="#cdd7e2" font-size="15">Plan</text>
|
||||
<rect x="400" y="40" width="150" height="46" rx="9" fill="#15202e" stroke="#3a4656"/>
|
||||
<text x="475" y="68" text-anchor="middle" fill="#e6edf3" font-size="15">Implement</text>
|
||||
<line x1="180" y1="63" x2="206" y2="63" stroke="#5b6b7d" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<line x1="350" y1="63" x2="396" y2="63" stroke="#5b6b7d" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<rect x="40" y="150" width="840" height="82" rx="12" fill="#0c1119" stroke="#2a3340"/>
|
||||
<text x="56" y="171" fill="#6b7a8d" font-size="11" letter-spacing="1.4">VERIFY-HEAVY GATES — most compute is spent checking, not writing</text>
|
||||
<rect x="56" y="180" width="148" height="42" rx="8" fill="#10141c" stroke="#38bdf8" stroke-opacity="0.55"/>
|
||||
<text x="130" y="206" text-anchor="middle" fill="#38bdf8" font-size="13.5">G1 · Build</text>
|
||||
<rect x="222" y="180" width="148" height="42" rx="8" fill="#10141c" stroke="#34d399" stroke-opacity="0.55"/>
|
||||
<text x="296" y="206" text-anchor="middle" fill="#9fe6c0" font-size="13.5">G2 · Tests</text>
|
||||
<rect x="388" y="180" width="148" height="42" rx="8" fill="#10141c" stroke="#a855f7" stroke-opacity="0.55"/>
|
||||
<text x="462" y="206" text-anchor="middle" fill="#c4a0f7" font-size="13.5">G3 · Behaviour</text>
|
||||
<rect x="554" y="180" width="148" height="42" rx="8" fill="#10141c" stroke="#f59e0b" stroke-opacity="0.55"/>
|
||||
<text x="628" y="206" text-anchor="middle" fill="#f5b44b" font-size="13.5">G4 · Feel</text>
|
||||
<rect x="720" y="180" width="148" height="42" rx="8" fill="#10141c" stroke="#c9935a" stroke-opacity="0.55"/>
|
||||
<text x="794" y="206" text-anchor="middle" fill="#d9ac7b" font-size="13.5">G5 · Visual</text>
|
||||
<line x1="475" y1="86" x2="475" y2="148" stroke="#5b6b7d" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<line x1="460" y1="232" x2="460" y2="276" stroke="#5b6b7d" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<text x="472" y="258" fill="#6b7a8d" font-size="11">all green ⇒ done · any fail ⇒ report</text>
|
||||
<rect x="380" y="278" width="160" height="46" rx="9" fill="#1b1505" stroke="#c9935a"/>
|
||||
<text x="460" y="306" text-anchor="middle" fill="#f3d6a0" font-size="15">Judge — honest verdict</text>
|
||||
<path d="M820,150 C 908,96 716,50 556,61" fill="none" stroke="#f59e0b" stroke-width="1.8" stroke-dasharray="6 5" marker-end="url(#ahA)"/>
|
||||
<text x="694" y="96" fill="#f59e0b" font-size="12.5">Reflexion · fix & retry ≤ 3</text>
|
||||
<rect x="40" y="40" width="140" height="46" rx="9" fill="#15171A" stroke="rgba(255,255,255,0.07)"/>
|
||||
<text x="110" y="68" text-anchor="middle" fill="#8A95A3" font-size="15">Context</text>
|
||||
<rect x="210" y="40" width="140" height="46" rx="9" fill="#15171A" stroke="rgba(255,255,255,0.07)"/>
|
||||
<text x="280" y="68" text-anchor="middle" fill="#8A95A3" font-size="15">Plan</text>
|
||||
<rect x="400" y="40" width="150" height="46" rx="9" fill="#15171A" stroke="rgba(255,255,255,0.07)"/>
|
||||
<text x="475" y="68" text-anchor="middle" fill="#ECEEF1" font-size="15">Implement</text>
|
||||
<line x1="180" y1="63" x2="206" y2="63" stroke="#8A95A3" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<line x1="350" y1="63" x2="396" y2="63" stroke="#8A95A3" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<rect x="40" y="150" width="840" height="82" rx="12" fill="#15171A" stroke="rgba(255,255,255,0.07)"/>
|
||||
<text x="56" y="171" fill="#8A95A3" font-size="11" letter-spacing="1.4">VERIFY-HEAVY GATES — most compute is spent checking, not writing</text>
|
||||
<rect x="56" y="180" width="148" height="42" rx="8" fill="#15171A" stroke="#7C5CFF" stroke-opacity="0.55"/>
|
||||
<text x="130" y="206" text-anchor="middle" fill="#7C5CFF" font-size="13.5">G1 · Build</text>
|
||||
<rect x="222" y="180" width="148" height="42" rx="8" fill="#15171A" stroke="#B6FF3C" stroke-opacity="0.55"/>
|
||||
<text x="296" y="206" text-anchor="middle" fill="#B6FF3C" font-size="13.5">G2 · Tests</text>
|
||||
<rect x="388" y="180" width="148" height="42" rx="8" fill="#15171A" stroke="#7C5CFF" stroke-opacity="0.55"/>
|
||||
<text x="462" y="206" text-anchor="middle" fill="#B6FF3C" font-size="13.5">G3 · Behaviour</text>
|
||||
<rect x="554" y="180" width="148" height="42" rx="8" fill="#15171A" stroke="#B6FF3C" stroke-opacity="0.55"/>
|
||||
<text x="628" y="206" text-anchor="middle" fill="#B6FF3C" font-size="13.5">G4 · Feel</text>
|
||||
<rect x="720" y="180" width="148" height="42" rx="8" fill="#15171A" stroke="rgba(255,255,255,0.15)" stroke-opacity="0.55"/>
|
||||
<text x="794" y="206" text-anchor="middle" fill="#8A95A3" font-size="13.5">G5 · Visual</text>
|
||||
<line x1="475" y1="86" x2="475" y2="148" stroke="#8A95A3" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<line x1="460" y1="232" x2="460" y2="276" stroke="#8A95A3" stroke-width="1.6" marker-end="url(#ah)"/>
|
||||
<text x="472" y="258" fill="#8A95A3" font-size="11">all green ⇒ done · any fail ⇒ report</text>
|
||||
<rect x="380" y="278" width="160" height="46" rx="9" fill="#15171A" stroke="#7C5CFF"/>
|
||||
<text x="460" y="306" text-anchor="middle" fill="#7C5CFF" font-size="15">Judge — honest verdict</text>
|
||||
<path d="M820,150 C 908,96 716,50 556,61" fill="none" stroke="#B6FF3C" stroke-width="1.8" stroke-dasharray="6 5" marker-end="url(#ahA)"/>
|
||||
<text x="694" y="96" fill="#B6FF3C" font-size="12.5">Reflexion · fix & retry ≤ 3</text>
|
||||
</svg>
|
||||
<figcaption style="color:#9aa7b4;font-size:0.85rem;margin-top:8px;">A real failure loops back to <em>implement</em> with gate evidence (bounded to three tries); anything green falls through to the judge.</figcaption>
|
||||
<figcaption style="color:#8A95A3;font-size:0.85rem;margin-top:8px;">A real failure loops back to <em>implement</em> with gate evidence (bounded to three tries); anything green falls through to the judge.</figcaption>
|
||||
</figure>
|
||||
|
||||
<h2>The Five Gates: What the Head Chef Checks</h2>
|
||||
@@ -515,19 +523,19 @@
|
||||
|
||||
<table style="width:100%;border-collapse:collapse;margin:18px 0;font-size:0.92rem;">
|
||||
<thead>
|
||||
<tr style="text-align:left;border-bottom:1px solid #2a3340;">
|
||||
<th style="padding:10px 12px;color:#c9935a;font-weight:600;">Layer</th>
|
||||
<th style="padding:10px 12px;color:#c9935a;font-weight:600;">What</th>
|
||||
<th style="padding:10px 12px;color:#c9935a;font-weight:600;">How</th>
|
||||
<tr style="text-align:left;border-bottom:1px solid rgba(255,255,255,0.07);">
|
||||
<th style="padding:10px 12px;color:#B6FF3C;font-weight:600;">Layer</th>
|
||||
<th style="padding:10px 12px;color:#B6FF3C;font-weight:600;">What</th>
|
||||
<th style="padding:10px 12px;color:#B6FF3C;font-weight:600;">How</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:9px 12px;color:#e6edf3;vertical-align:top;"><strong style="color:#f59e0b;">Flow engine</strong></td><td style="padding:9px 12px;color:#cdd7e2;vertical-align:top;">pi-flows orchestrator</td><td style="padding:9px 12px;color:#9aa7b4;vertical-align:top;">Composes agents, gates and decision points</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:9px 12px;color:#e6edf3;vertical-align:top;"><strong style="color:#f59e0b;">Oracle gates</strong></td><td style="padding:9px 12px;color:#cdd7e2;vertical-align:top;">verify_build, drive_game, game_frames</td><td style="padding:9px 12px;color:#9aa7b4;vertical-align:top;">Return structured PASS/FAIL with evidence</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:9px 12px;color:#e6edf3;vertical-align:top;"><strong style="color:#f59e0b;">Sub-agents</strong></td><td style="padding:9px 12px;color:#cdd7e2;vertical-align:top;">G1 build · G2 tests · G3 behaviour · G4 feel · G5 visual</td><td style="padding:9px 12px;color:#9aa7b4;vertical-align:top;">Role-split, each with its own toolset</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:9px 12px;color:#e6edf3;vertical-align:top;"><strong style="color:#f59e0b;">CI loop</strong></td><td style="padding:9px 12px;color:#cdd7e2;vertical-align:top;">tinqs-ci extension</td><td style="padding:9px 12px;color:#9aa7b4;vertical-align:top;">ci_status, ci_logs, ci_wait — polls Gitea Actions, reads logs, retries</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:9px 12px;color:#e6edf3;vertical-align:top;"><strong style="color:#f59e0b;">Decision</strong></td><td style="padding:9px 12px;color:#cdd7e2;vertical-align:top;">Agent-loop Reflexion</td><td style="padding:9px 12px;color:#9aa7b4;vertical-align:top;">Self-reflect on failures, retry (≤3) or escalate</td></tr>
|
||||
<tr><td style="padding:9px 12px;color:#e6edf3;vertical-align:top;"><strong style="color:#f59e0b;">Visualization</strong></td><td style="padding:9px 12px;color:#cdd7e2;vertical-align:top;">FlowDashboard</td><td style="padding:9px 12px;color:#9aa7b4;vertical-align:top;">Real-time pipeline state</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:9px 12px;color:#ECEEF1;vertical-align:top;"><strong style="color:#B6FF3C;">Flow engine</strong></td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">pi-flows orchestrator</td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">Composes agents, gates and decision points</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:9px 12px;color:#ECEEF1;vertical-align:top;"><strong style="color:#B6FF3C;">Oracle gates</strong></td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">verify_build, drive_game, game_frames</td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">Return structured PASS/FAIL with evidence</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:9px 12px;color:#ECEEF1;vertical-align:top;"><strong style="color:#B6FF3C;">Sub-agents</strong></td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">G1 build · G2 tests · G3 behaviour · G4 feel · G5 visual</td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">Role-split, each with its own toolset</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:9px 12px;color:#ECEEF1;vertical-align:top;"><strong style="color:#B6FF3C;">CI loop</strong></td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">tinqs-ci extension</td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">ci_status, ci_logs, ci_wait — polls Gitea Actions, reads logs, retries</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:9px 12px;color:#ECEEF1;vertical-align:top;"><strong style="color:#B6FF3C;">Decision</strong></td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">Agent-loop Reflexion</td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">Self-reflect on failures, retry (≤3) or escalate</td></tr>
|
||||
<tr><td style="padding:9px 12px;color:#ECEEF1;vertical-align:top;"><strong style="color:#B6FF3C;">Visualization</strong></td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">FlowDashboard</td><td style="padding:9px 12px;color:#8A95A3;vertical-align:top;">Real-time pipeline state</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -543,7 +551,7 @@
|
||||
|
||||
<div class="callout callout--purple">
|
||||
<span class="callout__kicker">Flow 2 · 4 June, 19:04</span>
|
||||
<p><strong>game-feature</strong> — "Make the player jump." Build: <span class="gate gate--build">PASS</span>. Tests: <span class="gate gate--test">PASS</span>. Behaviour/Feel/Visual: <span style="color:#f59e0b;">NOT RUN</span> — no live game instance was reachable. The flow didn't silently skip the visual gate. It <strong>hard-stopped</strong> and reported honestly: "FAIL — the feature has not been verified in-game." This is the kitchen saying: "The dish is cooked, but nobody tasted it. I'm not sending it out."</p>
|
||||
<p><strong>game-feature</strong> — "Make the player jump." Build: <span class="gate gate--build">PASS</span>. Tests: <span class="gate gate--test">PASS</span>. Behaviour/Feel/Visual: <span style="color:#B6FF3C;">NOT RUN</span> — no live game instance was reachable. The flow didn't silently skip the visual gate. It <strong>hard-stopped</strong> and reported honestly: "FAIL — the feature has not been verified in-game." This is the kitchen saying: "The dish is cooked, but nobody tasted it. I'm not sending it out."</p>
|
||||
</div>
|
||||
|
||||
<div class="callout callout--amber">
|
||||
@@ -664,28 +672,28 @@ export default async function run({ task, flow }) {
|
||||
<h2>The Setup: Extensions, Agents, and 15–20 Flows</h2>
|
||||
<p>"How did you set this up?" is the question I get most often. Here's the honest answer: there's no dashboard with drag-and-drop. You write three kinds of files.</p>
|
||||
|
||||
<p><strong style="color:#f59e0b;">Extensions</strong> are TypeScript tools that agents call. Each is about 300 lines, MIT licensed:</p>
|
||||
<p><strong style="color:#B6FF3C;">Extensions</strong> are TypeScript tools that agents call. Each is about 300 lines, MIT licensed:</p>
|
||||
|
||||
<table style="width:100%;border-collapse:collapse;margin:18px 0;font-size:0.89rem;">
|
||||
<thead>
|
||||
<tr style="text-align:left;border-bottom:1px solid #2a3340;">
|
||||
<th style="padding:8px 12px;color:#c9935a;">Extension</th>
|
||||
<th style="padding:8px 12px;color:#c9935a;">What agents call it for</th>
|
||||
<tr style="text-align:left;border-bottom:1px solid rgba(255,255,255,0.07);">
|
||||
<th style="padding:8px 12px;color:#B6FF3C;">Extension</th>
|
||||
<th style="padding:8px 12px;color:#B6FF3C;">What agents call it for</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>verify_build</code></td><td style="padding:7px 12px;color:#cdd7e2;">Compile the game + sim, return file:line errors</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>drive_game</code></td><td style="padding:7px 12px;color:#cdd7e2;">Send input to the live game, sample player body</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>game_frames</code></td><td style="padding:7px 12px;color:#cdd7e2;">Capture screenshot sequences for vision judging</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>ci_status</code></td><td style="padding:7px 12px;color:#cdd7e2;">Check Gitea Actions pipeline state for a branch</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>ci_logs</code></td><td style="padding:7px 12px;color:#cdd7e2;">Fetch full build log from the most recent failed run</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>ci_wait</code></td><td style="padding:7px 12px;color:#cdd7e2;">Poll every 15 seconds until the pipeline finishes</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>gen_image</code></td><td style="padding:7px 12px;color:#cdd7e2;">Generate brand/marketing images via fal.ai flux-2-pro</td></tr>
|
||||
<tr><td style="padding:7px 12px;color:#e6edf3;"><code>agent_catalog</code></td><td style="padding:7px 12px;color:#cdd7e2;">List available agents with their tools, inputs, outputs</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>verify_build</code></td><td style="padding:7px 12px;color:#8A95A3;">Compile the game + sim, return file:line errors</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>drive_game</code></td><td style="padding:7px 12px;color:#8A95A3;">Send input to the live game, sample player body</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>game_frames</code></td><td style="padding:7px 12px;color:#8A95A3;">Capture screenshot sequences for vision judging</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>ci_status</code></td><td style="padding:7px 12px;color:#8A95A3;">Check Gitea Actions pipeline state for a branch</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>ci_logs</code></td><td style="padding:7px 12px;color:#8A95A3;">Fetch full build log from the most recent failed run</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>ci_wait</code></td><td style="padding:7px 12px;color:#8A95A3;">Poll every 15 seconds until the pipeline finishes</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>gen_image</code></td><td style="padding:7px 12px;color:#8A95A3;">Generate brand/marketing images via fal.ai flux-2-pro</td></tr>
|
||||
<tr><td style="padding:7px 12px;color:#ECEEF1;"><code>agent_catalog</code></td><td style="padding:7px 12px;color:#8A95A3;">List available agents with their tools, inputs, outputs</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p><strong style="color:#f59e0b;">Agents</strong> are Markdown files with YAML frontmatter. Each declares its role, model tier, tools, inputs, and outputs:</p>
|
||||
<p><strong style="color:#B6FF3C;">Agents</strong> are Markdown files with YAML frontmatter. Each declares its role, model tier, tools, inputs, and outputs:</p>
|
||||
|
||||
<pre><code>---
|
||||
name: game-builder
|
||||
@@ -698,7 +706,7 @@ outputs: [summary, files]
|
||||
You are a game developer. Task: ${{task}}
|
||||
Context: ${{input.context}}</code></pre>
|
||||
|
||||
<p><strong style="color:#f59e0b;">Flows</strong> are JavaScript modules (<code>.flow.mjs</code>) that coordinate agents with real control flow. I have about <strong>15–20 flows</strong> running across different domains:</p>
|
||||
<p><strong style="color:#B6FF3C;">Flows</strong> are JavaScript modules (<code>.flow.mjs</code>) that coordinate agents with real control flow. I have about <strong>15–20 flows</strong> running across different domains:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Game dev:</strong> game-feature, review, bug-hunt, refactor</li>
|
||||
@@ -738,19 +746,19 @@ Context: ${{input.context}}</code></pre>
|
||||
|
||||
<table style="width:100%;border-collapse:collapse;margin:18px 0;font-size:0.89rem;">
|
||||
<thead>
|
||||
<tr style="text-align:left;border-bottom:1px solid #2a3340;">
|
||||
<th style="padding:8px 12px;color:#c9935a;">Tier</th>
|
||||
<th style="padding:8px 12px;color:#c9935a;">The Knife</th>
|
||||
<th style="padding:8px 12px;color:#c9935a;">What It Cuts</th>
|
||||
<tr style="text-align:left;border-bottom:1px solid rgba(255,255,255,0.07);">
|
||||
<th style="padding:8px 12px;color:#B6FF3C;">Tier</th>
|
||||
<th style="padding:8px 12px;color:#B6FF3C;">The Knife</th>
|
||||
<th style="padding:8px 12px;color:#B6FF3C;">What It Cuts</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>@coding</code></td><td style="padding:7px 12px;color:#f59e0b;">DeepSeek V4</td><td style="padding:7px 12px;color:#cdd7e2;"><strong>Chef's knife</strong> — your workhorse. Reads 800-line files, writes 200-line diffs. Game-builder, fixer, test-author. Free.</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>@planning</code></td><td style="padding:7px 12px;color:#f59e0b;">DeepSeek V4</td><td style="padding:7px 12px;color:#cdd7e2;"><strong>Boning knife</strong> — precision decomposition. Breaks tasks into steps, designs DAGs. Flow architect, feature planner.</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>@fast</code></td><td style="padding:7px 12px;color:#38bdf8;">DeepSeek V4 Flash</td><td style="padding:7px 12px;color:#cdd7e2;"><strong>Paring knife</strong> — quick, decisive cuts. Gate pass/fail, fork choices, loop exits. No overthinking.</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>@research</code></td><td style="padding:7px 12px;color:#f59e0b;">DeepSeek V4</td><td style="padding:7px 12px;color:#cdd7e2;"><strong>Fillet knife</strong> — flexible, follows contours. Reads codebase, traces patterns, finds what matters.</td></tr>
|
||||
<tr style="border-bottom:1px solid #1c2230;"><td style="padding:7px 12px;color:#e6edf3;"><code>@vision</code></td><td style="padding:7px 12px;color:#a855f7;">Gemini 2.5 Flash</td><td style="padding:7px 12px;color:#cdd7e2;"><strong>The inspector's eyes</strong> — the only knife that sees. Multimodal frame judging: T-poses, foot-slide, frozen anims.</td></tr>
|
||||
<tr><td style="padding:7px 12px;color:#e6edf3;"><code>@compact</code></td><td style="padding:7px 12px;color:#38bdf8;">DeepSeek V4 Flash</td><td style="padding:7px 12px;color:#cdd7e2;"><strong>Kitchen shears</strong> — lightweight, versatile. Summaries, verdicts, post-processing. Fast and cheap.</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>@coding</code></td><td style="padding:7px 12px;color:#B6FF3C;">DeepSeek V4</td><td style="padding:7px 12px;color:#8A95A3;"><strong>Chef's knife</strong> — your workhorse. Reads 800-line files, writes 200-line diffs. Game-builder, fixer, test-author. Free.</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>@planning</code></td><td style="padding:7px 12px;color:#B6FF3C;">DeepSeek V4</td><td style="padding:7px 12px;color:#8A95A3;"><strong>Boning knife</strong> — precision decomposition. Breaks tasks into steps, designs DAGs. Flow architect, feature planner.</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>@fast</code></td><td style="padding:7px 12px;color:#B6FF3C;">DeepSeek V4 Flash</td><td style="padding:7px 12px;color:#8A95A3;"><strong>Paring knife</strong> — quick, decisive cuts. Gate pass/fail, fork choices, loop exits. No overthinking.</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>@research</code></td><td style="padding:7px 12px;color:#B6FF3C;">DeepSeek V4</td><td style="padding:7px 12px;color:#8A95A3;"><strong>Fillet knife</strong> — flexible, follows contours. Reads codebase, traces patterns, finds what matters.</td></tr>
|
||||
<tr style="border-bottom:1px solid rgba(255,255,255,0.07);"><td style="padding:7px 12px;color:#ECEEF1;"><code>@vision</code></td><td style="padding:7px 12px;color:#7C5CFF;">Gemini 2.5 Flash</td><td style="padding:7px 12px;color:#8A95A3;"><strong>The inspector's eyes</strong> — the only knife that sees. Multimodal frame judging: T-poses, foot-slide, frozen anims.</td></tr>
|
||||
<tr><td style="padding:7px 12px;color:#ECEEF1;"><code>@compact</code></td><td style="padding:7px 12px;color:#B6FF3C;">DeepSeek V4 Flash</td><td style="padding:7px 12px;color:#8A95A3;"><strong>Kitchen shears</strong> — lightweight, versatile. Summaries, verdicts, post-processing. Fast and cheap.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
Before
After
|
+65
-53
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -359,7 +371,7 @@ The tools exist. DeepSeek V4 Flash is cheap enough to call on every commit. The
|
||||
|
||||
—
|
||||
|
||||
<em>The pre-commit hook is part of <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a>. The inference proxy, blocklist patterns, and review prompt are open and reusable. Every commit in <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a> runs through the same guard.</em></p>
|
||||
<em>The pre-commit hook is part of <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>. The inference proxy, blocklist patterns, and review prompt are open and reusable. Every commit in <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a> runs through the same guard.</em></p>
|
||||
|
||||
<div class="post__body">
|
||||
|
||||
|
||||
|
Before
After
|
+65
-53
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -317,7 +329,7 @@ Cross-compilation is trivial. We build Windows, Mac (arm64 + amd64), and Linux b
|
||||
|
||||
—
|
||||
|
||||
<em>The CLI is part of <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a>. Every time we find ourselves about to write a script that needs to work on multiple machines, we add a subcommand instead. One binary that makes the studio work — whether the operator is human or AI.</em></p>
|
||||
<em>The CLI is part of <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>. Every time we find ourselves about to write a script that needs to work on multiple machines, we add a subcommand instead. One binary that makes the studio work — whether the operator is human or AI.</em></p>
|
||||
|
||||
<div class="post__body">
|
||||
|
||||
|
||||
|
Before
After
|
@@ -39,21 +39,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ── Self-contained post styles (Studio provides site chrome) ── */
|
||||
/* ── Tinqs Studio brand — post styles ── */
|
||||
|
||||
:root {
|
||||
--c-accent: #c9935a;
|
||||
--c-accent-l: #d4a87c;
|
||||
--c-bg: #0d1117;
|
||||
--c-text: #e6edf3;
|
||||
--c-muted: #9aa7b4;
|
||||
--c-border: #2a3340;
|
||||
--c-blue: #38bdf8;
|
||||
--c-purple: #a855f7;
|
||||
--c-gold: #f59e0b;
|
||||
--c-code-bg: #1c2230;
|
||||
--c-pre-bg: #0a0e14;
|
||||
/* Studio near-black base */
|
||||
--c-bg: #0B0C0E;
|
||||
--c-bg-raised: #15171A;
|
||||
/* Foreground */
|
||||
--c-fg: #ECEEF1;
|
||||
--c-muted: #8A95A3;
|
||||
/* Family accents */
|
||||
--c-lime: #B6FF3C;
|
||||
--c-violet: #7C5CFF;
|
||||
/* Borders */
|
||||
--c-border: rgba(255,255,255,.07);
|
||||
--c-border-strong: rgba(255,255,255,.12);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
@@ -61,9 +66,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--c-text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: var(--c-bg);
|
||||
color: var(--c-fg);
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@@ -72,40 +78,42 @@
|
||||
.post {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 24px 48px;
|
||||
padding: 48px 24px 60px;
|
||||
}
|
||||
|
||||
/* ── Back link ── */
|
||||
.post__back {
|
||||
color: var(--c-blue);
|
||||
color: var(--c-muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 24px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.post__back:hover { color: var(--c-purple); }
|
||||
.post__back:hover { color: var(--c-lime); }
|
||||
|
||||
/* ── Gradient title ── */
|
||||
/* ── Gradient title — lime → violet ── */
|
||||
.post__title {
|
||||
background: linear-gradient(90deg, #c9935a, #f59e0b 40%, #38bdf8);
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.25;
|
||||
line-height: 1.2;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ── Date pill ── */
|
||||
.post__date {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.22em;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-blue);
|
||||
border: 1px solid rgba(147, 140, 129, 0.25);
|
||||
color: var(--c-muted);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
margin-bottom: 16px;
|
||||
@@ -124,16 +132,20 @@
|
||||
.post__body p { margin: 14px 0; }
|
||||
|
||||
.post__body h2 {
|
||||
font-size: 1.7rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 1.6rem;
|
||||
margin: 54px 0 6px;
|
||||
padding-left: 16px;
|
||||
border-left: 4px solid var(--c-accent);
|
||||
border-left: 4px solid var(--c-lime);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.post__body h3 {
|
||||
color: var(--c-purple);
|
||||
font-size: 1.18rem;
|
||||
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--c-violet);
|
||||
font-size: 1.15rem;
|
||||
margin: 30px 0 4px;
|
||||
}
|
||||
|
||||
@@ -143,27 +155,27 @@
|
||||
|
||||
/* ── Inline code ── */
|
||||
.post__body code {
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.86em;
|
||||
background: var(--c-code-bg);
|
||||
color: #9fe6c0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.84em;
|
||||
background: var(--c-bg-raised);
|
||||
color: var(--c-lime);
|
||||
padding: 2px 6px;
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--c-border);
|
||||
}
|
||||
|
||||
/* ── Code blocks ── */
|
||||
.post__body pre {
|
||||
background: var(--c-pre-bg);
|
||||
background: var(--c-bg);
|
||||
border: 1px solid var(--c-border);
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
overflow-x: auto;
|
||||
margin: 14px 0;
|
||||
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
|
||||
font-size: 0.85rem;
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
line-height: 1.55;
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
}
|
||||
|
||||
.post__body pre code {
|
||||
@@ -177,22 +189,22 @@
|
||||
|
||||
/* ── Blockquote ── */
|
||||
.post__body blockquote {
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||||
border-left: 4px solid var(--c-gold);
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: rgba(124, 92, 255, 0.06);
|
||||
border: 1px solid rgba(124, 92, 255, 0.15);
|
||||
border-left: 4px solid var(--c-violet);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 16px 18px;
|
||||
margin: 18px 0;
|
||||
color: #f4e3c4;
|
||||
color: var(--c-fg);
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
/* ── Links ── */
|
||||
.post__body a { color: var(--c-blue); }
|
||||
.post__body a:hover { color: var(--c-purple); }
|
||||
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.post__body a:hover { color: var(--c-violet); }
|
||||
|
||||
/* ── Strong ── */
|
||||
.post__body strong { color: var(--c-gold); }
|
||||
.post__body strong { color: var(--c-lime); font-weight: 600; }
|
||||
|
||||
/* ── HR ── */
|
||||
.post__body hr {
|
||||
@@ -233,8 +245,8 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-accent);
|
||||
color: var(--c-bg);
|
||||
background: var(--c-violet);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -250,7 +262,7 @@
|
||||
}
|
||||
|
||||
.post__author-name {
|
||||
color: var(--c-text);
|
||||
color: var(--c-fg);
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -360,7 +372,7 @@ Voice isn't a gimmick for game development. It's the input channel that matches
|
||||
|
||||
—
|
||||
|
||||
<em>We build <a href="https://tinqs.com" style="color: var(--c-accent-l);">Tinqs Studio</a> — a game dev platform with built-in AI agents, git hosting, and creative pipelines. <a href="https://arikigame.com" style="color: var(--c-accent-l);">Ariki</a> is the survival colony sim we're building with every tool described here.</em></p>
|
||||
<em>We build <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a> — a game dev platform with built-in AI agents, git hosting, and creative pipelines. <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a> is the survival colony sim we're building with every tool described here.</em></p>
|
||||
|
||||
<div class="post__body">
|
||||
|
||||
|
||||
|
Before
After
|
Reference in New Issue
Block a user