/* NullMoth Systems, the redesign: black, dark purple, Times and Courier, a drifting starfield.
   No external fonts (the CSP has no font-src): Times New Roman, Courier New and Verdana ship everywhere.
   Cyan comes from the circuit traces on the logbook moth and means "it worked". */
:root{--bg:#000;--panel:#0b0613;--panel2:#150a24;--deep:#07030d;--line:#2a1447;--line2:#5a3a8a;--hi:#8b5cc8;--text:#e6ddf3;
--soft:#cfc3e4;--muted:#a898c2;--purple:#b98aff;--btn:#5b27a3;--btn2:#7c3fd0;--link:#c9a3ff;--cyan:#58e6ea;--err:#ff7092;
--serif:"Times New Roman",Times,"Liberation Serif","Nimbus Roman",serif;--mono:"Courier New",Courier,"Liberation Mono",monospace;
--sans:Verdana,Geneva,Tahoma,"DejaVu Sans",sans-serif;color-scheme:dark}
*{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{margin:0;min-height:100vh;position:relative;z-index:0;background:var(--bg);color:var(--text);font:18px/1.6 var(--sans)}
/* element rules apply only to the rewritten pages (body.nm); a wrapped old page keeps its own inside <main> */
:where(body.nm) :is(h1,h2,h3,p,figure,fieldset){margin:0}
:where(body.nm) fieldset{border:0;padding:0}
:where(body.nm) a{color:var(--link)}:where(body.nm) a:hover{color:#fff}
:where(body.nm) img{max-width:100%}
body.legacy main{font:18px/1.45 var(--serif);overflow-wrap:anywhere}
body.legacy main :is(code,a,pre,td){overflow-wrap:anywhere;word-break:break-word}
.nmtop a:hover,.nmfoot a:hover{background:none}
.tab:visited{color:var(--soft)}.tab.on:visited,.btn:visited,.nmbrand:visited{color:#fff}.soc:visited{color:var(--text)}.soc.coffee:visited{color:#000}
.util a,.footlinks a,.util a:visited,.footlinks a:visited{color:var(--link)}
.wrap{max-width:1160px;margin:0 auto;padding:0 24px}

/* the sky: three tiled layers that drift at different speeds and fade on different rhythms.
   Each layer travels exactly two tiles across and one down per loop, so the loop has no seam. */
.sky{position:fixed;inset:-620px;z-index:-1;pointer-events:none;will-change:transform,opacity}
.sky1{background-image:radial-gradient(1px 1px at 23px 41px,#cdb6ff 50%,transparent 51%),radial-gradient(1px 1px at 157px 12px,#fff 50%,transparent 51%),radial-gradient(1.5px 1.5px at 201px 187px,#d9c8ff 50%,transparent 51%);background-size:240px 240px;animation:drift1 130s linear infinite,twinkle 5s ease-in-out infinite}
.sky2{background-image:radial-gradient(1px 1px at 91px 133px,#8e6ad0 50%,transparent 51%),radial-gradient(1px 1px at 37px 97px,#fff 50%,transparent 51%),radial-gradient(1px 1px at 131px 21px,#b89cff 50%,transparent 51%);background-size:180px 180px;animation:drift2 185s linear infinite,twinkle 7.5s ease-in-out -3s infinite}
.sky3{background-image:radial-gradient(2px 2px at 61px 211px,#fff 50%,transparent 51%),radial-gradient(1.5px 1.5px at 251px 71px,#58e6ea 50%,transparent 51%),radial-gradient(1px 1px at 171px 143px,#cdb6ff 50%,transparent 51%);background-size:300px 300px;animation:drift3 250s linear infinite,twinkle 11s ease-in-out -6s infinite}
@keyframes drift1{to{transform:translate3d(-480px,240px,0)}}
@keyframes drift2{to{transform:translate3d(-360px,180px,0)}}
@keyframes drift3{to{transform:translate3d(-600px,300px,0)}}
@keyframes twinkle{0%,100%{opacity:1}50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){.sky{animation:none}}

/* header */
.nmtop{background:var(--bg);border-bottom:1px solid var(--line)}
.bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px 24px;padding-top:12px;padding-bottom:12px}
.nmbrand{display:flex;align-items:center;gap:12px;text-decoration:none;color:#fff;font:bold 22px/1 var(--serif);letter-spacing:.16em}
.nmbrand img{border:2px ridge var(--hi);display:block}
.tabs{display:flex;flex-wrap:wrap;gap:2px;flex:1 1 auto}
.tab{display:inline-flex;align-items:center;min-height:44px;padding:8px 14px;font-size:15px;color:var(--soft);text-decoration:none;border-bottom:2px solid transparent}
.tab:hover{color:#fff}
.tab.on{color:#fff;border-bottom-color:var(--cyan)}
.acts{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.soc{display:inline-flex;align-items:center;min-height:44px;padding:0 14px;font:bold 14px var(--sans);color:var(--text);text-decoration:none;border:1px solid var(--line2);background:var(--panel)}
.soc:hover{border-color:var(--cyan);color:#fff}
.soc.coffee{background:var(--cyan);color:#000;border-color:var(--cyan)}
.soc.coffee:hover{background:#fff;border-color:#fff;color:#000}
.lang{position:relative}
.lang summary{display:inline-flex;align-items:center;min-height:44px;padding:0 12px;font-size:14px;color:var(--soft);border:1px solid var(--line2);cursor:pointer;list-style:none}
.lang summary::-webkit-details-marker{display:none}
.lang summary:hover{border-color:var(--cyan);color:#fff}
.langs{position:absolute;right:0;top:100%;z-index:5;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px;min-width:300px;padding:8px;background:var(--panel2);border:1px solid var(--line2)}
.langs a{display:flex;align-items:center;min-height:44px;padding:0 10px;font-size:15px;text-decoration:none;color:var(--text)}
.langs a:hover{background:var(--btn)}
.langs a[aria-current]{color:var(--cyan)}
.strip{border-top:1px solid var(--line);background:var(--deep)}
.striprow{display:flex;flex-wrap:wrap;gap:4px 20px;align-items:center;justify-content:space-between;padding-top:6px;padding-bottom:6px}
/* a marquee, as on the old site: cut off with an ellipsis it read as broken. The text starts off the right edge
   (padding-left:100%) and travels its own full width; the negative delay puts it mid-screen on arrival. */
.nmticker{flex:1 1 320px;min-width:0;overflow:hidden;white-space:nowrap;font:13px/1.9 var(--mono);color:var(--purple)}
.nmticker span{display:inline-block;padding-left:100%;animation:nmscroll 32s linear -11s infinite}
@keyframes nmscroll{to{transform:translateX(-100%)}}
@media (prefers-reduced-motion:reduce){.nmticker{text-overflow:ellipsis}.nmticker span{display:inline;padding-left:0;animation:none}}
.util{display:flex;flex-wrap:wrap;gap:4px 18px;font-size:14px}

/* type and buttons */
:where(body.nm) h1{font:bold 76px/.98 var(--serif);color:#fff;letter-spacing:-.02em}
:where(body.nm) h2{font:bold 44px/1.05 var(--serif);color:#fff;letter-spacing:-.01em}
:where(body.nm) h3{font:bold 28px/1.15 var(--serif);color:#fff}
.h56{font-size:56px;line-height:1.02}
.h36{font-size:36px}
.eyebrow{font:13px var(--mono);color:var(--cyan);letter-spacing:.18em;text-transform:uppercase}
.lead{max-width:40rem;font-size:20px;color:var(--soft)}
.lead.left{font-size:18px}
.btn{display:inline-flex;align-items:center;min-height:48px;padding:0 24px;font:bold 15px var(--sans);color:#fff;text-decoration:none;background:var(--btn);border:2px outset var(--purple);cursor:pointer}
.btn:hover{background:var(--btn2);color:#fff}
.btn:active{border-style:inset}
.btn.ghost{background:transparent;color:var(--text);border:1px solid var(--line2);font-weight:normal}
.btn.ghost:hover{border-color:var(--cyan);color:#fff}
.btn.small{min-height:44px;padding:0 18px}
.chip{display:inline-flex;align-items:center;min-height:44px;padding:0 16px;font:14px var(--sans);color:var(--soft);background:var(--panel);border:1px solid #3b1f5f;border-radius:22px;cursor:pointer}
.chip:hover{color:#fff;border-color:var(--hi)}
.chip.on,.chip.check:has(input:checked){background:var(--text);color:#000;border-color:var(--text)}
.chip.check input{position:absolute;opacity:0;width:1px;height:1px}
.chip.check:focus-within,a:focus-visible,button:focus-visible,summary:focus-visible,input:focus,textarea:focus{outline:2px solid var(--cyan);outline-offset:2px}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.row{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
.row.center,.center{justify-content:center;text-align:center}
.row small,.count{font-size:14px;color:var(--muted)}
.count{font-family:var(--mono);color:var(--cyan);text-transform:uppercase}

/* layout */
.g2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}
.g3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.g4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
.g2.mid{align-items:center}
.g2.wide{gap:48px;align-items:start}
.stack{display:flex;flex-direction:column;gap:20px}
.hero{display:flex;flex-direction:column;align-items:center;text-align:center;gap:24px;padding-top:88px;padding-bottom:56px}
.hero h1{max-width:15ch}
.shots{width:100%;margin-top:24px;align-items:start;text-align:left}
.sec{display:flex;flex-direction:column;gap:28px;padding-top:56px;padding-bottom:24px}
.sec.center{align-items:center}
.sec.last{padding-bottom:88px}
.page{display:flex;flex-direction:column;gap:28px;padding-top:72px;padding-bottom:88px}
.band{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--deep)}
.band .g4{padding-top:36px;padding-bottom:36px}
.band b{display:block;font:bold 48px/1 var(--serif);color:var(--cyan)}
.band span{font-size:15px;color:var(--soft)}
.outlets{max-width:46rem;font:15px var(--mono);color:var(--muted)}

/* cards */
.card{display:flex;flex-direction:column;gap:12px;padding:24px;background:var(--panel);border:1px solid var(--line)}
.card p{font-size:16px;color:var(--soft)}
.card.split{flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:20px;padding:32px}
.card.split>div{flex:1 1 360px;display:flex;flex-direction:column;gap:8px}
.card.hot,.big.hot{border-color:var(--line2);background:var(--panel2)}
.card.ok{border-color:var(--cyan)}
.card.ok h2{color:var(--cyan)}
.crt{background:var(--panel2);border:1px solid #3b1f5f;border-radius:14px;padding:14px;box-shadow:0 0 80px rgba(124,63,208,.35)}
.shot{width:100%;height:auto;display:block;border-radius:6px}
.crop .shot{height:260px;object-fit:cover;object-position:top}
:where(body.nm) figcaption{padding-top:10px;font:13px var(--mono);color:var(--muted)}
.mini,.mach{align-items:center;text-align:center;gap:8px}
.mini b,.mach b{font:bold 24px var(--serif);color:#fff}
.mini span,.mach span{font-size:15px;color:var(--soft)}
.mach small{font:13px var(--mono);color:var(--muted)}
.mach q{font-size:15px;font-style:italic;color:var(--soft)}
.mach q:empty,.mach small:empty{display:none}
.mini em,.mach em{font:13px var(--mono);font-style:normal;color:var(--cyan);letter-spacing:.14em}
.big{display:flex;flex-direction:column;gap:10px;padding:28px 24px;text-decoration:none;color:var(--text);background:var(--panel);border:1px solid var(--line2)}
.big:hover{border-color:var(--cyan);background:var(--panel2);color:#fff}
.big b{font:bold 30px var(--serif);color:#fff}
.big.hot b,.big.hot{border-color:var(--cyan)}
.big.hot b{color:var(--cyan)}
.big span{font-size:16px}
.big code{font:14px var(--mono);color:var(--cyan)}

/* press */
.plist{display:flex;flex-direction:column;border-bottom:1px solid var(--line)}
.prow{display:flex;flex-wrap:wrap;gap:6px 24px;align-items:baseline;min-height:44px;padding:16px 8px;border-top:1px solid var(--line);text-decoration:none}
.prow:hover{background:var(--panel2)}
.prow:hover .ptitle{text-decoration:underline}
.outlet{flex:0 0 210px;font:14px var(--mono);color:var(--cyan);letter-spacing:.06em}
.pt{flex:1 1 360px;display:flex;flex-direction:column;gap:4px}
.ptitle{font:22px/1.3 var(--serif);color:#fff}
.pt small,.date,.go{font:13px var(--mono);color:var(--muted)}
.pt small:empty{display:none}
.go{color:var(--cyan);text-transform:uppercase}

/* contribute */
form.card{gap:20px}
:where(body.nm) :is(label,legend){display:block;font-size:14px;color:var(--soft)}
:where(body.nm) legend{padding:0;margin-bottom:8px}
:where(body.nm) :is(input:not([type=checkbox]),textarea){display:block;width:100%;margin-top:8px;min-height:48px;padding:12px 14px;font:16px var(--sans);color:var(--text);background:var(--deep);border:1px solid var(--line2)}
.err{color:var(--err);font-size:15px}
.err:empty{display:none}
.moth{width:100%;max-width:360px;height:auto;border:1px solid #3b1f5f}
#ref{font-family:var(--mono);color:#fff}

/* footer */
.nmfoot{border-top:1px solid var(--line);background:var(--bg)}
.footrow{display:flex;flex-wrap:wrap;gap:12px 24px;align-items:center;justify-content:space-between;padding-top:28px}
.counter{margin:0;font:14px var(--mono);color:var(--soft)}
.counter b{display:inline-block;margin:0 10px;padding:4px 6px 4px 12px;font-size:22px;letter-spacing:.3em;color:var(--cyan);background:var(--deep);border:2px inset var(--hi)}
.counter small{font:13px var(--sans);color:var(--muted)}
.nmbadges{margin:0;display:flex;flex-wrap:wrap;gap:8px}
.nmbadges span{padding:4px 8px;font:bold 12px var(--mono);color:var(--soft);border:2px outset var(--hi)}
.nmbadges .free{color:#000;background:var(--purple);border-color:var(--text)}
.footlinks{display:flex;flex-wrap:wrap;gap:8px 24px;padding-top:18px;padding-bottom:32px;font-size:14px;color:var(--muted)}
.footlinks i{font:italic 15px var(--serif)}

@media (max-width:900px){.g4{grid-template-columns:repeat(2,minmax(0,1fr))}.g3{grid-template-columns:minmax(0,1fr)}.langs{left:0;right:auto}}
@media (max-width:760px){.g2{grid-template-columns:minmax(0,1fr)}:where(body.nm) h1{font-size:44px}:where(body.nm) h2,.h56{font-size:32px}.wrap{padding-left:16px;padding-right:16px}.hero{padding-top:48px}.outlet{flex-basis:100%}}

/* ---- review pass, 10-11: what looked wrong on real screens ---- */
/* a short page (Donate, 404) left the footer floating mid-screen: the page is a column and <main> takes the slack */
body{display:flex;flex-direction:column}
main{flex:1 0 auto;width:100%}
/* old pages: same left edge as the header and footer, text on the sky like the new pages, no scanline overlay */
body.legacy::after{content:none}
/* the old column keeps its own width (everything inside was laid out for it) and starts at the header's left edge */
body.legacy main{width:auto;max-width:46rem;margin:0 auto 0 max(24px,calc((100% - 1160px)/2 + 24px));padding:2.2rem 0 3.5rem;background:transparent}
.lang .lbl{margin-right:.4em}
/* 142 machines were 14,000px of page on a desktop and 36,000px on a phone: smaller cards, more per row */
#machines{grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}
.mach{padding:16px 12px;gap:6px}
.mach svg{width:64px;height:47px}
.mach b{font-size:20px}
.mach span,.mach q{font-size:14px}
/* the two hero screenshots have different shapes: frame both at 4:3 from the top so the pair lines up */
.shots .shot{aspect-ratio:4/3;object-fit:cover;object-position:top}
@media (max-width:1000px){#machines{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:760px){
#machines{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.mach svg{display:none}
.mach{padding:14px 8px}
.mach b{font-size:17px}
.moth{display:none}
.page{padding-top:40px;padding-bottom:56px}
.sec{padding-top:40px}
body.legacy main{max-width:none;margin:0 16px;padding:1.4rem 0 2.5rem}
/* the header was 285px tall on a phone: one swipeable row of tabs, one row of links, no second Download button */
.bar{gap:4px 12px;padding-top:8px;padding-bottom:8px}
.tabs,.util{flex:1 1 100%;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;white-space:nowrap}
.tabs::-webkit-scrollbar,.util::-webkit-scrollbar{display:none}
.tab{flex:none;padding:8px 10px;font-size:14px}
.util a{flex:none}
.acts{flex:1 1 100%;gap:6px;position:relative}
.acts .btn.small,.lang .lbl{display:none}
.soc,.lang summary{padding:0 9px;font-size:12px}
.lang{position:static}
.langs{left:0;right:0;min-width:0}
.striprow{gap:2px 12px}
}
