Input
{
"patchText": "*** Begin Patch\n*** Add File: var/www/n50.camp/index.html\n+<!doctype html>\n+<html lang=\"en\">\n+<head>\n+ <meta charset=\"utf-8\">\n+ <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n+ <meta name=\"description\" content=\"N50.CAMP is a small hackerish camping event near 50 north: tents, packets, solder smoke, kettle water, and field notes.\">\n+ <title>N50.CAMP - field packets + damp socks</title>\n+ <link rel=\"stylesheet\" href=\"/style.css\">\n+ <script src=\"/wires.js\" defer></script>\n+</head>\n+<body>\n+ <!-- If you are viewing source: yes, there is a table in the header. It worked, so it stayed. -->\n+ <div class=\"sky-noise\" aria-hidden=\"true\"></div>\n+\n+ <header class=\"top-shed\">\n+ <table class=\"mast\" role=\"presentation\">\n+ <tr>\n+ <td class=\"campfire\" aria-hidden=\"true\">\n+<pre>\n+ )\n+ ( ( )\n+ ) ) (\n+ /\\ /\\ /\\\n+ /__\\/__\\/__\\\n+ n 5 0\n+</pre>\n+ </td>\n+ <td class=\"title-cell\">\n+ <p class=\"stamp\">unofficial official webpage, hand pushed to the server</p>\n+ <h1>N50.CAMP</h1>\n+ <marquee behavior=\"alternate\" scrollamount=\"3\">tiny camp for hackers, radio goblins, tarp philosophers, and people who label cables with masking tape</marquee>\n+ </td>\n+ </tr>\n+ </table>\n+ </header>\n+\n+ <nav class=\"rope-nav\" aria-label=\"Page sections\">\n+ <a href=\"#what\">what</a>\n+ <a href=\"#when\">when-ish</a>\n+ <a href=\"#bring\">bring</a>\n+ <a href=\"#grid\">field grid</a>\n+ <a href=\"#hallmarks\">webpage bingo</a>\n+ <a href=\"/guestbook.txt\">guestbook.txt</a>\n+ </nav>\n+\n+ <main class=\"binder\">\n+ <aside class=\"warning-note\">\n+ <strong class=\"blink\">UNDER CONSTRUCTION</strong>\n+ <span>last updated: 2026-06-08, after rain, before dinner</span>\n+ </aside>\n+\n+ <section id=\"what\" class=\"card intro-card\">\n+ <h2>What Is This?</h2>\n+ <p>\n+ N50.CAMP is a small camping event somewhere around the 50 north line: a weekend of tents, field kitchens,\n+ small networks, radio mistakes, battery math, soldering on a folding table, and conversations that start with\n+ \"this should only take five minutes.\"\n+ </p>\n+ <p>\n+ It is not a conference. There is no keynote, no velvet rope, no growth strategy, and no hero button. Think\n+ campfire with a switch, a kettle, and one person trying to make DNS work from a chair slowly sinking into mud.\n+ </p>\n+ <div class=\"status-board\" aria-label=\"Camp status board\">\n+ <div><b>mood:</b> damp optimistic</div>\n+ <div><b>power:</b> negotiated</div>\n+ <div><b>wifi:</b> probably named after a mushroom</div>\n+ <div><b>weather:</b> check your own sky</div>\n+ </div>\n+ </section>\n+\n+ <section id=\"when\" class=\"card crooked\">\n+ <h2>When-ish / Where-ish</h2>\n+ <p>\n+ The exact date and field coordinates are shared with confirmed campers. This is partly because fields have\n+ owners, partly because indexing everything makes places weird, and partly because the planning pad currently\n+ contains three arrows and the word \"beans\".\n+ </p>\n+ <table class=\"schedule\">\n+ <caption>not a program, just a scratch table</caption>\n+ <tr>\n+ <th>time</th>\n+ <th>thing</th>\n+ <th>confidence</th>\n+ </tr>\n+ <tr>\n+ <td>Friday dusk</td>\n+ <td>arrive, stake tents, argue about antenna placement</td>\n+ <td>medium</td>\n+ </tr>\n+ <tr>\n+ <td>Saturday</td>\n+ <td>workshops if somebody writes them on cardboard</td>\n+ <td>excellent</td>\n+ </tr>\n+ <tr>\n+ <td>Saturday night</td>\n+ <td>fire, packets, stories, stubborn LED repairs</td>\n+ <td>high</td>\n+ </tr>\n+ <tr>\n+ <td>Sunday</td>\n+ <td>leave no trace, find lost tent pegs, promise better docs</td>\n+ <td>painfully real</td>\n+ </tr>\n+ </table>\n+ </section>\n+\n+ <section id=\"bring\" class=\"card gear-list\">\n+ <h2>Bring The Boring Things</h2>\n+ <ul>\n+ <li>tent, sleeping bag, ground sheet, actual warm clothes</li>\n+ <li>cup, spoon, water bottle, headlamp, towel you will forget exists</li>\n+ <li>extension cable if you need power, labeled so it can return home</li>\n+ <li>projects that can survive dust, drizzle, and people asking questions</li>\n+ <li>trash bag, earplugs, medication, and a plan for your own food</li>\n+ <li>curiosity, patience, and a tolerance for DHCP folklore</li>\n+ </ul>\n+ <p class=\"tiny-rant\">Do not bring: giant bluetooth speakers, glass in the field, or a drone that \"just needs one test flight\" over tents.</p>\n+ </section>\n+\n+ <section id=\"grid\" class=\"card map-card\">\n+ <h2>Unhelpful Field Map</h2>\n+ <pre class=\"ascii-map\" aria-label=\"ASCII map of imaginary campsite\">\n+ north-ish\n+ ^\n+ |\n+ tree line| [quiet tents]\n+ -----------+---------------------------\n+ [radio tarp] x = kettle\n+ \\ o = suspicious cable coil\n+ \\__ o\n+ \\____ [hack table]\n+ \\____ x fire bowl\n+ \\____ mud that looks shallow\n+\n+ if you find the creek, you went too far or became the network uplink\n+ </pre>\n+ <p id=\"field-note\" class=\"field-note\">field note loading from a tiny script...</p>\n+ </section>\n+\n+ <section class=\"card join-card\">\n+ <h2>How To Get Involved</h2>\n+ <p>\n+ If you know the humans organizing it, ask them directly. If you only found this page by typing a short domain\n+ into a browser at 1:13 in the morning, that also counts as a sign. Send a plain message with what you want to\n+ build, cook, fix, teach, or quietly observe.\n+ </p>\n+ <p class=\"contact-box\">\n+ contact route: <a href=\"mailto:camp@n50.camp?subject=n50%20camp%20question\">camp@n50.camp</a>\n+ <br>\n+ backup route: pass a note to the person holding the crimp tool\n+ </p>\n+ </section>\n+\n+ <section id=\"hallmarks\" class=\"card hallmarks\">\n+ <h2>10 Human Amateur Website Hallmarks Deliberately Preserved</h2>\n+ <ol>\n+ <li>Header layout uses a table because it lined up first try.</li>\n+ <li>There is a marquee even though everybody knows better.</li>\n+ <li>The background is tiled-ish and slightly too busy.</li>\n+ <li>Last-updated text is visible and weirdly specific.</li>\n+ <li>Visitor counter exists, but admits it is local and silly.</li>\n+ <li>Guestbook is a text file because databases attract chores.</li>\n+ <li>Fonts disagree in public.</li>\n+ <li>ASCII art is doing the work an image would normally do.</li>\n+ <li>One section is rotated by one degree for no strategic reason.</li>\n+ <li>There is a fake webring badge at the bottom, as tradition requires.</li>\n+ </ol>\n+ </section>\n+ </main>\n+\n+ <footer class=\"footer-hole\">\n+ <p>\n+ visitor number <span id=\"visitor-count\">000050</span>\n+ / best viewed from a camp chair / no cookies except the edible kind\n+ </p>\n+ <p class=\"webring\">\n+ << <a href=\"#what\">previous tarp</a> | N50 damp-web ring | <a href=\"#grid\">next tarp</a> >>\n+ </p>\n+ </footer>\n+</body>\n+</html>\n*** Add File: var/www/n50.camp/style.css\n+:root {\n+ color-scheme: dark;\n+ --canvas: #10160f;\n+ --paper: #f0e7c8;\n+ --ink: #14200f;\n+ --green: #8fd14f;\n+ --orange: #ff9b2f;\n+ --blue: #7ec8ff;\n+ --pink: #ff77bd;\n+}\n+\n+* {\n+ box-sizing: border-box;\n+}\n+\n+html {\n+ scroll-behavior: smooth;\n+}\n+\n+body {\n+ margin: 0;\n+ min-height: 100vh;\n+ color: var(--paper);\n+ font-family: \"Courier New\", Courier, monospace;\n+ background:\n+ repeating-linear-gradient(45deg, rgba(143, 209, 79, 0.08) 0 8px, transparent 8px 16px),\n+ radial-gradient(circle at 18% 20%, rgba(255, 155, 47, 0.14), transparent 28%),\n+ linear-gradient(130deg, #111c10, #080b07 65%, #1d160b);\n+ cursor: crosshair;\n+}\n+\n+a {\n+ color: #fff27a;\n+ text-decoration: underline wavy rgba(255, 242, 122, 0.65);\n+}\n+\n+a:visited {\n+ color: #d5a9ff;\n+}\n+\n+.sky-noise {\n+ position: fixed;\n+ inset: 0;\n+ pointer-events: none;\n+ opacity: 0.24;\n+ background-image: repeating-radial-gradient(circle at 0 0, transparent 0 5px, rgba(255,255,255,0.05) 6px 7px);\n+ mix-blend-mode: screen;\n+}\n+\n+.top-shed {\n+ width: min(980px, calc(100% - 20px));\n+ margin: 18px auto 6px;\n+ border: 4px double var(--green);\n+ background: #182313;\n+ box-shadow: 12px 12px 0 #000;\n+}\n+\n+.mast {\n+ width: 100%;\n+ border-collapse: collapse;\n+}\n+\n+.mast td {\n+ border: 2px dotted rgba(143, 209, 79, 0.55);\n+ vertical-align: middle;\n+ padding: 10px;\n+}\n+\n+.campfire {\n+ width: 185px;\n+ color: var(--orange);\n+ text-shadow: 0 0 8px rgba(255, 155, 47, 0.7);\n+}\n+\n+.campfire pre {\n+ margin: 0;\n+ font-size: 15px;\n+ line-height: 1.02;\n+}\n+\n+.stamp {\n+ margin: 0 0 4px;\n+ color: var(--blue);\n+ font-size: 13px;\n+}\n+\n+h1 {\n+ margin: 0;\n+ color: var(--paper);\n+ font-family: Georgia, \"Times New Roman\", serif;\n+ font-size: clamp(44px, 10vw, 96px);\n+ letter-spacing: -0.08em;\n+ text-shadow: 4px 4px 0 #4b2c0b, -2px 0 0 #315c21;\n+}\n+\n+marquee {\n+ display: block;\n+ margin-top: 5px;\n+ padding: 4px;\n+ color: #160a00;\n+ background: #f3c742;\n+ font-weight: bold;\n+}\n+\n+.rope-nav {\n+ width: min(980px, calc(100% - 20px));\n+ margin: 12px auto;\n+ padding: 8px;\n+ border: 2px dashed #c4a15b;\n+ background: rgba(0, 0, 0, 0.42);\n+ text-align: center;\n+}\n+\n+.rope-nav a {\n+ display: inline-block;\n+ margin: 4px 7px;\n+}\n+\n+.binder {\n+ width: min(980px, calc(100% - 20px));\n+ margin: 0 auto 30px;\n+}\n+\n+.warning-note {\n+ display: flex;\n+ flex-wrap: wrap;\n+ gap: 12px;\n+ align-items: center;\n+ justify-content: space-between;\n+ margin: 14px 0;\n+ padding: 8px 10px;\n+ color: #220400;\n+ background: #ffb6cf;\n+ border: 3px ridge #ff77bd;\n+ font-family: \"Comic Sans MS\", \"Comic Sans\", cursive;\n+}\n+\n+.blink {\n+ animation: blink 0.9s steps(2, start) infinite;\n+}\n+\n+@keyframes blink {\n+ 50% { visibility: hidden; }\n+}\n+\n+.card {\n+ margin: 20px 0;\n+ padding: 16px;\n+ color: var(--ink);\n+ background:\n+ linear-gradient(90deg, rgba(255,255,255,0.46), transparent 52%),\n+ var(--paper);\n+ border: 3px solid #24190b;\n+ box-shadow: 8px 8px 0 rgba(0,0,0,0.62);\n+}\n+\n+.card h2 {\n+ display: inline-block;\n+ margin: 0 0 12px;\n+ padding: 2px 6px;\n+ color: #fff7d1;\n+ background: #29451f;\n+ font-family: Georgia, \"Times New Roman\", serif;\n+ letter-spacing: 0.02em;\n+}\n+\n+.intro-card {\n+ border-left-width: 12px;\n+}\n+\n+.crooked {\n+ transform: rotate(-1deg);\n+ transform-origin: 42% 50%;\n+}\n+\n+.status-board {\n+ display: grid;\n+ grid-template-columns: repeat(2, minmax(0, 1fr));\n+ gap: 7px;\n+ margin-top: 12px;\n+}\n+\n+.status-board div,\n+.contact-box {\n+ padding: 8px;\n+ background: #d7e9b1;\n+ border: 2px inset #78935c;\n+}\n+\n+.schedule {\n+ width: 100%;\n+ border-collapse: collapse;\n+ background: #fff4c9;\n+}\n+\n+.schedule caption {\n+ caption-side: top;\n+ padding: 0 0 5px;\n+ font-style: italic;\n+ text-align: left;\n+}\n+\n+.schedule th,\n+.schedule td {\n+ border: 2px solid #4b3210;\n+ padding: 7px;\n+ text-align: left;\n+}\n+\n+.schedule th {\n+ background: #ffdc73;\n+}\n+\n+.gear-list ul {\n+ columns: 2;\n+ column-gap: 34px;\n+}\n+\n+.gear-list li {\n+ margin: 0 0 7px;\n+ break-inside: avoid;\n+}\n+\n+.tiny-rant {\n+ margin-bottom: 0;\n+ padding: 7px;\n+ color: #3c0813;\n+ background: #ffd4df;\n+ border: 1px dashed #a23b58;\n+}\n+\n+.map-card {\n+ color: #d9ffd1;\n+ background: #0b1309;\n+ border-color: #8fd14f;\n+}\n+\n+.map-card h2 {\n+ color: #111c10;\n+ background: var(--green);\n+}\n+\n+.ascii-map {\n+ overflow: auto;\n+ padding: 12px;\n+ color: #9eff72;\n+ background: #020402;\n+ border: 2px solid #315c21;\n+ font-size: 14px;\n+}\n+\n+.field-note {\n+ min-height: 1.4em;\n+ color: #fff27a;\n+}\n+\n+.join-card {\n+ background-color: #e6d4ff;\n+}\n+\n+.hallmarks ol {\n+ margin-bottom: 0;\n+}\n+\n+.hallmarks li {\n+ margin: 0 0 6px;\n+}\n+\n+.footer-hole {\n+ width: min(980px, calc(100% - 20px));\n+ margin: 0 auto 30px;\n+ padding: 10px;\n+ color: #d6ffd0;\n+ background: #050805;\n+ border: 2px groove #8fd14f;\n+ text-align: center;\n+ font-size: 14px;\n+}\n+\n+.webring {\n+ color: #ffcf73;\n+}\n+\n+@media (max-width: 650px) {\n+ .mast,\n+ .mast tbody,\n+ .mast tr,\n+ .mast td {\n+ display: block;\n+ width: 100%;\n+ }\n+\n+ .campfire {\n+ width: auto;\n+ }\n+\n+ .crooked {\n+ transform: none;\n+ }\n+\n+ .status-board {\n+ grid-template-columns: 1fr;\n+ }\n+\n+ .gear-list ul {\n+ columns: 1;\n+ }\n+}\n*** Add File: var/www/n50.camp/wires.js\n+(function () {\n+ var notes = [\n+ \"field note: somebody packed three serial adapters and zero sunscreen.\",\n+ \"field note: the kettle is infrastructure; treat it accordingly.\",\n+ \"field note: packet loss improves when the antenna stops touching wet leaves.\",\n+ \"field note: a tarp, two poles, and optimism is legally a hackerspace.\",\n+ \"field note: the quiet tent is not a myth, just badly signposted.\"\n+ ];\n+\n+ var note = document.getElementById(\"field-note\");\n+ if (note) {\n+ note.textContent = notes[Math.floor(Math.random() * notes.length)];\n+ }\n+\n+ var counter = document.getElementById(\"visitor-count\");\n+ if (counter) {\n+ var key = \"n50-local-visits\";\n+ var visits = parseInt(localStorage.getItem(key) || \"0\", 10) + 1;\n+ localStorage.setItem(key, String(visits));\n+ counter.textContent = String(50 + visits).padStart(6, \"0\") + \" (local)\",\n+ counter.title = \"This is not analytics. It only counts visits in this browser.\";\n+ }\n+}());\n*** Add File: var/www/n50.camp/guestbook.txt\n+N50.CAMP GUESTBOOK\n+==================\n+\n+This is a static text file because a real guestbook needs moderation, backups,\n+spam handling, and another person saying \"we should containerize it\".\n+\n+Entries so far:\n+\n+2026-06-08 server: page exists now. bring tent pegs.\n+2026-06-08 kettle committee: please stop storing crimp ends in the mug box.\n+\n+To be added here, send a small note to camp@n50.camp or hand somebody a paper\n+scrap at the field. Bonus points for weather reports, antenna drawings, and\n+recipes that can be made in one dented pot.\n*** Add File: var/www/n50.camp/robots.txt\n+User-agent: *\n+Allow: /\n+\n+# If you are an indexer: please be gentle. The field is small and the mud is shared.\n*** End Patch"
}