top of page

My Mexica Aztec Calendar

Sep 14
3 min read

By: Mr. Philip S. Wathen Jr.


<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width,initial-scale=1">

<title>Mexica 365-Day Calendar</title>

<style>

:root{

--bg:#0e0d0c; --panel:#1a1817; --line:#332f2c;

--ink:#e8e2d9; --dim:#8d857c; --acc:#c8553d; --gold:#d4a24c;

}

*{box-sizing:border-box}

body{margin:0;padding:24px;background:var(--bg);color:var(--ink);

font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}

h1{font-size:20px;margin:0 0 4px;letter-spacing:.06em;font-weight:600}

.sub{color:var(--dim);font-size:12px;margin-bottom:24px}

.today{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acc);

padding:18px 20px;margin-bottom:24px}

.today .big{font-size:26px;color:var(--gold);letter-spacing:.02em}

.today .row{color:var(--dim);font-size:12px;margin-top:8px}

.controls{display:flex;gap:12px;flex-wrap:wrap;align-items:center;margin-bottom:20px}

input[type=date]{background:var(--panel);border:1px solid var(--line);color:var(--ink);

padding:6px 10px;font:inherit;border-radius:3px}

button{background:var(--panel);border:1px solid var(--line);color:var(--ink);

padding:6px 14px;font:inherit;border-radius:3px;cursor:pointer}

button:hover{border-color:var(--acc)}

.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}

.v{background:var(--panel);border:1px solid var(--line);padding:10px 12px;border-radius:3px}

.v.current{border-color:var(--gold);box-shadow:0 0 0 1px var(--gold) inset}

.v .nm{font-size:12px;color:var(--gold);letter-spacing:.03em}

.v .pos{font-size:10px;color:var(--dim)}

.v .days{display:flex;flex-wrap:wrap;gap:2px;margin-top:8px}

.d{width:16px;height:16px;font-size:9px;display:flex;align-items:center;

justify-content:center;background:#221f1d;color:var(--dim);border-radius:2px}

.d.ev{background:var(--acc);color:#fff;font-weight:700}

.d.today{background:var(--gold);color:#000;font-weight:700}

.nem{grid-column:1/-1;border-style:dashed}

.evlist{margin-top:24px;background:var(--panel);border:1px solid var(--line);padding:16px 20px}

.evlist h2{font-size:13px;color:var(--gold);margin:0 0 10px;letter-spacing:.05em}

.evlist div{font-size:12px;color:var(--dim);padding:3px 0;border-bottom:1px solid #262322}

.evlist div span{color:var(--ink)}

footer{margin-top:32px;color:var(--dim);font-size:11px;line-height:1.7}

</style>

</head>

<body>


<h1>MEXICA 365-DAY CALENDAR</h1>

<div class="sub">18 veintenas × 20 days + 5 Nemontemi · structural layer</div>


<div class="today">

<div class="big" id="todayName">—</div>

<div class="row" id="todayDetail">—</div>

</div>


<div class="controls">

<input type="date" id="picker">

<button onclick="setToday()">Today</button>

</div>


<div class="grid" id="grid"></div>


<div class="evlist">

<h2>RITUAL EVENTS — CURRENT YEAR</h2>

<div id="events">—</div>

</div>


<footer>

Epoch A₀ = 13 Feb 1519 Julian (JDN 2275916) = Atlcahualo day 1.<br>

365-day recurrence. No leap day encoded. Intercalation is a separate hypothesis.<br>

Blank day slots indicate no secure ordinalized event — not absence of ritual.

</footer>


<script>

const EPOCH = 2275916; // 13 Feb 1519 Julian = Atlcahualo day 1


const VEINTENAS = [

[1,"Atlcahualo","Cuauhtlehua, Xilomanaliztli"],

[2,"Tlacaxipehualiztli",""],

[3,"Tozoztontli","Tozoztli"],

[4,"Huey Tozoztli","Hueytozoztli"],

[5,"Tóxcatl","Tepopochhuiliztli"],

[6,"Etzalcualiztli",""],

[7,"Tecuilhuitontli","Tecuilhuitl, Tecuilhuitzintli"],

[8,"Huey Tecuilhuitl",""],

[9,"Tlaxochimaco","Miccailhuitl, Miccailhuitontli"],

[10,"Xócotl Huetzi","Huey Miccailhuitl"],

[11,"Ochpaniztli",""],

[12,"Teotleco","Pachtli, Pachtontli"],

[13,"Tepeilhuitl","Huey Pachtli"],

[14,"Quecholli",""],

[15,"Panquetzaliztli",""],

[16,"Atemoztli",""],

[17,"Tititl",""],

[18,"Izcalli",""]

];


const EVENTS = {

1:{}, 2:{20:"Principal concluding ceremony"},

3:{1:"Tlaloc festival"}, 4:{1:"Cinteotl / maize festival"},

5:{}, 6:{4:"Fasting complex — 4th day"},

7:{}, 8:{1:"Xilonen festival",10:"Xilonen impersonator sacrifice"},

9:{1:"Huitzilopochtli / flower festival"},

10:{1:"Xiuhtecuhtli / xocotl ceremony"},

11:{1:"Toci / Teteoinnan festival"},

12:{16:"Teotleco interval begins",17:"Teotleco interval",

18:"Teotleco interval",19:"Teotleco interval",20:"Teotleco interval ends"},

13:{}, 14:{10:"Zacatepec journey",11:"Hunt"},

15:{2:"Songs and dances begin",9:"Victims prepared",

16:"Slave owners fast",19:"Serpent dance"},

16:{4:"Nexpixolo — closes Panquetzaliztli sequence"},

17:{}, 18:{10:"New Fire, midnight"},

N:{1:"Nemontemi",2:"Nemontemi",3:"Nemontemi",4:"Nemontemi",5:"Nemontemi"}

};


function toJDN(y,m,d){

const a = Math.floor((14-m)/12), yy = y+4800-a, mm = m+12*a-3;

return d + Math.floor((153*mm+2)/5) + 365*yy

+ Math.floor(yy/4) - Math.floor(yy/100) + Math.floor(yy/400) - 32045;

}


function convert(y,m,d){

const jdn = toJDN(y,m,d);

const since = jdn - EPOCH;

const n = ((since % 365) + 365) % 365;

const year = Math.floor(since/365) + 1;

if(n < 360){

const pos = Math.floor(n/20) + 1;

return {pos, day:(n%20)+1, year, n};

}

return {pos:"N", day:n-359, year, n};

}


function name(pos){

if(pos==="N") return "Nemontemi";

return VEINTENAS[pos-1][1];

}


let current = null;


function render(){

const grid = document.getElementById("grid");

grid.innerHTML = "";

for(let p=1;p<=18;p++){

const el = document.createElement("div");

el.className = "v" + (current.pos===p ? " current":"");

let days = "";

for(let d=1;d<=20;d++){

const isToday = (current.pos===p && current.day===d);

const isEv = EVENTS[p] && EVENTS[p][d];

days += `<div class="d${isEv?" ev":""}${isToday?" today":""}">${d}</div>`;

}

el.innerHTML = `<div class="pos">POSITION ${p}</div>

<div class="nm">${VEINTENAS[p-1][1]}</div>

<div class="days">${days}</div>`;

grid.appendChild(el);

}

const nem = document.createElement("div");

nem.className = "v nem" + (current.pos==="N" ? " current":"");

let nd = "";

for(let d=1;d<=5;d++){

const isToday = (current.pos==="N" && current.day===d);

nd += `<div class="d ev${isToday?" today":""}">${d}</div>`;

}

nem.innerHTML = `<div class="pos">TERMINAL</div><div class="nm">Nemontemi</div>

<div class="days">${nd}</div>`;

grid.appendChild(nem);


const box = document.getElementById("events");

let html = "";

const list = EVENTS[current.pos] || {};

const keys = Object.keys(list).map(Number).sort((a,b)=>a-b);

if(!keys.length){

html = `<div>No secure ordinalized event for this veintena <span>(month-level evidence only)</span></div>`;

} else {

keys.forEach(d=>{

html += `<div>${name(current.pos)} day ${d} — <span>${list[d]}</span></div>`;

});

}

box.innerHTML = html;

}


function show(y,m,d){

current = convert(y,m,d);

document.getElementById("todayName").textContent =

name(current.pos) + " day " + current.day;

const jdn = toJDN(y,m,d);

document.getElementById("todayDetail").textContent =

`${y}-${String(m).padStart(2,"0")}-${String(d).padStart(2,"0")} · JDN ${jdn} · `

+ `day ${current.n} of year · year ${current.year} of the count`;

render();

}


function setToday(){

const t = new Date();

show(t.getFullYear(), t.getMonth()+1, t.getDate());

document.getElementById("picker").value =

`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`;

}


document.getElementById("picker").addEventListener("change", e=>{

const [y,m,d] = e.target.value.split("-").map(Number);

if(y) show(y,m,d);

});


setToday();

</script>

</body>

</html>

 
 
 

Recent Posts

See All

Comments


© Copyright 2026 A.D. Philip S. Wathen Jr., All Autarchy Rights Reserved in Perpetuity without Reservation, Exception, Prejudice, or Ceasing.

bottom of page