|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | +<meta charset="utf-8"> |
| 5 | +<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> |
| 6 | +<meta name="theme-color" content="#0B1220"> |
| 7 | +<meta name="apple-mobile-web-app-capable" content="yes"> |
| 8 | +<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> |
| 9 | +<meta name="apple-mobile-web-app-title" content="Blog"> |
| 10 | +<title>RealMathModel — Blog</title> |
| 11 | + |
| 12 | +<!-- FontAwesome --> |
| 13 | +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer"> |
| 14 | +<link rel="apple-touch-icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Crect width='180' height='180' rx='38' fill='%230B1220'/%3E%3Ctext x='26' y='118' font-family='monospace' font-size='62' fill='%23E0B23C'%3E%26gt;_%3C/text%3E%3C/svg%3E"> |
| 15 | +<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Crect width='32' height='32' rx='7' fill='%230B1220'/%3E%3Ctext x='4' y='23' font-family='monospace' font-size='18' fill='%23E0B23C'%3E%26gt;_%3C/text%3E%3C/svg%3E"> |
| 16 | + |
| 17 | +<!-- MathJax --> |
| 18 | +<script> |
| 19 | +window.MathJax = { |
| 20 | + tex: { inlineMath: [['$','$']], displayMath: [['$$','$$']], processEscapes: true }, |
| 21 | + options: { skipHtmlTags: ['script','noscript','style','textarea','pre'] }, |
| 22 | + startup: { typeset: false } |
| 23 | +}; |
| 24 | +</script> |
| 25 | +<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" async></script> |
| 26 | + |
| 27 | +<style> |
| 28 | +:root{ |
| 29 | + --bg:#0B1220; --bg2:#0E1726; --panel:#141E33; --panel2:#192541; |
| 30 | + --line:#26334E; --line2:#33425f; |
| 31 | + --ink:#E7ECF7; --muted:#8A97AD; --faint:#5C6981; |
| 32 | + --amber:#E7B53D; --good:#4FC08A; --bad:#EB6A4E; |
| 33 | + --blue:#6F9BE8; --purple:#B79BE0; --orange:#E08A5B; --teal:#4FB89A; --green:#4FC08A; |
| 34 | + --mono:ui-monospace,"SF Mono","JetBrains Mono",Menlo,Consolas,"Liberation Mono",monospace; |
| 35 | + --sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; |
| 36 | +} |
| 37 | +*{box-sizing:border-box} html,body{margin:0;padding:0} |
| 38 | +body{background:var(--bg); color:var(--ink); font-family:var(--sans); |
| 39 | + -webkit-font-smoothing:antialiased; line-height:1.5; min-height:100vh; min-height:100dvh;} |
| 40 | +#mathbg{position:fixed; inset:0; width:100%; height:100%; z-index:0; pointer-events:none; display:block; opacity:.9;} |
| 41 | +.bgveil{position:fixed; inset:0; z-index:1; pointer-events:none; |
| 42 | + background: |
| 43 | + radial-gradient(1100px 620px at 72% -8%, rgba(231,181,61,.07), transparent 60%), |
| 44 | + radial-gradient(900px 520px at -8% 112%, rgba(79,184,154,.07), transparent 55%), |
| 45 | + radial-gradient(700px 700px at 50% 45%, rgba(11,18,32,.55), rgba(11,18,32,.0) 70%);} |
| 46 | +.wrap{position:relative; z-index:2; max-width:760px; margin:0 auto; |
| 47 | + padding:0 16px env(safe-area-inset-bottom) 16px; padding-top:calc(14px + env(safe-area-inset-top));} |
| 48 | +.term{position:relative; border:1px solid var(--line); border-radius:14px; overflow:hidden; |
| 49 | + background:linear-gradient(180deg, rgba(20,30,51,.82), rgba(14,23,38,.9)); |
| 50 | + -webkit-backdrop-filter:blur(9px) saturate(115%); backdrop-filter:blur(9px) saturate(115%); |
| 51 | + box-shadow:0 30px 70px -30px rgba(0,0,0,.8), 0 0 0 1px rgba(255,255,255,.02) inset, 0 1px 0 rgba(255,255,255,.04) inset;} |
| 52 | +.termbar{display:flex; align-items:center; gap:8px; padding:11px 14px; |
| 53 | + background:rgba(255,255,255,.025); border-bottom:1px solid var(--line);} |
| 54 | +.dot{width:11px;height:11px;border-radius:50%}.dot.r{background:#e8654b}.dot.y{background:#e7b53d}.dot.g{background:#4fc08a} |
| 55 | +.termtitle{font-family:var(--mono); font-size:12px; color:var(--faint); margin-left:8px; letter-spacing:.02em; |
| 56 | + display:flex; align-items:center; gap:7px} |
| 57 | +.termbody{padding:18px 18px 22px} |
| 58 | +@media(min-width:560px){.termbody{padding:26px 28px 30px}} |
| 59 | + |
| 60 | +.back{display:inline-flex; align-items:center; gap:7px; font-family:var(--mono); font-size:12.5px; |
| 61 | + color:var(--muted); text-decoration:none; margin-bottom:12px; transition:color .15s} |
| 62 | +.back:hover{color:var(--amber)} .back i{font-size:11px} |
| 63 | +.crumb{font-family:var(--mono); font-size:11.5px; color:var(--faint); margin:0 0 10px; word-break:break-word} |
| 64 | +.crumb a{color:var(--muted); text-decoration:none} .crumb a:hover{color:var(--amber)} |
| 65 | +.crumb .sep{color:var(--line2); margin:0 6px} |
| 66 | +.prompt{font-family:var(--mono); font-size:13px; color:var(--muted); margin:0 0 6px} |
| 67 | +.prompt .u{color:var(--good)} .prompt .p{color:var(--blue)} .prompt .d{color:var(--amber)} |
| 68 | +.cursor{display:inline-block;width:8px;height:15px;background:var(--amber);vertical-align:-2px;margin-left:3px;animation:blink 1.1s steps(1) infinite} |
| 69 | +@keyframes blink{50%{opacity:0}} |
| 70 | + |
| 71 | +h1{font-family:var(--mono); font-weight:700; font-size:27px; letter-spacing:-.01em; margin:6px 0 2px; line-height:1.12} |
| 72 | +@media(min-width:560px){h1{font-size:32px}} |
| 73 | +h1 .ac{color:var(--amber)} |
| 74 | +.sub{color:var(--muted); font-size:14px; margin:0 0 16px} |
| 75 | +.label{font-family:var(--mono); font-size:11px; letter-spacing:.16em; text-transform:uppercase; |
| 76 | + color:var(--faint); margin:18px 0 10px; display:flex; align-items:center; gap:9px} |
| 77 | +.label::before{content:""; width:16px; height:1px; background:var(--line2)} |
| 78 | + |
| 79 | +.search{display:flex; align-items:center; gap:10px; background:var(--bg2); border:1px solid var(--line); |
| 80 | + border-radius:10px; padding:11px 13px; margin:2px 0 4px; transition:border-color .15s, box-shadow .15s} |
| 81 | +.search:focus-within{border-color:var(--line2); box-shadow:0 0 0 3px rgba(231,181,61,.08)} |
| 82 | +.search i{color:var(--amber); font-size:13px} |
| 83 | +.search input{flex:1; background:none; border:none; outline:none; color:var(--ink); font-family:var(--mono); font-size:13px} |
| 84 | +.search input::placeholder{color:var(--faint)} |
| 85 | + |
| 86 | +.grid{display:grid; grid-template-columns:1fr; gap:10px; margin-top:4px} |
| 87 | +.card{display:flex; align-items:center; gap:13px; padding:14px; cursor:pointer; |
| 88 | + background:var(--panel); border:1px solid var(--line); border-radius:12px; |
| 89 | + text-decoration:none; color:inherit; transition:border-color .15s, background .15s, transform .12s, box-shadow .15s} |
| 90 | +.card:hover{border-color:var(--line2); background:linear-gradient(var(--panel),var(--panel2)); |
| 91 | + box-shadow:0 14px 30px -22px rgba(0,0,0,.9)} .card:active{transform:translateY(1px)} |
| 92 | +.ic{flex:0 0 auto; display:grid; place-items:center; border:1px solid transparent; |
| 93 | + width:42px;height:42px;border-radius:11px; font-size:17px} |
| 94 | +.ic.amber{background:rgba(231,181,61,.16); color:var(--amber); border-color:rgba(231,181,61,.3)} |
| 95 | +.ic.blue{background:rgba(111,155,232,.16); color:var(--blue); border-color:rgba(111,155,232,.3)} |
| 96 | +.ic.teal{background:rgba(79,184,154,.16); color:var(--teal); border-color:rgba(79,184,154,.3)} |
| 97 | +.ic.purple{background:rgba(183,155,224,.16); color:var(--purple); border-color:rgba(183,155,224,.3)} |
| 98 | +.cbody{flex:1 1 auto; min-width:0} |
| 99 | +.ctitle{font-size:14.5px; color:var(--ink); font-weight:600; display:flex; align-items:center; gap:8px} |
| 100 | +.cblurb{font-size:12.5px; color:var(--muted); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap} |
| 101 | +.cmeta{font-family:var(--mono); font-size:11px; color:var(--faint); flex:0 0 auto; text-align:right} |
| 102 | +.arrow{color:var(--faint); font-family:var(--mono); font-size:15px; flex:0 0 auto; transition:color .15s, transform .15s} |
| 103 | +.card:hover .arrow{color:var(--amber); transform:translateX(2px)} |
| 104 | + |
| 105 | +/* ---- post body ---- */ |
| 106 | +.post{font-family:var(--sans); font-size:15.5px; line-height:1.75; color:var(--ink); margin-top:6px} |
| 107 | +.post p{margin:0 0 18px} |
| 108 | +.post em{font-style:italic; color:var(--ink)} |
| 109 | +.post strong{font-weight:700; color:#fff} |
| 110 | +.post a{color:var(--amber); text-decoration:none; border-bottom:1px solid rgba(231,181,61,.35)} |
| 111 | +.post a:hover{border-bottom-color:var(--amber)} |
| 112 | +.post mjx-container[display="true"]{margin:22px 0 !important; overflow-x:auto; overflow-y:hidden} |
| 113 | + |
| 114 | +.empty,.miss{color:var(--faint); font-family:var(--mono); font-size:13.5px; padding:16px 2px} .miss a{color:var(--amber)} |
| 115 | +.loading{display:flex; align-items:center; gap:10px; color:var(--muted); font-family:var(--mono); font-size:13px; padding:26px 2px} |
| 116 | +.loading i{color:var(--amber)} |
| 117 | +.errbox{border:1px solid rgba(235,106,78,.4); background:rgba(235,106,78,.08); border-radius:11px; |
| 118 | + padding:14px 16px; margin-top:6px; font-size:13px; color:var(--ink)} |
| 119 | +.errbox b{color:var(--bad)} .errbox code{font-family:var(--mono); color:var(--amber); font-size:12px; |
| 120 | + background:rgba(231,181,61,.1); padding:1px 6px; border-radius:5px} |
| 121 | +.note{color:var(--faint); font-size:12.5px; line-height:1.6; margin:20px 2px 4px; border-top:1px solid var(--line); padding-top:14px} |
| 122 | +.note b{color:var(--muted); font-weight:600} .note code{font-family:var(--mono); color:var(--amber); font-size:12px} |
| 123 | +.foot{font-family:var(--mono); font-size:11px; color:var(--faint); text-align:center; margin:18px 0 6px; |
| 124 | + display:flex; align-items:center; justify-content:center; gap:7px} |
| 125 | +:focus-visible{outline:2px solid var(--amber); outline-offset:2px} |
| 126 | +@media (prefers-reduced-motion: reduce){ *{animation-duration:.001s !important; transition-duration:.05s !important} } |
| 127 | +</style> |
| 128 | +</head> |
| 129 | +<body> |
| 130 | +<canvas id="mathbg" aria-hidden="true"></canvas> |
| 131 | +<div class="bgveil" aria-hidden="true"></div> |
| 132 | + |
| 133 | +<div class="wrap"> |
| 134 | + <div class="term"> |
| 135 | + <div class="termbar"> |
| 136 | + <span class="dot r"></span><span class="dot y"></span><span class="dot g"></span> |
| 137 | + <span class="termtitle" id="ttl"><i class="fa-solid fa-terminal"></i> realmathmodel — blog — 80×24</span> |
| 138 | + </div> |
| 139 | + <div class="termbody" id="app"> |
| 140 | + <div class="loading"><i class="fa-solid fa-circle-notch fa-spin"></i> reading ./blogs …</div> |
| 141 | + </div> |
| 142 | + </div> |
| 143 | +</div> |
| 144 | + |
| 145 | +<script> |
| 146 | +/* ============================================================================ |
| 147 | + realmathmodel — blog |
| 148 | + Posts live in ./blogs/1, ./blogs/2, ... (plain text, no extension) |
| 149 | + Each post: first non-empty line = TITLE, rest = body. |
| 150 | + Body supports: $inline$ $$display$$ \href{u}{t} \bf{...} \it{...} |
| 151 | + Routing: # -> index (auto-enumerates posts) |
| 152 | + #2 -> post number 2 |
| 153 | + ========================================================================== */ |
| 154 | +var app=document.getElementById('app'), ttl=document.getElementById('ttl'); |
| 155 | +var BLOG_DIR='blogs', MAX_SCAN=500; |
| 156 | +var owner='hasan', host='iug'; |
| 157 | +var ACCENTS=['amber','blue','teal','purple']; |
| 158 | + |
| 159 | +/* ---------- parser ---------- */ |
| 160 | +function esc(s){return String(s).replace(/[&<>"]/g,function(c){return({'&':'&','<':'<','>':'>','"':'"'}[c]);});} |
| 161 | +function splitTitle(raw){ |
| 162 | + var lines=raw.replace(/\r\n?/g,'\n').split('\n'), i=0; |
| 163 | + while(i<lines.length && lines[i].trim()==='') i++; |
| 164 | + var title=(lines[i]||'Untitled').trim(); |
| 165 | + var body=lines.slice(i+1).join('\n').replace(/^\n+/,''); |
| 166 | + return {title:title, body:body}; |
| 167 | +} |
| 168 | +function renderBody(body){ |
| 169 | + var math=[]; |
| 170 | + function stash(s){ math.push(s); return ' |
0 commit comments