sergio/takana
> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…
feat(web): la franja es la misma de gioser.net y tawasuyu.net, y el enlace compartido trae tarjeta
1<!DOCTYPE html>
2<html lang="es" data-lang="es">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width,initial-scale=1">
6<title>takana — la forja determinista</title>
7<meta name="description" content="Una distribución de Linux con dos pisos: un laboratorio hermético que compila todo desde fuente y direcciona por hash, y un Linux clásico y mutable encima.">
8<meta name="color-scheme" content="dark light">
9<link rel="icon" href="simbolo.svg" type="image/svg+xml">
10<link rel="stylesheet" href="fuentes.css">
11<meta property="og:title" content="takana — la forja determinista">
12<meta property="og:description" content="Un laboratorio hermético abajo, un Linux clásico y mutable arriba. 954 recetas, todas selladas.">
13<meta property="og:url" content="https://takana-os.net/">
14<meta property="og:type" content="website">
15<meta property="og:image" content="https://takana-os.net/tarjeta.jpg">
16<meta property="og:image:width" content="1200">
17<meta property="og:image:height" content="630">
18<meta name="twitter:card" content="summary_large_image">
19<style>
20/* ── paleta oficial (docs/marca/README.md) ─────────────────────────────────────
21 Obsidiana #17130E · Piedra #2A241B · Alpaca #F2EBDD
22 Brasa #DF6B2A · Inti #E3A63D · Rojo fragua #A63A25 · Chispa #FFF6DE
23 El tema claro OSCURECE brasa para el texto: #DF6B2A sobre alpaca no llega a 3:1. */
24:root{
25 --obsidiana:#17130E;--piedra:#2A241B;--alpaca:#F2EBDD;
26 --brasa:#DF6B2A;--inti:#E3A63D;--fragua:#A63A25;--chispa:#17130E;
27 --fondo:#F2EBDD;--papel:#FAF6EC;--papel2:#EAE0CC;--linea:#DBCFB5;--linea2:#C4B593;
28 --texto:#17130E;--tenue:#544A3C;--debil:#6B604E;
29 --acento:#9E3F16;--acento2:#8A5A12;
30 --display:"Chivo","Arial Black",system-ui,sans-serif;
31 --sans:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
32 --mono:"IBM Plex Mono",ui-monospace,"DejaVu Sans Mono",monospace;
33 color-scheme:light}
34@media not all and (prefers-color-scheme:light){:root{
35 --chispa:#FFF6DE;
36 --fondo:#17130E;--papel:#1D1813;--papel2:#2A241B;--linea:#332B21;--linea2:#4A3F30;
37 --texto:#F2EBDD;--tenue:#B8AB95;--debil:#9C907B;
38 --acento:#E8834A;--acento2:#E3A63D;
39 color-scheme:dark}}
40:root[data-theme="dark"]{
41 --chispa:#FFF6DE;
42 --fondo:#17130E;--papel:#1D1813;--papel2:#2A241B;--linea:#332B21;--linea2:#4A3F30;
43 --texto:#F2EBDD;--tenue:#B8AB95;--debil:#9C907B;
44 --acento:#E8834A;--acento2:#E3A63D;
45 color-scheme:dark}
46
47/* Las tres luces de gioser.net y tawasuyu.net (2026-10-13): reemplazan las cinco manchas
48 saturadas que derivaban por guion. Más sobrias, y las mueve el CSS solo. */
49:root{--lz1:#9b7bff;--lz2:#f0a050;--lz3:#5b8ef0;--lz-op:.28}
50@media not all and (prefers-color-scheme:light){:root{--lz1:#8a63ff;--lz2:#f2a24e;--lz3:#4f86ff;--lz-op:.20}}
51.aurora{position:sticky;top:0;height:100vh;margin-bottom:-100vh;z-index:0;pointer-events:none;overflow:hidden}
52.aurora i{position:absolute;width:60vmax;height:60vmax;border-radius:50%;filter:blur(70px);
53 opacity:var(--lz-op);will-change:transform}
54.aurora i:nth-child(1){background:radial-gradient(circle,var(--lz1),transparent 65%);left:-20vmax;top:-15vmax;
55 animation:lz1 38s ease-in-out infinite alternate}
56.aurora i:nth-child(2){background:radial-gradient(circle,var(--lz2),transparent 65%);right:-25vmax;top:20vh;
57 animation:lz2 46s ease-in-out infinite alternate}
58.aurora i:nth-child(3){background:radial-gradient(circle,var(--lz3),transparent 65%);left:10vw;bottom:-30vmax;
59 animation:lz3 52s ease-in-out infinite alternate}
60@keyframes lz1{to{transform:translate(30vw,25vh) scale(1.15)}}
61@keyframes lz2{to{transform:translate(-35vw,15vh) scale(.9)}}
62@keyframes lz3{to{transform:translate(25vw,-35vh) scale(1.2)}}
63@media (prefers-reduced-motion:reduce){.aurora i{animation:none}}
64
65*{margin:0;padding:0;box-sizing:border-box}
66html{scroll-behavior:smooth}
67body{background:var(--fondo);color:var(--texto);font:17px/1.62 var(--sans);
68 -webkit-font-smoothing:antialiased;overflow-x:hidden}
69.envoltura{max-width:840px;margin:0 auto;padding:0 1.5rem}
70p{margin:0 0 1rem}
71a{color:inherit;text-decoration:none}
72h1,h2,h3{font-weight:600;letter-spacing:-.01em;line-height:1.15}
73/* el selector de variante: nombre, qué es, y entre llaves lo que trae */
74/* SIEMPRE dos y dos, y las cuatro del mismo alto: `grid-auto-rows:1fr` iguala las
75 dos filas entre sí, y el `stretch` por defecto iguala las dos de cada fila. */
76.selector{display:grid;grid-template-columns:1fr 1fr;grid-auto-rows:1fr;gap:.5rem;
77 margin:1.5rem 0 1.7rem}
78.opcion{display:flex;flex-direction:column;text-align:left;background:var(--papel);
79 border:1px solid var(--linea2);border-radius:12px;
80 padding:.72rem .85rem;cursor:pointer;font:inherit;color:var(--texto);
81 transition:border-color .15s,box-shadow .15s}
82.opcion:hover{border-color:var(--acento)}
83.opcion.on{border-color:var(--acento);box-shadow:inset 0 0 0 1px var(--acento)}
84.opcion .nom{display:block;font:500 .95rem/1.2 var(--mono)}
85.opcion.on .nom{color:var(--acento)}
86.opcion .que{display:block;font-size:.8rem;color:var(--tenue);margin-top:.18rem}
87.opcion .trae{display:block;font:.72rem/1.35 var(--mono);color:var(--debil);margin-top:.32rem}
88
89/* cada bloque de comandos: rótulo, peso a la derecha, y su botón de copiar */
90.bloque{margin:0 0 1.2rem}
91.rotulo{display:flex;align-items:baseline;gap:.5rem;margin:0 0 .38rem;
92 font:.7rem/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--debil)}
93.rotulo .peso{margin-left:auto;letter-spacing:0;text-transform:none;color:var(--tenue)}
94.codigo{position:relative}
95/* el botón vive en una banda propia arriba: así no pisa la primera línea ni cuando
96 el comando es largo y el bloque scrollea por debajo. Y el `min-height` deja todas
97 las cajas del mismo alto — con tres líneas, con dos, o con el aviso de que no hay. */
98.codigo pre{margin:0;padding:2.7rem 1rem .9rem;min-height:7.8rem}
99.copiar{position:absolute;top:.55rem;right:.6rem;font:500 .7rem/1 var(--sans);color:var(--tenue);
100 background:var(--papel);border:1px solid var(--linea2);border-radius:8px;padding:.35rem .58rem;
101 cursor:pointer;transition:color .15s,border-color .15s}
102.copiar:hover,.copiar.ok{color:var(--acento);border-color:var(--acento)}
103.bloque.novale .copiar{display:none}
104pre a{color:var(--acento);text-decoration:underline;text-underline-offset:2px}
105pre .vacio{color:var(--debil)}
106code{font:.86em/1.5 var(--mono);background:var(--papel2);border:1px solid var(--linea);
107 border-radius:5px;padding:.08em .38em}
108:root[data-lang="es"] [data-l="en"],:root[data-lang="en"] [data-l="es"]{display:none!important}
109
110/* el símbolo: martillo en retícula tocapu 7×7 */
111.simbolo{display:inline-block;flex:0 0 auto;aspect-ratio:1}
112.simbolo .chispa{fill:var(--chispa)}
113
114header.barra{position:sticky;top:0;z-index:60;
115 background:color-mix(in srgb,var(--fondo) 88%,transparent);
116 backdrop-filter:blur(10px);border-bottom:1px solid var(--linea)}
117.barra .envoltura{display:flex;align-items:center;gap:1rem;height:58px;max-width:1080px}
118.marca{display:flex;align-items:center;gap:.55rem;
119 font:900 .95rem/1 var(--display);letter-spacing:.06em;text-transform:uppercase}
120.marca .simbolo{width:20px}
121nav.enlaces{margin-left:auto;display:flex;gap:1.15rem;font-size:.88rem}
122nav.enlaces a{color:var(--tenue)}
123nav.enlaces a:hover{color:var(--acento)}
124.perillas{display:flex;gap:.35rem}
125/* ⚠ Estas pastillas eran `background:transparent`, y con el fondo vivo detrás eso dejó de ser
126 gratis: la barra es translúcida (88 %), así que por un control transparente pasaban las manchas
127 de color en movimiento y el rótulo perdía contraste a ratos — legible en una captura y no en la
128 siguiente, que es la peor forma de estar ilegible. Un relleno propio lo ancla sin taparlo. */
129.perilla{font:500 .76rem/1 var(--sans);color:var(--tenue);
130 background:color-mix(in srgb,var(--papel) 72%,transparent);
131 border:1px solid var(--linea2);border-radius:99px;padding:.42rem .6rem;cursor:pointer;
132 transition:background-color .15s,color .15s,border-color .15s}
133.perilla:hover{color:var(--texto);border-color:var(--acento);
134 background:color-mix(in srgb,var(--papel) 90%,transparent)}
135/* La activa va más opaca que las demás: es la que tiene que leerse de un vistazo. */
136.perilla.on{color:var(--acento);font-weight:700;border-color:var(--acento);
137 background:color-mix(in srgb,var(--papel) 94%,transparent)}
138@media(max-width:860px){nav.enlaces{display:none}.perillas{margin-left:auto}}
139
140.portada{position:relative;padding:4.6rem 0 2.6rem;overflow:hidden}
141.portada .fragua{position:absolute;inset:-45% -25% 5% -25%;pointer-events:none;z-index:0;
142 background:radial-gradient(42% 46% at 22% 32%,color-mix(in srgb,var(--brasa) 26%,transparent),transparent 70%),
143 radial-gradient(42% 46% at 76% 22%,color-mix(in srgb,var(--inti) 20%,transparent),transparent 70%),
144 radial-gradient(38% 42% at 55% 60%,color-mix(in srgb,var(--fragua) 16%,transparent),transparent 70%);
145 filter:blur(14px)}
146.portada .envoltura{position:relative;z-index:1}
147.antetitulo{font:.72rem/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;
148 color:var(--debil);margin-bottom:1rem}
149.titular{display:flex;align-items:center;gap:1.1rem;margin-bottom:.9rem}
150.titular .simbolo{width:clamp(48px,9vw,74px)}
151h1{font:900 clamp(3rem,10vw,5.2rem)/.92 var(--display);letter-spacing:.01em;
152 text-transform:uppercase;
153 background:linear-gradient(100deg,var(--fragua),var(--brasa) 52%,var(--inti));
154 -webkit-background-clip:text;background-clip:text;color:transparent}
155.lema{font:400 clamp(1.1rem,2.4vw,1.35rem)/1.45 var(--sans);color:var(--texto);max-width:44ch}
156.botones{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:1.6rem}
157.boton{display:inline-flex;align-items:center;gap:.4rem;font:600 .9rem/1 var(--sans);
158 padding:.75rem 1.1rem;border-radius:99px;border:1px solid var(--linea2);color:var(--texto);
159 transition:border-color .2s,transform .2s}
160.boton:hover{transform:translateY(-1px);border-color:var(--acento)}
161.boton.lleno{border-color:transparent;color:#17130E;
162 background:linear-gradient(100deg,var(--brasa),var(--inti))}
163
164section.franja{padding:3.4rem 0;border-top:1px solid var(--linea)}
165.sello{display:flex;align-items:center;gap:.5rem;font:.7rem/1 var(--mono);letter-spacing:.18em;
166 text-transform:uppercase;color:var(--debil);margin-bottom:.9rem}
167.sello .simbolo{width:12px}
168.franja h2{font-size:clamp(1.55rem,3.4vw,2rem);margin-bottom:1rem}
169.franja p{color:var(--tenue)}
170.franja p strong,.franja li strong{color:var(--texto)}
171
172ul.limpia{list-style:none;margin:.4rem 0 1rem}
173ul.limpia li{position:relative;padding-left:1.15rem;margin-bottom:.45rem;color:var(--tenue);font-size:.95rem}
174ul.limpia li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:2px;background:var(--brasa)}
175
176/* las decisiones: cada una es una ficha con tres lecturas de lo mismo —
177 contra qué se decide, qué implica por dentro, y qué quiere decir sin jerga */
178/* el diagrama de los dos pisos: SVG inline, no una imagen. Los colores van por
179 variable ⇒ cambia con el tema; el texto es texto ⇒ se traduce con el resto y lo
180 lee un lector de pantalla. En pantalla angosta scrollea DENTRO de su caja: encoger
181 un diagrama hasta que las etiquetas no se lean es peor que dejarlo desplazarse. */
182.diagrama{overflow-x:auto;margin:1.7rem 0 1.5rem}
183.diagrama svg{display:block;width:100%;max-width:560px;min-width:404px;height:auto;margin:0 auto;
184 font-family:var(--sans)}
185.diagrama .caja{fill:var(--papel);stroke:var(--linea)}
186.diagrama .cajita{fill:var(--papel2);stroke:var(--linea2)}
187.diagrama .encima{fill:none;stroke:var(--linea2);stroke-dasharray:5 4}
188.diagrama .t{fill:var(--texto)}
189.diagrama .s{fill:var(--tenue)}
190.diagrama .d{fill:var(--debil)}
191.diagrama .a{fill:var(--acento)}
192.diagrama .mono{font-family:var(--mono);letter-spacing:1.7px}
193.diagrama .flecha{stroke:var(--acento);stroke-width:1.6;fill:none}
194.diagrama .cabeza{fill:var(--acento)}
195
196.decisiones{display:grid;gap:.5rem;margin-top:1.5rem}
197.decision{border:1px solid var(--linea);border-radius:14px;background:var(--papel)}
198/* plegadas de entrada: trece fichas abiertas son una pared. La aseveración basta
199 para elegir cuál abrir, y `<details>` funciona sin una línea de JavaScript. */
200.decision summary{display:flex;gap:.65rem;align-items:baseline;cursor:pointer;
201 list-style:none;position:relative;padding:.9rem 2.7rem .9rem 1.3rem;
202 font-size:1.02rem;line-height:1.35}
203.decision summary::-webkit-details-marker{display:none}
204.decision summary::after{content:"";position:absolute;right:1.3rem;top:1.25rem;
205 width:.46rem;height:.46rem;border-right:1.5px solid var(--debil);
206 border-bottom:1.5px solid var(--debil);transform:rotate(45deg);transition:transform .18s}
207.decision[open] summary::after{transform:rotate(-135deg);border-color:var(--acento)}
208.decision summary:hover::after{border-color:var(--acento)}
209.decision .num{font:500 .72rem/1 var(--mono);letter-spacing:.1em;color:var(--acento);flex:0 0 auto}
210.decision dl{margin:0;padding:0 1.3rem 1.25rem}
211.decision dt{font:500 .65rem/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
212 color:var(--debil);margin-bottom:.32rem}
213.decision dd{margin:0 0 .9rem;color:var(--tenue);font-size:.93rem}
214.decision dd:last-child{margin-bottom:0}
215.decision dt.simple{color:var(--acento)}
216.decision dd.simple{color:var(--texto);border-left:2px solid var(--acento);padding-left:.8rem}
217@media(max-width:600px){.decision summary{padding:.85rem 2.4rem .85rem 1.05rem;
218 flex-direction:column;gap:.25rem}
219 .decision dl{padding:0 1.05rem 1.05rem}}
220
221.marco{border:1px solid var(--linea);border-radius:14px;background:var(--papel);
222 padding:1.3rem 1.4rem;margin-bottom:1rem;position:relative;overflow:hidden}
223.marco::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;
224 background:linear-gradient(90deg,var(--fragua),var(--brasa),var(--inti))}
225.marco h3{font-size:1.15rem;margin-bottom:.4rem}
226
227/* la ficha de repo: la dirección, grande y copiable */
228.direccion{border:1px solid var(--linea2);border-radius:12px;background:var(--papel);
229 padding:1rem 1.1rem;margin:.2rem 0 1rem}
230.direccion .etiqueta{font:.68rem/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;
231 color:var(--debil);margin-bottom:.5rem}
232.direccion .url{font:500 clamp(.86rem,2.3vw,1.02rem)/1.45 var(--mono);color:var(--acento);
233 word-break:break-all}
234.direccion .url:hover{text-decoration:underline}
235
236pre{font:.84rem/1.65 var(--mono);background:var(--papel2);border:1px solid var(--linea);
237 border-radius:10px;padding:.85rem 1rem;overflow-x:auto;margin:0 0 1rem;color:var(--texto)}
238pre .p{color:var(--debil);user-select:none}
239pre .c{color:var(--debil)}
240
241table{border-collapse:collapse;width:100%;margin:1rem 0 1.4rem;font-size:.9rem;display:block;overflow-x:auto}
242th,td{border:1px solid var(--linea);padding:.52rem .7rem;text-align:left;vertical-align:top}
243th{background:var(--papel2);font-weight:600;white-space:nowrap}
244td{color:var(--tenue)}
245td.n{font-family:var(--mono);white-space:nowrap;color:var(--texto)}
246.semaforo{white-space:nowrap}
247
248/* los paquetes principales al estilo de una ficha de distro: nombre y versión en
249 rejilla, para que entren de un vistazo y no en una tabla de quince filas */
250.versiones{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));
251 gap:.22rem .9rem;margin:.7rem 0 1.3rem;list-style:none}
252.versiones li{display:flex;justify-content:space-between;align-items:baseline;gap:.5rem;
253 font:.85rem/1.85 var(--mono);border-bottom:1px dotted var(--linea)}
254.versiones li b{font-weight:500;color:var(--texto)}
255.versiones li span{color:var(--tenue)}
256
257.nota{font-size:.82rem;color:var(--debil);border-left:2px solid var(--linea2);padding-left:.8rem}
258
259footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6rem 0 3.4rem}
260.pie-rejilla{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:1.4rem}
261.pie-rejilla a.casa{display:block;font-weight:600;margin-bottom:.15rem}
262.pie-rejilla a.casa:hover{color:var(--acento)}
263.pie-rejilla p{font-size:.84rem;color:var(--debil);margin:0}
264.pie-fin{margin-top:2rem;font-size:.8rem;color:var(--debil)}
265@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
266
267/* ── la franja, la portada y las pestañas (2026-10-13) ──────────────────────────────────────────
268 El mismo lenguaje que gioser.net y tawasuyu.net: la portada queda clavada arriba y el cuerpo sube
269 por encima; la franja no es barra hasta que hace falta —el símbolo sube desde la portada con el
270 primer scroll— y su menú son las cuatro pestañas de las secciones, que se encogen y se acomodan
271 en ella al llegar arriba (el guion les mueve `--p` de 0 a 1). Sin perilla de tema: oscuro de
272 fábrica, claro si el navegador lo pide. Clases con `t-` para no chocar con las de la página. */
273:root{--t-franja:64px;--t-vidrio:rgba(23,19,14,.74)}
274@media (prefers-color-scheme:light){:root{--t-vidrio:rgba(242,235,221,.82)}}
275.t-franja{position:fixed;top:0;left:0;right:0;z-index:60;height:var(--t-franja);display:flex;
276 align-items:center;gap:1rem;padding:0 clamp(1rem,4vw,2.5rem);color:var(--texto);pointer-events:none;
277 transition:color .35s}
278.t-franja.sobre-portada{color:#F2EBDD}
279.t-franja>*{pointer-events:auto}
280/* El enlace al inicio responde sólo sobre el símbolo: la palabra, aunque invisible en el teléfono,
281 ocupaba lugar encima de la primera pestaña cuando el menú se pega y se quedaba con el clic. */
282.t-franja>.t-marca{pointer-events:none}
283.t-marca .simbolo{pointer-events:auto}
284.t-marca{display:flex;align-items:center;gap:.6rem;font:900 .95rem/1 var(--display);letter-spacing:.06em;
285 text-transform:uppercase}
286.t-marca .simbolo{width:28px;transform-origin:0 0;will-change:transform}
287.t-marca-nombre{opacity:0;transition:opacity .3s}
288.t-franja.llego .t-marca-nombre{opacity:1}
289html:not(.js) .t-marca-nombre{opacity:1}
290html.js .t-tarjeta .titular .simbolo{visibility:hidden}
291.t-glifos{margin-left:auto;display:flex;align-items:center;gap:.5rem}
292.t-glifo{display:grid;place-items:center;width:34px;height:34px;border-radius:99px;border:1px solid currentColor;
293 background:none;color:inherit;cursor:pointer;opacity:.85;font:500 .76rem/1 var(--mono);letter-spacing:.08em;
294 transition:opacity .2s,color .2s}
295.t-glifo svg{width:17px;height:17px}
296.t-glifo:hover{opacity:1;color:var(--acento)}
297.t-glifo.idioma{width:auto;padding:0 .75rem}
298.t-portada-fondo{position:fixed;inset:0;z-index:0;overflow:hidden;background:#17130E}
299.t-portada-fondo img{display:block;width:100%;height:100%;object-fit:cover;object-position:62% 45%}
300.t-portada-fondo::after{content:"";position:absolute;inset:0;
301 background:linear-gradient(to bottom,rgba(10,8,6,.5),rgba(10,8,6,0) 20%),
302 linear-gradient(to top,rgba(10,8,6,.78),rgba(10,8,6,0) 45%)}
303.t-portada{position:relative;z-index:1;min-height:100svh;display:flex;align-items:flex-end;
304 padding:0 clamp(1rem,5vw,3rem) clamp(3rem,10vh,6.5rem)}
305.t-tarjeta{max-width:40rem;color:#F2EBDD;padding:clamp(1.1rem,3vw,1.8rem) clamp(1.2rem,3.5vw,2.2rem);
306 border-radius:22px;background:rgba(14,11,8,.5);border:1px solid rgba(255,255,255,.09);
307 backdrop-filter:blur(14px) saturate(1.25);-webkit-backdrop-filter:blur(14px) saturate(1.25);
308 box-shadow:0 20px 60px rgba(0,0,0,.35)}
309.t-tarjeta .antetitulo{color:#E3A63D}
310.t-tarjeta .lema{color:rgba(242,235,221,.9);margin:0}
311.t-cuerpo{position:relative;z-index:2;background:var(--fondo);box-shadow:0 -40px 80px rgba(0,0,0,.35)}
312.t-cuerpo>section,.t-cuerpo>footer{position:relative;z-index:1}
313.t-cuerpo>footer.pie{background:color-mix(in srgb,var(--papel) 85%,transparent)}
314
315.t-tabs{position:sticky;top:var(--t-tabs-top,0px);z-index:61;display:flex;justify-content:center;gap:.4rem;
316 max-width:840px;margin:0 auto;padding:2.6rem 1.5rem .9rem;pointer-events:none;--p:0}
317.t-tabs::before{content:"";position:absolute;left:50%;bottom:0;width:100vw;height:var(--t-franja);
318 transform:translateX(-50%);background:var(--t-vidrio);backdrop-filter:blur(14px) saturate(1.3);
319 -webkit-backdrop-filter:blur(14px) saturate(1.3);border-bottom:1px solid var(--linea);opacity:var(--p);z-index:-1}
320.t-tab{pointer-events:auto;position:relative;isolation:isolate;appearance:none;cursor:pointer;display:inline-flex;
321 align-items:center;gap:.45rem;white-space:nowrap;padding:.55rem .95rem;border-radius:99px;
322 border:1px solid color-mix(in srgb,var(--linea2) calc((1 - var(--p)) * 100%),transparent);
323 background:color-mix(in srgb,var(--papel) calc((1 - var(--p)) * 85%),transparent);
324 color:var(--tenue);font:600 .9rem/1 var(--sans);will-change:transform;transition:color .2s}
325.t-tab:hover{color:var(--texto)}
326.t-tab[aria-selected="true"]{color:var(--texto);
327 background:color-mix(in srgb,var(--acento) calc((1 - var(--p)) * 18%),transparent);
328 border-color:color-mix(in srgb,var(--acento) calc((1 - var(--p)) * 60%),transparent)}
329.t-tab svg{width:17px;height:17px;flex:none;color:var(--acento);opacity:calc(1 - var(--p) * 1.6)}
330.t-tab .rot{position:relative}
331.t-tab .rot::before{content:"";position:absolute;inset:-.42em -.85em;border-radius:99px;z-index:-1;
332 background:color-mix(in srgb,var(--acento) 22%,transparent);opacity:0}
333.t-tab[aria-selected="true"] .rot::before{opacity:var(--p)}
334.t-tab:focus-visible{outline:2px solid var(--acento);outline-offset:2px}
335html.js .t-panel:not(.activo){display:none}
336html.js .t-panel.activo{animation:t-entra .4s ease both}
337@keyframes t-entra{from{opacity:0;transform:translateY(10px)}}
338/* La ficha del sistema (03): pieza y versión en una línea, y la observación DEBAJO de las dos —
339 una tercera columna con el encabezado vacío se leía como si faltara. Poco convencional para
340 una tabla, a propósito. */
341table.ficha{display:block;overflow:visible;border-top:1px solid var(--linea)}
342table.ficha thead tr,table.ficha tbody tr{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.7fr);
343 column-gap:1rem;border-bottom:1px solid var(--linea)}
344table.ficha th,table.ficha td{border:0;padding:.55rem .2rem}
345table.ficha th{background:none;font:500 .66rem/1.2 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--debil)}
346table.ficha th:nth-child(3){display:none}
347table.ficha td:first-child{color:var(--texto);font-weight:600}
348/* las versiones largas («PipeWire 1.2.7 · WirePlumber 0.5.15») se parten antes que estirar la página */
349table.ficha td.n{white-space:normal;overflow-wrap:anywhere}
350table.ficha td:nth-child(3){grid-column:1/-1;padding-top:0;font-size:.86rem;color:var(--debil)}
351
352/* Deslizar entre pestañas con el dedo, como un PageView: el panel sigue al dedo y, al soltar
353 pasado el umbral, entra el vecino desde ese lado. */
354/* El deslizamiento horizontal es de la página: sin esto Chrome lo toma como «volver atrás» y el
355 visitante se va del sitio queriendo ir a la pestaña anterior (medido: quedaba en about:blank). */
356html,body{overscroll-behavior-x:none}
357@keyframes t-desde-der{from{opacity:0;transform:translateX(48px)}}
358@keyframes t-desde-izq{from{opacity:0;transform:translateX(-48px)}}
359html.js .t-panel.activo.desde-der{animation:t-desde-der .32s cubic-bezier(.2,.8,.2,1) both}
360html.js .t-panel.activo.desde-izq{animation:t-desde-izq .32s cubic-bezier(.2,.8,.2,1) both}
361
362.t-panel.franja{border-top:0;padding-top:1.4rem}
363@media(max-width:720px){
364 .t-tabs{justify-content:flex-start;overflow-x:auto;scrollbar-width:none;gap:.3rem}
365 .t-tabs::-webkit-scrollbar{display:none}
366 .t-tab{padding:.5rem .7rem;font-size:.82rem}
367 .t-franja.con-menu .t-marca-nombre{opacity:0}}
368</style>
369</head>
370<body>
371
372<svg width="0" height="0" style="position:absolute" aria-hidden="true">
373 <symbol id="tocapu" viewBox="0 0 748 748">
374 <rect x="0" y="0" width="100" height="100" fill="#A63A25"/>
375 <rect x="108" y="0" width="100" height="100" fill="#DF6B2A"/>
376 <rect x="216" y="0" width="100" height="100" fill="#E3A63D"/>
377 <rect x="324" y="0" width="100" height="100" fill="#E3A63D"/>
378 <rect x="432" y="0" width="100" height="100" fill="#E3A63D"/>
379 <rect x="540" y="0" width="100" height="100" fill="#DF6B2A"/>
380 <rect x="648" y="0" width="100" height="100" fill="#A63A25"/>
381 <rect x="108" y="108" width="100" height="100" fill="#DF6B2A"/>
382 <rect x="216" y="108" width="100" height="100" fill="#E3A63D"/>
383 <rect x="324" y="108" width="100" height="100" class="chispa"/>
384 <rect x="432" y="108" width="100" height="100" fill="#E3A63D"/>
385 <rect x="540" y="108" width="100" height="100" fill="#DF6B2A"/>
386 <rect x="0" y="216" width="100" height="100" fill="#A63A25"/>
387 <rect x="108" y="216" width="100" height="100" fill="#DF6B2A"/>
388 <rect x="216" y="216" width="100" height="100" fill="#E3A63D"/>
389 <rect x="324" y="216" width="100" height="100" fill="#E3A63D"/>
390 <rect x="432" y="216" width="100" height="100" fill="#E3A63D"/>
391 <rect x="540" y="216" width="100" height="100" fill="#DF6B2A"/>
392 <rect x="648" y="216" width="100" height="100" fill="#A63A25"/>
393 <rect x="324" y="324" width="100" height="100" fill="#DF6B2A"/>
394 <rect x="324" y="432" width="100" height="100" fill="#A63A25"/>
395 <rect x="324" y="540" width="100" height="100" fill="#A63A25"/>
396 <rect x="324" y="648" width="100" height="100" fill="#A63A25"/>
397 </symbol>
398</svg>
399
400<header class="t-franja sobre-portada" id="t-franja">
401 <a class="t-marca" href="#" id="t-marca" aria-label="takana"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span class="t-marca-nombre">takana</span></a>
402 <div class="t-glifos" id="t-glifos">
403 <a class="t-glifo" href="https://git.gioser.net/sergio/takana" title="git.gioser.net/sergio/takana" aria-label="repositorio / repository"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 18 3 12l6-6M15 6l6 6-6 6"/></svg></a>
404 <button class="t-glifo idioma" type="button" id="t-idioma" aria-label="English / español"><span data-l="es" lang="en">EN</span><span data-l="en" lang="es">ES</span></button>
405 </div>
406</header>
407
408<div class="t-portada-fondo" aria-hidden="true"><img src="among.webp" alt="" fetchpriority="high"></div>
409
410<section class="t-portada"><div class="t-tarjeta">
411 <p class="antetitulo"><span data-l="es">takana · el martillo</span><span data-l="en">takana · the hammer</span></p>
412 <div class="titular">
413 <svg class="simbolo" viewBox="0 0 748 748" aria-hidden="true"><use href="#tocapu"/></svg>
414 <h1>takana</h1>
415 </div>
416 <p class="lema">
417 <span data-l="es">Un Linux mutable que puedes romper y recuperar, manteniendo su pureza hasta el último bit.</span>
418 <span data-l="en">A mutable Linux you can break and recover, its purity intact down to the last bit.</span>
419 </p>
420</div></section>
421
422<div class="t-cuerpo">
423<!-- El fondo vivo. `aria-hidden` porque no dice nada: es color. -->
424<div class="aurora" aria-hidden="true"><i></i><i></i><i></i></div>
425<div class="t-tabs" id="t-tabs" role="tablist" aria-label="secciones / sections"><button class="t-tab" role="tab" type="button" id="tab-descargar" data-tab="descargar" aria-controls="descargar" aria-selected="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7 11l5 5 5-5M5 20h14"/></svg><span class="rot"><span data-l="es">Descargar</span><span data-l="en">Download</span></span></button><button class="t-tab" role="tab" type="button" id="tab-decisiones" data-tab="decisiones" aria-controls="decisiones" aria-selected="false"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v18M5 7h14"/><path d="M8 7 5 13h6zM16 7l-3 6h6z"/></svg><span class="rot"><span data-l="es">Decisiones</span><span data-l="en">Decisions</span></span></button><button class="t-tab" role="tab" type="button" id="tab-componentes" data-tab="componentes" aria-controls="componentes" aria-selected="false"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 3 8 4.5v9L12 21l-8-4.5v-9z"/><path d="m4 7.5 8 4.5 8-4.5M12 12v9"/></svg><span class="rot"><span data-l="es">Componentes</span><span data-l="en">Components</span></span></button><button class="t-tab" role="tab" type="button" id="tab-codigo" data-tab="codigo" aria-controls="codigo" aria-selected="false"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 18 3 12l6-6M15 6l6 6-6 6"/></svg><span class="rot"><span data-l="es">Código</span><span data-l="en">Code</span></span></button></div>
426
427<section class="franja t-panel activo" id="descargar" role="tabpanel" aria-labelledby="tab-descargar"><div class="envoltura">
428 <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">01 · descargar</span><span data-l="en">01 · download</span></p>
429 <h2><span data-l="es">Descargar</span><span data-l="en">Download</span></h2>
430
431 <div class="selector" id="variantes" role="group" aria-label="variante">
432 <button class="opcion" data-v="base" type="button">
433 <span class="nom">base</span>
434 <span class="que"><span data-l="es">sólo el arranque</span><span data-l="en">boot only</span></span>
435 <span class="trae">{<span data-l="es">consola</span><span data-l="en">console</span>}</span>
436 </button>
437 <button class="opcion" data-v="mirada" type="button">
438 <span class="nom">mirada</span>
439 <span class="que"><span data-l="es">el escritorio de la suite</span><span data-l="en">the suite's desktop</span></span>
440 <span class="trae">{userland + mirada}</span>
441 </button>
442 <button class="opcion" data-v="servidor" type="button">
443 <span class="nom">servidor</span>
444 <span class="que"><span data-l="es">la máquina que sirve</span><span data-l="en">the serving machine</span></span>
445 <span class="trae">{userland + <span data-l="es">servicios</span><span data-l="en">services</span>}</span>
446 </button>
447 <button class="opcion" data-v="full" type="button">
448 <span class="nom">full</span>
449 <span class="que"><span data-l="es">todo junto</span><span data-l="en">everything at once</span></span>
450 <span class="trae">{userland + cli + <span data-l="es">5 escritorios + servicios</span><span data-l="en">5 desktops + services</span>}</span>
451 </button>
452 </div>
453
454 <div class="bloque" id="bloque-sh">
455 <p class="rotulo"><span data-l="es">un archivo</span><span data-l="en">one file</span><span class="peso" id="peso-sh"></span></p>
456 <div class="codigo"><pre id="cmd-sh"></pre></div>
457 </div>
458 <div class="bloque">
459 <p class="rotulo"><span data-l="es">imagen USB</span><span data-l="en">USB image</span><span class="peso" id="peso-img"></span></p>
460 <div class="codigo"><pre id="cmd-img"></pre></div>
461 </div>
462
463 <div class="bloque">
464 <p class="rotulo"><span data-l="es">desde el código</span><span data-l="en">from source</span></p>
465 <div class="codigo"><pre>$ git clone https://git.gioser.net/sergio/takana.git
466<span class="p">$</span> cd takana && cargo build --release
467<span class="p">$</span> ./target/release/takana --help</pre></div>
468 </div>
469
470 <p class="nota" id="nota-full" hidden>
471 <span data-l="es"><code>full</code> son 8,6 GiB y trae <strong>los cinco escritorios</strong>: mirada, sway, COSMIC, GNOME y KDE Plasma. Entra en un pendrive de 16 GB. No hay archivo único para esta variante: ése carga el sistema entero en memoria, y 17 GiB de rootfs no entran.</span>
472 <span data-l="en"><code>full</code> is 8.6 GiB and carries <strong>all five desktops</strong>: mirada, sway, COSMIC, GNOME and KDE Plasma. It fits on a 16 GB stick. There is no single file for this variant: that one loads the whole system into memory, and a 17 GiB rootfs does not fit.</span>
473 </p>
474
475 <noscript><p class="nota"><span data-l="es">Las descargas se arman con JavaScript. Sin él: takana-os.net/descargas/</span><span data-l="en">Downloads are assembled with JavaScript. Without it: takana-os.net/descargas/</span></p></noscript>
476</div></section>
477
478<section class="franja t-panel" id="decisiones" role="tabpanel" aria-labelledby="tab-decisiones"><div class="envoltura">
479 <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">02 · las decisiones</span><span data-l="en">02 · the decisions</span></p>
480 <h2><span data-l="es">Trece decisiones, y contra qué se tomaron</span><span data-l="en">Thirteen decisions, and what they were taken against</span></h2>
481 <p>
482 <span data-l="es">Cada una se abre: en qué se aparta de lo habitual, qué implica por dentro, y qué quiere decir sin jerga.</span>
483 <span data-l="en">Each one opens: how it departs from the usual, what it involves under the hood, and what it means without jargon.</span>
484 </p>
485<div class="diagrama">
486<svg viewBox="0 0 520 470" xmlns="http://www.w3.org/2000/svg">
487 <defs>
488 <linearGradient id="fragua" x1="0" y1="0" x2="0" y2="1">
489 <stop offset="0%" stop-color="#E3A63D"/><stop offset="55%" stop-color="#DF6B2A"/>
490 <stop offset="100%" stop-color="#A63A25"/>
491 </linearGradient>
492 <marker id="punta" viewBox="0 0 8 8" refX="6.5" refY="4" markerWidth="5.5" markerHeight="5.5" orient="auto">
493 <path class="cabeza" d="M0.5,0.5 L7.5,4 L0.5,7.5 Z"/>
494 </marker>
495 </defs>
496
497 <rect x="0" y="14" width="5" height="442" rx="2.5" fill="url(#fragua)"/>
498
499 <rect class="encima" x="26" y="14" width="480" height="58" rx="12"/>
500 <text data-l="es" class="s" x="46" y="40" font-size="18" font-weight="600" text-anchor="start">tawasuyu</text>
501 <text data-l="en" class="s" x="46" y="40" font-size="18" font-weight="600" text-anchor="start">tawasuyu</text>
502 <text data-l="es" class="d" x="46" y="59" font-size="12" font-weight="400" text-anchor="start">el escritorio y la suite, encima</text>
503 <text data-l="en" class="d" x="46" y="59" font-size="12" font-weight="400" text-anchor="start">the desktop and the suite, on top</text>
504 <path class="flecha" d="M266,102 L266,80" marker-end="url(#punta)"/>
505
506 <rect class="caja" x="26" y="104" width="480" height="94" rx="14"/>
507 <text data-l="es" class="d mono" x="46" y="130" font-size="10" font-weight="500" text-anchor="start">EL PISO DE ARRIBA</text>
508 <text data-l="en" class="d mono" x="46" y="130" font-size="10" font-weight="500" text-anchor="start">THE UPPER FLOOR</text>
509 <text data-l="es" class="t" x="46" y="155" font-size="17" font-weight="600" text-anchor="start">Tu máquina, mutable</text>
510 <text data-l="en" class="t" x="46" y="155" font-size="17" font-weight="600" text-anchor="start">Your machine, mutable</text>
511 <text data-l="es" class="s" x="46" y="178" font-size="12.5" font-weight="400" text-anchor="start">/bin · /lib · /etc reales — se rompe, se prueba, se vuelve atrás</text>
512 <text data-l="en" class="s" x="46" y="178" font-size="12.5" font-weight="400" text-anchor="start">a real /bin · /lib · /etc — break it, try it, go back</text>
513
514 <path class="flecha" d="M140,306 L140,210" marker-end="url(#punta)"/>
515 <path class="flecha" d="M392,210 L392,306" marker-end="url(#punta)"/>
516 <text data-l="es" class="a" x="158" y="238" font-size="12.5" font-weight="500" text-anchor="start">hidratación</text>
517 <text data-l="en" class="a" x="158" y="238" font-size="12.5" font-weight="500" text-anchor="start">hydration</text>
518 <text data-l="es" class="s" x="158" y="256" font-size="11.5" font-weight="400" text-anchor="start">enlaces duros desde el almacén</text>
519 <text data-l="en" class="s" x="158" y="256" font-size="11.5" font-weight="400" text-anchor="start">hard links from the store</text>
520 <text data-l="es" class="a" x="374" y="282" font-size="12.5" font-weight="500" text-anchor="end">diario</text>
521 <text data-l="en" class="a" x="374" y="282" font-size="12.5" font-weight="500" text-anchor="end">journal</text>
522 <text data-l="es" class="s" x="374" y="300" font-size="11.5" font-weight="400" text-anchor="end">lo que cambias a mano, registrado</text>
523 <text data-l="en" class="s" x="374" y="300" font-size="11.5" font-weight="400" text-anchor="end">what you change by hand, recorded</text>
524
525 <rect class="caja" x="26" y="316" width="480" height="140" rx="14"/>
526 <text data-l="es" class="d mono" x="46" y="342" font-size="10" font-weight="500" text-anchor="start">EL PISO DE ABAJO</text>
527 <text data-l="en" class="d mono" x="46" y="342" font-size="10" font-weight="500" text-anchor="start">THE LOWER FLOOR</text>
528 <text data-l="es" class="t" x="46" y="367" font-size="17" font-weight="600" text-anchor="start">La fábrica, cerrada</text>
529 <text data-l="en" class="t" x="46" y="367" font-size="17" font-weight="600" text-anchor="start">The factory, closed</text>
530 <text data-l="es" class="s" x="46" y="389" font-size="12.5" font-weight="400" text-anchor="start">compila desde el código fuente, aislada y sin red</text>
531 <text data-l="en" class="s" x="46" y="389" font-size="12.5" font-weight="400" text-anchor="start">builds from source code, sandboxed and offline</text>
532 <rect class="cajita" x="46" y="398" width="440" height="46" rx="10"/>
533 <text data-l="es" class="t" x="62" y="418" font-size="12.5" font-weight="600" text-anchor="start">el almacén</text>
534 <text data-l="en" class="t" x="62" y="418" font-size="12.5" font-weight="600" text-anchor="start">the store</text>
535 <text data-l="es" class="s" x="62" y="435" font-size="11.5" font-weight="400" text-anchor="start">cada artefacto por su hash BLAKE3</text>
536 <text data-l="en" class="s" x="62" y="435" font-size="11.5" font-weight="400" text-anchor="start">every artefact by its BLAKE3 hash</text>
537</svg>
538</div>
539
540 <div class="decisiones">
541<details class="decision">
542<summary><span class="num">01</span><span data-l="es">Una fábrica cerrada abajo, tu máquina de siempre arriba</span><span data-l="en">A closed factory below, your usual machine above</span></summary>
543<dl>
544 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
545 <dd><span data-l="es">Hay que elegir: una distro inmutable, que da reproducibilidad y te quita la terminal, o una clásica, que te la deja y no sabe decir de dónde salió un binario.</span><span data-l="en">You have to choose: an immutable distro, which gives reproducibility and takes the terminal away, or a classic one, which leaves it to you and cannot say where a binary came from.</span></dd>
546 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
547 <dd><span data-l="es">Abajo, compilación aislada y direccionada por hash BLAKE3, sin efectos de borde. Arriba, un Linux con <code>/bin</code>, <code>/lib</code> y <code>/etc</code> de verdad; los binarios se proyectan del almacén por enlaces duros, normalizados para no arrastrar rutas internas. El puente —la hidratación— va en un solo sentido.</span><span data-l="en">Below, sandboxed builds addressed by BLAKE3 hash, with no side effects. Above, a Linux with a real <code>/bin</code>, <code>/lib</code> and <code>/etc</code>; binaries are projected from the store by hard links, normalised so they carry no internal paths. The bridge — hydration — goes one way only.</span></dd>
548 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
549 <dd class="simple"><span data-l="es">La parte que tiene que ser exacta lo es, y la parte donde trabajas sigue siendo un Linux normal. Lo demás de esta lista sale de ahí.</span><span data-l="en">The part that has to be exact is exact, and the part where you work is still an ordinary Linux. Everything else on this list follows from that.</span></dd>
550</dl>
551</details>
552
553<details class="decision">
554<summary><span class="num">02</span><span data-l="es">Se instala con un archivo, sin ISO y sin red</span><span data-l="en">It installs from one file, no ISO and no network</span></summary>
555<dl>
556 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
557 <dd><span data-l="es">Lo normal es bajar un ISO, grabarlo en un pendrive, y que el instalador se baje los paquetes mientras instala — justo en la máquina que todavía no tiene red.</span><span data-l="en">The usual is downloading an ISO, burning it to a stick, and having the installer fetch packages while it installs — on the very machine that has no network yet.</span></dd>
558 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
559 <dd><span data-l="es">El fichero es una cabecera POSIX de shell con el sistema entero pegado detrás: comprueba su propio contenido, se carga en memoria y salta con <code>kexec</code> al instalador, que suelta el disco de la máquina viva para poder formatearlo. <strong>Nada se descarga durante la instalación.</strong> Si ese kernel no deja saltar, lo dice y nombra cuál de las tres condiciones falta; para ese caso está la imagen USB, que es el mismo instalador por otro camino.</span><span data-l="en">The file is a POSIX shell header with the whole system appended: it verifies its own contents, loads into memory and jumps with <code>kexec</code> into the installer, which releases the live machine's disk so it can be formatted. <strong>Nothing is downloaded while installing.</strong> If that kernel will not allow the jump, it says so and names which of the three conditions is missing; for that case there is the USB image, the same installer arriving another way.</span></dd>
560 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
561 <dd class="simple"><span data-l="es">Un archivo, permiso de ejecución, y ya. Se puede leer con <code>head</code> antes de correrlo, no necesita internet, y el disco desde el que arrancaste nunca aparece como destino.</span><span data-l="en">One file, make it executable, done. You can read it with <code>head</code> before running it, it needs no internet, and the disk you booted from is never offered as a target.</span></dd>
562</dl>
563</details>
564
565<details class="decision">
566<summary><span class="num">03</span><span data-l="es">Trae su propio escritorio, y el ecosistema que va encima</span><span data-l="en">It brings its own desktop, and the ecosystem above it</span></summary>
567<dl>
568 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
569 <dd><span data-l="es">Una distribución suele ensamblar escritorios ajenos y ahí termina su alcance: lo que corre encima es problema de otro proyecto.</span><span data-l="en">A distribution usually assembles other people's desktops and that is where its scope ends: what runs on top is another project's problem.</span></dd>
570 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
571 <dd><span data-l="es"><code>mirada</code> es el escritorio propio y viaja en la imagen. Encima está <strong>tawasuyu</strong>, que no es un añadido: comparten el almacén direccionado por contenido, el grafo de arranque y <code>arje</code> —su proceso número uno— como init de las imágenes. Y los cuatro escritorios conocidos están construidos igual, con su clausura sellada: KDE, GNOME, COSMIC y sway.</span><span data-l="en"><code>mirada</code> is the project's own desktop and travels in the image. Above it sits <strong>tawasuyu</strong>, which is not an add-on: they share the content-addressed store, the boot graph and <code>arje</code> — its process number one — as the init of the images. And the four well-known desktops are built the same way, with their closure sealed: KDE, GNOME, COSMIC and sway.</span></dd>
572 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
573 <dd class="simple"><span data-l="es">No es sólo una base para que otros pongan cosas encima: el escritorio y lo que corre en él son parte del mismo proyecto y están pensados juntos. Si prefieres uno conocido, también está.</span><span data-l="en">It is not just a base for others to put things on: the desktop and what runs on it belong to the same project and are designed together. If you prefer a well-known one, it is there too.</span></dd>
574</dl>
575</details>
576
577<details class="decision">
578<summary><span class="num">04</span><span data-l="es">Todo se compila desde fuente, y la fuente está clavada</span><span data-l="en">Everything is compiled from source, and the source is pinned</span></summary>
579<dl>
580 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
581 <dd><span data-l="es">Una distro normal te entrega un binario que compiló otra persona en otra máquina; lo que verificas es la firma de quien lo subió, no lo que hay adentro.</span><span data-l="en">A normal distro hands you a binary somebody else compiled on another machine; what you verify is the signature of whoever uploaded it, not what is inside.</span></dd>
582 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
583 <dd><span data-l="es">Cada receta fija su fuente por <em>commit</em> de git o por <code>sha256</code> — nunca contra una rama viva. El hash del artefacto se deriva de la receta entera: fuente, compilador, banderas, fases de build y los hashes de cada dependencia. <code>takana hash</code> lo calcula sin construir nada.</span><span data-l="en">Each recipe pins its source by git <em>commit</em> or <code>sha256</code> — never against a live branch. The artefact hash is derived from the whole recipe: source, compiler, flags, build phases and the hash of every dependency. <code>takana hash</code> computes it without building anything.</span></dd>
584 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
585 <dd class="simple"><span data-l="es">Nadie te manda comida hecha: te manda la receta y la cocina tu máquina. Y la receta dice exactamente qué ingredientes, no «harina» a secas.</span><span data-l="en">Nobody sends you cooked food: they send the recipe and your machine cooks it. And the recipe names the exact ingredients, not just «flour».</span></dd>
586</dl>
587</details>
588
589<details class="decision">
590<summary><span class="num">05</span><span data-l="es">Reproducible bit a bit — y cuando no, se dice por qué</span><span data-l="en">Bit-for-bit reproducible — and when it isn't, it says why</span></summary>
591<dl>
592 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
593 <dd><span data-l="es">Compilar el mismo paquete dos veces casi nunca da el mismo fichero, y en la práctica nadie lo comprueba: la diferencia se acepta como normal.</span><span data-l="en">Building the same package twice almost never yields the same file, and in practice nobody checks: the difference is accepted as normal.</span></dd>
594 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
595 <dd><span data-l="es">El build corre aislado con <code>bubblewrap</code>, sin red y con la fecha fijada. Cuando dos artefactos difieren, <code>why-differs</code> desciende sólo por donde los hashes no coinciden y <strong>nombra la causa</strong>: un mtime dentro de un <code>.gz</code>, la cabecera <code>ar</code> de un <code>.a</code>, qué sección ELF cambió, una ruta del árbol de build filtrada al binario.</span><span data-l="en">Builds run sandboxed with <code>bubblewrap</code>, without network and with a fixed date. When two artefacts differ, <code>why-differs</code> descends only where the hashes disagree and <strong>names the cause</strong>: an mtime inside a <code>.gz</code>, the <code>ar</code> header of a <code>.a</code>, which ELF section changed, a build-tree path leaked into the binary.</span></dd>
596 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
597 <dd class="simple"><span data-l="es">Si dos personas hacen el mismo paquete, tiene que salir el mismo fichero. Y si sale distinto, el sistema te dice en qué — no te deja adivinando.</span><span data-l="en">If two people build the same package, the same file must come out. And if it doesn't, the system tells you where it differed — it doesn't leave you guessing.</span></dd>
598</dl>
599</details>
600
601<details class="decision">
602<summary><span class="num">06</span><span data-l="es">Un paquete es una receta, no un binario</span><span data-l="en">A package is a recipe, not a binary</span></summary>
603<dl>
604 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
605 <dd><span data-l="es">El repositorio te manda el programa ya hecho, así que hay que confiar en el repositorio — y en cada espejo suyo.</span><span data-l="en">The repository sends you the finished program, so you have to trust the repository — and every one of its mirrors.</span></dd>
606 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
607 <dd><span data-l="es">El índice va firmado con Ed25519 y ancla el <code>digest</code> de cada paquete. <code>install</code> resuelve el nombre, verifica la firma, <strong>reconstruye desde fuente</strong> y recién entonces hidrata. <code>--repo</code> acepta varios orígenes separados por comas y los prueba en orden.</span><span data-l="en">The index is Ed25519-signed and anchors each package's <code>digest</code>. <code>install</code> resolves the name, verifies the signature, <strong>rebuilds from source</strong> and only then hydrates. <code>--repo</code> takes several comma-separated origins and tries them in order.</span></dd>
608 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
609 <dd class="simple"><span data-l="es">El sitio del que lo bajas no necesita ser de fiar, porque no te da el resultado: te da las instrucciones, y se comprueba que sean las firmadas.</span><span data-l="en">The site you download from doesn't need to be trustworthy, because it doesn't give you the result: it gives you the instructions, and they are checked against the signed ones.</span></dd>
610</dl>
611</details>
612
613<details class="decision">
614<summary><span class="num">07</span><span data-l="es">Se reconstruye a sí misma, sin creerle a ningún binario</span><span data-l="en">It rebuilds itself, without trusting anybody's binary</span></summary>
615<dl>
616 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
617 <dd><span data-l="es">El compilador de tu distro salió de un binario que compiló otra máquina, que salió de otro, hacia atrás sin fondo. Ese primer eslabón se cree por fe.</span><span data-l="en">Your distro's compiler came from a binary built by another machine, which came from another, backwards without end. That first link is taken on faith.</span></dd>
618 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
619 <dd><span data-l="es">Cadena de Rust pura de <code>mrustc</code> a <code>rustc</code>, kernel Linux compilado acá que arranca la máquina, y el toolchain reconstruyéndose a sí mismo dentro de una máquina virtual. Hecho dos veces: mismo resultado, bit por bit.</span><span data-l="en">A pure Rust chain from <code>mrustc</code> to <code>rustc</code>, a Linux kernel built here that boots the machine, and the toolchain rebuilding itself inside a virtual machine. Done twice: same result, bit for bit.</span></dd>
620 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
621 <dd class="simple"><span data-l="es">La distro se puede fabricar a sí misma casi desde cero. No queda un eslabón que haya que aceptar sin poder mirarlo.</span><span data-l="en">The distro can manufacture itself from near zero. No link is left that you must accept without being able to look at it.</span></dd>
622</dl>
623</details>
624
625<details class="decision">
626<summary><span class="num">08</span><span data-l="es">musl, estático, y <code>zig cc</code> de compilador</span><span data-l="en">musl, static, and <code>zig cc</code> as the compiler</span></summary>
627<dl>
628 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
629 <dd><span data-l="es">Lo habitual es glibc y enlazado dinámico: actualizar una librería puede romper un programa que no tocaste, y descubrirlo al arrancarlo.</span><span data-l="en">The usual is glibc and dynamic linking: updating one library can break a program you never touched, and you find out when you launch it.</span></dd>
630 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
631 <dd><span data-l="es"><code>zig cc</code> es el compilador por defecto del laboratorio —trae los headers y la libc de cada target, sin cross-toolchain a mano— y es reemplazable receta por receta. El rootfs del lab se ancla a una imagen pineada por <code>sha256</code>, no se resuelve con un gestor de paquetes.</span><span data-l="en"><code>zig cc</code> is the lab's default compiler — it brings each target's headers and libc, with no hand-built cross-toolchain — and is replaceable recipe by recipe. The lab rootfs is pinned to an image by <code>sha256</code>, not resolved by a package manager.</span></dd>
632 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
633 <dd class="simple"><span data-l="es">Cada programa se lleva sus piezas adentro, así que tocar uno no rompe a los demás. Y el código de la libc es lo bastante chico como para leerlo.</span><span data-l="en">Each program carries its pieces inside, so touching one doesn't break the others. And the libc's code is small enough to actually read.</span></dd>
634</dl>
635</details>
636
637<details class="decision">
638<summary><span class="num">09</span><span data-l="es">Sin systemd: el init es propio y el arranque es un grafo</span><span data-l="en">No systemd: the init is our own and boot is a graph</span></summary>
639<dl>
640 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
641 <dd><span data-l="es">El arranque lo gobierna un binario grande con formato de unidades propio y un registro binario que hay que consultar con su propia herramienta.</span><span data-l="en">Boot is governed by a large binary with its own unit format and a binary log you must query with its own tool.</span></dd>
642 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
643 <dd><span data-l="es"><code>arje-zero</code> es el proceso número uno, estático contra musl. Los servicios se declaran en <em>Cards</em> JSON, con supervisión y reintento con backoff, y hablan por un socket Unix con <code>SO_PEERCRED</code>. El menú de arranque es la navegación del grafo de estados del sistema.</span><span data-l="en"><code>arje-zero</code> is process number one, statically linked against musl. Services are declared in JSON <em>Cards</em>, with supervision and backoff restarts, and talk over a Unix socket with <code>SO_PEERCRED</code>. The boot menu is navigation of the system's state graph.</span></dd>
644 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
645 <dd class="simple"><span data-l="es">Lo que enciende tu máquina se puede leer con un editor de texto y contar de memoria. No hay una pieza central que decida por ti y cueste inspeccionar.</span><span data-l="en">What starts your machine can be read in a text editor and held in your head. There is no central piece deciding for you that is hard to inspect.</span></dd>
646</dl>
647</details>
648
649<details class="decision">
650<summary><span class="num">10</span><span data-l="es">Romper a mano está permitido — y se puede volver</span><span data-l="en">Breaking things by hand is allowed — and you can come back</span></summary>
651<dl>
652 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
653 <dd><span data-l="es">Las inmutables no te dejan tocar sin aprender antes un lenguaje declarativo; las clásicas te dejan tocar y después el gestor de paquetes pierde el rastro de lo que hiciste.</span><span data-l="en">Immutable ones won't let you touch anything until you learn a declarative language; classic ones let you touch and then the package manager loses track of what you did.</span></dd>
654 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
655 <dd><span data-l="es"><code>try</code> monta un overlay sobre el FHS real; <code>commit</code> lo promueve y <code>discard</code> lo tira. Un demonio <code>fanotify</code> registra cada cambio a mano y calcula el delta contra la base limpia; <code>export</code> lo convierte en un manifiesto compartible.</span><span data-l="en"><code>try</code> mounts an overlay over the real FHS; <code>commit</code> promotes it and <code>discard</code> throws it away. A <code>fanotify</code> daemon records every hand edit and computes the delta against the clean base; <code>export</code> turns it into a shareable manifest.</span></dd>
656 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
657 <dd class="simple"><span data-l="es">Prueba lo que quieras: si sale mal se desmonta la capa y listo. Y lo que cambiaste a mano queda anotado solo — el registro <em>es</em> tu configuración, sin que hayas escrito ninguna.</span><span data-l="en">Try whatever you want: if it goes wrong the layer is unmounted and that's it. And what you changed by hand gets written down on its own — the log <em>is</em> your configuration, without you having written one.</span></dd>
658</dl>
659</details>
660
661<details class="decision">
662<summary><span class="num">11</span><span data-l="es">Wayland y nada más; el audio es PipeWire</span><span data-l="en">Wayland and nothing else; audio is PipeWire</span></summary>
663<dl>
664 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
665 <dd><span data-l="es">Casi todas arrastran X11 y varios servidores de audio a la vez por compatibilidad, y mantienen los dos caminos para siempre.</span><span data-l="en">Almost all of them drag X11 and several audio servers along for compatibility, and maintain both paths forever.</span></dd>
666 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
667 <dd><span data-l="es">Ninguna receta del catálogo publica <code>libGL.so</code> de escritorio ni GLX: las aplicaciones de gráficos van por EGL, y a las que no sabían hubo que portarlas. El audio es <code>pipewire</code> con <code>wireplumber</code>, como servicio de sesión, sin capa de compatibilidad permanente.</span><span data-l="en">No recipe in the catalogue ships a desktop <code>libGL.so</code> or GLX: graphics applications go through EGL, and the ones that didn't know how had to be ported. Audio is <code>pipewire</code> with <code>wireplumber</code>, as a session service, with no permanent compatibility layer.</span></dd>
668 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
669 <dd class="simple"><span data-l="es">Se eligió el camino nuevo y se borró el viejo, en vez de cargar los dos para siempre. Cuesta más al principio y se paga una sola vez.</span><span data-l="en">The new path was chosen and the old one deleted, instead of carrying both forever. It costs more up front and is paid only once.</span></dd>
670</dl>
671</details>
672
673<details class="decision">
674<summary><span class="num">12</span><span data-l="es">Lo ajeno corre enjaulado, y fuera del almacén</span><span data-l="en">Foreign software runs caged, and outside the store</span></summary>
675<dl>
676 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
677 <dd><span data-l="es">O se mezclan binarios de terceros con los del sistema —y ya no se sabe de dónde salió cada cosa—, o directamente no hay forma de correrlos.</span><span data-l="en">Either third-party binaries get mixed in with the system's — and then you no longer know where anything came from — or there is simply no way to run them.</span></dd>
678 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
679 <dd><span data-l="es">Un rootfs de otra distribución se trae pineado por <code>digest</code> y corre enjaulado con <code>bubblewrap</code> sobre el mismo kernel, sin compartir un solo <code>.so</code> con el anfitrión. <strong>No entra al store</strong>: no reproduce desde fuente, y meterlo ahí haría que el almacén mienta.</span><span data-l="en">Another distribution's rootfs is fetched pinned by <code>digest</code> and runs caged with <code>bubblewrap</code> on the same kernel, without sharing a single <code>.so</code> with the host. <strong>It does not enter the store</strong>: it does not reproduce from source, and putting it there would make the store lie.</span></dd>
680 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
681 <dd class="simple"><span data-l="es">Lo que no se puede cocinar acá igual se usa, pero en su propia caja y sin mezclarse. Así el catálogo no dice «esto es mío» de algo que no lo es.</span><span data-l="en">What cannot be cooked here is still used, but in its own box and unmixed. That way the catalogue never claims as its own something that isn't.</span></dd>
682</dl>
683</details>
684
685<details class="decision">
686<summary><span class="num">13</span><span data-l="es">Hecha para que una IA la opere, con el humano decidiendo</span><span data-l="en">Built for an AI to operate it, with the human deciding</span></summary>
687<dl>
688 <dt><span data-l="es">Frente a lo habitual</span><span data-l="en">Compared to the usual</span></dt>
689 <dd><span data-l="es">Están pensadas para manos humanas: la automatización termina simulando a una persona —parsear salidas, adivinar formatos— y el sistema esconde su estado en bases binarias.</span><span data-l="en">They are designed for human hands: automation ends up simulating a person — parsing output, guessing formats — and the system hides its state in binary databases.</span></dd>
690 <dt><span data-l="es">Técnicamente</span><span data-l="en">Technically</span></dt>
691 <dd><span data-l="es">Todo el estado del sistema es texto plano y binarios inspeccionables con <code>readelf</code> u <code>objdump</code>; nada de bases de configuración opacas. Hay un bus por socket Unix por el que un agente dispara compilaciones, escucha fallos y propone cambios — siempre contra un overlay, nunca contra el sistema vivo.</span><span data-l="en">All system state is plain text and binaries inspectable with <code>readelf</code> or <code>objdump</code>; no opaque configuration databases. There is a Unix-socket bus through which an agent triggers builds, listens for failures and proposes changes — always against an overlay, never against the live system.</span></dd>
692 <dt class="simple"><span data-l="es">En simple</span><span data-l="en">In plain words</span></dt>
693 <dd class="simple"><span data-l="es">Un asistente puede entender y cambiar el sistema entero sin adivinar nada, y cada cosa que hace es reversible y queda anotada. Propone; tú dispones.</span><span data-l="en">An assistant can understand and change the whole system without guessing, and everything it does is reversible and recorded. It proposes; you decide.</span></dd>
694</dl>
695</details>
696 </div>
697</div></section>
698
699<section class="franja t-panel" id="componentes" role="tabpanel" aria-labelledby="tab-componentes"><div class="envoltura">
700 <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">03 · los componentes</span><span data-l="en">03 · the components</span></p>
701 <h2><span data-l="es">Qué lleva dentro</span><span data-l="en">What is inside</span></h2>
702
703 <table class="ficha">
704 <thead><tr>
705 <th><span data-l="es">pieza</span><span data-l="en">piece</span></th>
706 <th><span data-l="es">versión</span><span data-l="en">version</span></th>
707 <th></th>
708 </tr></thead>
709 <tbody>
710 <tr><td><span data-l="es">init</span><span data-l="en">init</span></td><td class="n">arje-zero</td><td><span data-l="es">el proceso número uno, estático contra musl; los servicios se declaran en Cards JSON</span><span data-l="en">process number one, statically linked against musl; services are declared in JSON Cards</span></td></tr>
711 <tr><td>libc</td><td class="n">musl 1.2.5</td><td><span data-l="es">estática por defecto</span><span data-l="en">static by default</span></td></tr>
712 <tr><td><span data-l="es">compilador del laboratorio</span><span data-l="en">laboratory compiler</span></td><td class="n">zig cc 0.16.0</td><td><span data-l="es">reemplazable receta por receta; también hay LLVM 21.1.2 y clang 18.1.8</span><span data-l="en">replaceable recipe by recipe; LLVM 21.1.2 and clang 18.1.8 are there too</span></td></tr>
713 <tr><td>kernel</td><td class="n">Linux 6.16.12 · 7.1.2</td><td><span data-l="es">compilados acá; arrancan la máquina y reproducen idénticos</span><span data-l="en">built here; they boot the machine and reproduce identically</span></td></tr>
714 <tr><td><span data-l="es">gráficos</span><span data-l="en">graphics</span></td><td class="n">Wayland 1.25.0 · Mesa 24.0.9</td><td><span data-l="es">sin X11 en todo el catálogo</span><span data-l="en">no X11 anywhere in the catalogue</span></td></tr>
715 <tr><td><span data-l="es">audio</span><span data-l="en">audio</span></td><td class="n">PipeWire 1.2.7 · WirePlumber 0.5.15</td><td><span data-l="es">servicio de sesión</span><span data-l="en">session service</span></td></tr>
716 <tr><td><span data-l="es">almacén</span><span data-l="en">store</span></td><td class="n">BLAKE3</td><td><span data-l="es"><strong>1.490 artefactos</strong> direccionados por contenido</span><span data-l="en"><strong>1,490 artefacts</strong> addressed by content</span></td></tr>
717 <tr><td><span data-l="es">catálogo</span><span data-l="en">catalogue</span></td><td class="n">954</td><td><span data-l="es">recetas, <strong>las 954 selladas</strong>, sin deuda</span><span data-l="en">recipes, <strong>all 954 sealed</strong>, no debt</span></td></tr>
718 <tr><td><span data-l="es">paquetes</span><span data-l="en">packages</span></td><td class="n">.tkn</td><td><span data-l="es">índice firmado Ed25519; se reconstruyen desde fuente al instalar</span><span data-l="en">Ed25519-signed index; rebuilt from source on install</span></td></tr>
719 <tr><td><span data-l="es">herramienta</span><span data-l="en">tool</span></td><td class="n">takana 0.0.1</td><td><code>build · hash · hydrate · install · kernel · qorpa</code></td></tr>
720 </tbody>
721 </table>
722
723 <h3><span data-l="es">Escritorios</span><span data-l="en">Desktops</span></h3>
724 <table>
725 <thead><tr>
726 <th><span data-l="es">escritorio</span><span data-l="en">desktop</span></th>
727 <th><span data-l="es">versión</span><span data-l="en">version</span></th>
728 <th><span data-l="es">de su clausura, sellados</span><span data-l="en">of its closure, sealed</span></th>
729 </tr></thead>
730 <tbody>
731 <tr><td><code>mirada</code></td><td class="n"><span data-l="es">propio</span><span data-l="en">our own</span></td><td class="n">41/41</td></tr>
732 <tr><td>KDE Plasma</td><td class="n">6.7.2</td><td class="n">430/431</td></tr>
733 <tr><td>GNOME</td><td class="n">48.8</td><td class="n">359/359</td></tr>
734 <tr><td>COSMIC</td><td class="n">1.5.0</td><td class="n">294/294</td></tr>
735 <tr><td>sway</td><td class="n">1.10</td><td class="n">281/281</td></tr>
736 </tbody>
737 </table>
738
739 <h3><span data-l="es">Paquetes principales</span><span data-l="en">Main packages</span></h3>
740 <ul class="versiones">
741 <li><b>bash</b><span>5.3</span></li>
742 <li><b>coreutils</b><span>9.8</span></li>
743 <li><b>uutils</b><span>0.9.0</span></li>
744 <li><b>busybox</b><span>1.36.1</span></li>
745 <li><b>git</b><span>2.54.0</span></li>
746 <li><b>curl</b><span>8.20.0</span></li>
747 <li><b>openssl</b><span>3.5.4</span></li>
748 <li><b>openssh</b><span>10.3p1</span></li>
749 <li><b>gnupg</b><span>2.4.9</span></li>
750 <li><b>python</b><span>3.12.10</span></li>
751 <li><b>go</b><span>1.26.4</span></li>
752 <li><b>rust</b><span>1.97.0</span></li>
753 <li><b>llvm</b><span>21.1.2</span></li>
754 <li><b>sqlite</b><span>3.46.1</span></li>
755 <li><b>zstd</b><span>1.5.7</span></li>
756 <li><b>ffmpeg</b><span>7.1</span></li>
757 <li><b>vim</b><span>9.2.0747</span></li>
758 <li><b>nano</b><span>9.0</span></li>
759 <li><b>helix</b><span>25.07.1</span></li>
760 <li><b>ripgrep</b><span>14.1.1</span></li>
761 <li><b>zellij</b><span>0.44.3</span></li>
762 <li><b>foot</b><span>1.27.0</span></li>
763 <li><b>firefox</b><span>154.0</span></li>
764 <li><b>atuq</b><span>0.5.0</span></li>
765 </ul>
766
767 <p class="nota">
768 <span data-l="es">Las versiones salen de las recetas del catálogo y las cifras de <code>docs/state/build-state.json</code> y del almacén de la caja. No se estiman: se cuentan. Lo que sigue abierto también está escrito: consenso de reconstrucción M-de-N.</span>
769 <span data-l="en">Versions come from the catalogue's recipes and the figures from <code>docs/state/build-state.json</code> and the box's store. They are not estimated: they are counted. What is still open is written down too: M-of-N rebuild consensus.</span>
770 </p>
771</div></section>
772
773<section class="franja t-panel" id="codigo" role="tabpanel" aria-labelledby="tab-codigo"><div class="envoltura">
774 <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">04 · el código</span><span data-l="en">04 · the code</span></p>
775 <h2><span data-l="es">Dónde vive y cómo se llama</span><span data-l="en">Where it lives and how it is called</span></h2>
776
777 <div class="direccion">
778 <p class="etiqueta"><span data-l="es">código · licencia MIT</span><span data-l="en">code · MIT licence</span></p>
779 <a class="url" href="https://git.gioser.net/sergio/takana">https://git.gioser.net/sergio/takana</a>
780 </div>
781
782 <div class="direccion">
783 <p class="etiqueta"><span data-l="es">paquetes · índice firmado</span><span data-l="en">packages · signed index</span></p>
784 <a class="url" href="/repo/">https://takana-os.net/repo/</a>
785 </div>
786
787 <div class="marco">
788 <h3><span data-l="es">Cómo está repartido</span><span data-l="en">How it is laid out</span></h3>
789 <ul class="limpia">
790 <li><code>crates/</code> — <span data-l="es">el CLI, el laboratorio de build, el demonio, el diario y el overlay.</span><span data-l="en">the CLI, the build lab, the daemon, the journal and the overlay.</span></li>
791 <li><code>recipes/</code> — <span data-l="es">el catálogo: una receta <code>.toml</code> por paquete.</span><span data-l="en">the catalogue: one <code>.toml</code> recipe per package.</span></li>
792 <li><code>docs/</code> — <span data-l="es">el diseño entero (SDD y ADR). Empieza por <code>00-vision.md</code>.</span><span data-l="en">the entire design (SDDs and ADRs). Start at <code>00-vision.md</code>.</span></li>
793 <li><code>scripts/</code> — <span data-l="es">la granja de compilación, la cosecha y los arneses de verificación.</span><span data-l="en">the build farm, the harvest and the verification harnesses.</span></li>
794 </ul>
795 </div>
796
797<div class="bloque">
798 <p class="rotulo"><span data-l="es">el laboratorio</span><span data-l="en">the laboratory</span></p>
799 <div class="codigo"><pre>$ takana hash ripgrep <span class="c"># <span data-l="es">el hash vigente, sin construir</span><span data-l="en">the current hash, without building</span></span>
800<span class="p">$</span> takana build ripgrep <span class="c"># <span data-l="es">compila aislado y sella en el almacén</span><span data-l="en">builds sandboxed and seals into the store</span></span>
801<span class="p">$</span> takana why-differs a/ b/ <span class="c"># <span data-l="es">nombra la causa de una diferencia</span><span data-l="en">names the cause of a difference</span></span></pre></div>
802 </div>
803
804 <div class="bloque">
805 <p class="rotulo"><span data-l="es">los paquetes</span><span data-l="en">packages</span></p>
806 <div class="codigo"><pre>$ takana repo list --repo https://takana-os.net/repo
807<span class="p">$</span> takana repo verify --repo https://takana-os.net/repo --trust ./trust
808<span class="p">$</span> takana install age --repo https://takana-os.net/repo --trust ./trust</pre></div>
809 </div>
810
811 <div class="bloque">
812 <p class="rotulo"><span data-l="es">el sistema vivo</span><span data-l="en">the live system</span></p>
813 <div class="codigo"><pre>$ takana try <span class="c"># <span data-l="es">abre el overlay sobre el sistema real</span><span data-l="en">opens the overlay over the real system</span></span>
814<span class="p">$</span> takana journal <span class="c"># <span data-l="es">lo que cambiaste a mano, registrado</span><span data-l="en">what you changed by hand, recorded</span></span>
815<span class="p">$</span> takana commit <span class="c"># <span data-l="es">promueve · <code>discard</code> lo descarta</span><span data-l="en">promotes · <code>discard</code> throws it away</span></span></pre></div>
816 </div>
817</div></section>
818
819<footer class="pie"><div class="envoltura">
820 <div class="pie-rejilla">
821 <div>
822 <a class="casa" href="https://git.gioser.net/sergio/takana"><span data-l="es">El repositorio</span><span data-l="en">The repository</span> ↗</a>
823 <p>git.gioser.net/sergio/takana</p>
824 </div>
825 <div>
826 <a class="casa" href="/repo/"><span data-l="es">Paquetes</span><span data-l="en">Packages</span></a>
827 <p>takana-os.net/repo</p>
828 </div>
829 <div>
830 <a class="casa" href="https://tawasuyu.net">tawasuyu.net ↗</a>
831 <p><span data-l="es">El territorio que se para encima.</span><span data-l="en">The territory that stands on top.</span></p>
832 </div>
833 <div>
834 <a class="casa" href="https://hifas.gioser.net">hifas ↗</a>
835 <p><span data-l="es">Réplicas sin coordinarse, con demostración.</span><span data-l="en">Replicas without coordination, with a proof.</span></p>
836 </div>
837 </div>
838 <p class="pie-fin">
839 <span data-l="es">takana · licencia MIT · esta página se sirve del propio repositorio (<code>web/takana-os.net/</code>) y no le pide nada a terceros: las tipografías —Chivo e IBM Plex, ambas SIL OFL— viajan con ella.</span>
840 <span data-l="en">takana · MIT licence · this page is served from the repository itself (<code>web/takana-os.net/</code>) and asks nothing of third parties: the typefaces — Chivo and IBM Plex, both SIL OFL — travel with it.</span>
841 </p>
842</div></footer>
843</div>
844
845<script>
846(function(){
847 var r=document.documentElement;
848 function pintar(){
849 var l=r.dataset.lang;
850 document.querySelectorAll('[data-poner-lang]').forEach(function(b){
851 b.classList.toggle('on', b.dataset.ponerLang===l);
852 });
853 r.setAttribute('lang', l);
854 }
855 try{ var g=localStorage.getItem('takana-lang'); if(g) r.dataset.lang=g;
856 }catch(e){}
857 if(!r.dataset.lang) r.dataset.lang = (navigator.language||'es').slice(0,2)==='es' ? 'es' : 'en';
858 pintar();
859 var bIdioma=document.getElementById('t-idioma');
860 if (bIdioma) [bIdioma].forEach(function(b){
861 b.addEventListener('click', function(){
862 r.dataset.lang = r.dataset.lang==='es' ? 'en' : 'es'; pintar();
863 if(SEL) pinta(vAhora); // la coma decimal del peso cambia con el idioma
864 try{ localStorage.setItem('takana-lang', r.dataset.lang); }catch(e){}
865 });
866 });
867
868 /* ── las descargas se arman ACÁ, no en el HTML ──────────────────────────────────
869 Ninguna URL de instalador está en el documento: se compone al pulsar el
870 selector. Un rastreador que lee el HTML no encuentra ninguna, y estos ficheros
871 pesan de 81 MiB a 8,6 GiB — no son para que se los baje un bot. */
872 var SEL = document.getElementById('variantes'), vAhora = 'mirada', pinta;
873 if (SEL) {
874 var DIR = '/de'+'scargas/', PRE = 'takana-'+'instalador-';
875 var PESO = { base: {sh:85315515, img:374341632},
876 mirada: {sh:327408298, img:1073741824},
877 servidor: {sh:405422449, img:2535456768},
878 full: {sh:0, img:9230614528} };
879 var notaFull=document.getElementById('nota-full');
880 var bSh=document.getElementById('bloque-sh'),
881 preSh=document.getElementById('cmd-sh'), preImg=document.getElementById('cmd-img'),
882 pSh=document.getElementById('peso-sh'), pImg=document.getElementById('peso-img');
883
884 function tam(b){
885 if(!b) return '';
886 var coma = r.dataset.lang==='es' ? ',' : '.';
887 return b>=1073741824 ? (b/1073741824).toFixed(1).replace('.',coma)+' GiB'
888 : Math.round(b/1048576)+' MiB';
889 }
890 function esc(t){ return t.replace(/&/g,'&').replace(/</g,'<'); }
891 function cmd(t,u){ return '<span class="p">$</span> '+esc(t)+(u?'<a href="'+u+'">'+esc(u)+'</a>':''); }
892 /* el peso REAL, por si el instalador se reconstruyó: un HEAD lo corrige solo.
893 Si falla, se queda el medido — nunca en blanco. */
894 function pesar(u,donde){ try{
895 fetch(u,{method:'HEAD'}).then(function(res){
896 var n=parseInt(res.headers.get('content-length'),10);
897 if(n>0) donde.textContent=tam(n);
898 })['catch'](function(){});
899 }catch(e){} }
900
901 pinta = function(v){
902 vAhora = v;
903 var raiz=location.protocol+'//'+location.host, sh=PRE+v+'.sh', img=PRE+'usb-'+v+'.img';
904 var hay = !!PESO[v].sh;
905 /* `full` no tiene archivo único. El bloque NO se esconde: se queda del mismo
906 tamaño con el aviso adentro, para que la página no salte al elegir. */
907 bSh.classList.toggle('novale', !hay);
908 preSh.innerHTML = hay
909 ? [cmd('curl -LO ', raiz+DIR+sh), cmd('chmod +x '+sh), cmd('sudo ./'+sh)].join('\n')
910 : '<span class="vacio">— ' + (r.dataset.lang==='es' ? 'sin archivo único · sólo USB'
911 : 'no single file · USB only') + '</span>';
912 preImg.innerHTML = [cmd('curl -LO ', raiz+DIR+img),
913 cmd('sudo dd if='+img+' of=/dev/sdX bs=4M oflag=sync status=progress')].join('\n');
914 pSh.textContent = tam(PESO[v].sh); pImg.textContent = tam(PESO[v].img);
915 if(hay) pesar(DIR+sh,pSh);
916 pesar(DIR+img,pImg);
917 /* `full` tiene dos cosas que hay que decir ANTES de bajar 17 GiB: el tamaño del pendrive
918 que pide, y que GNOME no está — con su motivo, para que no se lea como un olvido. */
919 if(notaFull) notaFull.hidden = (v!=='full');
920 SEL.querySelectorAll('.opcion').forEach(function(b){ b.classList.toggle('on', b.dataset.v===v); });
921 };
922 SEL.querySelectorAll('.opcion').forEach(function(b){
923 b.addEventListener('click', function(){ pinta(b.dataset.v); });
924 });
925 pinta(vAhora);
926 }
927
928 /* un botón de copiar por bloque de comandos, puesto desde acá para no repetirlo
929 diez veces en el HTML. Copia sin el `$` del prompt. */
930 function rotulo(txt_es, txt_en){
931 return '<span data-l="es">'+txt_es+'</span><span data-l="en">'+txt_en+'</span>';
932 }
933 document.querySelectorAll('.codigo').forEach(function(c){
934 var b=document.createElement('button');
935 b.className='copiar'; b.type='button';
936 b.innerHTML=rotulo('copiar','copy');
937 b.addEventListener('click', function(){
938 var t=c.querySelector('pre').innerText.replace(/^\$ /gm,'');
939 var ok=function(){
940 b.classList.add('ok'); b.innerHTML=rotulo('copiado ✓','copied ✓');
941 setTimeout(function(){ b.classList.remove('ok'); b.innerHTML=rotulo('copiar','copy'); },1600);
942 };
943 if(navigator.clipboard && navigator.clipboard.writeText){
944 navigator.clipboard.writeText(t).then(ok,function(){});
945 } else {
946 var ta=document.createElement('textarea'); ta.value=t; document.body.appendChild(ta);
947 ta.select(); try{ document.execCommand('copy'); ok(); }catch(e){}
948 document.body.removeChild(ta);
949 }
950 });
951 c.appendChild(b);
952 });
953
954})();
955
956
957</script>
958<script src="franja.js"></script>
959<script>
960/* ── las pestañas de las cuatro secciones ───────────────────────────────────────────────────────
961 La franja —el símbolo que sube desde la portada, las pestañas que se vuelven el menú, el gesto de
962 deslizar entre secciones y la señal de lectura— es `franja.js`, la misma de gioser.net y
963 tawasuyu.net. Es una COPIA de la de gioser-web (allí `scripts/franja-copias.sh` compara las
964 tres): este sitio no le pide nada a terceros. Acá queda lo de esta página: mostrar la sección
965 elegida, el `#` de la dirección y los enlaces internos. Sin JS se ven las cuatro. */
966(function(){
967 var cuerpo=document.querySelector('.t-cuerpo'), barra=document.getElementById('t-tabs');
968 var tabs=[].slice.call(document.querySelectorAll('.t-tab'));
969 if(!cuerpo||!barra||!window.Franja) return;
970 function elegir(id){
971 // sin un id que sea de una pestaña no se toca nada (al cargar sin ancla, «Descargar» queda)
972 if(!tabs.some(function(t){return t.dataset.tab===id})) return false;
973 tabs.forEach(function(t){ var on=t.dataset.tab===id;
974 t.setAttribute('aria-selected',String(on)); t.tabIndex=on?0:-1;
975 var panel=document.getElementById(t.dataset.tab); if(panel) panel.classList.toggle('activo',on); });
976 try{ history.replaceState(null,'','#'+id); }catch(e){}
977 return true;
978 }
979 tabs.forEach(function(t){ t.tabIndex = t.getAttribute('aria-selected')==='true' ? 0 : -1; });
980 var franja=window.Franja({
981 franja:document.getElementById('t-franja'),
982 marca:document.querySelector('#t-marca .simbolo'),
983 grande:document.querySelector('.t-tarjeta .titular .simbolo'),
984 glifos:document.getElementById('t-glifos'),
985 cuerpo:cuerpo,
986 inicio:document.getElementById('t-marca'),
987 barra:barra, tabs:tabs, rotulo:'.rot', varTop:'--t-tabs-top', margen:110,
988 apagar:[document.querySelector('.t-tarjeta')],
989 inicioBarra:function(){ return cuerpo.getBoundingClientRect().top; },
990 zonaGesto:cuerpo, senal:true,
991 id:function(t){ return t.dataset.tab; },
992 panel:function(){ return document.querySelector('.t-panel.activo'); },
993 elegir:elegir
994 });
995 // un enlace con ancla a una sección (#codigo, #descargar…) abre esa pestaña
996 var pedido=decodeURIComponent((location.hash||'').slice(1));
997 if(elegir(pedido)) franja.irALista();
998 addEventListener('hashchange',function(){ if(elegir(decodeURIComponent((location.hash||'').slice(1)))) franja.irALista(); });
999 document.addEventListener('click',function(e){ var a=e.target.closest('a[href^="#"]'); if(!a) return;
1000 var id=a.getAttribute('href').slice(1); if(tabs.some(function(t){return t.dataset.tab===id})){
1001 e.preventDefault(); elegir(id); franja.irALista(); } });
1002})();
1003</script>
1004</body>
1005</html>