code-the-jewels 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/PROMPTS/01-build-v0.1.md +10 -0
  3. package/README.md +186 -0
  4. package/dist/ast.d.ts +143 -0
  5. package/dist/ast.js +2 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +145 -0
  8. package/dist/diagnostics.d.ts +7 -0
  9. package/dist/diagnostics.js +16 -0
  10. package/dist/generator.d.ts +11 -0
  11. package/dist/generator.js +126 -0
  12. package/dist/index.d.ts +7 -0
  13. package/dist/index.js +15 -0
  14. package/dist/lexer.d.ts +18 -0
  15. package/dist/lexer.js +210 -0
  16. package/dist/parser.d.ts +40 -0
  17. package/dist/parser.js +394 -0
  18. package/dist/repl.d.ts +1 -0
  19. package/dist/repl.js +132 -0
  20. package/dist/runtime/atl-data.d.ts +4 -0
  21. package/dist/runtime/atl-data.js +18 -0
  22. package/dist/runtime/atl-flow.d.ts +1 -0
  23. package/dist/runtime/atl-flow.js +5 -0
  24. package/dist/runtime/bk-parse.d.ts +3 -0
  25. package/dist/runtime/bk-parse.js +9 -0
  26. package/dist/runtime/bk-text.d.ts +5 -0
  27. package/dist/runtime/bk-text.js +13 -0
  28. package/dist/runtime/rtj-core.d.ts +1 -0
  29. package/dist/runtime/rtj-core.js +51 -0
  30. package/dist/semantic.d.ts +11 -0
  31. package/dist/semantic.js +153 -0
  32. package/dist/tests/basic.test.d.ts +1 -0
  33. package/dist/tests/basic.test.js +69 -0
  34. package/dist/token.d.ts +56 -0
  35. package/dist/token.js +77 -0
  36. package/examples/cities.rtj +11 -0
  37. package/examples/count-words.rtj +12 -0
  38. package/examples/duo.rtj +12 -0
  39. package/examples/hello.rtj +1 -0
  40. package/examples/pipes.rtj +6 -0
  41. package/package.json +22 -0
  42. package/public/_redirects +1 -0
  43. package/public/index.html +559 -0
  44. package/src/ast.ts +189 -0
  45. package/src/cli.ts +120 -0
  46. package/src/diagnostics.ts +15 -0
  47. package/src/generator.ts +129 -0
  48. package/src/index.ts +7 -0
  49. package/src/lexer.ts +208 -0
  50. package/src/parser.ts +461 -0
  51. package/src/repl.ts +105 -0
  52. package/src/runtime/atl-data.ts +11 -0
  53. package/src/runtime/atl-flow.ts +1 -0
  54. package/src/runtime/bk-parse.ts +3 -0
  55. package/src/runtime/bk-text.ts +5 -0
  56. package/src/runtime/rtj-core.ts +21 -0
  57. package/src/semantic.ts +144 -0
  58. package/src/tests/basic.test.ts +74 -0
  59. package/src/token.ts +85 -0
  60. package/tsconfig.json +15 -0
@@ -0,0 +1,6 @@
1
+ feature trim, upper from "bk:text"
2
+
3
+ jewel line = " code the jewels "
4
+ jewel clean = line |> trim |> upper
5
+
6
+ talk clean
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "code-the-jewels",
3
+ "version": "0.1.0",
4
+ "description": "A stylized programming language inspired by Run The Jewels. .rtj files compile to JavaScript.",
5
+ "bin": {
6
+ "rtj": "./dist/cli.js"
7
+ },
8
+ "main": "dist/index.js",
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "ts-node src/cli.ts",
12
+ "test": "node dist/tests/basic.test.js"
13
+ },
14
+ "keywords": ["rtj", "code-the-jewels", "programming-language"],
15
+ "license": "MIT",
16
+ "type": "commonjs",
17
+ "devDependencies": {
18
+ "@types/node": "^25.5.0",
19
+ "ts-node": "^10.9.2",
20
+ "typescript": "^6.0.2"
21
+ }
22
+ }
@@ -0,0 +1 @@
1
+ # No redirects needed — single page site, wrangler serves index.html automatically
@@ -0,0 +1,559 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Code The Jewels — .rtj</title>
7
+ <meta name="description" content="A programming language built like Run The Jewels makes music. Two cities. Two voices. One compiler. .rtj files transpile to JavaScript.">
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link href="https://fonts.googleapis.com/css2?family=Anton&family=IBM+Plex+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400&family=IBM+Plex+Sans:wght@300;400;500&display=swap" rel="stylesheet">
10
+ <style>
11
+ :root {
12
+ --bg: #000000;
13
+ --surface: #0D0D0D;
14
+ --surface2:#141414;
15
+ --border: rgba(255,255,255,0.08);
16
+ --text: #FFFFFF;
17
+ --muted: #808080;
18
+ --dim: #444444;
19
+ --pink: #FF1F6E;
20
+ --pink-dim:rgba(255,31,110,0.1);
21
+ --pink-border:rgba(255,31,110,0.25);
22
+ --gold: #FFE600;
23
+ --gold-dim:rgba(255,230,0,0.08);
24
+ --green: #00CC66;
25
+ --blue: #4499FF;
26
+ }
27
+
28
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
29
+ html { scroll-behavior: smooth; }
30
+
31
+ body {
32
+ background: var(--bg);
33
+ color: var(--text);
34
+ font-family: 'IBM Plex Mono', monospace;
35
+ font-size: 14px;
36
+ line-height: 1.7;
37
+ -webkit-font-smoothing: antialiased;
38
+ overflow-x: hidden;
39
+ }
40
+
41
+ body::before {
42
+ content: '';
43
+ position: fixed;
44
+ inset: 0;
45
+ background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.2) 2px, rgba(0,0,0,0.2) 4px);
46
+ pointer-events: none;
47
+ z-index: 9999;
48
+ }
49
+
50
+ nav {
51
+ position: sticky;
52
+ top: 0;
53
+ z-index: 200;
54
+ background: rgba(0,0,0,0.92);
55
+ backdrop-filter: blur(12px);
56
+ border-bottom: 1px solid var(--border);
57
+ padding: 0 2rem;
58
+ height: 52px;
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: space-between;
62
+ }
63
+
64
+ .nav-logo { font-family: 'IBM Plex Mono', monospace; font-size: 13px; font-weight: 500; color: var(--text); text-decoration: none; }
65
+ .nav-logo .brace { color: var(--pink); }
66
+ .nav-logo .ext { color: var(--gold); }
67
+
68
+ .nav-links { display: flex; gap: 2rem; }
69
+ .nav-links a { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); text-decoration: none; transition: color 0.15s; }
70
+ .nav-links a:hover { color: var(--gold); }
71
+
72
+ #hero {
73
+ padding: 80px 2rem 72px;
74
+ text-align: center;
75
+ border-bottom: 3px solid var(--pink);
76
+ position: relative;
77
+ overflow: hidden;
78
+ }
79
+
80
+ #hero::before {
81
+ content: '';
82
+ position: absolute;
83
+ top: -60px; left: 50%;
84
+ transform: translateX(-50%);
85
+ width: 900px; height: 500px;
86
+ background: radial-gradient(ellipse at center, rgba(255,31,110,0.12) 0%, transparent 65%);
87
+ pointer-events: none;
88
+ }
89
+
90
+ .hero-mark { display: block; font-size: 5rem; line-height: 1; margin-bottom: 2rem; position: relative; }
91
+ .hero-mark .brace { color: var(--pink); font-weight: 500; }
92
+ .hero-mark .ext { color: var(--gold); font-size: 3rem; vertical-align: middle; }
93
+
94
+ h1.hero-title {
95
+ font-family: 'Anton', sans-serif;
96
+ font-size: clamp(4.5rem, 13vw, 11rem);
97
+ font-weight: 400;
98
+ line-height: 0.9;
99
+ text-transform: uppercase;
100
+ letter-spacing: -0.02em;
101
+ color: var(--text);
102
+ white-space: nowrap;
103
+ }
104
+
105
+ .hero-cities { margin-top: 1.2rem; font-size: 12px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted); }
106
+ .hero-cities .city-bk { color: var(--pink); }
107
+ .hero-cities .city-atl { color: var(--gold); }
108
+
109
+ .hero-rule { width: 64px; height: 3px; margin: 1.8rem auto; background: linear-gradient(90deg, var(--pink), var(--gold)); }
110
+
111
+ .hero-tagline { font-family: 'IBM Plex Sans', sans-serif; font-size: 16px; color: var(--muted); margin-bottom: 2.4rem; letter-spacing: 0.02em; }
112
+ .hero-tagline strong { color: var(--text); font-weight: 500; }
113
+
114
+ .install-btn {
115
+ display: inline-flex;
116
+ align-items: center;
117
+ gap: 0.8rem;
118
+ background: var(--text);
119
+ border: none;
120
+ border-radius: 2px;
121
+ padding: 0.75rem 1.4rem;
122
+ font-family: 'IBM Plex Mono', monospace;
123
+ font-size: 13px;
124
+ color: var(--bg);
125
+ cursor: pointer;
126
+ transition: background 0.15s;
127
+ position: relative;
128
+ user-select: none;
129
+ }
130
+ .install-btn:hover { background: var(--pink); color: var(--text); }
131
+ .install-btn .hint { font-size: 10px; color: rgba(0,0,0,0.45); transition: color 0.15s; }
132
+ .install-btn:hover .hint { color: rgba(255,255,255,0.5); }
133
+
134
+ .toast { position: absolute; top: -36px; left: 50%; transform: translateX(-50%); background: var(--gold); color: #000; font-size: 10px; font-weight: 500; letter-spacing: 0.1em; padding: 3px 10px; border-radius: 2px; opacity: 0; pointer-events: none; transition: opacity 0.15s; white-space: nowrap; }
135
+ .toast.on { opacity: 1; }
136
+
137
+ .hero-tags { margin-top: 1.6rem; display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; }
138
+ .tag { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; padding: 3px 8px; border: 1px solid var(--border); border-radius: 2px; color: var(--dim); }
139
+
140
+ .section { padding: 80px 2rem; max-width: 980px; margin: 0 auto; border-bottom: 1px solid var(--border); }
141
+ .section:last-of-type { border-bottom: none; }
142
+
143
+ .sec-eyebrow { font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--pink); margin-bottom: 0.6rem; }
144
+ .sec-title { font-family: 'Anton', sans-serif; font-size: clamp(2.4rem, 6vw, 4.5rem); font-weight: 400; text-transform: uppercase; line-height: 1; color: var(--text); margin-bottom: 0.3em; }
145
+ .sec-sub { font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: var(--muted); letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 2rem; }
146
+ .sec-body { font-family: 'IBM Plex Sans', sans-serif; font-size: 15px; line-height: 1.85; color: rgba(255,255,255,0.75); max-width: 660px; margin-bottom: 2.5rem; }
147
+
148
+ .pull-quote { border-left: 3px solid var(--gold); padding: 0.8rem 1.4rem; margin: 2rem 0 2.5rem; background: var(--gold-dim); }
149
+ .pull-quote p { font-family: 'IBM Plex Sans', sans-serif; font-size: 14px; color: var(--gold); line-height: 1.65; font-style: italic; }
150
+ .pull-quote cite { display: block; margin-top: 0.4rem; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); font-style: normal; }
151
+
152
+ .codeblock { background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--pink); border-radius: 2px; padding: 1.4rem 1.6rem; overflow-x: auto; margin-bottom: 1.5rem; position: relative; }
153
+ .codeblock .lang { position: absolute; top: 0.6rem; right: 0.8rem; font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dim); }
154
+ .codeblock pre { font-family: 'IBM Plex Mono', monospace; font-size: 13px; line-height: 1.85; white-space: pre; }
155
+
156
+ .k { color: var(--pink); font-weight: 500; }
157
+ .s { color: var(--green); }
158
+ .n { color: var(--gold); }
159
+ .c { color: var(--dim); font-style: italic; }
160
+ .f { color: var(--blue); }
161
+ .op { color: rgba(255,255,255,0.25); }
162
+ .id { color: var(--text); }
163
+
164
+ .kw-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 2px; overflow: hidden; margin-top: 2rem; }
165
+ .kw-item { background: var(--surface); padding: 1.1rem 1.2rem; display: flex; flex-direction: column; gap: 0.25rem; }
166
+ .kw-word { color: var(--pink); font-size: 14px; font-weight: 500; }
167
+ .kw-maps { font-size: 11px; color: var(--muted); }
168
+ .kw-origin { font-family: 'IBM Plex Sans', sans-serif; font-size: 12px; color: var(--gold); font-style: italic; line-height: 1.45; }
169
+ .kw-desc { font-family: 'IBM Plex Sans', sans-serif; font-size: 12px; color: rgba(255,255,255,0.5); line-height: 1.5; margin-top: 2px; }
170
+
171
+ .callout { background: var(--pink-dim); border: 1px solid var(--pink-border); border-radius: 2px; padding: 1.2rem 1.4rem; margin: 2rem 0 1rem; }
172
+ .callout-label { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--pink); margin-bottom: 0.5rem; }
173
+ .callout p { font-family: 'IBM Plex Sans', sans-serif; font-size: 14px; line-height: 1.7; color: rgba(255,255,255,0.8); }
174
+
175
+ .stdlib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1.2rem; margin-top: 2rem; }
176
+ .stdlib-card { border: 1px solid var(--border); border-radius: 2px; overflow: hidden; }
177
+ .stdlib-head { background: var(--surface2); padding: 0.7rem 1rem; border-bottom: 1px solid var(--border); display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
178
+ .stdlib-mod { color: var(--pink); font-size: 13px; font-weight: 500; }
179
+ .stdlib-city { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
180
+ .stdlib-city-bk { color: var(--pink); }
181
+ .stdlib-city-atl { color: var(--gold); }
182
+ .stdlib-body { padding: 0.8rem 1rem; background: var(--surface); }
183
+ .stdlib-lore { font-family: 'IBM Plex Sans', sans-serif; font-size: 12px; color: var(--muted); font-style: italic; line-height: 1.5; margin-bottom: 0.7rem; border-bottom: 1px solid var(--border); padding-bottom: 0.7rem; }
184
+ .stdlib-fn { font-size: 12px; padding: 2px 0; color: rgba(255,255,255,0.6); }
185
+ .stdlib-fn code { color: var(--blue); }
186
+
187
+ .cli-rows { border: 1px solid var(--border); border-radius: 2px; overflow: hidden; margin-top: 1.5rem; }
188
+ .cli-row { display: flex; gap: 1.5rem; padding: 1rem 1.2rem; border-bottom: 1px solid var(--border); align-items: flex-start; }
189
+ .cli-row:last-child { border-bottom: none; }
190
+ .cli-cmd { flex: 0 0 auto; color: var(--pink); font-size: 13px; font-weight: 500; min-width: 200px; }
191
+ .cli-desc { font-family: 'IBM Plex Sans', sans-serif; font-size: 13px; color: rgba(255,255,255,0.6); line-height: 1.5; }
192
+
193
+ .arch-row { display: flex; align-items: center; overflow-x: auto; background: var(--surface); border: 1px solid var(--border); border-radius: 2px; padding: 1.6rem; margin-top: 2rem; gap: 0; }
194
+ .arch-box { flex: 0 0 auto; background: var(--surface2); border: 1px solid var(--border); border-radius: 2px; padding: 0.7rem 1rem; text-align: center; }
195
+ .arch-name { display: block; font-size: 12px; font-weight: 500; }
196
+ .arch-bk { color: var(--pink); }
197
+ .arch-atl { color: var(--gold); }
198
+ .arch-neutral { color: var(--text); }
199
+ .arch-sub { display: block; color: var(--muted); font-size: 10px; margin-top: 2px; }
200
+ .arch-arrow { flex: 0 0 auto; padding: 0 0.6rem; color: var(--dim); font-size: 14px; }
201
+
202
+ .roadmap-rows { border: 1px solid var(--border); border-radius: 2px; overflow: hidden; margin-top: 1.5rem; }
203
+ .roadmap-row { display: flex; gap: 1rem; padding: 0.9rem 1.2rem; border-bottom: 1px solid var(--border); align-items: flex-start; }
204
+ .roadmap-row:last-child { border-bottom: none; }
205
+ .rs { flex: 0 0 auto; font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; padding: 2px 7px; border-radius: 2px; margin-top: 3px; }
206
+ .rs-done { background: rgba(0,204,102,0.1); color: var(--green); border: 1px solid rgba(0,204,102,0.2); }
207
+ .rs-next { background: var(--pink-dim); color: var(--pink); border: 1px solid var(--pink-border); }
208
+ .rs-later { background: rgba(255,255,255,0.04);color: var(--muted); border: 1px solid var(--border); }
209
+ .roadmap-text { font-family: 'IBM Plex Sans', sans-serif; font-size: 13px; color: rgba(255,255,255,0.7); line-height: 1.5; }
210
+
211
+ .version-rows { border: 1px solid var(--border); border-radius: 2px; overflow: hidden; margin-top: 1.5rem; }
212
+ .version-row { display: grid; grid-template-columns: 80px 1fr 1fr; gap: 1rem; padding: 0.85rem 1.2rem; border-bottom: 1px solid var(--border); align-items: center; font-size: 12px; }
213
+ .version-row:last-child { border-bottom: none; }
214
+ .version-row.active { background: var(--pink-dim); }
215
+ .v-num { color: var(--pink); font-weight: 500; }
216
+ .v-name { color: var(--gold); font-family: 'IBM Plex Sans', sans-serif; font-style: italic; }
217
+ .v-era { color: var(--muted); font-family: 'IBM Plex Sans', sans-serif; }
218
+
219
+ footer { max-width: 980px; margin: 0 auto; padding: 2.4rem 2rem; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem; border-top: 3px solid var(--gold); }
220
+ .footer-mark { font-size: 13px; font-weight: 500; }
221
+ .footer-mark .brace { color: var(--pink); }
222
+ .footer-mark .ext { color: var(--gold); }
223
+ .footer-links { display: flex; gap: 1.5rem; }
224
+ .footer-links a { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); text-decoration: none; transition: color 0.15s; }
225
+ .footer-links a:hover { color: var(--gold); }
226
+ .footer-copy { font-size: 11px; color: var(--dim); letter-spacing: 0.04em; }
227
+
228
+ .reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.5s ease, transform 0.5s ease; }
229
+ .reveal.in { opacity: 1; transform: none; }
230
+
231
+ @media (max-width: 700px) {
232
+ nav { padding: 0 1.2rem; }
233
+ .nav-links { gap: 1.2rem; }
234
+ #hero { padding: 56px 1.2rem 52px; }
235
+ h1.hero-title { font-size: clamp(2.8rem, 11vw, 4.5rem); white-space: normal; }
236
+ .section { padding: 56px 1.2rem; }
237
+ .cli-row { flex-direction: column; gap: 0.3rem; }
238
+ .arch-row { flex-direction: column; align-items: flex-start; }
239
+ .arch-arrow { transform: rotate(90deg); padding: 0.3rem 0; }
240
+ .version-row { grid-template-columns: 1fr; gap: 0.2rem; }
241
+ }
242
+ </style>
243
+ </head>
244
+ <body>
245
+
246
+ <nav>
247
+ <a href="#" class="nav-logo">&#128073;<span class="brace">{</span>&#128142;<span class="brace">}</span><span class="ext">.rtj</span></a>
248
+ <div class="nav-links">
249
+ <a href="#vocabulary">Keywords</a>
250
+ <a href="#cities">Stdlib</a>
251
+ <a href="#examples">Examples</a>
252
+ <a href="#cli">CLI</a>
253
+ <a href="https://github.com/everettsteele/code-the-jewels" target="_blank" rel="noopener">GitHub &#8599;</a>
254
+ </div>
255
+ </nav>
256
+
257
+ <section id="hero">
258
+ <span class="hero-mark">&#128073;<span class="brace">{</span>&#128142;<span class="brace">}</span><span class="ext">.rtj</span></span>
259
+ <h1 class="hero-title">Code The Jewels</h1>
260
+ <p class="hero-cities"><span class="city-bk">Brooklyn</span> &nbsp;&middot;&nbsp; <span class="city-atl">Atlanta</span> &nbsp;&middot;&nbsp; MIT Forever</p>
261
+ <div class="hero-rule"></div>
262
+ <p class="hero-tagline">A programming language built the way <strong>Run The Jewels</strong> makes music.<br>Two cities. Two voices. One compiler.</p>
263
+ <button class="install-btn" onclick="copyInstall()">
264
+ <span>npm install -g code-the-jewels</span>
265
+ <span class="hint">&#10152; copy</span>
266
+ <span class="toast" id="toast">Copied</span>
267
+ </button>
268
+ <div class="hero-tags">
269
+ <span class="tag">v0.1 RTJ0</span>
270
+ <span class="tag">MIT License</span>
271
+ <span class="tag">TypeScript Compiler</span>
272
+ <span class="tag">Transpiles to JavaScript</span>
273
+ <span class="tag">13 Keywords</span>
274
+ <span class="tag">Free Forever</span>
275
+ </div>
276
+ </section>
277
+
278
+ <div class="section reveal">
279
+ <p class="sec-eyebrow">Legend Has It</p>
280
+ <h2 class="sec-title">The Origin</h2>
281
+ <p class="sec-sub">RTJ3 &middot; Track 1 &middot; 2016</p>
282
+ <div class="pull-quote">
283
+ <p>El-P is from Brooklyn. Killer Mike is from Atlanta. They make music that sounds like neither city alone &mdash; dense, righteous, mechanical, earned. Two voices that shouldn't work together, and then do, completely.</p>
284
+ <cite>The philosophy behind the language</cite>
285
+ </div>
286
+ <p class="sec-body">Code The Jewels is a transpiled programming language. You write <code>.rtj</code> files. The compiler &mdash; written in TypeScript &mdash; turns them into clean JavaScript. Every design decision traces to a song, an album, a lyric, or a city. This is not superficial theming. The language is built the way RTJ makes music: two halves that require each other.</p>
287
+ <p class="sec-body" style="margin-bottom:0;">The stdlib modules are named after cities. The composition construct is named after the duo. The compiler stages are named after the RTJ logo. The whole thing is free, because RTJ releases their albums for free. Code The Jewels is MIT licensed. Always will be.</p>
288
+ </div>
289
+
290
+ <div id="vocabulary" class="section reveal">
291
+ <p class="sec-eyebrow">A Report to the Shareholders</p>
292
+ <h2 class="sec-title">The Vocabulary</h2>
293
+ <p class="sec-sub">13 keywords &middot; every one has an origin</p>
294
+ <p class="sec-body">Every reserved word in Code The Jewels traces back to something in the RTJ catalog. Nothing was named arbitrarily.</p>
295
+ <div class="kw-grid">
296
+ <div class="kw-item"><span class="kw-word">jewel</span><span class="kw-maps">&rarr; const / let</span><span class="kw-origin">"Run the jewels" &mdash; the thing worth having, worth taking, worth carrying.</span><span class="kw-desc">A variable is a jewel. You declare it, you carry it through the program with intent.</span></div>
297
+ <div class="kw-item"><span class="kw-word">verse</span><span class="kw-maps">&rarr; function</span><span class="kw-origin">RTJ songs are built from verses. El takes one. Mike takes one.</span><span class="kw-desc">A function is a verse &mdash; self-contained, expressive, contributes to the whole.</span></div>
298
+ <div class="kw-item"><span class="kw-word">send</span><span class="kw-maps">&rarr; return</span><span class="kw-origin">Deliver the jewel. In RTJ, nothing is wasted.</span><span class="kw-desc">When a verse has something to say, it sends it back to whoever called.</span></div>
299
+ <div class="kw-item"><span class="kw-word">talk</span><span class="kw-maps">&rarr; console.log</span><span class="kw-origin">"Talk to Me" &mdash; RTJ3, track 9, ft. Trina &amp; Gangsta Boo.</span><span class="kw-desc">RTJ talks directly to people. So does your program. Not print, not log &mdash; talk.</span></div>
300
+ <div class="kw-item"><span class="kw-word">ifwild</span><span class="kw-maps">&rarr; if</span><span class="kw-origin">RTJ energy in conditional form. When the condition holds, things get wild.</span><span class="kw-desc">Execute the branch when the expression is true. The run is live.</span></div>
301
+ <div class="kw-item"><span class="kw-word">elsewild</span><span class="kw-maps">&rarr; else</span><span class="kw-origin">Still wild. Just differently.</span><span class="kw-desc">The other branch. Both sides of a conditional are wild in this language.</span></div>
302
+ <div class="kw-item"><span class="kw-word">run</span><span class="kw-maps">&rarr; for loop</span><span class="kw-origin">"Run the Jewels." The whole operation. Also the CLI: <code>rtj run</code>.</span><span class="kw-desc">You run a program. You run a loop. You run the jewels. Everything is a run.</span></div>
303
+ <div class="kw-item"><span class="kw-word">in</span><span class="kw-maps">&rarr; loop target</span><span class="kw-origin">"In Brooklyn. In Atlanta. In the cut. In the booth."</span><span class="kw-desc">Where something moves through. Pairs with run.</span></div>
304
+ <div class="kw-item"><span class="kw-word">feature</span><span class="kw-maps">&rarr; import</span><span class="kw-origin">A feature is a guest appearance. You give collaborators their credit.</span><span class="kw-desc">When you import a module, you feature it. Origin matters, so you declare it.</span></div>
305
+ <div class="kw-item"><span class="kw-word">from</span><span class="kw-maps">&rarr; import source</span><span class="kw-origin">"From Brooklyn. From Atlanta." Where something comes from is part of what it is.</span><span class="kw-desc">The module's city of origin. Pairs with feature.</span></div>
306
+ <div class="kw-item"><span class="kw-word">yank</span><span class="kw-maps">&rarr; throw</span><span class="kw-origin">Pull the emergency brake. RTJ doesn't let things slide.</span><span class="kw-desc">When something is wrong, you yank. Throws an error and stops the run.</span></div>
307
+ <div class="kw-item"><span class="kw-word">duo</span><span class="kw-maps">&rarr; two-branch composition</span><span class="kw-origin">Mike and El. The whole thing. Requires exactly two branches, always.</span><span class="kw-desc">The signature construct. You cannot have a duo without both voices.</span></div>
308
+ <div class="kw-item"><span class="kw-word">mike &nbsp;/&nbsp; el</span><span class="kw-maps">&rarr; duo branches</span><span class="kw-origin">Killer Mike (Atlanta). El-P (Brooklyn). mike opens. el responds.</span><span class="kw-desc">Both required inside every duo(). mike runs first, el receives the output and closes.</span></div>
309
+ </div>
310
+ </div>
311
+
312
+ <div class="section reveal">
313
+ <p class="sec-eyebrow">yankee and the brave (ep. 4)</p>
314
+ <h2 class="sec-title">The duo() Construct</h2>
315
+ <p class="sec-sub">RTJ4 &middot; Track 1 &middot; 2020</p>
316
+ <div class="pull-quote">
317
+ <p>The opening track of RTJ4. Mike is the Yankee. El is the Brave. Two perspectives, one statement. Neither makes sense without the other. The duo() construct works exactly the same way.</p>
318
+ <cite>yankee and the brave (ep. 4) &mdash; RTJ4</cite>
319
+ </div>
320
+ <div class="callout">
321
+ <p class="callout-label">The construct</p>
322
+ <p><strong>mike</strong> runs first &mdash; the opening verse, sets the tone. <strong>el</strong> receives what mike produced and closes it out. Both branches are required. The output chains between them. This is the most RTJ thing in the language.</p>
323
+ </div>
324
+ <div class="codeblock">
325
+ <span class="lang">.rtj</span>
326
+ <pre><span class="k">jewel</span> <span class="id">result</span> <span class="op">=</span> <span class="f">duo</span><span class="op">(</span><span class="id">inputValue</span><span class="op">)</span> <span class="op">{</span>
327
+ <span class="k">mike</span><span class="op">:</span> <span class="f">processFirst</span> <span class="c">// Killer Mike opens &mdash; Atlanta</span>
328
+ <span class="k">el</span><span class="op">:</span> <span class="f">processSecond</span> <span class="c">// El-P responds &mdash; Brooklyn</span>
329
+ <span class="op">}</span>
330
+
331
+ <span class="c">// compiles to: processSecond(processFirst(inputValue))</span>
332
+ <span class="c">// mike is always inner. el is always outer.</span>
333
+ <span class="c">// El produces the foundation. Mike lays the bar on top.</span></pre>
334
+ </div>
335
+ <div class="callout" style="margin-top:2rem;">
336
+ <p class="callout-label">|&gt; The pipe operator &mdash; Passing the Jewel</p>
337
+ <p>Thread a value through a chain. Each output becomes the next input. You are running the jewels through a sequence, each step handling them before passing forward.</p>
338
+ </div>
339
+ <div class="codeblock">
340
+ <span class="lang">.rtj</span>
341
+ <pre><span class="k">feature</span> <span class="op">{</span> <span class="id">trim</span><span class="op">,</span> <span class="id">upper</span><span class="op">,</span> <span class="id">split</span> <span class="op">}</span> <span class="k">from</span> <span class="s">"bk:text"</span>
342
+
343
+ <span class="k">jewel</span> <span class="id">result</span> <span class="op">=</span> <span class="s">" legend has it "</span>
344
+ <span class="op">|&gt;</span> <span class="f">trim</span>
345
+ <span class="op">|&gt;</span> <span class="f">upper</span>
346
+ <span class="op">|&gt;</span> <span class="f">split</span><span class="op">(</span><span class="s">" "</span><span class="op">)</span>
347
+
348
+ <span class="c">// ["LEGEND", "HAS", "IT"]</span></pre>
349
+ </div>
350
+ </div>
351
+
352
+ <div id="examples" class="section reveal">
353
+ <p class="sec-eyebrow">Blockbuster Night</p>
354
+ <h2 class="sec-title">Run It</h2>
355
+ <p class="sec-sub">RTJ2 &middot; Track 1 &middot; 2014 &middot; Five programs</p>
356
+
357
+ <p style="font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:var(--muted);margin-bottom:0.5rem;">1 &mdash; Hello world</p>
358
+ <div class="codeblock"><span class="lang">.rtj</span><pre><span class="k">talk</span> <span class="s">"Run The Jewels forever"</span></pre></div>
359
+
360
+ <p style="font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:var(--muted);margin-bottom:0.5rem;">2 &mdash; Variables and functions</p>
361
+ <div class="codeblock"><span class="lang">.rtj</span><pre><span class="k">jewel</span> <span class="id">trackName</span> <span class="op">=</span> <span class="s">"Legend Has It"</span>
362
+ <span class="k">jewel</span> <span class="id">bpm</span> <span class="op">=</span> <span class="n">118</span>
363
+
364
+ <span class="k">verse</span> <span class="f">describe</span><span class="op">(</span><span class="id">name</span><span class="op">,</span> <span class="id">tempo</span><span class="op">)</span> <span class="op">{</span>
365
+ <span class="k">send</span> <span class="s">`${name} hits at ${tempo} BPM`</span>
366
+ <span class="op">}</span>
367
+
368
+ <span class="k">talk</span> <span class="f">describe</span><span class="op">(</span><span class="id">trackName</span><span class="op">,</span> <span class="id">bpm</span><span class="op">)</span>
369
+ <span class="c">// "Legend Has It hits at 118 BPM"</span></pre></div>
370
+
371
+ <p style="font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:var(--muted);margin-bottom:0.5rem;">3 &mdash; Loop and conditional (RTJ3 tracklist)</p>
372
+ <div class="codeblock"><span class="lang">.rtj</span><pre><span class="k">jewel</span> <span class="id">rtj3</span> <span class="op">=</span> <span class="op">[</span>
373
+ <span class="s">"Talk to Me"</span><span class="op">,</span>
374
+ <span class="s">"Legend Has It"</span><span class="op">,</span>
375
+ <span class="s">"Call Ticketron"</span><span class="op">,</span>
376
+ <span class="s">"Stay Gold"</span>
377
+ <span class="op">]</span>
378
+
379
+ <span class="k">run</span> <span class="id">track</span> <span class="k">in</span> <span class="id">rtj3</span> <span class="op">{</span>
380
+ <span class="k">ifwild</span> <span class="op">(</span><span class="id">track</span><span class="op">.</span><span class="id">length</span> <span class="op">&gt;</span> <span class="n">9</span><span class="op">)</span> <span class="op">{</span>
381
+ <span class="k">talk</span> <span class="s">`long title: ${track}`</span>
382
+ <span class="op">}</span> <span class="k">elsewild</span> <span class="op">{</span>
383
+ <span class="k">talk</span> <span class="s">`short: ${track}`</span>
384
+ <span class="op">}</span>
385
+ <span class="op">}</span></pre></div>
386
+
387
+ <p style="font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:var(--muted);margin-bottom:0.5rem;">4 &mdash; Pipe chain</p>
388
+ <div class="codeblock"><span class="lang">.rtj</span><pre><span class="k">feature</span> <span class="op">{</span> <span class="id">trim</span><span class="op">,</span> <span class="id">upper</span><span class="op">,</span> <span class="id">split</span> <span class="op">}</span> <span class="k">from</span> <span class="s">"bk:text"</span>
389
+
390
+ <span class="k">jewel</span> <span class="id">words</span> <span class="op">=</span> <span class="s">" stay gold ponyboy "</span>
391
+ <span class="op">|&gt;</span> <span class="f">trim</span>
392
+ <span class="op">|&gt;</span> <span class="f">upper</span>
393
+ <span class="op">|&gt;</span> <span class="f">split</span><span class="op">(</span><span class="s">" "</span><span class="op">)</span>
394
+
395
+ <span class="k">talk</span> <span class="id">words</span>
396
+ <span class="c">// ["STAY", "GOLD", "PONYBOY"]</span></pre></div>
397
+
398
+ <p style="font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:var(--muted);margin-bottom:0.5rem;">5 &mdash; duo() in action</p>
399
+ <div class="codeblock"><span class="lang">.rtj</span><pre><span class="k">feature</span> <span class="op">{</span> <span class="id">words</span> <span class="op">}</span> <span class="k">from</span> <span class="s">"bk:parse"</span>
400
+ <span class="k">feature</span> <span class="op">{</span> <span class="id">count</span> <span class="op">}</span> <span class="k">from</span> <span class="s">"atl:data"</span>
401
+
402
+ <span class="k">jewel</span> <span class="id">line</span> <span class="op">=</span> <span class="s">"walking in the snow"</span>
403
+
404
+ <span class="k">jewel</span> <span class="id">wordCount</span> <span class="op">=</span> <span class="f">duo</span><span class="op">(</span><span class="id">line</span><span class="op">)</span> <span class="op">{</span>
405
+ <span class="k">mike</span><span class="op">:</span> <span class="id">words</span> <span class="c">// ATL: break it into words</span>
406
+ <span class="k">el</span><span class="op">:</span> <span class="id">count</span> <span class="c">// BK: count them</span>
407
+ <span class="op">}</span>
408
+
409
+ <span class="k">talk</span> <span class="id">wordCount</span> <span class="c">// 4</span></pre></div>
410
+ </div>
411
+
412
+ <div id="cities" class="section reveal">
413
+ <p class="sec-eyebrow">Two Cities</p>
414
+ <h2 class="sec-title">The Standard Library</h2>
415
+ <p class="sec-sub">Brooklyn &middot; Atlanta &middot; Every module has a hometown</p>
416
+ <p class="sec-body">El-P is from Brooklyn. Killer Mike is from Atlanta. Every stdlib module carries a city prefix because where something comes from is part of what it is. <code>bk:</code> is El's borough. <code>atl:</code> is Mike's city.</p>
417
+ <div class="stdlib-grid">
418
+ <div class="stdlib-card">
419
+ <div class="stdlib-head"><span class="stdlib-mod">bk:text</span><span class="stdlib-city stdlib-city-bk">Brooklyn &mdash; El-P</span></div>
420
+ <div class="stdlib-body">
421
+ <p class="stdlib-lore">El's production is precision &mdash; every sound placed exactly right, nothing wasted. Text manipulation mirrors that discipline.</p>
422
+ <div class="stdlib-fn"><code>trim(str)</code> &mdash; remove whitespace</div>
423
+ <div class="stdlib-fn"><code>upper(str)</code> &mdash; to uppercase</div>
424
+ <div class="stdlib-fn"><code>lower(str)</code> &mdash; to lowercase</div>
425
+ <div class="stdlib-fn"><code>split(str, sep)</code> &mdash; split to array</div>
426
+ <div class="stdlib-fn"><code>join(arr, sep)</code> &mdash; join to string</div>
427
+ </div>
428
+ </div>
429
+ <div class="stdlib-card">
430
+ <div class="stdlib-head"><span class="stdlib-mod">bk:parse</span><span class="stdlib-city stdlib-city-bk">Brooklyn &mdash; El-P</span></div>
431
+ <div class="stdlib-body">
432
+ <p class="stdlib-lore">El's style: deconstruct, examine, reconstruct. Break raw material into its components.</p>
433
+ <div class="stdlib-fn"><code>words(str)</code> &mdash; split into words</div>
434
+ <div class="stdlib-fn"><code>lines(str)</code> &mdash; split into lines</div>
435
+ <div class="stdlib-fn"><code>chars(str)</code> &mdash; split into chars</div>
436
+ </div>
437
+ </div>
438
+ <div class="stdlib-card">
439
+ <div class="stdlib-head"><span class="stdlib-mod">atl:data</span><span class="stdlib-city stdlib-city-atl">Atlanta &mdash; Killer Mike</span></div>
440
+ <div class="stdlib-body">
441
+ <p class="stdlib-lore">Mike's delivery: direct, efficient, no motion wasted. Data operations with ATL economy.</p>
442
+ <div class="stdlib-fn"><code>count(arr)</code> &mdash; array length</div>
443
+ <div class="stdlib-fn"><code>countBy(arr, fn)</code> &mdash; conditional count</div>
444
+ <div class="stdlib-fn"><code>first(arr)</code> &mdash; first element</div>
445
+ <div class="stdlib-fn"><code>last(arr)</code> &mdash; last element</div>
446
+ </div>
447
+ </div>
448
+ <div class="stdlib-card">
449
+ <div class="stdlib-head"><span class="stdlib-mod">atl:flow</span><span class="stdlib-city stdlib-city-atl">Atlanta &mdash; Killer Mike</span></div>
450
+ <div class="stdlib-body">
451
+ <p class="stdlib-lore">Atlanta moves with deliberate weight. Control flow that passes through clean.</p>
452
+ <div class="stdlib-fn"><code>identity(x)</code> &mdash; returns x unchanged</div>
453
+ </div>
454
+ </div>
455
+ </div>
456
+ <div class="pull-quote" style="margin-top:2rem;">
457
+ <p>Planned: <code>htx:</code> (Houston &mdash; chopped &amp; screwed async), <code>chi:</code> (Chicago &mdash; DOM), <code>det:</code> (Detroit &mdash; file system), <code>la:</code> (Los Angeles &mdash; HTTP). Every city in the RTJ universe.</p>
458
+ <cite>Roadmap &mdash; more cities coming</cite>
459
+ </div>
460
+ </div>
461
+
462
+ <div id="cli" class="section reveal">
463
+ <p class="sec-eyebrow">Run the Jewels</p>
464
+ <h2 class="sec-title">The CLI</h2>
465
+ <p class="sec-sub">Four commands &middot; npm install -g code-the-jewels &middot; then: rtj</p>
466
+ <div class="cli-rows">
467
+ <div class="cli-row"><span class="cli-cmd">rtj run file.rtj</span><span class="cli-desc">Execute a .rtj file. Transpiles to JavaScript in memory and runs immediately. The full run.</span></div>
468
+ <div class="cli-row"><span class="cli-cmd">rtj compile file.rtj</span><span class="cli-desc">Transpile to output.js. Writes the generated JavaScript to disk.</span></div>
469
+ <div class="cli-row"><span class="cli-cmd">rtj check file.rtj</span><span class="cli-desc">Semantic analysis without execution. Reports scope and type errors. The Mike Pass, isolated.</span></div>
470
+ <div class="cli-row"><span class="cli-cmd">rtj repl</span><span class="cli-desc">Interactive REPL. Prompt shows <code style="color:var(--pink)">rtj&gt;</code>. Type .exit to quit. .legend for version info.</span></div>
471
+ </div>
472
+ <div class="codeblock" style="margin-top:1.8rem;">
473
+ <span class="lang">terminal</span>
474
+ <pre><span class="op">$</span> <span class="id">rtj repl</span>
475
+
476
+ <span class="id">&#128073;{&#128142;}.rtj</span>
477
+ <span class="id">Code The Jewels v0.1 &mdash; RTJ0 "The Self-Titled Era"</span>
478
+ <span class="id">El-P (Brooklyn) &amp; Killer Mike (Atlanta) &mdash; MIT Forever</span>
479
+
480
+ <span class="c"> .help for commands &middot; .exit to quit</span>
481
+
482
+ <span class="op">rtj&gt;</span> <span class="k">jewel</span> <span class="id">x</span> <span class="op">=</span> <span class="s">"legend has it"</span>
483
+ <span class="op">rtj&gt;</span> <span class="k">talk</span> <span class="id">x</span>
484
+ <span class="s">legend has it</span>
485
+ <span class="op">rtj&gt;</span></pre>
486
+ </div>
487
+ </div>
488
+
489
+ <div class="section reveal">
490
+ <p class="sec-eyebrow">The Logo</p>
491
+ <h2 class="sec-title">The Fist &amp; The Gun</h2>
492
+ <p class="sec-sub">Six stages &middot; all named after RTJ &middot; The Fist is El, The Gun is Mike</p>
493
+ <p class="sec-body">The RTJ logo is two objects: a fist (El-P's half) and a gun (Killer Mike's half). The compiler stages carry those names. Each stage has an owner.</p>
494
+ <div class="arch-row">
495
+ <div class="arch-box"><span class="arch-name arch-bk">The Fist</span><span class="arch-sub">Lexer + Parser (El)</span></div>
496
+ <span class="arch-arrow">&rarr;</span>
497
+ <div class="arch-box"><span class="arch-name arch-neutral">The Hands</span><span class="arch-sub">AST</span></div>
498
+ <span class="arch-arrow">&rarr;</span>
499
+ <div class="arch-box"><span class="arch-name arch-atl">Mike Pass</span><span class="arch-sub">Semantic (Mike)</span></div>
500
+ <span class="arch-arrow">&rarr;</span>
501
+ <div class="arch-box"><span class="arch-name arch-bk">El Pass</span><span class="arch-sub">Lowering (El)</span></div>
502
+ <span class="arch-arrow">&rarr;</span>
503
+ <div class="arch-box"><span class="arch-name arch-atl">The Gun</span><span class="arch-sub">JS Generator (Mike)</span></div>
504
+ <span class="arch-arrow">&rarr;</span>
505
+ <div class="arch-box"><span class="arch-name arch-neutral">Jewel Box</span><span class="arch-sub">Runtime + stdlib</span></div>
506
+ </div>
507
+ <div class="pull-quote" style="margin-top:2rem;">
508
+ <p><strong>The Fist</strong> (El-P) reads every token and builds the AST &mdash; dense, mechanical, precise. <strong>Mike Pass</strong> validates meaning. <strong>El Pass</strong> rewrites and lowers. <strong>The Gun</strong> (Killer Mike) fires: generates clean JavaScript.</p>
509
+ <cite>El builds the foundation. Mike closes it out.</cite>
510
+ </div>
511
+ </div>
512
+
513
+ <div class="section reveal">
514
+ <p class="sec-eyebrow">Stay Gold</p>
515
+ <h2 class="sec-title">What's Next</h2>
516
+ <p class="sec-sub">RTJ3 &middot; Track 8 &middot; 2016</p>
517
+ <div class="roadmap-rows" style="margin-bottom:2rem;">
518
+ <div class="roadmap-row"><span class="rs rs-done">Done</span><span class="roadmap-text">Full language spec &mdash; 13 keywords with RTJ origins, pipe operator, duo() construct</span></div>
519
+ <div class="roadmap-row"><span class="rs rs-done">Done</span><span class="roadmap-text">Compiler architecture &mdash; The Fist, Hands, Mike Pass, El Pass, The Gun, Jewel Box</span></div>
520
+ <div class="roadmap-row"><span class="rs rs-done">Done</span><span class="roadmap-text">Standard library &mdash; bk:text, bk:parse, atl:data, atl:flow</span></div>
521
+ <div class="roadmap-row"><span class="rs rs-next">Next</span><span class="roadmap-text">Ship v0.1 to npm &mdash; <code>rtj</code> installable globally, REPL with RTJ welcome banner</span></div>
522
+ <div class="roadmap-row"><span class="rs rs-next">Next</span><span class="roadmap-text">VSCode extension &mdash; .rtj syntax highlighting in pink and gold</span></div>
523
+ <div class="roadmap-row"><span class="rs rs-later">Later</span><span class="roadmap-text">More stdlib cities &mdash; htx:, chi:, det:, la: &mdash; every city in the RTJ universe</span></div>
524
+ <div class="roadmap-row"><span class="rs rs-later">Later</span><span class="roadmap-text">RTJ-flavored error messages &mdash; "this jewel don't exist", "duo() needs both mike and el"</span></div>
525
+ <div class="roadmap-row"><span class="rs rs-later">Later</span><span class="roadmap-text">Browser playground &mdash; run .rtj without installing anything</span></div>
526
+ </div>
527
+ <p class="sec-sub" style="margin-top:1.5rem;">Version naming follows the RTJ album eras</p>
528
+ <div class="version-rows">
529
+ <div class="version-row active"><span class="v-num">v0.1</span><span class="v-name">RTJ0 &mdash; "The Self-Titled Era"</span><span class="v-era">Before the albums. The demo.</span></div>
530
+ <div class="version-row"><span class="v-num">v0.2</span><span class="v-name">RTJ1 &mdash; "Run the Jewels"</span><span class="v-era">First release. Free forever.</span></div>
531
+ <div class="version-row"><span class="v-num">v0.3</span><span class="v-name">RTJ2 &mdash; "Blockbuster"</span><span class="v-era">The leap. Bigger, harder.</span></div>
532
+ <div class="version-row"><span class="v-num">v1.0</span><span class="v-name">RTJ3 &mdash; "Legend Has It"</span><span class="v-era">Stable. Earned.</span></div>
533
+ <div class="version-row"><span class="v-num">v2.0</span><span class="v-name">RTJ4 &mdash; "Walking in the Snow"</span><span class="v-era">The reckoning.</span></div>
534
+ </div>
535
+ </div>
536
+
537
+ <footer>
538
+ <span class="footer-mark">&#128073;<span class="brace">{</span>&#128142;<span class="brace">}</span><span class="ext">.rtj</span></span>
539
+ <div class="footer-links">
540
+ <a href="https://github.com/everettsteele/code-the-jewels" target="_blank" rel="noopener">GitHub</a>
541
+ <a href="https://neverstill.llc" target="_blank" rel="noopener">Meridian</a>
542
+ </div>
543
+ <span class="footer-copy">MIT License &middot; Meridian Creative Shit &middot; 2026</span>
544
+ </footer>
545
+
546
+ <script>
547
+ function copyInstall() {
548
+ navigator.clipboard.writeText('npm install -g code-the-jewels').catch(function(){});
549
+ var t = document.getElementById('toast');
550
+ t.classList.add('on');
551
+ setTimeout(function(){ t.classList.remove('on'); }, 1800);
552
+ }
553
+ var obs = new IntersectionObserver(function(entries) {
554
+ entries.forEach(function(e) { if (e.isIntersecting) { e.target.classList.add('in'); obs.unobserve(e.target); }});
555
+ }, { threshold: 0.06 });
556
+ document.querySelectorAll('.reveal').forEach(function(el){ obs.observe(el); });
557
+ </script>
558
+ </body>
559
+ </html>